本文整理汇总了C++中BList::ItemAt方法的典型用法代码示例。如果您正苦于以下问题:C++ BList::ItemAt方法的具体用法?C++ BList::ItemAt怎么用?C++ BList::ItemAt使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BList
的用法示例。
在下文中一共展示了BList::ItemAt方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: BString
void
TBarView::ChangeState(int32 state, bool vertical, bool left, bool top)
{
bool vertSwap = (fVertical != vertical);
bool leftSwap = (fLeft != left);
fState = state;
fVertical = vertical;
fLeft = left;
fTop = top;
BRect screenFrame = (BScreen(Window())).Frame();
PlaceBeMenu();
PlaceTray(vertSwap, leftSwap, screenFrame);
// We need to keep track of what apps are expanded.
BList expandedItems;
BString* signature = NULL;
if (fVertical && Expando()
&& static_cast<TBarApp*>(be_app)->Settings()->superExpando) {
// Get a list of the signatures of expanded apps. Can't use
// team_id because there can be more than one team per application
if (fVertical && Expando() && vertical && fExpando) {
for (int index = 0; index < fExpando->CountItems(); index++) {
TTeamMenuItem* item
= dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(index));
if (item != NULL && item->IsExpanded()) {
signature = new BString(item->Signature());
expandedItems.AddItem((void*)signature);
}
}
}
}
PlaceApplicationBar(screenFrame);
SizeWindow(screenFrame);
PositionWindow(screenFrame);
Window()->UpdateIfNeeded();
// Re-expand those apps.
if (expandedItems.CountItems() > 0) {
for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) {
signature = static_cast<BString*>(expandedItems.ItemAt(sigIndex));
if (signature == NULL)
continue;
// Start at the 'bottom' of the list working up.
// Prevents being thrown off by expanding items.
for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) {
TTeamMenuItem* item
= dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(teamIndex));
if (item != NULL && !signature->Compare(item->Signature())) {
item->ToggleExpandState(false);
break;
}
}
}
// Clean up expanded signature list.
while (!expandedItems.IsEmpty()) {
delete static_cast<BString*>(expandedItems.RemoveItem((int32)0));
}
fExpando->SizeWindow();
}
Invalidate();
}
示例2: MessageReceived
void PeepsWindow::MessageReceived(BMessage *msg)
{
switch(msg->what)
{
case B_ABOUT_REQUESTED:
{
be_app->PostMessage(msg);
break;
}
case M_RUN_TOOL:
{
BString sig;
if(msg->FindString("signature",&sig)==B_OK)
{
if(strcmp(sig.String(),"application/x-vnd.wgp-PeopleMover")==0)
{
be_roster->Launch(sig.String());
break;
}
// Get the filename for the currently-selected person
int32 selection=fPeopleList->CurrentSelection();
if(selection<0)
break;
PeepsListItem *peepsitem=(PeepsListItem*)fPeopleList->ItemAt(selection);
if(!peepsitem || peepsitem->IsGroup())
break;
PersonItem *personitem=(PersonItem*)peepsitem;
PersonData *persondata=personitem->GetData();
if(!persondata)
break;
entry_ref ref=persondata->FileRef();
BPath path(&ref);
char *launchv[1];
launchv[0]=new char[255];
sprintf(launchv[0],"%s",path.Path());
be_roster->Launch(sig.String(),1,launchv,NULL);
delete [] launchv[0];
}
break;
}
case M_SHOW_ACTIONS:
{
uint32 buttons;
BPoint pt;
fPeopleList->GetMouse(&pt,&buttons,false);
pt.x=(pt.x>5)?pt.x-5:0;
pt.y=(pt.y>5)?pt.y-5:0;
fPeopleList->ShowContextMenu(fPeopleList->ConvertToScreen(pt));
break;
}
case M_BITMAP_REMOVED:
case M_PHOTO_MODIFIED:
{
fPeopleList->SaveImageData();
break;
}
case B_REFS_RECEIVED:
case B_SIMPLE_DATA:
{
entry_ref ref;
if(msg->FindRef("refs",0,&ref)==B_OK)
{
if(!IsPerson(ref))
{
// Might be an image dropped on the photo view. find out which child is the
// target
BPoint pt;
if(msg->FindPoint("_drop_offset",&pt)!=B_OK)
break;
BView *target=FindView(pt);
if(!target || strcmp(target->Name(),"photoview")!=0)
break;
// This will set the image, if possible
target->MessageReceived(msg);
// Save the image data to a real file and attach the Person attributes
// to it
fPeopleList->SaveImageData();
}
// Offer to move/copy file if not in People directory
BDirectory dir,peopledir("/boot/home/people");
BEntry entry(&ref);
entry.GetParent(&dir);
if(dir!=peopledir)
{
BString refname(ref.name);
//.........这里部分代码省略.........
示例3: PerformLoop
/* EEAAAAAAAGHH! My new code uses the current time from the transport
* to add signature information to the params. God I hope this is OK.
*/
int32 AmInputQueue::PerformLoop()
{
while (mPerformAvail >= B_OK) {
while (acquire_sem(mPerformAvail) == B_INTERRUPTED) ;
BList items;
if (mPerformLock.Lock()) {
items = mPerformItems;
mPerformItems.MakeEmpty();
mPerformLock.Unlock();
}
am_filter_params params;
am_filter_params* p = 0;
AmSongRef songRef = AmGlobals().SongRef(mSong);
if (songRef.IsValid()) {
for (int32 i=0; i<items.CountItems(); i++) {
record_item* ri = (record_item*)items.ItemAt(i);
if (!ri) continue;
{
// READ SONG BLOCK
#ifdef AM_TRACE_LOCKS
printf("AmInputQueue::PerformLoop() read lock\n"); fflush(stdout);
#endif
const AmSong* song = songRef.ReadLock();
const AmTrack* track = song ? song->Track(ri->track) : NULL;
if (track) {
p = 0;
AmEvent* signatures = 0;
AmTime currentTime = song->Transport().CurrentTime();
if (currentTime >= 0) {
signatures = song->PlaybackList(currentTime, currentTime, PLAYBACK_NO_PERFORMANCE | PLAYBACK_NO_TEMPO | PLAYBACK_RAW_CONTEXT);
if (signatures) {
// printf("Sigs: \n"); signatures->PrintChain();
params.cur_signature = dynamic_cast<AmSignature*>(signatures);
} else params.cur_signature = 0;
p = ¶ms;
}
// Run events through input filters
ri->events = ArpExecFilters(ri->events, REALTIME_EXEC_TYPE, false, p, 0, 0, 0, signatures);
if (ri->events) ri->events = ri->events->HeadEvent();
// Run result through output filters.
AmFilterHolderI* h = track->Filter(OUTPUT_PIPELINE);
if (h) {
AmEvent* pos = ri->events;
while (pos) {
if (!pos->NextFilter()) pos->SetNextFilter(h);
pos = pos->NextEvent();
}
ri->events = ArpExecFilters(ri->events, REALTIME_EXEC_TYPE, false, p, 0, 0, 0, signatures);
if (ri->events) ri->events = ri->events->HeadEvent();
}
song->Transport().Merge(ri->events);
ri->events = NULL;
}
params.cur_signature = 0;
songRef.ReadUnlock(song);
// END READ SONG BLOCK
}
if (ri->events) ri->events->DeleteChain();
delete ri;
}
}
}
return B_OK;
}
示例4: RecordLoop
int32 AmInputQueue::RecordLoop()
{
while (mRecordAvail >= B_OK) {
while (acquire_sem(mRecordAvail) == B_INTERRUPTED) ;
BList items;
if (mRecordLock.Lock()) {
items = mRecordItems;
mRecordItems.MakeEmpty();
mRecordLock.Unlock();
}
AmSongRef songRef = AmGlobals().SongRef(mSong);
if (songRef.IsValid()) {
for (int32 i=0; i<items.CountItems(); i++) {
record_item* ri = (record_item*)items.ItemAt(i);
if (!ri) continue;
{
// READ SONG BLOCK
#ifdef AM_TRACE_LOCKS
printf("AmInputQueue::RecordLoop() read lock\n"); fflush(stdout);
#endif
const AmSong* song = songRef.ReadLock();
if (song) {
ri->events = ArpExecFilters(ri->events, REALTIME_EXEC_TYPE, false);
if (ri->events) ri->events = ri->events->HeadEvent();
songRef.ReadUnlock(song);
}
// END READ SONG BLOCK
}
{
// WRITE SONG BLOCK
AmSong* song = songRef.WriteLock();
if (song) {
#if 1
/* New mechanism -- all events should have been supplied
* a track by the last filter they went through. So,
* record to the requested track. This wouldn't be
* necessary if we had a full architecture -- that is,
* the tracks were just another filter in the pipeline.
*/
AmTrack* track = 0;
AmEvent* e = 0;
AmEvent* head = ri->events;
while ((e = _get_record_t_and_e(head, song, &head, &track)) != 0) {
if (track) track->RecordEvents(e);
else e->DeleteChain();
}
if (head) head->DeleteChain();
ri->events = 0;
#endif
#if 0
AmTrack* track = song->Track(ri->track);
if (track && ri->events) {
track->RecordEvents(ri->events);
ri->events = NULL;
}
#endif
songRef.WriteUnlock(song);
}
// END WRITE SONG BLOCK
}
if (ri->events) ri->events->DeleteChain();
delete ri;
}
}
}
return B_OK;
}
示例5: if
void
update_preferred_app_menu(BMenu* menu, BMimeType* type, uint32 what,
const char* preferredFrom)
{
// clear menu (but leave the first entry, ie. "None")
for (int32 i = menu->CountItems(); i-- > 1;) {
delete menu->RemoveItem(i);
}
// fill it again
menu->ItemAt(0)->SetMarked(true);
BMessage applications;
if (type == NULL || type->GetSupportingApps(&applications) != B_OK)
return;
char preferred[B_MIME_TYPE_LENGTH];
if (type->GetPreferredApp(preferred) != B_OK)
preferred[0] = '\0';
int32 lastFullSupport;
if (applications.FindInt32("be:sub", &lastFullSupport) != B_OK)
lastFullSupport = -1;
BList subList;
BList superList;
const char* signature;
int32 i = 0;
while (applications.FindString("applications", i, &signature) == B_OK) {
BMenuItem* item = create_application_item(signature, what);
if (i < lastFullSupport)
subList.AddItem(item);
else
superList.AddItem(item);
i++;
}
// sort lists
subList.SortItems(compare_menu_items);
superList.SortItems(compare_menu_items);
// add lists to the menu
if (subList.CountItems() != 0 || superList.CountItems() != 0)
menu->AddSeparatorItem();
for (int32 i = 0; i < subList.CountItems(); i++) {
menu->AddItem((BMenuItem*)subList.ItemAt(i));
}
// Add type separator
if (superList.CountItems() != 0 && subList.CountItems() != 0)
menu->AddSeparatorItem();
for (int32 i = 0; i < superList.CountItems(); i++) {
menu->AddItem((BMenuItem*)superList.ItemAt(i));
}
// make items unique and select current choice
bool lastItemSame = false;
const char* lastSignature = NULL;
BMenuItem* last = NULL;
BMenuItem* select = NULL;
for (int32 index = 0; index < menu->CountItems(); index++) {
BMenuItem* item = menu->ItemAt(index);
if (item == NULL)
continue;
if (item->Message() == NULL
|| item->Message()->FindString("signature", &signature) != B_OK)
continue;
if ((preferredFrom == NULL && !strcasecmp(signature, preferred))
|| (preferredFrom != NULL
&& !strcasecmp(signature, preferredFrom))) {
select = item;
}
if (last == NULL || strcmp(last->Label(), item->Label())) {
if (lastItemSame)
add_signature(last, lastSignature);
lastItemSame = false;
last = item;
lastSignature = signature;
continue;
}
lastItemSame = true;
add_signature(last, lastSignature);
last = item;
//.........这里部分代码省略.........
示例6: cached_url_proto
void
Win::UrlTypedHandler( bool show_all )
{
// printf( "Win::UrlTypedHandler()\n" );
// get the stripped list from GlobalHistory
BList* slist = ( ( App* )be_app )->GetGlobalHistory()->GetStrippedList();
// create the matching urls list
BList* list = new BList( 0 );
BString typed_url; // the typed url
BString cached_url; // the cached url
BString cached_url_proto( "" ); // protocol of the cached url
if( show_all == true )
typed_url.SetTo( "" );
else
{
typed_url.SetTo( navview->urlview->Text() );
typed_url.ToLower();
}
// printf( " typed_url: %s length: %ld\n", typed_url.String(), typed_url.Length() );
int32 count = slist->CountItems();
for( int32 i = 0; i < count; i++ )
{
GlobalHistoryItem* item = ( GlobalHistoryItem* )slist->ItemAt( i );
if( item != NULL )
{
cached_url.SetTo( item->Text() );
// printf( " cached_url: %s\n", cached_url.String() );
if( typed_url.Length() != 0 )
{
// if the typed url matches beginning of cached url, add it
if( strncmp( cached_url.String(), typed_url.String(), typed_url.Length() ) == 0 )
{
list->AddItem( new BStringItem( cached_url.String() ) );
}
else
{
// if the urls dont match, take away the protocol of the cached url
if( cached_url.FindFirst( "://" ) > 0 )
{
cached_url.MoveInto( cached_url_proto, 0, cached_url.FindFirst( "://" ) + 3 );
}
// if the urls fit now
if( strncmp( cached_url.String(), typed_url.String(), typed_url.Length() ) == 0 )
{
// add the missing proto again
if( cached_url_proto.Length() != 0 )
cached_url.Prepend( cached_url_proto );
list->AddItem( new BStringItem( cached_url.String() ) );
}
else
{
// if they still don't fit, remove 'www.' from cached url
if( cached_url.FindFirst( "www." ) == 0 )
{
cached_url.Remove( 0, 4 );
}
// check if they finally fit
if( strncmp( cached_url.String(), typed_url.String(), typed_url.Length() ) == 0 )
{
// add missing 'www.' and proto
cached_url.Prepend( "www." );
if( cached_url_proto.Length() != 0 )
cached_url.Prepend( cached_url_proto );
list->AddItem( new BStringItem( cached_url.String() ) );
}
}
cached_url_proto.SetTo( "" );
}
}
else
{
list->AddItem( new BStringItem( cached_url.String() ) );
}
} // if( item != NULL )
}
// delete slist ( not needed anymore )
for( int32 i = 0; i < count; i++ )
{
GlobalHistoryItem* item = ( GlobalHistoryItem* )slist->ItemAt( i );
if( item != NULL )
{
slist->RemoveItem( item );
delete item;
}
}
delete slist;
//.........这里部分代码省略.........
示例7: msgr
//.........这里部分代码省略.........
if (termpref.FindInt32(TP_TABWIDTH, &ival) >= B_OK) {
//XXX: handle that ?
}
BFont tFont;
tp.p.font_size = 12;
strcpy(tp.p.font, "Courier10 BT/Roman");
if (FindFont(termpref, TP_FONT, 0, &tFont) == B_OK) {
font_family ff;
font_style fs;
tFont.GetFamilyAndStyle(&ff, &fs);
s = "";
s << ff;
lines.AddString(PREF_HALF_FONT_FAMILY, s.String());
s = "";
s << fs;
lines.AddString(PREF_HALF_FONT_STYLE, s.String());
s = "";
s << tFont.Size();
lines.AddString(PREF_HALF_FONT_SIZE, s.String());
}
if (FindRGBColor(termpref, TP_BG, 0, &color) != B_OK)
color = make_color(255,255,255,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_TEXT_BACK_COLOR, s.String());
if (FindRGBColor(termpref, TP_FG, 0, &color) != B_OK)
color = make_color(0,0,0,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_TEXT_FORE_COLOR, s.String());
if (FindRGBColor(termpref, TP_CURBG, 0, &color) != B_OK)
color = make_color(255,255,255,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_CURSOR_BACK_COLOR, s.String());
if (FindRGBColor(termpref, TP_CURFG, 0, &color) != B_OK)
color = make_color(0,0,0,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_CURSOR_FORE_COLOR, s.String());
if (FindRGBColor(termpref, TP_SELBG, 0, &color) != B_OK)
color = make_color(0,0,0,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_SELECT_BACK_COLOR, s.String());
if (FindRGBColor(termpref, TP_SELFG, 0, &color) != B_OK)
color = make_color(255,255,255,255);
s = "";
s << color.red << ", " << color.green << ", " << color.blue;
lines.AddString(PREF_SELECT_FORE_COLOR, s.String());
/* XXX: handle PREF_IM_FORE_COLOR PREF_IM_BACK_COLOR PREF_IM_SELECT_COLOR */
if (termpref.FindInt32(TP_ENCODING, &ival) != B_OK)
ival = 0; // UTF-8
s = "";
s << ival;
//XXX: shouldn't really be touched...
//lines.AddString(, s.String());
if (flags & UI_THEME_SETTINGS_SAVE && AddonFlags() & Z_THEME_ADDON_DO_SAVE) {
SaveHaikuTerminalSettings(lines);
}
if (flags & UI_THEME_SETTINGS_APPLY && AddonFlags() & Z_THEME_ADDON_DO_APPLY) {
BList teamList;
app_info ainfo;
int32 count, i;
be_roster->GetAppList(&teamList);
count = teamList.CountItems();
for (i = 0; i < count; i++) {
if (be_roster->GetRunningAppInfo((team_id)(teamList.ItemAt(i)), &ainfo) == B_OK) {
if (!strcmp(ainfo.signature, kHaikuTerminalAppSig)) {
err = B_OK;
//XXX: WRITEME
/* BMessage msg(MSG_R5_SET_PREF);
BMessenger msgr(NULL, ainfo.team);
tp.x = 0;
tp.y = 0;
//msg.AddData("", 'UBYT', &(tp.p), sizeof(struct tpref));
msg.AddData("", 'UBYT', &(tp), sizeof(struct termprefs));
msg.AddSpecifier("Window", 0L);
err = msgr.SendMessage(&msg);
*/
}
}
}
}
return B_OK;
}
示例8: fTermPref
status_t
TerminalThemesAddon::ApplyThemeR5(BMessage &theme, uint32 flags)
{
BMessage termpref;
status_t err;
struct termprefs tp;
err = MyMessage(theme, termpref);
if (err)
return err;
tp.magic = TP_MAGIC;
tp.version = TP_VERSION;
tp.x = 0; // don't open at specific coords
tp.y = 0;
if (termpref.FindInt32(TP_COLS, (int32 *)&tp.p.cols) != B_OK)
tp.p.cols = 80;
if (termpref.FindInt32(TP_ROWS, (int32 *)&tp.p.rows) != B_OK)
tp.p.rows = 25;
if (termpref.FindInt32(TP_TABWIDTH, (int32 *)&tp.p.tab_width) != B_OK)
tp.p.tab_width = 8;
BFont tFont;
tp.p.font_size = 12;
strcpy(tp.p.font, "Courier10 BT/Roman");
if (FindFont(termpref, TP_FONT, 0, &tFont) == B_OK) {
font_family ff;
font_style fs;
tFont.GetFamilyAndStyle(&ff, &fs);
strcpy(tp.p.font, ff);
strcat(tp.p.font, "/");
strcat(tp.p.font, fs);
tp.p.font_size = (uint32)tFont.Size();
}
tp.p.cursor_blink_rate = 1000000;
tp.p.refresh_rate = 0;
if (FindRGBColor(termpref, TP_BG, 0, &tp.p.bg) != B_OK)
tp.p.bg = make_color(255,255,255,255);
if (FindRGBColor(termpref, TP_FG, 0, &tp.p.fg) != B_OK)
tp.p.fg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_CURBG, 0, &tp.p.curbg) != B_OK)
tp.p.curbg = make_color(255,255,255,255);
if (FindRGBColor(termpref, TP_CURFG, 0, &tp.p.curfg) != B_OK)
tp.p.curfg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_SELBG, 0, &tp.p.selbg) != B_OK)
tp.p.selbg = make_color(0,0,0,255);
if (FindRGBColor(termpref, TP_SELFG, 0, &tp.p.selfg) != B_OK)
tp.p.selfg = make_color(255,255,255,255);
if (termpref.FindInt32(TP_ENCODING, (int32 *)&tp.p.encoding) != B_OK)
tp.p.encoding = 0; // UTF-8
if (flags & UI_THEME_SETTINGS_SAVE && AddonFlags() & Z_THEME_ADDON_DO_SAVE) {
BPath pTermPref;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &pTermPref) < B_OK)
return EINVAL;
pTermPref.Append("Terminal");
BFile fTermPref(pTermPref.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_ERASE_FILE);
if (fTermPref.InitCheck() != B_OK) {
return fTermPref.InitCheck();
}
fTermPref.Write(&tp, sizeof(struct termprefs));
BNodeInfo ni(&fTermPref);
if (ni.InitCheck() == B_OK)
ni.SetType("application/x-vnd.Be-pref");
}
if (flags & UI_THEME_SETTINGS_APPLY && AddonFlags() & Z_THEME_ADDON_DO_APPLY) {
BList teamList;
app_info ainfo;
int32 count, i;
be_roster->GetAppList(&teamList);
count = teamList.CountItems();
for (i = 0; i < count; i++) {
if (be_roster->GetRunningAppInfo((team_id)(teamList.ItemAt(i)), &ainfo) == B_OK) {
if (!strcmp(ainfo.signature, kBeOSTerminalAppSig)) {
err = B_OK;
BMessage msg(MSG_R5_SET_PREF);
BMessenger msgr(NULL, ainfo.team);
tp.x = 0;
tp.y = 0;
//msg.AddData("", 'UBYT', &(tp.p), sizeof(struct tpref));
msg.AddData("", 'UBYT', &(tp), sizeof(struct termprefs));
msg.AddSpecifier("Window", 0L);
err = msgr.SendMessage(&msg);
}
}
}
}
return B_OK;
}
示例9: ConvertWordToCharset
_EXPORT ssize_t utf8_to_rfc2047 (char **bufp, ssize_t length, uint32 charset, char encoding) {
struct word {
BString originalWord;
BString convertedWord;
bool needsEncoding;
// Convert the word from UTF-8 to the desired character set. The
// converted version also includes the escape codes to return to ASCII
// mode, if relevant. Also note if it uses unprintable characters,
// which means it will need that special encoding treatment later.
void ConvertWordToCharset (uint32 charset) {
int32 state = 0;
int32 originalLength = originalWord.Length();
int32 convertedLength = originalLength * 5 + 1;
char *convertedBuffer = convertedWord.LockBuffer (convertedLength);
mail_convert_from_utf8 (charset, originalWord.String(),
&originalLength, convertedBuffer, &convertedLength, &state);
for (int i = 0; i < convertedLength; i++) {
if ((convertedBuffer[i] & (1 << 7)) ||
(convertedBuffer[i] >= 0 && convertedBuffer[i] < 32)) {
needsEncoding = true;
break;
}
}
convertedWord.UnlockBuffer (convertedLength);
};
};
struct word *currentWord;
BList words;
// Break the header into words. White space characters (including tabs and
// newlines) separate the words. Each word includes any space before it as
// part of the word. Actually, quotes and other special characters
// (",()<>@) are treated as separate words of their own so that they don't
// get encoded (because MIME headers get the quotes parsed before character
// set unconversion is done). The reader is supposed to ignore all white
// space between encoded words, which can be inserted so that older mail
// parsers don't have overly long line length problems.
const char *source = *bufp;
const char *bufEnd = *bufp + length;
const char *specialChars = "\"()<>@,";
while (source < bufEnd) {
currentWord = new struct word;
currentWord->needsEncoding = false;
int wordEnd = 0;
// Include leading spaces as part of the word.
while (source + wordEnd < bufEnd && isspace (source[wordEnd]))
wordEnd++;
if (source + wordEnd < bufEnd &&
strchr (specialChars, source[wordEnd]) != NULL) {
// Got a quote mark or other special character, which is treated as
// a word in itself since it shouldn't be encoded, which would hide
// it from the mail system.
wordEnd++;
} else {
// Find the end of the word. Leave wordEnd pointing just after the
// last character in the word.
while (source + wordEnd < bufEnd) {
if (isspace(source[wordEnd]) ||
strchr (specialChars, source[wordEnd]) != NULL)
break;
if (wordEnd > 51 /* Makes Base64 ISO-2022-JP "word" a multiple of 4 bytes */ &&
0xC0 == (0xC0 & (unsigned int) source[wordEnd])) {
// No English words are that long (46 is the longest),
// break up what is likely Asian text (which has no spaces)
// at the start of the next non-ASCII UTF-8 character (high
// two bits are both ones). Note that two encoded words in
// a row get joined together, even if there is a space
// between them in the final output text, according to the
// standard. Next word will also be conveniently get
// encoded due to the 0xC0 test.
currentWord->needsEncoding = true;
break;
}
wordEnd++;
}
}
currentWord->originalWord.SetTo (source, wordEnd);
currentWord->ConvertWordToCharset (charset);
words.AddItem(currentWord);
source += wordEnd;
}
// Combine adjacent words which contain unprintable text so that the
// overhead of switching back and forth between regular text and specially
// encoded text is reduced. However, the combined word must be shorter
// than the maximum of 75 bytes, including character set specification and
// all those delimiters (worst case 22 bytes of overhead).
struct word *run;
for (int32 i = 0; (currentWord = (struct word *) words.ItemAt (i)) != NULL; i++) {
if (!currentWord->needsEncoding)
continue; // No need to combine unencoded words.
for (int32 g = i+1; (run = (struct word *) words.ItemAt (g)) != NULL; g++) {
//.........这里部分代码省略.........