source: trunk/libdjvu/GUnicode.cpp @ 280

Last change on this file since 280 was 280, checked in by rbri, 12 years ago

DJVU plugin: djvulibre updated to version 3.5.22

File size: 20.1 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.14 2009/05/17 23:57:42 leonb Exp $
57// $Name: release_3_5_22 $
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
68#if HAS_ICONV
69#include <iconv.h>
70#endif
71
72#if !defined(AUTOCONF) || HAVE_STDINT_H
73# include <stdint.h>
74#elif HAVE_INTTYPES_H
75# include <inttypes.h>
76#endif
77
78
79#ifdef HAVE_NAMESPACES
80namespace DJVU {
81# ifdef NOT_DEFINED // Just to fool emacs c++ mode
82}
83#endif
84#endif
85
86static unsigned char nill=0;
87
88static void const * 
89checkmarks(void const * const xbuf,
90           unsigned int &bufsize,
91           GStringRep::EncodeType &rep)
92{
93  unsigned char const *buf=(unsigned char const *)xbuf;
94  if(bufsize >= 2 || (xbuf && !bufsize && rep != GStringRep::XOTHER))
95  {
96    const unsigned int s=(((unsigned int)buf[0])<<8)+(unsigned int)buf[1];
97    switch(s)
98    {
99      case 0:
100        if((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4BE)
101          ||(!bufsize && rep == GStringRep::XUCS4_2143))
102        {
103          const unsigned int s=(((unsigned int)buf[2])<<8)+(unsigned int)buf[3];
104          if(s == 0xfeff)
105          { 
106            rep=GStringRep::XUCS4BE;
107            buf+=4;
108          }else if(s == 0xfffe)
109          {
110            rep=GStringRep::XUCS4_2143;
111            buf+=4;
112          }
113        }
114        break;
115      case 0xfffe:
116        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4LE)) 
117           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
118        {
119          rep=GStringRep::XUCS4LE;
120          buf+=4;
121        }else
122        {
123          rep=GStringRep::XUTF16LE;
124          buf+=2;
125        }
126        break;
127      case 0xfeff:
128        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4_3412)) 
129           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
130        {
131          rep=GStringRep::XUCS4_3412;
132          buf+=4;
133        }else
134        {
135          rep=GStringRep::XUTF16LE;
136          buf+=2;
137        }
138        break;
139      case 0xefbb:
140        if(((bufsize>=3)||(!bufsize && GStringRep::XUTF8 == rep))&&(buf[2] == 0xbf))
141        {
142          rep=GStringRep::XUTF8;
143          buf+=3;
144        }
145        break;
146      default:
147        break;
148    }
149  }
150  if(buf != xbuf)
151  {
152    if(bufsize)
153    {
154      const size_t s=(size_t)xbuf-(size_t)buf;
155      if(bufsize> s)
156      {
157        bufsize-=s;
158      }else
159      {
160        bufsize=0;
161        buf=(const unsigned char *)&nill;
162      }
163    }
164  }
165  return buf;
166}
167
168class GStringRep::Unicode : public GStringRep::UTF8
169{
170public:
171  GP<GStringRep> encoding;
172  EncodeType encodetype;
173  void *remainder;
174  GPBufferBase gremainder;
175public:
176  Unicode(void);
177  /// virtual destructor.
178  virtual ~Unicode();
179
180  static GP<GStringRep> create(const unsigned int sz);
181  static GP<GStringRep> create(void const * const buf, unsigned int bufsize,
182                               const EncodeType, const GP<GStringRep> &encoding);
183  static GP<GStringRep> create( void const * const buf,
184    unsigned int size, const EncodeType encodetype );
185  static GP<GStringRep> create( void const * const buf,
186    const unsigned int size, GP<GStringRep> encoding );
187  static GP<GStringRep> create( void const * const buf,
188    const unsigned int size, const GP<Unicode> &remainder );
189
190protected:
191  virtual void set_remainder( void const * const buf, const unsigned int size,
192    const EncodeType encodetype );
193  virtual void set_remainder( void const * const buf, const unsigned int size,
194    const GP<GStringRep> &encoding );
195  virtual void set_remainder( const GP<Unicode> &remainder );
196  virtual GP<Unicode> get_remainder(void) const;
197};
198// static uint32_t UTF8toUCS4(unsigned char const *&,void const * const);
199static uint32_t xUTF16toUCS4(uint16_t const *&s,void const * const);
200static uint32_t UTF16BEtoUCS4(unsigned char const *&s,void const * const);
201static uint32_t UTF16LEtoUCS4(unsigned char const *&s,void const * const);
202static uint32_t UCS4BEtoUCS4(unsigned char const *&s,void const * const);
203static uint32_t UCS4LEtoUCS4(unsigned char const *&s,void const * const);
204static uint32_t UCS4_3412toUCS4(unsigned char const *&s,void const * const);
205static uint32_t UCS4_2143toUCS4(unsigned char const *&s,void const * const);
206
207GP<GStringRep>
208GStringRep::Unicode::create(const unsigned int sz)
209{
210  GP<GStringRep> gaddr;
211  if (sz > 0)
212  {
213    GStringRep *addr;
214    gaddr=(addr=new GStringRep::Unicode);
215    addr->data=(char *)(::operator new(sz+1));
216    addr->size = sz;
217    addr->data[sz] = 0;
218  }
219  return gaddr;
220}
221
222GStringRep::Unicode::Unicode(void)
223: encodetype(XUTF8), gremainder(remainder,0,1) {}
224
225GStringRep::Unicode::~Unicode() {}
226
227GP<GStringRep>
228GStringRep::Unicode::create(
229  void const * const xbuf,
230  unsigned int bufsize,
231  const EncodeType t,
232  const GP<GStringRep> &encoding)
233{
234  return (encoding->size)
235    ?create(xbuf,bufsize,encoding)
236    :create(xbuf,bufsize,t);
237}
238
239GP<GStringRep>
240GStringRep::Unicode::create(
241  void const * const xbuf,
242  const unsigned int bufsize,
243  const GP<Unicode> &xremainder )
244{
245  Unicode *r=xremainder;
246  GP<GStringRep> retval;
247  if(r)
248  {
249    const int s=r->gremainder;
250    if(xbuf && bufsize)
251    {
252      if(s)
253      {
254        void *buf;
255        GPBufferBase gbuf(buf,s+bufsize,1);
256        memcpy(buf,r->remainder,s);
257        memcpy((void *)((size_t)buf+s),xbuf,bufsize);
258        retval=((r->encoding)
259          ?create(buf,s+bufsize,r->encoding)
260          :create(buf,s+bufsize,r->encodetype));
261      }else
262      {
263        retval=((r->encoding)
264          ?create(xbuf,bufsize,r->encoding)
265          :create(xbuf,bufsize,r->encodetype));
266      }
267    }else if(s)
268        {
269      void *buf;
270      GPBufferBase gbuf(buf,s,1);
271      memcpy(buf,r->remainder,s);
272      retval=((r->encoding)
273        ?create(buf,s,r->encoding)
274        :create(buf,s,r->encodetype));
275        }else
276    {
277      retval=((r->encoding)
278        ?create(0,0,r->encoding)
279        :create(0,0,r->encodetype));
280    }
281  }else
282  {
283    retval=create(xbuf,bufsize,XUTF8);
284  }
285  return retval;
286}
287
288#if HAS_ICONV
289/* This template works around incompatible iconv protoypes */
290template<typename _T> inline size_t 
291iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t *, char**, size_t*),
292              iconv_t cd, char **inbuf, size_t *inbytesleft,
293              char **outbuf, size_t *outbytesleft)
294{
295  return iconv_func (cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
296}
297#endif
298
299GP<GStringRep>
300GStringRep::Unicode::create(
301  void const * const xbuf,
302  unsigned int bufsize,
303  GP<GStringRep> encoding)
304{
305  GP<GStringRep> retval;
306  GStringRep *e=encoding;
307  if(e)
308  {
309    e=(encoding=e->upcase());
310  }
311  if(!e || !e->size)
312  {
313    retval=create(xbuf,bufsize,XOTHER);
314  }else if(!e->cmp("UTF8") || !e->cmp("UTF-8"))
315  {
316    retval=create(xbuf,bufsize,XUTF8);
317  }else if(!e->cmp("UTF16")|| !e->cmp("UTF-16")
318    || !e->cmp("UCS2") || !e->cmp("UCS2"))
319  {
320    retval=create(xbuf,bufsize,XUTF16);
321  }else if(!e->cmp("UCS4") || !e->cmp("UCS-4"))
322  {
323    retval=create(xbuf,bufsize,XUCS4);
324  }else
325  {
326#if HAS_ICONV
327    EncodeType t=XOTHER;
328    void const * const buf=checkmarks(xbuf,bufsize,t); 
329    if(t != XOTHER)
330    {
331      retval=create(xbuf,bufsize,t);
332    }else if(buf && bufsize)
333    {
334      unsigned char const *eptr=(unsigned char *)buf;
335      unsigned int j=0;
336      for(j=0;(j<bufsize)&&*eptr;j++,eptr++)
337        EMPTY_LOOP;
338      if (j)
339      {
340        unsigned char const *ptr=(unsigned char *)buf;
341        if(e)
342        {
343          iconv_t cv=iconv_open("UTF-8",(const char *)e);
344          if(cv == (iconv_t)(-1))
345          { 
346            const int i=e->search('-');
347            if(i>=0)
348            {
349              cv=iconv_open("UTF-8",e->data+i+1);
350            }
351          }
352          if(cv == (iconv_t)(-1))
353          { 
354            retval=create(0,0,XOTHER);
355          }else
356          {
357            size_t ptrleft=(eptr-ptr); 
358            char *utf8buf;
359            size_t pleft=6*ptrleft+1;
360            GPBuffer<char> gutf8buf(utf8buf,pleft);
361            char *p=utf8buf;
362            char *nptr = (char*)ptr;
363            while(iconv_adaptor(iconv, cv, &nptr, &ptrleft, &p, &pleft)) 
364              ptr = (unsigned char*)nptr;
365            iconv_close(cv);
366            retval=create(utf8buf,(size_t)ptr-(size_t)buf,t);
367            retval->set_remainder(ptr,(size_t)eptr-(size_t)ptr,e);
368          }
369        }
370      }else
371      {
372        retval=create(0,0,XOTHER);
373        retval->set_remainder(0,0,e);
374      }
375    }
376#else
377    retval=create(xbuf,bufsize,XOTHER);
378#endif
379  }
380  return retval;
381}
382
383GP<GStringRep>
384GStringRep::Unicode::create(
385  void const * const xbuf,
386  unsigned int bufsize,
387  EncodeType t)
388{
389  GP<GStringRep> gretval;
390  GStringRep *retval=0;
391  void const * const buf=checkmarks(xbuf,bufsize,t); 
392  if(buf && bufsize)
393  {
394    unsigned char const *eptr=(unsigned char *)buf;
395    unsigned int maxutf8size=0;
396    void const* const xeptr=(void const *)((size_t)eptr+bufsize);
397    switch(t)
398    {
399      case XUCS4:
400      case XUCS4BE:
401      case XUCS4LE:
402      case XUCS4_2143:
403      case XUCS4_3412:
404      {
405        for(uint32_t w;
406          (eptr<xeptr)&&(w=*(uint32_t const *)eptr);
407          eptr+=sizeof(uint32_t))
408        {
409          maxutf8size+=(w>0x7f)?6:1;
410        }
411        break;
412      }
413      case XUTF16:
414      case XUTF16BE:
415      case XUTF16LE:
416      {
417        for(uint16_t w;
418          (eptr<xeptr)&&(w=*(uint16_t const *)eptr);
419          eptr+=sizeof(uint16_t))
420        {
421          maxutf8size+=3;
422        }
423        break;
424      }
425      case XUTF8:
426        for(;(eptr<xeptr)&&*eptr;maxutf8size++,eptr++)
427          EMPTY_LOOP;
428        break;
429      case XEBCDIC:
430        for(;(eptr<xeptr)&&*eptr;eptr++)
431        {
432          maxutf8size+=(*eptr>0x7f)?2:1;
433        }
434        break;
435      default:
436        break;
437    }
438    unsigned char *utf8buf=0;
439    GPBuffer<unsigned char> gutf8buf(utf8buf,maxutf8size+1);
440    utf8buf[0]=0;
441    if (maxutf8size)
442    {
443      unsigned char *optr=utf8buf;
444      int len=0;
445      unsigned char const *iptr=(unsigned char *)buf;
446      uint16_t const *sptr=(uint16_t *)buf;
447      uint32_t w;
448      switch(t)
449      {
450        case XUCS4:
451          for(;
452            (iptr<eptr)&&(w=*(uint32_t const *)iptr);
453            len++,iptr+=sizeof(uint32_t const))
454          {
455            optr=UCS4toUTF8(w,optr);
456          }
457          break;
458        case XUCS4BE:
459          for(;(w=UCS4BEtoUCS4(iptr,eptr));len++)
460          {
461            optr=UCS4toUTF8(w,optr);
462          }
463          break;
464        case XUCS4LE:
465          for(;(w=UCS4LEtoUCS4(iptr,eptr));len++)
466          {
467            optr=UCS4toUTF8(w,optr);
468          }
469          break;
470        case XUCS4_2143:
471          for(;(w=UCS4_2143toUCS4(iptr,eptr));len++)
472          {
473            optr=UCS4toUTF8(w,optr);
474          }
475          break;
476        case XUCS4_3412:
477          for(;(w=UCS4_3412toUCS4(iptr,eptr));len++)
478          {
479            optr=UCS4toUTF8(w,optr);
480          }
481          break;
482        case XUTF16:
483          for(;(w=xUTF16toUCS4(sptr,eptr));len++)
484          {
485            optr=UCS4toUTF8(w,optr);
486          }
487          break;
488        case XUTF16BE:
489          for(;(w=UTF16BEtoUCS4(iptr,eptr));len++)
490          {
491            optr=UCS4toUTF8(w,optr);
492          }
493          break;
494        case XUTF16LE:
495          for(;(w=UTF16LEtoUCS4(iptr,eptr));len++)
496          {
497            optr=UCS4toUTF8(w,optr);
498          }
499          break;
500        case XUTF8:
501          for(;(w=UTF8toUCS4(iptr,eptr));len++)
502          {
503            optr=UCS4toUTF8(w,optr);
504          }
505          break;
506        case XEBCDIC:
507          for(;(iptr<eptr)&&(w=*iptr++);len++)
508          {
509            optr=UCS4toUTF8(w,optr);
510          }
511          break;
512        default:
513          break;
514      }
515      const unsigned int size=(size_t)optr-(size_t)utf8buf;
516      if(size)
517      {
518                  retval=(gretval=GStringRep::Unicode::create(size));
519        memcpy(retval->data,utf8buf,size);
520      }else
521      {
522                  retval=(gretval=GStringRep::Unicode::create(1));
523        retval->size=size;
524      }
525      retval->data[size]=0;
526      gutf8buf.resize(0);
527      const size_t s=(size_t)eptr-(size_t)iptr;
528      retval->set_remainder(iptr,s,t);
529    }
530  }
531  if(!retval)
532  {
533    retval=(gretval=GStringRep::Unicode::create(1));
534    retval->data[0]=0;
535    retval->size=0;
536    retval->set_remainder(0,0,t);
537  }
538  return gretval;
539}
540
541static uint32_t
542xUTF16toUCS4(uint16_t const *&s,void const * const eptr)
543{
544  uint32_t U=0;
545  uint16_t const * const r=s+1;
546  if(r <= eptr)
547  {
548    uint32_t const W1=s[0];
549    if((W1<0xD800)||(W1>0xDFFF))
550    {
551      if((U=W1))
552      {
553        s=r;
554      }
555    }else if(W1<=0xDBFF)
556    {
557      uint16_t const * const rr=r+1;
558      if(rr <= eptr)
559      {
560        uint32_t const W2=s[1];
561        if(((W2>=0xDC00)||(W2<=0xDFFF))&&((U=(0x1000+((W1&0x3ff)<<10))|(W2&0x3ff))))
562        {
563          s=rr;
564        }else
565        {
566          U=(unsigned int)(-1)-W1;
567          s=r;
568        }
569      }
570    }
571  }
572  return U;
573}
574
575static uint32_t
576UTF16BEtoUCS4(unsigned char const *&s,void const * const eptr)
577{
578  uint32_t U=0;
579  unsigned char const * const r=s+2;
580  if(r <= eptr)
581  {
582    uint32_t const C1MSB=s[0];
583    if((C1MSB<0xD8)||(C1MSB>0xDF))
584    {
585      if((U=((C1MSB<<8)|((uint32_t)s[1]))))
586      {
587        s=r;
588      }
589    }else if(C1MSB<=0xDB)
590    {
591      unsigned char const * const rr=r+2;
592      if(rr <= eptr)
593      {
594        uint32_t const C2MSB=s[2];
595        if((C2MSB>=0xDC)||(C2MSB<=0xDF))
596        {
597          U=0x10000+((uint32_t)s[1]<<10)+(uint32_t)s[3]
598            +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
599          s=rr;
600        }else
601        {
602          U=(unsigned int)(-1)-((C1MSB<<8)|((uint32_t)s[1]));
603          s=r;
604        }
605      }
606    }
607  }
608  return U;
609}
610
611static uint32_t
612UTF16LEtoUCS4(unsigned char const *&s,void const * const eptr)
613{
614  uint32_t U=0;
615  unsigned char const * const r=s+2;
616  if(r <= eptr)
617  {
618    uint32_t const C1MSB=s[1];
619    if((C1MSB<0xD8)||(C1MSB>0xDF))
620    {
621      if((U=((C1MSB<<8)|((uint32_t)s[0]))))
622      {
623        s=r;
624      }
625    }else if(C1MSB<=0xDB)
626    {
627      unsigned char const * const rr=r+2;
628      if(rr <= eptr)
629      {
630        uint32_t const C2MSB=s[3];
631        if((C2MSB>=0xDC)||(C2MSB<=0xDF))
632        {
633          U=0x10000+((uint32_t)s[0]<<10)+(uint32_t)s[2]
634            +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
635          s=rr;
636        }else
637        {
638          U=(unsigned int)(-1)-((C1MSB<<8)|((uint32_t)s[1]));
639          s=r;
640        }
641      }
642    }
643  }
644  return U;
645}
646
647static uint32_t
648UCS4BEtoUCS4(unsigned char const *&s,void const * const eptr)
649{
650  uint32_t U=0;
651  unsigned char const * const r=s+4;
652  if(r<=eptr)
653  {
654    U=(((((((uint32_t)s[0]<<8)|(uint32_t)s[1])<<8)|(uint32_t)s[2])<<8)|(uint32_t)s[3]);
655    if(U)
656    {
657      s=r;
658    } 
659  }
660  return U;
661}
662
663static uint32_t
664UCS4LEtoUCS4(unsigned char const *&s,void const * const eptr)
665{
666  uint32_t U=0;
667  unsigned char const * const r=s+4;
668  if(r<=eptr)
669  {
670    U=(((((((uint32_t)s[3]<<8)|(uint32_t)s[2])<<8)|(uint32_t)s[1])<<8)|(uint32_t)s[0]);
671    if(U)
672    {
673      s=r;
674    }
675  }
676  return U;
677}
678
679static uint32_t
680UCS4_2143toUCS4(unsigned char const *&s,void const * const eptr)
681{
682  uint32_t U=0;
683  unsigned char const * const r=s+4;
684  if(r<=eptr)
685  {
686    U=(((((((uint32_t)s[1]<<8)|(uint32_t)s[0])<<8)|(uint32_t)s[3])<<8)|(uint32_t)s[2]);
687    if(U)
688    {
689      s=r;
690    }
691  }
692  return U;
693}
694
695static uint32_t
696UCS4_3412toUCS4(unsigned char const *&s,void const * const eptr)
697{
698  uint32_t U=0;
699  unsigned char const * const r=s+4;
700  if(r<=eptr)
701  {
702    U=(((((((uint32_t)s[2]<<8)|(uint32_t)s[3])<<8)|(uint32_t)s[0])<<8)|(uint32_t)s[1]);
703    if(U)
704    {
705      s=r;
706    }
707  }
708  return U;
709}
710
711void
712GStringRep::Unicode::set_remainder( void const * const buf,
713   const unsigned int size, const EncodeType xencodetype )
714{
715  gremainder.resize(size,1);
716  if(size)
717    memcpy(remainder,buf,size);
718  encodetype=xencodetype;
719  encoding=0;
720}
721
722void
723GStringRep::Unicode::set_remainder( void const * const buf,
724   const unsigned int size, const GP<GStringRep> &xencoding )
725{
726  gremainder.resize(size,1);
727  if(size)
728    memcpy(remainder,buf,size);
729  encoding=xencoding;
730  encodetype=XOTHER;
731}
732
733void
734GStringRep::Unicode::set_remainder( const GP<GStringRep::Unicode> &xremainder )
735{
736  if(xremainder)
737  {
738    const int size=xremainder->gremainder;
739    gremainder.resize(size,1);
740    if(size)
741      memcpy(remainder,xremainder->remainder,size);
742    encodetype=xremainder->encodetype;
743  }else
744  {
745    gremainder.resize(0,1);
746    encodetype=XUTF8;
747  }
748}
749
750GP<GStringRep::Unicode>
751GStringRep::Unicode::get_remainder( void ) const
752{
753  return const_cast<GStringRep::Unicode *>(this);
754}
755
756GUTF8String
757GUTF8String::create(void const * const buf,const unsigned int size,
758    const EncodeType encodetype, const GUTF8String &encoding)
759{
760  return encoding.length()
761    ?create(buf,size,encodetype)
762    :create(buf,size,encoding);
763}
764
765GUTF8String
766GUTF8String::create( void const * const buf,
767  unsigned int size, const EncodeType encodetype )
768{
769  GUTF8String retval;
770  retval.init(GStringRep::Unicode::create(buf,size,encodetype));
771  return retval;
772}
773
774GUTF8String
775GUTF8String::create( void const * const buf,
776  const unsigned int size, const GP<GStringRep::Unicode> &remainder)
777{
778  GUTF8String retval;
779  retval.init(GStringRep::Unicode::create(buf,size,remainder));
780  return retval;
781}
782
783GUTF8String
784GUTF8String::create( void const * const buf,
785  const unsigned int size, const GUTF8String &encoding )
786{
787  GUTF8String retval;
788  retval.init(GStringRep::Unicode::create(buf,size,encoding ));
789  return retval;
790}
791
792
793#ifdef HAVE_NAMESPACES
794}
795# ifndef NOT_USING_DJVU_NAMESPACE
796using namespace DJVU;
797# endif
798#endif
Note: See TracBrowser for help on using the repository browser.