GURL getDjViewDataFile(const char *fname) { GList<GURL> paths = DjVuMessage::GetProfilePaths(); GUTF8String file = fname; // end hack alert static const char *osi = "/osi/"; static const char *djview3 = "/djview3/"; for (GPosition pos=paths; pos; ++pos) { GURL url = GURL(file, paths[pos]); GUTF8String urls = (const char*)url; int pos = urls.search(osi); if (pos >= 0) { GUTF8String urlx; urlx += urls.substr(0, pos); urlx += djview3; urlx += urls.substr(pos+strlen(osi), -1); GURL url = GURL::UTF8(urlx); if (url.is_file()) return url; } } // end hack alert for (GPosition pos=paths; pos; ++pos) { GURL url = GURL(file, paths[pos]); if(url.is_file()) return url; } return GURL(); }
void GIFFChunk::set_name(GUTF8String name) { DEBUG_MSG("GIFFChunk::set_name(): name='" << name << "'\n"); DEBUG_MAKE_INDENT(3); const int colon=name.search(':'); if(colon>=0) { type=name.substr(0,colon); name=name.substr(colon+1,(unsigned int)-1); if(name.search(':')>=0) G_THROW( ERR_MSG("GIFFManager.one_colon") ); } DEBUG_MSG("auto-setting type to '" << type << "'\n"); if (name.contains(".[]")>=0) G_THROW( ERR_MSG("GIFFManager.bad_char") ); strncpy(GIFFChunk::name, (const char *)name, 4); GIFFChunk::name[4]=0; for(int i=strlen(GIFFChunk::name);i<4;i++) GIFFChunk::name[i]=' '; }
// Expands a single message and inserts the arguments. Single_Message // contains no separators (newlines), but includes all the parameters // separated by tabs. GUTF8String DjVuMessageLite::LookUpSingle( const GUTF8String &Single_Message ) const { #if HAS_CTRL_C_IN_ERR_MSG if (Single_Message[0] != '\003') return Single_Message; #endif // Isolate the message ID and get the corresponding message text int ending_posn = Single_Message.contains("\t\v"); if( ending_posn < 0 ) ending_posn = Single_Message.length(); GUTF8String msg_text; GUTF8String msg_number; const GUTF8String message=Single_Message.substr(0,ending_posn); LookUpID( message, msg_text, msg_number ); // Check whether we found anything if( !msg_text.length()) { if(message == unrecognized) { msg_text = unrecognized_default; }else if(message == uparameter) { msg_text = uparameter_default; }else if(message == failed_to_parse_XML) { msg_text = failed_to_parse_XML_default; }else { return LookUpSingle(unrecognized + ("\t" + Single_Message)); } } // Insert the parameters (if any) unsigned int param_num = 0; while( (unsigned int)ending_posn < Single_Message.length() ) { GUTF8String arg; const int start_posn = ending_posn+1; if(Single_Message[ending_posn] == '\v') { ending_posn=Single_Message.length(); arg=LookUpSingle(Single_Message.substr(start_posn,ending_posn)); }else { ending_posn = Single_Message.contains("\v\t",start_posn); if( ending_posn < 0 ) ending_posn = Single_Message.length(); arg=Single_Message.substr(start_posn, ending_posn-start_posn); } InsertArg( msg_text, ++param_num, arg); } // Insert the message number InsertArg( msg_text, 0, msg_number ); return msg_text; }
void GIFFManager::del_chunk(GUTF8String name) // "name" should be fully qualified, that is contain dots. // It may also end with [] to set the chunk order number { DEBUG_MSG("GIFFManager::del_chunk(): Deleting chunk '" << name << "'\n"); DEBUG_MAKE_INDENT(3); if (!name.length()) G_THROW( ERR_MSG("GIFFManager.del_empty") ); if (name[0]=='.') { const int next_dot=name.search('.',1); if (next_dot < 0) { if (top_level->check_name(name.substr(1,(unsigned int)-1))) { DEBUG_MSG("Removing top level chunk..\n"); top_level=GIFFChunk::create(); return; } G_THROW( ERR_MSG("GIFFManager.wrong_name2") "\t"+name.substr(1,(unsigned int)-1)); } const GUTF8String top_name=name.substr(1,next_dot-1); if (!top_level->check_name(top_name)) G_THROW( ERR_MSG("GIFFManager.wrong_name2") "\t"+top_name); name=name.substr(next_dot+1,(unsigned int)-1); } GP<GIFFChunk> cur_sec=top_level; const char * start, * end=(const char *)name-1; do { for(start=++end;*end&&(*end!='.');end++) EMPTY_LOOP; if (end>start && *end=='.') cur_sec=cur_sec->get_chunk(GUTF8String(start, end-start)); if (!cur_sec) G_THROW( ERR_MSG("GIFFManager.cant_find") "\t"+GUTF8String(name)); } while(*end); if (!start[0]) { G_THROW(GUTF8String( ERR_MSG("GIFFManager.malformed") "\t")+name); } cur_sec->del_chunk(start); }
static void writeText( ByteStream & str_out, const GUTF8String &textUTF8, const DjVuTXT::Zone &zone, const int WindowHeight ) { // DEBUG_MSG( "--zonetype=" << zone.ztype << "\n" ); const GUTF8String xindent(indent( 2 * zone.ztype + 2 )); GPosition pos=zone.children; // Build attribute string if( ! pos ) { GUTF8String coords; coords.format("coords=\"%d,%d,%d,%d\"", zone.rect.xmin, WindowHeight - 1 - zone.rect.ymin, zone.rect.xmax, WindowHeight - 1 - zone.rect.ymax); const int start=zone.text_start; const int end=textUTF8.firstEndSpace(start,zone.text_length); str_out.writestring(start_tag(zone.ztype,coords)); str_out.writestring(textUTF8.substr(start,end-start).toEscaped()); str_out.writestring(end_tag(zone.ztype)); } else { writeText(str_out,textUTF8,zone.ztype,zone.children,WindowHeight); } }
void DjVuSource::ReadAnnotations(GP<ByteStream> pInclStream, set<GUTF8String>& processed, GP<ByteStream> pAnnoStream) { // Look for shared annotations GUTF8String strInclude; char buf[1024]; int nLength; while ((nLength = pInclStream->read(buf, 1024))) strInclude += GUTF8String(buf, nLength); // Eat '\n' in the beginning and at the end while (strInclude.length() > 0 && strInclude[0] == '\n') strInclude = strInclude.substr(1, static_cast<unsigned int>(-1)); while (strInclude.length() > 0 && strInclude[static_cast<int>(strInclude.length()) - 1] == '\n') strInclude.setat(strInclude.length() - 1, 0); if (strInclude.length() > 0 && processed.find(strInclude) == processed.end()) { processed.insert(strInclude); GURL urlInclude = m_pDjVuDoc->id_to_url(strInclude); GP<DataPool> pool = m_pDjVuDoc->request_data(NULL, urlInclude); GP<ByteStream> stream = pool->get_stream(); GP<IFFByteStream> iff(IFFByteStream::create(stream)); // Check file format GUTF8String chkid; if (!iff->get_chunk(chkid) || (chkid != "FORM:DJVI" && chkid != "FORM:DJVU" && chkid != "FORM:PM44" && chkid != "FORM:BM44")) { return; } // Find chunk with page info while (iff->get_chunk(chkid) != 0) { GP<ByteStream> chunk_stream = iff->get_bytestream(); if (chkid == "INCL") { ReadAnnotations(pInclStream, processed, pAnnoStream); } else if (chkid == "FORM:ANNO") { pAnnoStream->copy(*chunk_stream); } else if (chkid == "ANTa" || chkid == "ANTz") { const GP<IFFByteStream> iffout = IFFByteStream::create(pAnnoStream); iffout->put_chunk(chkid); iffout->copy(*chunk_stream); iffout->close_chunk(); } iff->seek_close_chunk(); } } }
// Looks up the msgID in the file of messages and returns a pointer to // the beginning of the translated message, if found; and an empty string // otherwise. void DjVuMessageLite::LookUpID( const GUTF8String &xmsgID, GUTF8String &message_text, GUTF8String &message_number ) const { if(!Map.isempty()) { GUTF8String msgID = xmsgID; #if HAS_CTRL_C_IN_ERR_MSG int start = 0; while (msgID[start] == '\003') start ++; if (start > 0) msgID = msgID.substr(start, msgID.length() - start); #endif GPosition pos=Map.contains(msgID); if(pos) { const GP<lt_XMLTags> tag=Map[pos]; GPosition valuepos=tag->get_args().contains(valuestring); if(valuepos) { message_text=tag->get_args()[valuepos]; }else { const GUTF8String raw(tag->get_raw()); const int start_line=raw.search((unsigned long)'\n',0); const int start_text=raw.nextNonSpace(0); const int end_text=raw.firstEndSpace(0); if(start_line<0 || start_text<0 || start_text < start_line) { message_text=raw.substr(0,end_text).fromEscaped(); }else { message_text=raw.substr(start_line+1,end_text-start_line-1).fromEscaped(); } } GPosition numberpos=tag->get_args().contains(numberstring); if(numberpos) { message_number=tag->get_args()[numberpos]; } } } }
bool GIFFChunk::check_name(GUTF8String name) { GUTF8String type; const int colon=name.search(':'); if(colon>=0) { type=name.substr(0,colon); name=name.substr(colon+1,(unsigned int)-1); } const GUTF8String sname=(name.substr(0,4)+" ").substr(0,4); DEBUG_MSG("GIFFChunk::check_name(): type='" << type << "' name='" << sname << "'\n"); return (type==GIFFChunk::type || (!type.length() && GIFFChunk::type=="FORM")) && sname==GIFFChunk::name; }
GP<GIFFChunk> GIFFManager::get_chunk(GUTF8String name, int * pos_num) // "name" should be fully qualified, that is contain dots. // It may also end with [] to set the chunk order number { DEBUG_MSG("GIFFManager::get_chunk(): Returning chunk '" << name << "'\n"); DEBUG_MAKE_INDENT(3); if (!name.length()) G_THROW( ERR_MSG("GIFFManager.get_empty") ); if (name[0]=='.') { const int next_dot=name.search('.',1); if (next_dot < 0) { if (top_level->check_name(name.substr(1,(unsigned int)-1))) { DEBUG_MSG("Removing top level chunk..\n"); return top_level; } G_THROW( ERR_MSG("GIFFManager.wrong_name2") "\t"+name.substr(1,(unsigned int)-1)); } const GUTF8String top_name=name.substr(1,next_dot-1); if (!top_level->check_name(top_name)) G_THROW( ERR_MSG("GIFFManager.wrong_name2") "\t"+top_name); name=name.substr(next_dot+1,(unsigned int)-1); } GP<GIFFChunk> cur_sec=top_level; const char * start, * end=(const char *) name-1; do { for(start=++end;*end&&(*end!='.');end++) EMPTY_LOOP; if (end>start) cur_sec=cur_sec->get_chunk(GUTF8String(start, end-start), pos_num); if (!cur_sec) break; } while(*end); return cur_sec; }
int DjVuANT::get_zoom(GLParser & parser) // Returns: // <0 - special zoom (like ZOOM_STRETCH) // =0 - not set // >0 - numeric zoom (%%) { int retval=ZOOM_UNSPEC; DEBUG_MSG("DjVuANT::get_zoom(): getting zoom factor ...\n"); DEBUG_MAKE_INDENT(3); G_TRY { GP<GLObject> obj=parser.get_object(ZOOM_TAG); if (obj && obj->get_list().size()==1) { const GUTF8String zoom((*obj)[0]->get_symbol()); DEBUG_MSG("zoom='" << zoom << "'\n"); for(int i=0;(i<zoom_strings_size);++i) { if(zoom == zoom_strings[i]) { retval=(-i); break; } } if(retval == ZOOM_UNSPEC) { if (zoom[0]!='d') { G_THROW( ERR_MSG("DjVuAnno.bad_zoom") ); }else { retval=zoom.substr(1, zoom.length()).toInt(); //atoi((const char *) zoom+1); } } } #ifndef NDEBUG if(retval == ZOOM_UNSPEC) { DEBUG_MSG("can't find any.\n"); } #endif // NDEBUG } G_CATCH_ALL {} G_ENDCATCH; #ifndef NDEBUG if(retval == ZOOM_UNSPEC) { DEBUG_MSG("resetting zoom to 0 (UNSPEC)\n"); } #endif // NDEBUG return retval; }
GUTF8String GIFFChunk::decode_name(const GUTF8String &name, int &number) { DEBUG_MSG("GIFFChunk::decode_name(): Checking brackets in name '" << name << "'\n"); DEBUG_MAKE_INDENT(3); if (name.search('.')>=0) G_THROW( ERR_MSG("GIFFManager.no_dots") ); number=0; const int obracket=name.search('['); GUTF8String short_name; if (obracket >= 0) { const int cbracket=name.search(']',obracket+1); if (cbracket < 0) G_THROW( ERR_MSG("GIFFManager.unmatched") ); if (name.length() > (unsigned int)(cbracket+1)) G_THROW( ERR_MSG("GIFFManager.garbage") ); // number =atoi((const char *)name.substr(obracket+1,cbracket-obracket-1)); number= name.substr(obracket+1,cbracket-obracket-1).toInt(); short_name=name.substr(0,obracket); }else { short_name=name; } const int colon=short_name.search(':'); if (colon>=0) short_name=short_name.substr(colon+1,(unsigned int)-1); for(int i=short_name.length();i<4;i++) short_name.setat(i, ' '); DEBUG_MSG("short_name='" << short_name << "'\n"); DEBUG_MSG("number=" << number << "\n"); return short_name; }
void GIFFManager::add_chunk(GUTF8String name, const TArray<char> & data) // name is fully qualified name of the chunk TO BE INSERTED. // it may contain brackets at the end to set the position // All the required chunks will be created { DEBUG_MSG("GIFFManager::add_chunk(): adding plain chunk with name='" << name << "'\n"); DEBUG_MAKE_INDENT(3); GUTF8String chunk_name; const int lastdot=name.rsearch('.'); if(lastdot < 0) { chunk_name=name; name=name.substr(0,lastdot); }else { chunk_name=name.substr(lastdot+1,(unsigned int)-1); } int pos=-1; const int obracket=chunk_name.search('['); if (obracket >= 0) { const int cbracket=chunk_name.search(']',obracket+1); if (cbracket < 0) G_THROW( ERR_MSG("GIFFManager.unmatched") ); if (name.length() > (unsigned int)(cbracket+1)) G_THROW( ERR_MSG("GIFFManager.garbage") ); // pos=atoi((const char *)chunk_name.substr(obracket+1,cbracket-obracket-1)); pos = chunk_name.substr(obracket+1,cbracket-obracket-1).toInt(); chunk_name=chunk_name.substr(0,obracket); } DEBUG_MSG("Creating new chunk with name " << chunk_name << "\n"); GP<GIFFChunk> chunk; chunk=GIFFChunk::create(chunk_name, data); add_chunk(name, chunk, pos); }
int GIFFManager::get_chunks_number(const GUTF8String &name) // Returns the number of chunks with given fully qualified name { DEBUG_MSG("GIFFManager::get_chunks_number(): name='" << name << "'\n"); DEBUG_MAKE_INDENT(3); int retval; const int last_dot=name.rsearch('.'); if (last_dot<0) { retval=top_level->get_chunks_number(name); }else if(!last_dot) { retval=(top_level->get_name()==name.substr(1,(unsigned int)-1))?1:0; }else { GP<GIFFChunk> chunk=get_chunk(name.substr(0,last_dot)); retval=( chunk ?(chunk->get_chunks_number(name.substr(last_dot+1,(unsigned int)-1))) :0 ); } return retval; }
static unsigned long convertToColor(const GUTF8String &s) { unsigned long retval=0; if(s.length()) { int endpos; if(s[0] == '#') { retval=s.substr(1,-1).toULong(0,endpos,16); } if(endpos < 0) { G_THROW( (ERR_MSG("XMLAnno.bad_color") "\t")+s ); } } return retval; }
// Expands message lists by looking up the message IDs and inserting // arguments into the retrieved messages. // N.B. The resulting string may be encoded in UTF-8 format (ISO 10646-1 Annex R) // and SHOULD NOT BE ASSUMED TO BE ASCII. GUTF8String DjVuMessageLite::LookUp( const GUTF8String & MessageList ) const { // DEBUG_MSG( "========== DjVuMessageLite::LookUp ==========\n" << // MessageList << // "\n========== DjVuMessageLite::LookUp ==========\n" ); GUTF8String result; // Result string; begins empty if(errors.length()) { const GUTF8String err1(errors); (const_cast<GUTF8String &>(errors)).empty(); result=LookUp(err1)+"\n"; } int start = 0; // Beginning of next message int end = MessageList.length(); // End of the message string // Isolate single messages and process them while( start < end ) { if( MessageList[start] == '\n' ) { result += MessageList[start++]; // move the newline to the result // and advance to the next message } else { // Find the end of the next message and process it int next_ending = MessageList.search((unsigned long)'\n', start); if( next_ending < 0 ) next_ending = end; result += LookUpSingle( MessageList.substr(start, next_ending-start) ); // Advance to the next message start = next_ending; } } // All done return result; }
// used to build the zone tree // true is returned if the GRect is known for this object, // and false, if the rectangle's size is just the parent size. static bool make_child_layer( DjVuTXT::Zone &parent, const lt_XMLTags &tag, ByteStream &bs, const int height, const double ws, const double hs) { bool retval=true; // the plugin thinks there are only Pages, Lines and Words // so we don't make Paragraphs, Regions and Columns zones // if we did the plugin is not able to search the text but // DjVuToText writes out all the text anyway DjVuTXT::Zone *self_ptr; char sepchar; const GUTF8String name(tag.get_name()); if(name == charactertag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::CHARACTER; sepchar=0; }else if(name == wordtag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::WORD; sepchar=' '; }else if(name == linetag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::LINE; sepchar=DjVuTXT::end_of_line; }else if(name == paragraphtag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::PARAGRAPH; sepchar=DjVuTXT::end_of_paragraph; }else if(name == regiontag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::REGION; sepchar=DjVuTXT::end_of_region; }else if(name == pagecolumntag) { self_ptr=parent.append_child(); self_ptr->ztype = DjVuTXT::COLUMN; sepchar=DjVuTXT::end_of_column; }else { self_ptr = &parent; self_ptr->ztype = DjVuTXT::PAGE; sepchar=0; } DjVuTXT::Zone &self = *self_ptr; self.text_start = bs.tell(); int &xmin=self.rect.xmin, &ymin=self.rect.ymin, &xmax=self.rect.xmax, &ymax=self.rect.ymax; GRect default_rect; default_rect.xmin=max(parent.rect.xmax,parent.rect.xmin); default_rect.xmax=min(parent.rect.xmax,parent.rect.xmin); default_rect.ymin=max(parent.rect.ymax,parent.rect.ymin); default_rect.ymax=min(parent.rect.ymax,parent.rect.ymin); // Now if there are coordinates, use those. GPosition pos(tag.get_args().contains("coords")); if(pos) { GList<int> rectArgs; intList(tag.get_args()[pos], rectArgs); if((pos=rectArgs)) { xmin=(int)(ws*(double)rectArgs[pos]); if(++pos) { ymin=(height-1)-(int)(hs*(double)rectArgs[pos]); if(++pos) { xmax=(int)(ws*(double)rectArgs[pos]); if(++pos) { ymax=(height-1)-(int)(hs*(double)rectArgs[pos]); if(xmin>xmax) // Make sure xmin is really minimum { const int t=xmin; xmin=xmax; xmax=t; } if(ymin>ymax) // Make sure ymin is really minimum { const int t=ymin; ymin=ymax; ymax=t; } } } } } } if(self.ztype == DjVuTXT::CHARACTER) { if(! pos) { self.rect=default_rect; retval=false; } const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else if(pos) { pos=tag.get_content(); if(pos) { for(pos=tag.get_content(); pos; ++pos) { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); make_child_layer(self, *t, bs, height,ws,hs); } if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else { const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; } }else { self.rect=default_rect; if((pos=tag.get_content())) { do { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); const GRect save_rect(self.rect); self.rect=default_rect; if ((retval = make_child_layer(self, *t, bs, height, ws, hs))) { xmin=min(save_rect.xmin,xmin); xmax=max(save_rect.xmax,xmax); ymin=min(save_rect.ymin,ymin); ymax=max(save_rect.ymax,ymax); }else { // If the child doesn't have coordinates, we need to use a box // at least as big as the parent's coordinates. xmin=min(save_rect.xmin,default_rect.xmax); xmax=max(save_rect.xmax,default_rect.xmin); ymin=min(save_rect.ymin,default_rect.ymax); ymax=max(save_rect.ymax,default_rect.ymin); for(; pos; ++pos) { const GP<lt_XMLTags> t(tag.get_content()[pos].tag); make_child_layer(self, *t, bs, height,ws,hs); } break; } } while(++pos); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; }else { const GUTF8String raw(tag.get_raw().fromEscaped()); const int i=raw.nextNonSpace(0); bs.writestring(raw.substr(i,raw.firstEndSpace(i)-i)); if(sepchar) bs.write8(sepchar); self.text_length = bs.tell() - self.text_start; } } parent.rect.xmin=min(xmin,parent.rect.xmin); parent.rect.ymin=min(ymin,parent.rect.ymin); parent.rect.xmax=max(xmax,parent.rect.xmax); parent.rect.ymax=max(ymax,parent.rect.ymax); if(xmin>xmax) { const int t=xmin; xmin=xmax; xmax=t; } if(ymin>ymax) { const int t=ymin; ymin=ymax; ymax=t; } // DjVuPrintMessage("(%d,%d)(%d,%d)<<<\\%o>>>\n", // xmin,ymin,xmax,ymax, sepchar); return retval; }
void GIFFManager::add_chunk(GUTF8String parent_name, const GP<GIFFChunk> & chunk, int pos) // parent_name is the fully qualified name of the PARENT // IT MAY BE EMPTY // All the required chunks will be created // pos=-1 means to append the chunk { DEBUG_MSG("GIFFManager::add_chunk(): Adding chunk to name='" << parent_name << "'\n"); DEBUG_MAKE_INDENT(3); if (!top_level->get_name().length()) { if ((!parent_name.length())||(parent_name[0]!='.')) G_THROW( ERR_MSG("GIFFManager.no_top_name") ); if (parent_name.length() < 2) { // 'chunk' is actually the new top-level chunk DEBUG_MSG("since parent_name=='.', making the chunk top-level\n"); if (!chunk->is_container()) G_THROW( ERR_MSG("GIFFManager.no_top_cont") ); top_level=chunk; return; } DEBUG_MSG("Setting the name of the top-level chunk\n"); const int next_dot=parent_name.search('.',1); if(next_dot>=0) { top_level->set_name(parent_name.substr(1,next_dot-1)); }else { top_level->set_name(parent_name.substr(1,(unsigned int)-1)); } } DEBUG_MSG("top level chunk name='" << top_level->get_name() << "'\n"); if (parent_name.length() && parent_name[0] == '.') { int next_dot=parent_name.search('.',1); if(next_dot<0) { next_dot=parent_name.length(); } GUTF8String top_name=parent_name.substr(1,next_dot-1); if (!top_level->check_name(top_name)) G_THROW( ERR_MSG("GIFFManager.wrong_name") "\t"+top_name); parent_name=parent_name.substr(next_dot,(unsigned int)-1); } GP<GIFFChunk> cur_sec=top_level; const char * start, * end=(const char *)parent_name-1; do { for(start=++end;*end&&(*end!='.');end++) EMPTY_LOOP; if (end>start) { GUTF8String name(start,end-start); GUTF8String short_name; int number=0; const int obracket=name.search('['); if (obracket >= 0) { const int cbracket=name.search(']',obracket+1); if (cbracket < 0) G_THROW( ERR_MSG("GIFFManager.unmatched") ); // number=atoi((const char *)name.substr(obracket+1,cbracket-obracket-1)); number = name.substr(obracket+1,cbracket-obracket-1).toInt(); short_name=name.substr(0,obracket); }else { short_name=name; } for(int i=cur_sec->get_chunks_number(short_name);i<number+1;i++) cur_sec->add_chunk(GIFFChunk::create(short_name)); cur_sec=cur_sec->get_chunk(name); if (!cur_sec) G_THROW( ERR_MSG("GIFFManager.unknown") "\t"+name); } } while(*end); cur_sec->add_chunk(chunk, pos); }
// Insert a string into the message text. Will insert into any field // description. Except for an ArgId of zero (message number), if the ArgId // is not found, the routine adds a line with the parameter so information // will not be lost. void DjVuMessageLite::InsertArg( GUTF8String &message, const int ArgId, const GUTF8String &arg ) const { // argument target string const GUTF8String target= "%"+GUTF8String(ArgId)+"!"; // location of target string int format_start = message.search( (const char *)target ); if( format_start >= 0 ) { do { const int n=format_start+target.length()+1; const int format_end=message.search((unsigned long)'!',n); if(format_end > format_start) { const int len=1+format_end-n; if(len && isascii(message[n-1])) { GUTF8String narg; GUTF8String format="%"+message.substr(n-1,len); switch(format[len]) { case 'd': case 'i': narg.format((const char *)format,arg.toInt()); break; case 'u': case 'o': case 'x': case 'X': narg.format((const char *)format,(unsigned int)arg.toInt()); break; case 'f': case 'g': case 'e': { int endpos; narg.format((const char *)format, arg.toDouble(0,endpos)); if( endpos < 0 ) narg = arg; } break; default: narg.format((const char *)format,(const char *)arg); break; } message = message.substr( 0, format_start )+narg +message.substr( format_end+1, -1 ); }else { message = message.substr( 0, format_start )+arg +message.substr( format_end+1, -1 ); } } format_start=message.search((const char*)target, format_start+arg.length()); } while(format_start >= 0); } else { // Not found, fake it if( ArgId != 0 ) { message += "\n"+LookUpSingle(uparameter+("\t"+arg)); } } }