source: trunk/libdjvu/GUnicode.cpp @ 209

Last change on this file since 209 was 206, checked in by Eugene Romanenko, 14 years ago

DJVU plugin: djvulibre updated to version 3.5.19

File size: 20.4 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, either Version 2 of the license,
9//C- or (at your option) any later version. The license should have
10//C- accompanied the software or you may obtain a copy of the license
11//C- from the Free Software Foundation at http://www.fsf.org .
12//C-
13//C- This program is distributed in the hope that it will be useful,
14//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
15//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16//C- GNU General Public License for more details.
17//C-
18//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
19//C- Lizardtech Software.  Lizardtech Software has authorized us to
20//C- replace the original DjVu(r) Reference Library notice by the following
21//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
22//C-
23//C-  ------------------------------------------------------------------
24//C- | DjVu (r) Reference Library (v. 3.5)
25//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
26//C- | The DjVu Reference Library is protected by U.S. Pat. No.
27//C- | 6,058,214 and patents pending.
28//C- |
29//C- | This software is subject to, and may be distributed under, the
30//C- | GNU General Public License, either Version 2 of the license,
31//C- | or (at your option) any later version. The license should have
32//C- | accompanied the software or you may obtain a copy of the license
33//C- | from the Free Software Foundation at http://www.fsf.org .
34//C- |
35//C- | The computer code originally released by LizardTech under this
36//C- | license and unmodified by other parties is deemed "the LIZARDTECH
37//C- | ORIGINAL CODE."  Subject to any third party intellectual property
38//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
39//C- | non-exclusive license to make, use, sell, or otherwise dispose of
40//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
41//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
42//C- | General Public License.   This grant only confers the right to
43//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
44//C- | the extent such infringement is reasonably necessary to enable
45//C- | recipient to make, have made, practice, sell, or otherwise dispose
46//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
47//C- | any greater extent that may be necessary to utilize further
48//C- | modifications or combinations.
49//C- |
50//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
51//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
52//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
53//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
54//C- +------------------------------------------------------------------
55//
56// $Id: GUnicode.cpp,v 1.12 2007/03/25 20:48:32 leonb Exp $
57// $Name: release_3_5_19 $
58
59#ifdef HAVE_CONFIG_H
60# include "config.h"
61#endif
62#if NEED_GNUG_PRAGMAS
63# pragma implementation
64#endif
65
66#include "GString.h"
67#if HAS_ICONV
68#include <iconv.h>
69#endif
70
71
72#ifdef HAVE_NAMESPACES
73namespace DJVU {
74# ifdef NOT_DEFINED // Just to fool emacs c++ mode
75}
76#endif
77#endif
78
79static unsigned char nill=0;
80
81static void const * 
82checkmarks(void const * const xbuf,
83           unsigned int &bufsize,
84           GStringRep::EncodeType &rep)
85{
86  unsigned char const *buf=(unsigned char const *)xbuf;
87  if(bufsize >= 2 || (xbuf && !bufsize && rep != GStringRep::XOTHER))
88  {
89    const unsigned int s=(((unsigned int)buf[0])<<8)+(unsigned int)buf[1];
90    switch(s)
91    {
92      case 0:
93        if((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4BE)
94          ||(!bufsize && rep == GStringRep::XUCS4_2143))
95        {
96          const unsigned int s=(((unsigned int)buf[2])<<8)+(unsigned int)buf[3];
97          if(s == 0xfeff)
98          { 
99            rep=GStringRep::XUCS4BE;
100            buf+=4;
101          }else if(s == 0xfffe)
102          {
103            rep=GStringRep::XUCS4_2143;
104            buf+=4;
105          }
106        }
107        break;
108      case 0xfffe:
109        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4LE)) 
110           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
111        {
112          rep=GStringRep::XUCS4LE;
113          buf+=4;
114        }else
115        {
116          rep=GStringRep::XUTF16LE;
117          buf+=2;
118        }
119        break;
120      case 0xfeff:
121        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4_3412)) 
122           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
123        {
124          rep=GStringRep::XUCS4_3412;
125          buf+=4;
126        }else
127        {
128          rep=GStringRep::XUTF16LE;
129          buf+=2;
130        }
131        break;
132      case 0xefbb:
133        if(((bufsize>=3)||(!bufsize && GStringRep::XUTF8 == rep))&&(buf[2] == 0xbf))
134        {
135          rep=GStringRep::XUTF8;
136          buf+=3;
137        }
138        break;
139      default:
140        break;
141    }
142  }
143  if(buf != xbuf)
144  {
145    if(bufsize)
146    {
147      const size_t s=(size_t)xbuf-(size_t)buf;
148      if(bufsize> s)
149      {
150        bufsize-=s;
151      }else
152      {
153        bufsize=0;
154        buf=(const unsigned char *)&nill;
155      }
156    }
157  }
158  return buf;
159}
160
161class GStringRep::Unicode : public GStringRep::UTF8
162{
163public:
164  GP<GStringRep> encoding;
165  EncodeType encodetype;
166  void *remainder;
167  GPBufferBase gremainder;
168public:
169  Unicode(void);
170  /// virtual destructor.
171  virtual ~Unicode();
172
173  static GP<GStringRep> create(const unsigned int sz);
174  static GP<GStringRep> create(void const * const buf, unsigned int bufsize,
175                               const EncodeType, const GP<GStringRep> &encoding);
176  static GP<GStringRep> create( void const * const buf,
177    unsigned int size, const EncodeType encodetype );
178  static GP<GStringRep> create( void const * const buf,
179    const unsigned int size, GP<GStringRep> encoding );
180  static GP<GStringRep> create( void const * const buf,
181    const unsigned int size, const GP<Unicode> &remainder );
182
183protected:
184  virtual void set_remainder( void const * const buf, const unsigned int size,
185    const EncodeType encodetype );
186  virtual void set_remainder( void const * const buf, const unsigned int size,
187    const GP<GStringRep> &encoding );
188  virtual void set_remainder( const GP<Unicode> &remainder );
189  virtual GP<Unicode> get_remainder(void) const;
190};
191// static unsigned long UTF8toUCS4(unsigned char const *&,void const * const);
192static unsigned long xUTF16toUCS4(unsigned short const *&s,void const * const);
193static unsigned long UTF16BEtoUCS4(unsigned char const *&s,void const * const);
194static unsigned long UTF16LEtoUCS4(unsigned char const *&s,void const * const);
195static unsigned long UCS4BEtoUCS4(unsigned char const *&s,void const * const);
196static unsigned long UCS4LEtoUCS4(unsigned char const *&s,void const * const);
197static unsigned long UCS4_3412toUCS4(unsigned char const *&s,void const * const);
198static unsigned long UCS4_2143toUCS4(unsigned char const *&s,void const * const);
199
200GP<GStringRep>
201GStringRep::Unicode::create(const unsigned int sz)
202{
203  GP<GStringRep> gaddr;
204  if (sz > 0)
205  {
206    GStringRep *addr;
207    gaddr=(addr=new GStringRep::Unicode);
208    addr->data=(char *)(::operator new(sz+1));
209    addr->size = sz;
210    addr->data[sz] = 0;
211  }
212  return gaddr;
213}
214
215GStringRep::Unicode::Unicode(void)
216: encodetype(XUTF8), gremainder(remainder,0,1) {}
217
218GStringRep::Unicode::~Unicode() {}
219
220GP<GStringRep>
221GStringRep::Unicode::create(
222  void const * const xbuf,
223  unsigned int bufsize,
224  const EncodeType t,
225  const GP<GStringRep> &encoding)
226{
227  return (encoding->size)
228    ?create(xbuf,bufsize,encoding)
229    :create(xbuf,bufsize,t);
230}
231
232GP<GStringRep>
233GStringRep::Unicode::create(
234  void const * const xbuf,
235  const unsigned int bufsize,
236  const GP<Unicode> &xremainder )
237{
238  Unicode *r=xremainder;
239  GP<GStringRep> retval;
240  if(r)
241  {
242    const int s=r->gremainder;
243    if(xbuf && bufsize)
244    {
245      if(s)
246      {
247        void *buf;
248        GPBufferBase gbuf(buf,s+bufsize,1);
249        memcpy(buf,r->remainder,s);
250        memcpy((void *)((size_t)buf+s),xbuf,bufsize);
251        retval=((r->encoding)
252          ?create(buf,s+bufsize,r->encoding)
253          :create(buf,s+bufsize,r->encodetype));
254      }else
255      {
256        retval=((r->encoding)
257          ?create(xbuf,bufsize,r->encoding)
258          :create(xbuf,bufsize,r->encodetype));
259      }
260    }else if(s)
261        {
262      void *buf;
263      GPBufferBase gbuf(buf,s,1);
264      memcpy(buf,r->remainder,s);
265      retval=((r->encoding)
266        ?create(buf,s,r->encoding)
267        :create(buf,s,r->encodetype));
268        }else
269    {
270      retval=((r->encoding)
271        ?create(0,0,r->encoding)
272        :create(0,0,r->encodetype));
273    }
274  }else
275  {
276    retval=create(xbuf,bufsize,XUTF8);
277  }
278  return retval;
279}
280
281#if HAS_ICONV
282/* This template works around incompatible iconv protoypes */
283template<typename _T> inline size_t 
284iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t *, char**, size_t*),
285              iconv_t cd, char **inbuf, size_t *inbytesleft,
286              char **outbuf, size_t *outbytesleft)
287{
288  return iconv_func (cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
289}
290#endif
291
292GP<GStringRep>
293GStringRep::Unicode::create(
294  void const * const xbuf,
295  unsigned int bufsize,
296  GP<GStringRep> encoding)
297{
298  GP<GStringRep> retval;
299  GStringRep *e=encoding;
300  if(e)
301  {
302    e=(encoding=e->upcase());
303  }
304  if(!e || !e->size)
305  {
306    retval=create(xbuf,bufsize,XOTHER);
307  }else if(!e->cmp("UTF8") || !e->cmp("UTF-8"))
308  {
309    retval=create(xbuf,bufsize,XUTF8);
310  }else if(!e->cmp("UTF16")|| !e->cmp("UTF-16")
311    || !e->cmp("UCS2") || !e->cmp("UCS2"))
312  {
313    retval=create(xbuf,bufsize,XUTF16);
314  }else if(!e->cmp("UCS4") || !e->cmp("UCS-4"))
315  {
316    retval=create(xbuf,bufsize,XUCS4);
317  }else
318  {
319#if HAS_ICONV
320    EncodeType t=XOTHER;
321    void const * const buf=checkmarks(xbuf,bufsize,t); 
322    if(t != XOTHER)
323    {
324      retval=create(xbuf,bufsize,t);
325    }else if(buf && bufsize)
326    {
327      unsigned char const *eptr=(unsigned char *)buf;
328      unsigned int j=0;
329      for(j=0;(j<bufsize)&&*eptr;j++,eptr++)
330        EMPTY_LOOP;
331      if (j)
332      {
333        unsigned char const *ptr=(unsigned char *)buf;
334        if(e)
335        {
336          iconv_t cv=iconv_open("UTF-8",(const char *)e);
337          if(cv == (iconv_t)(-1))
338          { 
339            const int i=e->search('-');
340            if(i>=0)
341            {
342              cv=iconv_open("UTF-8",e->data+i+1);
343            }
344          }
345          if(cv == (iconv_t)(-1))
346          { 
347            retval=create(0,0,XOTHER);
348          }else
349          {
350            size_t ptrleft=(eptr-ptr); 
351            char *utf8buf;
352            size_t pleft=6*ptrleft+1;
353            GPBuffer<char> gutf8buf(utf8buf,pleft);
354            char *p=utf8buf;
355            unsigned char const *last=ptr;
356            for(;iconv_adaptor(iconv, cv, (char**)&ptr, &ptrleft, &p, &pleft);last=ptr) 
357              EMPTY_LOOP;
358            iconv_close(cv);
359            retval=create(utf8buf,(size_t)last-(size_t)buf,t);
360            retval->set_remainder(last,(size_t)eptr-(size_t)last,e);
361          }
362        }
363      }else
364      {
365        retval=create(0,0,XOTHER);
366        retval->set_remainder(0,0,e);
367      }
368    }
369#else
370    retval=create(xbuf,bufsize,XOTHER);
371#endif
372  }
373  return retval;
374}
375
376GP<GStringRep>
377GStringRep::Unicode::create(
378  void const * const xbuf,
379  unsigned int bufsize,
380  EncodeType t)
381{
382  GP<GStringRep> gretval;
383  GStringRep *retval=0;
384  void const * const buf=checkmarks(xbuf,bufsize,t); 
385  if(buf && bufsize)
386  {
387    unsigned char const *eptr=(unsigned char *)buf;
388    unsigned int maxutf8size=0;
389    void const* const xeptr=(void const *)((size_t)eptr+bufsize);
390    switch(t)
391    {
392      case XUCS4:
393      case XUCS4BE:
394      case XUCS4LE:
395      case XUCS4_2143:
396      case XUCS4_3412:
397      {
398        for(unsigned long w;
399          (eptr<xeptr)&&(w=*(unsigned long const *)eptr);
400          eptr+=sizeof(unsigned long))
401        {
402          maxutf8size+=(w>0x7f)?6:1;
403        }
404        break;
405      }
406      case XUTF16:
407      case XUTF16BE:
408      case XUTF16LE:
409      {
410        for(unsigned short w;
411          (eptr<xeptr)&&(w=*(unsigned short const *)eptr);
412          eptr+=sizeof(unsigned short))
413        {
414          maxutf8size+=3;
415        }
416        break;
417      }
418      case XUTF8:
419        for(;(eptr<xeptr)&&*eptr;maxutf8size++,eptr++)
420          EMPTY_LOOP;
421        break;
422      case XEBCDIC:
423        for(;(eptr<xeptr)&&*eptr;eptr++)
424        {
425          maxutf8size+=(*eptr>0x7f)?2:1;
426        }
427        break;
428      default:
429        break;
430    }
431    unsigned char *utf8buf=0;
432    GPBuffer<unsigned char> gutf8buf(utf8buf,maxutf8size+1);
433    utf8buf[0]=0;
434    if (maxutf8size)
435    {
436      unsigned char *optr=utf8buf;
437      int len=0;
438      unsigned char const *iptr=(unsigned char *)buf;
439      unsigned long w;
440      switch(t)
441      {
442        case XUCS4:
443          for(;
444            (iptr<eptr)&&(w=*(unsigned long const *)iptr);
445            len++,iptr+=sizeof(unsigned long const))
446          {
447            optr=UCS4toUTF8(w,optr);
448          }
449          break;
450        case XUCS4BE:
451          for(;(w=UCS4BEtoUCS4(iptr,eptr));len++)
452          {
453            optr=UCS4toUTF8(w,optr);
454          }
455          break;
456        case XUCS4LE:
457          for(;(w=UCS4LEtoUCS4(iptr,eptr));len++)
458          {
459            optr=UCS4toUTF8(w,optr);
460          }
461          break;
462        case XUCS4_2143:
463          for(;(w=UCS4_2143toUCS4(iptr,eptr));len++)
464          {
465            optr=UCS4toUTF8(w,optr);
466          }
467          break;
468        case XUCS4_3412:
469          for(;(w=UCS4_3412toUCS4(iptr,eptr));len++)
470          {
471            optr=UCS4toUTF8(w,optr);
472          }
473          break;
474        case XUTF16:
475          for(;
476            (w=xUTF16toUCS4((unsigned short const*&)iptr,eptr));
477            len++)
478          {
479            optr=UCS4toUTF8(w,optr);
480          }
481          break;
482        case XUTF16BE:
483          for(;(w=UTF16BEtoUCS4(iptr,eptr));len++)
484          {
485            optr=UCS4toUTF8(w,optr);
486          }
487          break;
488        case XUTF16LE:
489          for(;(w=UTF16LEtoUCS4(iptr,eptr));len++)
490          {
491            optr=UCS4toUTF8(w,optr);
492          }
493          break;
494        case XUTF8:
495          for(;(w=UTF8toUCS4(iptr,eptr));len++)
496          {
497            optr=UCS4toUTF8(w,optr);
498          }
499          break;
500        case XEBCDIC:
501          for(;(iptr<eptr)&&(w=*iptr++);len++)
502          {
503            optr=UCS4toUTF8(w,optr);
504          }
505          break;
506        default:
507          break;
508      }
509      const unsigned int size=(size_t)optr-(size_t)utf8buf;
510      if(size)
511      {
512                  retval=(gretval=GStringRep::Unicode::create(size));
513        memcpy(retval->data,utf8buf,size);
514      }else
515      {
516                  retval=(gretval=GStringRep::Unicode::create(1));
517        retval->size=size;
518      }
519      retval->data[size]=0;
520      gutf8buf.resize(0);
521      const size_t s=(size_t)eptr-(size_t)iptr;
522      retval->set_remainder(iptr,s,t);
523    }
524  }
525  if(!retval)
526  {
527    retval=(gretval=GStringRep::Unicode::create(1));
528    retval->data[0]=0;
529    retval->size=0;
530    retval->set_remainder(0,0,t);
531  }
532  return gretval;
533}
534
535static unsigned long
536xUTF16toUCS4(unsigned short const *&s,void const * const eptr)
537{
538  unsigned long U=0;
539  unsigned short const * const r=s+1;
540  if(r <= eptr)
541  {
542    unsigned long const W1=s[0];
543    if((W1<0xD800)||(W1>0xDFFF))
544    {
545      if((U=W1))
546      {
547        s=r;
548      }
549    }else if(W1<=0xDBFF)
550    {
551      unsigned short const * const rr=r+1;
552      if(rr <= eptr)
553      {
554        unsigned long const W2=s[1];
555        if(((W2>=0xDC00)||(W2<=0xDFFF))&&((U=(0x1000+((W1&0x3ff)<<10))|(W2&0x3ff))))
556        {
557          s=rr;
558        }else
559        {
560          U=(unsigned int)(-1)-W1;
561          s=r;
562        }
563      }
564    }
565  }
566  return U;
567}
568
569static unsigned long
570UTF16BEtoUCS4(unsigned char const *&s,void const * const eptr)
571{
572  unsigned long U=0;
573  unsigned char const * const r=s+2;
574  if(r <= eptr)
575  {
576    unsigned long const C1MSB=s[0];
577    if((C1MSB<0xD8)||(C1MSB>0xDF))
578    {
579      if((U=((C1MSB<<8)|((unsigned long)s[1]))))
580      {
581        s=r;
582      }
583    }else if(C1MSB<=0xDB)
584    {
585      unsigned char const * const rr=r+2;
586      if(rr <= eptr)
587      {
588        unsigned long const C2MSB=s[2];
589        if((C2MSB>=0xDC)||(C2MSB<=0xDF))
590        {
591          U=0x10000+((unsigned long)s[1]<<10)+(unsigned long)s[3]
592            +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
593          s=rr;
594        }else
595        {
596          U=(unsigned int)(-1)-((C1MSB<<8)|((unsigned long)s[1]));
597          s=r;
598        }
599      }
600    }
601  }
602  return U;
603}
604
605static unsigned long
606UTF16LEtoUCS4(unsigned char const *&s,void const * const eptr)
607{
608  unsigned long U=0;
609  unsigned char const * const r=s+2;
610  if(r <= eptr)
611  {
612    unsigned long const C1MSB=s[1];
613    if((C1MSB<0xD8)||(C1MSB>0xDF))
614    {
615      if((U=((C1MSB<<8)|((unsigned long)s[0]))))
616      {
617        s=r;
618      }
619    }else if(C1MSB<=0xDB)
620    {
621      unsigned char const * const rr=r+2;
622      if(rr <= eptr)
623      {
624        unsigned long const C2MSB=s[3];
625        if((C2MSB>=0xDC)||(C2MSB<=0xDF))
626        {
627          U=0x10000+((unsigned long)s[0]<<10)+(unsigned long)s[2]
628            +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
629          s=rr;
630        }else
631        {
632          U=(unsigned int)(-1)-((C1MSB<<8)|((unsigned long)s[1]));
633          s=r;
634        }
635      }
636    }
637  }
638  return U;
639}
640
641static unsigned long
642UCS4BEtoUCS4(unsigned char const *&s,void const * const eptr)
643{
644  unsigned long U=0;
645  unsigned char const * const r=s+4;
646  if(r<=eptr)
647  {
648    U=(((((((unsigned long)s[0]<<8)|(unsigned long)s[1])<<8)|(unsigned long)s[2])<<8)|(unsigned long)s[3]);
649    if(U)
650    {
651      s=r;
652    } 
653  }
654  return U;
655}
656
657static unsigned long
658UCS4LEtoUCS4(unsigned char const *&s,void const * const eptr)
659{
660  unsigned long U=0;
661  unsigned char const * const r=s+4;
662  if(r<=eptr)
663  {
664    U=(((((((unsigned long)s[3]<<8)|(unsigned long)s[2])<<8)|(unsigned long)s[1])<<8)|(unsigned long)s[0]);
665    if(U)
666    {
667      s=r;
668    }
669  }
670  return U;
671}
672
673static unsigned long
674UCS4_2143toUCS4(unsigned char const *&s,void const * const eptr)
675{
676  unsigned long U=0;
677  unsigned char const * const r=s+4;
678  if(r<=eptr)
679  {
680    U=(((((((unsigned long)s[1]<<8)|(unsigned long)s[0])<<8)|(unsigned long)s[3])<<8)|(unsigned long)s[2]);
681    if(U)
682    {
683      s=r;
684    }
685  }
686  return U;
687}
688
689static unsigned long
690UCS4_3412toUCS4(unsigned char const *&s,void const * const eptr)
691{
692  unsigned long U=0;
693  unsigned char const * const r=s+4;
694  if(r<=eptr)
695  {
696    U=(((((((unsigned long)s[2]<<8)|(unsigned long)s[3])<<8)|(unsigned long)s[0])<<8)|(unsigned long)s[1]);
697    if(U)
698    {
699      s=r;
700    }
701  }
702  return U;
703}
704
705void
706GStringRep::Unicode::set_remainder( void const * const buf,
707   const unsigned int size, const EncodeType xencodetype )
708{
709  gremainder.resize(size,1);
710  if(size)
711    memcpy(remainder,buf,size);
712  encodetype=xencodetype;
713  encoding=0;
714}
715
716void
717GStringRep::Unicode::set_remainder( void const * const buf,
718   const unsigned int size, const GP<GStringRep> &xencoding )
719{
720  gremainder.resize(size,1);
721  if(size)
722    memcpy(remainder,buf,size);
723  encoding=xencoding;
724  encodetype=XOTHER;
725}
726
727void
728GStringRep::Unicode::set_remainder( const GP<GStringRep::Unicode> &xremainder )
729{
730  if(xremainder)
731  {
732    const int size=xremainder->gremainder;
733    gremainder.resize(size,1);
734    if(size)
735      memcpy(remainder,xremainder->remainder,size);
736    encodetype=xremainder->encodetype;
737  }else
738  {
739    gremainder.resize(0,1);
740    encodetype=XUTF8;
741  }
742}
743
744GP<GStringRep::Unicode>
745GStringRep::Unicode::get_remainder( void ) const
746{
747  return const_cast<GStringRep::Unicode *>(this);
748}
749
750GUTF8String
751GUTF8String::create(void const * const buf,const unsigned int size,
752    const EncodeType encodetype, const GUTF8String &encoding)
753{
754  return encoding.length()
755    ?create(buf,size,encodetype)
756    :create(buf,size,encoding);
757}
758
759GUTF8String
760GUTF8String::create( void const * const buf,
761  unsigned int size, const EncodeType encodetype )
762{
763  GUTF8String retval;
764  retval.init(GStringRep::Unicode::create(buf,size,encodetype));
765  return retval;
766}
767
768GUTF8String
769GUTF8String::create( void const * const buf,
770  const unsigned int size, const GP<GStringRep::Unicode> &remainder)
771{
772  GUTF8String retval;
773  retval.init(GStringRep::Unicode::create(buf,size,remainder));
774  return retval;
775}
776
777GUTF8String
778GUTF8String::create( void const * const buf,
779  const unsigned int size, const GUTF8String &encoding )
780{
781  GUTF8String retval;
782  retval.init(GStringRep::Unicode::create(buf,size,encoding ));
783  return retval;
784}
785
786
787#ifdef HAVE_NAMESPACES
788}
789# ifndef NOT_USING_DJVU_NAMESPACE
790using namespace DJVU;
791# endif
792#endif
Note: See TracBrowser for help on using the repository browser.