00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063
00064 #include "GString.h"
00065 #if HAS_ICONV
00066 #include <iconv.h>
00067 #endif
00068
00069
00070 #ifdef HAVE_NAMESPACES
00071 namespace DJVU {
00072 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00073 }
00074 #endif
00075 #endif
00076
00077 static unsigned char nill=0;
00078
00079 static void const *
00080 checkmarks(void const * const xbuf,
00081 unsigned int &bufsize,
00082 GStringRep::EncodeType &rep)
00083 {
00084 unsigned char const *buf=(unsigned char const *)xbuf;
00085 if(bufsize >= 2 || (xbuf && !bufsize && rep != GStringRep::XOTHER))
00086 {
00087 const unsigned int s=(((unsigned int)buf[0])<<8)+(unsigned int)buf[1];
00088 switch(s)
00089 {
00090 case 0:
00091 if((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4BE)
00092 ||(!bufsize && rep == GStringRep::XUCS4_2143))
00093 {
00094 const unsigned int s=(((unsigned int)buf[2])<<8)+(unsigned int)buf[3];
00095 if(s == 0xfeff)
00096 {
00097 rep=GStringRep::XUCS4BE;
00098 buf+=4;
00099 }else if(s == 0xfffe)
00100 {
00101 rep=GStringRep::XUCS4_2143;
00102 buf+=4;
00103 }
00104 }
00105 break;
00106 case 0xfffe:
00107 if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4LE))
00108 && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
00109 {
00110 rep=GStringRep::XUCS4LE;
00111 buf+=4;
00112 }else
00113 {
00114 rep=GStringRep::XUTF16LE;
00115 buf+=2;
00116 }
00117 break;
00118 case 0xfeff:
00119 if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4_3412))
00120 && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
00121 {
00122 rep=GStringRep::XUCS4_3412;
00123 buf+=4;
00124 }else
00125 {
00126 rep=GStringRep::XUTF16LE;
00127 buf+=2;
00128 }
00129 break;
00130 case 0xefbb:
00131 if(((bufsize>=3)||(!bufsize && GStringRep::XUTF8 == rep))&&(buf[2] == 0xbf))
00132 {
00133 rep=GStringRep::XUTF8;
00134 buf+=3;
00135 }
00136 break;
00137 default:
00138 break;
00139 }
00140 }
00141 if(buf != xbuf)
00142 {
00143 if(bufsize)
00144 {
00145 const size_t s=(size_t)xbuf-(size_t)buf;
00146 if(bufsize> s)
00147 {
00148 bufsize-=s;
00149 }else
00150 {
00151 bufsize=0;
00152 buf=(const unsigned char *)&nill;
00153 }
00154 }
00155 }
00156 return buf;
00157 }
00158
00159 class GStringRep::Unicode : public GStringRep::UTF8
00160 {
00161 public:
00162 GP<GStringRep> encoding;
00163 EncodeType encodetype;
00164 void *remainder;
00165 GPBufferBase gremainder;
00166 public:
00167 Unicode(void);
00169 virtual ~Unicode();
00170
00171 static GP<GStringRep> create(const unsigned int sz);
00172 static GP<GStringRep> create(void const * const buf, unsigned int bufsize,
00173 const EncodeType, const GP<GStringRep> &encoding);
00174 static GP<GStringRep> create( void const * const buf,
00175 unsigned int size, const EncodeType encodetype );
00176 static GP<GStringRep> create( void const * const buf,
00177 const unsigned int size, GP<GStringRep> encoding );
00178 static GP<GStringRep> create( void const * const buf,
00179 const unsigned int size, const GP<Unicode> &remainder );
00180
00181 protected:
00182 virtual void set_remainder( void const * const buf, const unsigned int size,
00183 const EncodeType encodetype );
00184 virtual void set_remainder( void const * const buf, const unsigned int size,
00185 const GP<GStringRep> &encoding );
00186 virtual void set_remainder( const GP<Unicode> &remainder );
00187 virtual GP<Unicode> get_remainder(void) const;
00188 };
00189
00190 static unsigned long xUTF16toUCS4(unsigned short const *&s,void const * const);
00191 static unsigned long UTF16BEtoUCS4(unsigned char const *&s,void const * const);
00192 static unsigned long UTF16LEtoUCS4(unsigned char const *&s,void const * const);
00193 static unsigned long UCS4BEtoUCS4(unsigned char const *&s,void const * const);
00194 static unsigned long UCS4LEtoUCS4(unsigned char const *&s,void const * const);
00195 static unsigned long UCS4_3412toUCS4(unsigned char const *&s,void const * const);
00196 static unsigned long UCS4_2143toUCS4(unsigned char const *&s,void const * const);
00197
00198 GP<GStringRep>
00199 GStringRep::Unicode::create(const unsigned int sz)
00200 {
00201 GP<GStringRep> gaddr;
00202 if (sz > 0)
00203 {
00204 GStringRep *addr;
00205 gaddr=(addr=new GStringRep::Unicode);
00206 addr->data=(char *)(::operator new(sz+1));
00207 addr->size = sz;
00208 addr->data[sz] = 0;
00209 }
00210 return gaddr;
00211 }
00212
00213 GStringRep::Unicode::Unicode(void)
00214 : encodetype(XUTF8), gremainder(remainder,0,1) {}
00215
00216 GStringRep::Unicode::~Unicode() {}
00217
00218 GP<GStringRep>
00219 GStringRep::Unicode::create(
00220 void const * const xbuf,
00221 unsigned int bufsize,
00222 const EncodeType t,
00223 const GP<GStringRep> &encoding)
00224 {
00225 return (encoding->size)
00226 ?create(xbuf,bufsize,encoding)
00227 :create(xbuf,bufsize,t);
00228 }
00229
00230 GP<GStringRep>
00231 GStringRep::Unicode::create(
00232 void const * const xbuf,
00233 const unsigned int bufsize,
00234 const GP<Unicode> &xremainder )
00235 {
00236 Unicode *r=xremainder;
00237 GP<GStringRep> retval;
00238 if(r)
00239 {
00240 const int s=r->gremainder;
00241 if(xbuf && bufsize)
00242 {
00243 if(s)
00244 {
00245 void *buf;
00246 GPBufferBase gbuf(buf,s+bufsize,1);
00247 memcpy(buf,r->remainder,s);
00248 memcpy((void *)((size_t)buf+s),xbuf,bufsize);
00249 retval=((r->encoding)
00250 ?create(buf,s+bufsize,r->encoding)
00251 :create(buf,s+bufsize,r->encodetype));
00252 }else
00253 {
00254 retval=((r->encoding)
00255 ?create(xbuf,bufsize,r->encoding)
00256 :create(xbuf,bufsize,r->encodetype));
00257 }
00258 }else if(s)
00259 {
00260 void *buf;
00261 GPBufferBase gbuf(buf,s,1);
00262 memcpy(buf,r->remainder,s);
00263 retval=((r->encoding)
00264 ?create(buf,s,r->encoding)
00265 :create(buf,s,r->encodetype));
00266 }else
00267 {
00268 retval=((r->encoding)
00269 ?create(0,0,r->encoding)
00270 :create(0,0,r->encodetype));
00271 }
00272 }else
00273 {
00274 retval=create(xbuf,bufsize,XUTF8);
00275 }
00276 return retval;
00277 }
00278
00279 #if HAS_ICONV
00280
00281 template<typename _T> inline size_t
00282 iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t *, char**, size_t*),
00283 iconv_t cd, char **inbuf, size_t *inbytesleft,
00284 char **outbuf, size_t *outbytesleft)
00285 {
00286 return iconv_func (cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
00287 }
00288 #endif
00289
00290 GP<GStringRep>
00291 GStringRep::Unicode::create(
00292 void const * const xbuf,
00293 unsigned int bufsize,
00294 GP<GStringRep> encoding)
00295 {
00296 GP<GStringRep> retval;
00297 GStringRep *e=encoding;
00298 if(e)
00299 {
00300 e=(encoding=e->upcase());
00301 }
00302 if(!e || !e->size)
00303 {
00304 retval=create(xbuf,bufsize,XOTHER);
00305 }else if(!e->cmp("UTF8") || !e->cmp("UTF-8"))
00306 {
00307 retval=create(xbuf,bufsize,XUTF8);
00308 }else if(!e->cmp("UTF16")|| !e->cmp("UTF-16")
00309 || !e->cmp("UCS2") || !e->cmp("UCS2"))
00310 {
00311 retval=create(xbuf,bufsize,XUTF16);
00312 }else if(!e->cmp("UCS4") || !e->cmp("UCS-4"))
00313 {
00314 retval=create(xbuf,bufsize,XUCS4);
00315 }else
00316 {
00317 #if HAS_ICONV
00318 EncodeType t=XOTHER;
00319 void const * const buf=checkmarks(xbuf,bufsize,t);
00320 if(t != XOTHER)
00321 {
00322 retval=create(xbuf,bufsize,t);
00323 }else if(buf && bufsize)
00324 {
00325 unsigned char const *eptr=(unsigned char *)buf;
00326 unsigned int j=0;
00327 for(j=0;(j<bufsize)&&*eptr;j++,eptr++)
00328 EMPTY_LOOP;
00329 if (j)
00330 {
00331 unsigned char const *ptr=(unsigned char *)buf;
00332 if(e)
00333 {
00334 iconv_t cv=iconv_open("UTF-8",(const char *)e);
00335 if(cv == (iconv_t)(-1))
00336 {
00337 const int i=e->search('-');
00338 if(i>=0)
00339 {
00340 cv=iconv_open("UTF-8",e->data+i+1);
00341 }
00342 }
00343 if(cv == (iconv_t)(-1))
00344 {
00345 retval=create(0,0,XOTHER);
00346 }else
00347 {
00348 size_t ptrleft=(eptr-ptr);
00349 char *utf8buf;
00350 size_t pleft=6*ptrleft+1;
00351 GPBuffer<char> gutf8buf(utf8buf,pleft);
00352 char *p=utf8buf;
00353 unsigned char const *last=ptr;
00354 for(;iconv_adaptor(iconv, cv, (char**)&ptr, &ptrleft, &p, &pleft);last=ptr)
00355 EMPTY_LOOP;
00356 iconv_close(cv);
00357 retval=create(utf8buf,(size_t)last-(size_t)buf,t);
00358 retval->set_remainder(last,(size_t)eptr-(size_t)last,e);
00359 }
00360 }
00361 }else
00362 {
00363 retval=create(0,0,XOTHER);
00364 retval->set_remainder(0,0,e);
00365 }
00366 }
00367 #else
00368 retval=create(xbuf,bufsize,XOTHER);
00369 #endif
00370 }
00371 return retval;
00372 }
00373
00374 GP<GStringRep>
00375 GStringRep::Unicode::create(
00376 void const * const xbuf,
00377 unsigned int bufsize,
00378 EncodeType t)
00379 {
00380 GP<GStringRep> gretval;
00381 GStringRep *retval=0;
00382 void const * const buf=checkmarks(xbuf,bufsize,t);
00383 if(buf && bufsize)
00384 {
00385 unsigned char const *eptr=(unsigned char *)buf;
00386 unsigned int maxutf8size=0;
00387 void const* const xeptr=(void const *)((size_t)eptr+bufsize);
00388 switch(t)
00389 {
00390 case XUCS4:
00391 case XUCS4BE:
00392 case XUCS4LE:
00393 case XUCS4_2143:
00394 case XUCS4_3412:
00395 {
00396 for(unsigned long w;
00397 (eptr<xeptr)&&(w=*(unsigned long const *)eptr);
00398 eptr+=sizeof(unsigned long))
00399 {
00400 maxutf8size+=(w>0x7f)?6:1;
00401 }
00402 break;
00403 }
00404 case XUTF16:
00405 case XUTF16BE:
00406 case XUTF16LE:
00407 {
00408 for(unsigned short w;
00409 (eptr<xeptr)&&(w=*(unsigned short const *)eptr);
00410 eptr+=sizeof(unsigned short))
00411 {
00412 maxutf8size+=3;
00413 }
00414 break;
00415 }
00416 case XUTF8:
00417 for(;(eptr<xeptr)&&*eptr;maxutf8size++,eptr++)
00418 EMPTY_LOOP;
00419 break;
00420 case XEBCDIC:
00421 for(;(eptr<xeptr)&&*eptr;eptr++)
00422 {
00423 maxutf8size+=(*eptr>0x7f)?2:1;
00424 }
00425 break;
00426 default:
00427 break;
00428 }
00429 unsigned char *utf8buf=0;
00430 GPBuffer<unsigned char> gutf8buf(utf8buf,maxutf8size+1);
00431 utf8buf[0]=0;
00432 if (maxutf8size)
00433 {
00434 unsigned char *optr=utf8buf;
00435 int len=0;
00436 unsigned char const *iptr=(unsigned char *)buf;
00437 unsigned long w;
00438 switch(t)
00439 {
00440 case XUCS4:
00441 for(;
00442 (iptr<eptr)&&(w=*(unsigned long const *)iptr);
00443 len++,iptr+=sizeof(unsigned long const))
00444 {
00445 optr=UCS4toUTF8(w,optr);
00446 }
00447 break;
00448 case XUCS4BE:
00449 for(;(w=UCS4BEtoUCS4(iptr,eptr));len++)
00450 {
00451 optr=UCS4toUTF8(w,optr);
00452 }
00453 break;
00454 case XUCS4LE:
00455 for(;(w=UCS4LEtoUCS4(iptr,eptr));len++)
00456 {
00457 optr=UCS4toUTF8(w,optr);
00458 }
00459 break;
00460 case XUCS4_2143:
00461 for(;(w=UCS4_2143toUCS4(iptr,eptr));len++)
00462 {
00463 optr=UCS4toUTF8(w,optr);
00464 }
00465 break;
00466 case XUCS4_3412:
00467 for(;(w=UCS4_3412toUCS4(iptr,eptr));len++)
00468 {
00469 optr=UCS4toUTF8(w,optr);
00470 }
00471 break;
00472 case XUTF16:
00473 for(;
00474 (w=xUTF16toUCS4((unsigned short const*&)iptr,eptr));
00475 len++)
00476 {
00477 optr=UCS4toUTF8(w,optr);
00478 }
00479 break;
00480 case XUTF16BE:
00481 for(;(w=UTF16BEtoUCS4(iptr,eptr));len++)
00482 {
00483 optr=UCS4toUTF8(w,optr);
00484 }
00485 break;
00486 case XUTF16LE:
00487 for(;(w=UTF16LEtoUCS4(iptr,eptr));len++)
00488 {
00489 optr=UCS4toUTF8(w,optr);
00490 }
00491 break;
00492 case XUTF8:
00493 for(;(w=UTF8toUCS4(iptr,eptr));len++)
00494 {
00495 optr=UCS4toUTF8(w,optr);
00496 }
00497 break;
00498 case XEBCDIC:
00499 for(;(iptr<eptr)&&(w=*iptr++);len++)
00500 {
00501 optr=UCS4toUTF8(w,optr);
00502 }
00503 break;
00504 default:
00505 break;
00506 }
00507 const unsigned int size=(size_t)optr-(size_t)utf8buf;
00508 if(size)
00509 {
00510 retval=(gretval=GStringRep::Unicode::create(size));
00511 memcpy(retval->data,utf8buf,size);
00512 }else
00513 {
00514 retval=(gretval=GStringRep::Unicode::create(1));
00515 retval->size=size;
00516 }
00517 retval->data[size]=0;
00518 gutf8buf.resize(0);
00519 const size_t s=(size_t)eptr-(size_t)iptr;
00520 retval->set_remainder(iptr,s,t);
00521 }
00522 }
00523 if(!retval)
00524 {
00525 retval=(gretval=GStringRep::Unicode::create(1));
00526 retval->data[0]=0;
00527 retval->size=0;
00528 retval->set_remainder(0,0,t);
00529 }
00530 return gretval;
00531 }
00532
00533 static unsigned long
00534 xUTF16toUCS4(unsigned short const *&s,void const * const eptr)
00535 {
00536 unsigned long U=0;
00537 unsigned short const * const r=s+1;
00538 if(r <= eptr)
00539 {
00540 unsigned long const W1=s[0];
00541 if((W1<0xD800)||(W1>0xDFFF))
00542 {
00543 if((U=W1))
00544 {
00545 s=r;
00546 }
00547 }else if(W1<=0xDBFF)
00548 {
00549 unsigned short const * const rr=r+1;
00550 if(rr <= eptr)
00551 {
00552 unsigned long const W2=s[1];
00553 if(((W2>=0xDC00)||(W2<=0xDFFF))&&((U=(0x1000+((W1&0x3ff)<<10))|(W2&0x3ff))))
00554 {
00555 s=rr;
00556 }else
00557 {
00558 U=(unsigned int)(-1)-W1;
00559 s=r;
00560 }
00561 }
00562 }
00563 }
00564 return U;
00565 }
00566
00567 static unsigned long
00568 UTF16BEtoUCS4(unsigned char const *&s,void const * const eptr)
00569 {
00570 unsigned long U=0;
00571 unsigned char const * const r=s+2;
00572 if(r <= eptr)
00573 {
00574 unsigned long const C1MSB=s[0];
00575 if((C1MSB<0xD8)||(C1MSB>0xDF))
00576 {
00577 if((U=((C1MSB<<8)|((unsigned long)s[1]))))
00578 {
00579 s=r;
00580 }
00581 }else if(C1MSB<=0xDB)
00582 {
00583 unsigned char const * const rr=r+2;
00584 if(rr <= eptr)
00585 {
00586 unsigned long const C2MSB=s[2];
00587 if((C2MSB>=0xDC)||(C2MSB<=0xDF))
00588 {
00589 U=0x10000+((unsigned long)s[1]<<10)+(unsigned long)s[3]
00590 +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
00591 s=rr;
00592 }else
00593 {
00594 U=(unsigned int)(-1)-((C1MSB<<8)|((unsigned long)s[1]));
00595 s=r;
00596 }
00597 }
00598 }
00599 }
00600 return U;
00601 }
00602
00603 static unsigned long
00604 UTF16LEtoUCS4(unsigned char const *&s,void const * const eptr)
00605 {
00606 unsigned long U=0;
00607 unsigned char const * const r=s+2;
00608 if(r <= eptr)
00609 {
00610 unsigned long const C1MSB=s[1];
00611 if((C1MSB<0xD8)||(C1MSB>0xDF))
00612 {
00613 if((U=((C1MSB<<8)|((unsigned long)s[0]))))
00614 {
00615 s=r;
00616 }
00617 }else if(C1MSB<=0xDB)
00618 {
00619 unsigned char const * const rr=r+2;
00620 if(rr <= eptr)
00621 {
00622 unsigned long const C2MSB=s[3];
00623 if((C2MSB>=0xDC)||(C2MSB<=0xDF))
00624 {
00625 U=0x10000+((unsigned long)s[0]<<10)+(unsigned long)s[2]
00626 +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
00627 s=rr;
00628 }else
00629 {
00630 U=(unsigned int)(-1)-((C1MSB<<8)|((unsigned long)s[1]));
00631 s=r;
00632 }
00633 }
00634 }
00635 }
00636 return U;
00637 }
00638
00639 static unsigned long
00640 UCS4BEtoUCS4(unsigned char const *&s,void const * const eptr)
00641 {
00642 unsigned long U=0;
00643 unsigned char const * const r=s+4;
00644 if(r<=eptr)
00645 {
00646 U=(((((((unsigned long)s[0]<<8)|(unsigned long)s[1])<<8)|(unsigned long)s[2])<<8)|(unsigned long)s[3]);
00647 if(U)
00648 {
00649 s=r;
00650 }
00651 }
00652 return U;
00653 }
00654
00655 static unsigned long
00656 UCS4LEtoUCS4(unsigned char const *&s,void const * const eptr)
00657 {
00658 unsigned long U=0;
00659 unsigned char const * const r=s+4;
00660 if(r<=eptr)
00661 {
00662 U=(((((((unsigned long)s[3]<<8)|(unsigned long)s[2])<<8)|(unsigned long)s[1])<<8)|(unsigned long)s[0]);
00663 if(U)
00664 {
00665 s=r;
00666 }
00667 }
00668 return U;
00669 }
00670
00671 static unsigned long
00672 UCS4_2143toUCS4(unsigned char const *&s,void const * const eptr)
00673 {
00674 unsigned long U=0;
00675 unsigned char const * const r=s+4;
00676 if(r<=eptr)
00677 {
00678 U=(((((((unsigned long)s[1]<<8)|(unsigned long)s[0])<<8)|(unsigned long)s[3])<<8)|(unsigned long)s[2]);
00679 if(U)
00680 {
00681 s=r;
00682 }
00683 }
00684 return U;
00685 }
00686
00687 static unsigned long
00688 UCS4_3412toUCS4(unsigned char const *&s,void const * const eptr)
00689 {
00690 unsigned long U=0;
00691 unsigned char const * const r=s+4;
00692 if(r<=eptr)
00693 {
00694 U=(((((((unsigned long)s[2]<<8)|(unsigned long)s[3])<<8)|(unsigned long)s[0])<<8)|(unsigned long)s[1]);
00695 if(U)
00696 {
00697 s=r;
00698 }
00699 }
00700 return U;
00701 }
00702
00703 void
00704 GStringRep::Unicode::set_remainder( void const * const buf,
00705 const unsigned int size, const EncodeType xencodetype )
00706 {
00707 gremainder.resize(size,1);
00708 if(size)
00709 memcpy(remainder,buf,size);
00710 encodetype=xencodetype;
00711 encoding=0;
00712 }
00713
00714 void
00715 GStringRep::Unicode::set_remainder( void const * const buf,
00716 const unsigned int size, const GP<GStringRep> &xencoding )
00717 {
00718 gremainder.resize(size,1);
00719 if(size)
00720 memcpy(remainder,buf,size);
00721 encoding=xencoding;
00722 encodetype=XOTHER;
00723 }
00724
00725 void
00726 GStringRep::Unicode::set_remainder( const GP<GStringRep::Unicode> &xremainder )
00727 {
00728 if(xremainder)
00729 {
00730 const int size=xremainder->gremainder;
00731 gremainder.resize(size,1);
00732 if(size)
00733 memcpy(remainder,xremainder->remainder,size);
00734 encodetype=xremainder->encodetype;
00735 }else
00736 {
00737 gremainder.resize(0,1);
00738 encodetype=XUTF8;
00739 }
00740 }
00741
00742 GP<GStringRep::Unicode>
00743 GStringRep::Unicode::get_remainder( void ) const
00744 {
00745 return const_cast<GStringRep::Unicode *>(this);
00746 }
00747
00748 GUTF8String
00749 GUTF8String::create(void const * const buf,const unsigned int size,
00750 const EncodeType encodetype, const GUTF8String &encoding)
00751 {
00752 return encoding.length()
00753 ?create(buf,size,encodetype)
00754 :create(buf,size,encoding);
00755 }
00756
00757 GUTF8String
00758 GUTF8String::create( void const * const buf,
00759 unsigned int size, const EncodeType encodetype )
00760 {
00761 GUTF8String retval;
00762 retval.init(GStringRep::Unicode::create(buf,size,encodetype));
00763 return retval;
00764 }
00765
00766 GUTF8String
00767 GUTF8String::create( void const * const buf,
00768 const unsigned int size, const GP<GStringRep::Unicode> &remainder)
00769 {
00770 GUTF8String retval;
00771 retval.init(GStringRep::Unicode::create(buf,size,remainder));
00772 return retval;
00773 }
00774
00775 GUTF8String
00776 GUTF8String::create( void const * const buf,
00777 const unsigned int size, const GUTF8String &encoding )
00778 {
00779 GUTF8String retval;
00780 retval.init(GStringRep::Unicode::create(buf,size,encoding ));
00781 return retval;
00782 }
00783
00784
00785 #ifdef HAVE_NAMESPACES
00786 }
00787 # ifndef NOT_USING_DJVU_NAMESPACE
00788 using namespace DJVU;
00789 # endif
00790 #endif