Blame libdjvu/GUnicode.cpp

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
# include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma implementation
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#include "GString.h"
Packit df99a1
Packit df99a1
#include <stddef.h>
Packit df99a1
Packit df99a1
#if HAS_ICONV
Packit df99a1
#include <iconv.h>
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
static unsigned char nill=0;
Packit df99a1
Packit df99a1
static void const * 
Packit df99a1
checkmarks(void const * const xbuf,
Packit df99a1
           unsigned int &bufsize,
Packit df99a1
           GStringRep::EncodeType &rep)
Packit df99a1
{
Packit df99a1
  unsigned char const *buf=(unsigned char const *)xbuf;
Packit df99a1
  if(bufsize >= 2 || (xbuf && !bufsize && rep != GStringRep::XOTHER))
Packit df99a1
  {
Packit df99a1
    const unsigned int s=(((unsigned int)buf[0])<<8)+(unsigned int)buf[1];
Packit df99a1
    switch(s)
Packit df99a1
    {
Packit df99a1
      case 0:
Packit df99a1
        if((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4BE)
Packit df99a1
          ||(!bufsize && rep == GStringRep::XUCS4_2143))
Packit df99a1
        {
Packit df99a1
          const unsigned int s=(((unsigned int)buf[2])<<8)+(unsigned int)buf[3];
Packit df99a1
          if(s == 0xfeff)
Packit df99a1
          { 
Packit df99a1
            rep=GStringRep::XUCS4BE;
Packit df99a1
            buf+=4;
Packit df99a1
          }else if(s == 0xfffe)
Packit df99a1
          {
Packit df99a1
            rep=GStringRep::XUCS4_2143;
Packit df99a1
            buf+=4;
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      case 0xfffe:
Packit df99a1
        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4LE)) 
Packit df99a1
           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
Packit df99a1
        {
Packit df99a1
          rep=GStringRep::XUCS4LE;
Packit df99a1
          buf+=4;
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          rep=GStringRep::XUTF16LE;
Packit df99a1
          buf+=2;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      case 0xfeff:
Packit df99a1
        if(((bufsize>=4)||(!bufsize && rep == GStringRep::XUCS4_3412)) 
Packit df99a1
           && !((unsigned char *)buf)[2] && !((unsigned char *)buf)[3])
Packit df99a1
        {
Packit df99a1
          rep=GStringRep::XUCS4_3412;
Packit df99a1
          buf+=4;
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          rep=GStringRep::XUTF16LE;
Packit df99a1
          buf+=2;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      case 0xefbb:
Packit df99a1
        if(((bufsize>=3)||(!bufsize && GStringRep::XUTF8 == rep))&&(buf[2] == 0xbf))
Packit df99a1
        {
Packit df99a1
          rep=GStringRep::XUTF8;
Packit df99a1
          buf+=3;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      default:
Packit df99a1
        break;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  if(buf != xbuf)
Packit df99a1
  {
Packit df99a1
    if(bufsize)
Packit df99a1
    {
Packit df99a1
      const size_t s=(size_t)xbuf-(size_t)buf;
Packit df99a1
      if(bufsize> s)
Packit df99a1
      {
Packit df99a1
        bufsize-=s;
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        bufsize=0;
Packit df99a1
        buf=(const unsigned char *)&nil;;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return buf;
Packit df99a1
}
Packit df99a1
Packit df99a1
class GStringRep::Unicode : public GStringRep::UTF8
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  GP<GStringRep> encoding;
Packit df99a1
  EncodeType encodetype;
Packit df99a1
  void *remainder;
Packit df99a1
  GPBufferBase gremainder;
Packit df99a1
public:
Packit df99a1
  Unicode(void);
Packit df99a1
  /// virtual destructor.
Packit df99a1
  virtual ~Unicode();
Packit df99a1
Packit df99a1
  static GP<GStringRep> create(const unsigned int sz);
Packit df99a1
  static GP<GStringRep> create(void const * const buf, unsigned int bufsize,
Packit df99a1
                               const EncodeType, const GP<GStringRep> &encoding);
Packit df99a1
  static GP<GStringRep> create( void const * const buf,
Packit df99a1
    unsigned int size, const EncodeType encodetype );
Packit df99a1
  static GP<GStringRep> create( void const * const buf,
Packit df99a1
    const unsigned int size, GP<GStringRep> encoding );
Packit df99a1
  static GP<GStringRep> create( void const * const buf,
Packit df99a1
    const unsigned int size, const GP<Unicode> &remainder );
Packit df99a1
Packit df99a1
protected:
Packit df99a1
  virtual void set_remainder( void const * const buf, const unsigned int size,
Packit df99a1
    const EncodeType encodetype );
Packit df99a1
  virtual void set_remainder( void const * const buf, const unsigned int size,
Packit df99a1
    const GP<GStringRep> &encoding );
Packit df99a1
  virtual void set_remainder( const GP<Unicode> &remainder );
Packit df99a1
  virtual GP<Unicode> get_remainder(void) const;
Packit df99a1
};
Packit df99a1
// static uint32_t UTF8toUCS4(unsigned char const *&,void const * const);
Packit df99a1
static uint32_t xUTF16toUCS4(uint16_t const *&s,void const * const);
Packit df99a1
static uint32_t UTF16BEtoUCS4(unsigned char const *&s,void const * const);
Packit df99a1
static uint32_t UTF16LEtoUCS4(unsigned char const *&s,void const * const);
Packit df99a1
static uint32_t UCS4BEtoUCS4(unsigned char const *&s,void const * const);
Packit df99a1
static uint32_t UCS4LEtoUCS4(unsigned char const *&s,void const * const);
Packit df99a1
static uint32_t UCS4_3412toUCS4(unsigned char const *&s,void const * const);
Packit df99a1
static uint32_t UCS4_2143toUCS4(unsigned char const *&s,void const * const);
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Unicode::create(const unsigned int sz)
Packit df99a1
{
Packit df99a1
  GP<GStringRep> gaddr;
Packit df99a1
  if (sz > 0)
Packit df99a1
  {
Packit df99a1
    GStringRep *addr;
Packit df99a1
    gaddr=(addr=new GStringRep::Unicode);
Packit df99a1
    addr->data=(char *)(::operator new(sz+1));
Packit df99a1
    addr->size = sz;
Packit df99a1
    addr->data[sz] = 0;
Packit df99a1
  }
Packit df99a1
  return gaddr;
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::Unicode::Unicode(void)
Packit df99a1
: encodetype(XUTF8), gremainder(remainder,0,1) {}
Packit df99a1
Packit df99a1
GStringRep::Unicode::~Unicode() {}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Unicode::create(
Packit df99a1
  void const * const xbuf,
Packit df99a1
  unsigned int bufsize,
Packit df99a1
  const EncodeType t,
Packit df99a1
  const GP<GStringRep> &encoding)
Packit df99a1
{
Packit df99a1
  return (encoding->size)
Packit df99a1
    ?create(xbuf,bufsize,encoding)
Packit df99a1
    :create(xbuf,bufsize,t);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Unicode::create(
Packit df99a1
  void const * const xbuf,
Packit df99a1
  const unsigned int bufsize,
Packit df99a1
  const GP<Unicode> &xremainder )
Packit df99a1
{
Packit df99a1
  Unicode *r=xremainder;
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(r)
Packit df99a1
  {
Packit df99a1
    const int s=r->gremainder;
Packit df99a1
    if(xbuf && bufsize)
Packit df99a1
    {
Packit df99a1
      if(s)
Packit df99a1
      {
Packit df99a1
        void *buf;
Packit df99a1
        GPBufferBase gbuf(buf,s+bufsize,1);
Packit df99a1
        memcpy(buf,r->remainder,s);
Packit df99a1
        memcpy((void *)((size_t)buf+s),xbuf,bufsize);
Packit df99a1
        retval=((r->encoding)
Packit df99a1
          ?create(buf,s+bufsize,r->encoding)
Packit df99a1
          :create(buf,s+bufsize,r->encodetype));
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=((r->encoding)
Packit df99a1
          ?create(xbuf,bufsize,r->encoding)
Packit df99a1
          :create(xbuf,bufsize,r->encodetype));
Packit df99a1
      }
Packit df99a1
    }else if(s)
Packit df99a1
	{
Packit df99a1
      void *buf;
Packit df99a1
      GPBufferBase gbuf(buf,s,1);
Packit df99a1
      memcpy(buf,r->remainder,s);
Packit df99a1
      retval=((r->encoding)
Packit df99a1
        ?create(buf,s,r->encoding)
Packit df99a1
        :create(buf,s,r->encodetype));
Packit df99a1
	}else
Packit df99a1
    {
Packit df99a1
      retval=((r->encoding)
Packit df99a1
        ?create(0,0,r->encoding)
Packit df99a1
        :create(0,0,r->encodetype));
Packit df99a1
    }
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=create(xbuf,bufsize,XUTF8);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
#if HAS_ICONV
Packit df99a1
/* This template works around incompatible iconv protoypes */
Packit df99a1
template<typename _T> inline size_t 
Packit df99a1
iconv_adaptor(size_t(*iconv_func)(iconv_t, _T, size_t *, char**, size_t*),
Packit df99a1
              iconv_t cd, char **inbuf, size_t *inbytesleft,
Packit df99a1
              char **outbuf, size_t *outbytesleft)
Packit df99a1
{
Packit df99a1
  return iconv_func (cd, (_T)inbuf, inbytesleft, outbuf, outbytesleft);
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Unicode::create(
Packit df99a1
  void const * const xbuf,
Packit df99a1
  unsigned int bufsize,
Packit df99a1
  GP<GStringRep> encoding)
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  GStringRep *e=encoding;
Packit df99a1
  if(e)
Packit df99a1
  {
Packit df99a1
    e=(encoding=e->upcase());
Packit df99a1
  }
Packit df99a1
  if(!e || !e->size)
Packit df99a1
  {
Packit df99a1
    retval=create(xbuf,bufsize,XOTHER);
Packit df99a1
  }else if(!e->cmp("UTF8") || !e->cmp("UTF-8"))
Packit df99a1
  {
Packit df99a1
    retval=create(xbuf,bufsize,XUTF8);
Packit df99a1
  }else if(!e->cmp("UTF16")|| !e->cmp("UTF-16")
Packit df99a1
        || !e->cmp("UCS2") || !e->cmp("UCS-2"))
Packit df99a1
  {
Packit df99a1
    retval=create(xbuf,bufsize,XUTF16);
Packit df99a1
  }else if(!e->cmp("UCS4") || !e->cmp("UCS-4"))
Packit df99a1
  {
Packit df99a1
    retval=create(xbuf,bufsize,XUCS4);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
#if HAS_ICONV
Packit df99a1
    EncodeType t=XOTHER;
Packit df99a1
    void const * const buf=checkmarks(xbuf,bufsize,t); 
Packit df99a1
    if(t != XOTHER)
Packit df99a1
    {
Packit df99a1
      retval=create(xbuf,bufsize,t);
Packit df99a1
    }else if(buf && bufsize)
Packit df99a1
    {
Packit df99a1
      unsigned char const *eptr=(unsigned char *)buf;
Packit df99a1
      unsigned int j=0;
Packit df99a1
      for(j=0;(j
Packit df99a1
        EMPTY_LOOP;
Packit df99a1
      if (j)
Packit df99a1
      {
Packit df99a1
        unsigned char const *ptr=(unsigned char *)buf;
Packit df99a1
        if(e)
Packit df99a1
        {
Packit df99a1
          iconv_t cv=iconv_open("UTF-8",(const char *)e);
Packit df99a1
          if(cv == (iconv_t)(-1))
Packit df99a1
          { 
Packit df99a1
            const int i=e->search('-');
Packit df99a1
            if(i>=0)
Packit df99a1
            {
Packit df99a1
              cv=iconv_open("UTF-8",e->data+i+1);
Packit df99a1
            }
Packit df99a1
          }
Packit df99a1
          if(cv == (iconv_t)(-1))
Packit df99a1
          { 
Packit df99a1
            retval=create(0,0,XOTHER);
Packit df99a1
          }else
Packit df99a1
          {
Packit df99a1
            size_t ptrleft=(eptr-ptr); 
Packit df99a1
            char *utf8buf;
Packit df99a1
            size_t pleft=6*ptrleft+1;
Packit df99a1
            GPBuffer<char> gutf8buf(utf8buf,pleft);
Packit df99a1
            char *p=utf8buf;
Packit df99a1
            char *nptr = (char*)ptr;
Packit df99a1
            while(iconv_adaptor(iconv, cv, &nptr, &ptrleft, &p, &pleft)) 
Packit df99a1
              ptr = (unsigned char*)nptr;
Packit df99a1
            iconv_close(cv);
Packit df99a1
            retval=create(utf8buf,(size_t)ptr-(size_t)buf,t);
Packit df99a1
            retval->set_remainder(ptr,(size_t)eptr-(size_t)ptr,e);
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=create(0,0,XOTHER);
Packit df99a1
        retval->set_remainder(0,0,e);
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
#else
Packit df99a1
    retval=create(xbuf,bufsize,XOTHER);
Packit df99a1
#endif
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Unicode::create(
Packit df99a1
  void const * const xbuf,
Packit df99a1
  unsigned int bufsize,
Packit df99a1
  EncodeType t)
Packit df99a1
{
Packit df99a1
  GP<GStringRep> gretval;
Packit df99a1
  GStringRep *retval=0;
Packit df99a1
  void const * const buf=checkmarks(xbuf,bufsize,t); 
Packit df99a1
  if(buf && bufsize)
Packit df99a1
  {
Packit df99a1
    unsigned char const *eptr=(unsigned char *)buf;
Packit df99a1
    unsigned int maxutf8size=0;
Packit df99a1
    void const* const xeptr=(void const *)((size_t)eptr+bufsize);
Packit df99a1
    switch(t)
Packit df99a1
    {
Packit df99a1
      case XUCS4:
Packit df99a1
      case XUCS4BE:
Packit df99a1
      case XUCS4LE:
Packit df99a1
      case XUCS4_2143:
Packit df99a1
      case XUCS4_3412:
Packit df99a1
      {
Packit df99a1
        for(uint32_t w;
Packit df99a1
          (eptr
Packit df99a1
          eptr+=sizeof(uint32_t))
Packit df99a1
        {
Packit df99a1
          maxutf8size+=(w>0x7f)?6:1;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      }
Packit df99a1
      case XUTF16:
Packit df99a1
      case XUTF16BE:
Packit df99a1
      case XUTF16LE:
Packit df99a1
      {
Packit df99a1
        for(uint16_t w;
Packit df99a1
          (eptr
Packit df99a1
          eptr+=sizeof(uint16_t))
Packit df99a1
        {
Packit df99a1
          maxutf8size+=3;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      }
Packit df99a1
      case XUTF8:
Packit df99a1
        for(;(eptr
Packit df99a1
          EMPTY_LOOP;
Packit df99a1
        break;
Packit df99a1
      case XEBCDIC:
Packit df99a1
        for(;(eptr
Packit df99a1
        {
Packit df99a1
          maxutf8size+=(*eptr>0x7f)?2:1;
Packit df99a1
        }
Packit df99a1
        break;
Packit df99a1
      default:
Packit df99a1
        break;
Packit df99a1
    }
Packit df99a1
    unsigned char *utf8buf=0;
Packit df99a1
    GPBuffer<unsigned char> gutf8buf(utf8buf,maxutf8size+1);
Packit df99a1
    utf8buf[0]=0;
Packit df99a1
    if (maxutf8size)
Packit df99a1
    {
Packit df99a1
      unsigned char *optr=utf8buf;
Packit df99a1
      int len=0;
Packit df99a1
      unsigned char const *iptr=(unsigned char *)buf;
Packit df99a1
      uint16_t const *sptr=(uint16_t *)buf;
Packit df99a1
      uint32_t w;
Packit df99a1
      switch(t)
Packit df99a1
      {
Packit df99a1
        case XUCS4:
Packit df99a1
          for(;
Packit df99a1
            (iptr
Packit df99a1
            len++,iptr+=sizeof(uint32_t const))
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUCS4BE:
Packit df99a1
          for(;(w=UCS4BEtoUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUCS4LE:
Packit df99a1
          for(;(w=UCS4LEtoUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUCS4_2143:
Packit df99a1
          for(;(w=UCS4_2143toUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUCS4_3412:
Packit df99a1
          for(;(w=UCS4_3412toUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUTF16:
Packit df99a1
          for(;(w=xUTF16toUCS4(sptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUTF16BE:
Packit df99a1
          for(;(w=UTF16BEtoUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUTF16LE:
Packit df99a1
          for(;(w=UTF16LEtoUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XUTF8:
Packit df99a1
          for(;(w=UTF8toUCS4(iptr,eptr));len++)
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        case XEBCDIC:
Packit df99a1
          for(;(iptr
Packit df99a1
          {
Packit df99a1
            optr=UCS4toUTF8(w,optr);
Packit df99a1
          }
Packit df99a1
          break;
Packit df99a1
        default:
Packit df99a1
          break;
Packit df99a1
      }
Packit df99a1
      const unsigned int size=(size_t)optr-(size_t)utf8buf;
Packit df99a1
      if(size)
Packit df99a1
      {
Packit df99a1
        retval=(gretval=GStringRep::Unicode::create(size));
Packit df99a1
        memcpy(retval->data,utf8buf,size);
Packit df99a1
      }
Packit df99a1
      else
Packit df99a1
      {
Packit df99a1
        retval=(gretval=GStringRep::Unicode::create(1));
Packit df99a1
        retval->size=size;
Packit df99a1
      }
Packit df99a1
      retval->data[size]=0;
Packit df99a1
      gutf8buf.resize(0);
Packit df99a1
      const size_t s=(size_t)eptr-(size_t)iptr;
Packit df99a1
      retval->set_remainder(iptr,s,t);
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  if(!retval)
Packit df99a1
    {
Packit df99a1
      retval=(gretval=GStringRep::Unicode::create(1));
Packit df99a1
      retval->data[0]=0;
Packit df99a1
      retval->size=0;
Packit df99a1
      retval->set_remainder(0,0,t);
Packit df99a1
    }
Packit df99a1
  return gretval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
xUTF16toUCS4(uint16_t const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  uint16_t const * const r=s+1;
Packit df99a1
  if(r <= eptr)
Packit df99a1
  {
Packit df99a1
    uint32_t const W1=s[0];
Packit df99a1
    if((W1<0xD800)||(W1>0xDFFF))
Packit df99a1
    {
Packit df99a1
      if((U=W1))
Packit df99a1
        {
Packit df99a1
          s=r;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
    else if(W1<=0xDBFF)
Packit df99a1
      {
Packit df99a1
        uint16_t const * const rr=r+1;
Packit df99a1
        if(rr <= eptr)
Packit df99a1
          {
Packit df99a1
            uint32_t const W2=s[1];
Packit df99a1
            if(((W2>=0xDC00)||(W2<=0xDFFF))
Packit df99a1
               &&((U=(0x1000+((W1&0x3ff)<<10))|(W2&0x3ff))))
Packit df99a1
              {
Packit df99a1
                s=rr;
Packit df99a1
              }
Packit df99a1
            else
Packit df99a1
              {
Packit df99a1
                U=(unsigned int)(-1)-W1;
Packit df99a1
                s=r;
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
  }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UTF16BEtoUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+2;
Packit df99a1
  if(r <= eptr)
Packit df99a1
    {
Packit df99a1
      uint32_t const C1MSB=s[0];
Packit df99a1
      if((C1MSB<0xD8)||(C1MSB>0xDF))
Packit df99a1
        {
Packit df99a1
          if((U=((C1MSB<<8)|((uint32_t)s[1]))))
Packit df99a1
            {
Packit df99a1
              s=r;
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      else if(C1MSB<=0xDB)
Packit df99a1
        {
Packit df99a1
          unsigned char const * const rr=r+2;
Packit df99a1
          if(rr <= eptr)
Packit df99a1
            {
Packit df99a1
              uint32_t const C2MSB=s[2];
Packit df99a1
              if((C2MSB>=0xDC)||(C2MSB<=0xDF))
Packit df99a1
                {
Packit df99a1
                  U=0x10000+((uint32_t)s[1]<<10)+(uint32_t)s[3]
Packit df99a1
                    +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
Packit df99a1
                  s=rr;
Packit df99a1
                }
Packit df99a1
              else
Packit df99a1
                {
Packit df99a1
                  U=(unsigned int)(-1)-((C1MSB<<8)|((uint32_t)s[1]));
Packit df99a1
                  s=r;
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UTF16LEtoUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+2;
Packit df99a1
  if(r <= eptr)
Packit df99a1
    {
Packit df99a1
      uint32_t const C1MSB=s[1];
Packit df99a1
      if((C1MSB<0xD8)||(C1MSB>0xDF))
Packit df99a1
        {
Packit df99a1
          if((U=((C1MSB<<8)|((uint32_t)s[0]))))
Packit df99a1
            {
Packit df99a1
              s=r;
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      else if(C1MSB<=0xDB)
Packit df99a1
        {
Packit df99a1
          unsigned char const * const rr=r+2;
Packit df99a1
          if(rr <= eptr)
Packit df99a1
            {
Packit df99a1
              uint32_t const C2MSB=s[3];
Packit df99a1
              if((C2MSB>=0xDC)||(C2MSB<=0xDF))
Packit df99a1
                {
Packit df99a1
                  U=0x10000+((uint32_t)s[0]<<10)+(uint32_t)s[2]
Packit df99a1
                    +(((C1MSB<<18)|(C2MSB<<8))&0xc0300);
Packit df99a1
                  s=rr;
Packit df99a1
                }
Packit df99a1
              else
Packit df99a1
                {
Packit df99a1
                  U=(unsigned int)(-1)-((C1MSB<<8)|((uint32_t)s[1]));
Packit df99a1
                  s=r;
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UCS4BEtoUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+4;
Packit df99a1
  if(r<=eptr)
Packit df99a1
    {
Packit df99a1
      U=(((((((uint32_t)s[0]<<8)|(uint32_t)s[1])<<8)
Packit df99a1
           |(uint32_t)s[2])<<8)|(uint32_t)s[3]);
Packit df99a1
      if(U)
Packit df99a1
        {
Packit df99a1
          s=r;
Packit df99a1
        } 
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UCS4LEtoUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+4;
Packit df99a1
  if(r<=eptr)
Packit df99a1
    {
Packit df99a1
      U=(((((((uint32_t)s[3]<<8)|(uint32_t)s[2])<<8)|
Packit df99a1
           (uint32_t)s[1])<<8)|(uint32_t)s[0]);
Packit df99a1
      if(U)
Packit df99a1
        {
Packit df99a1
          s=r;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UCS4_2143toUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+4;
Packit df99a1
  if(r<=eptr)
Packit df99a1
    {
Packit df99a1
      U=(((((((uint32_t)s[1]<<8)|(uint32_t)s[0])<<8)
Packit df99a1
           |(uint32_t)s[3])<<8)|(uint32_t)s[2]);
Packit df99a1
      if(U)
Packit df99a1
        {
Packit df99a1
          s=r;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
static uint32_t
Packit df99a1
UCS4_3412toUCS4(unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const * const r=s+4;
Packit df99a1
  if(r<=eptr)
Packit df99a1
    {
Packit df99a1
      U=(((((((uint32_t)s[2]<<8)|(uint32_t)s[3])<<8)
Packit df99a1
           |(uint32_t)s[0])<<8)|(uint32_t)s[1]);
Packit df99a1
      if(U)
Packit df99a1
        {
Packit df99a1
          s=r;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GStringRep::Unicode::set_remainder( void const * const buf,
Packit df99a1
   const unsigned int size, const EncodeType xencodetype )
Packit df99a1
{
Packit df99a1
  gremainder.resize(size,1);
Packit df99a1
  if(size)
Packit df99a1
    memcpy(remainder,buf,size);
Packit df99a1
  encodetype=xencodetype;
Packit df99a1
  encoding=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GStringRep::Unicode::set_remainder( void const * const buf,
Packit df99a1
   const unsigned int size, const GP<GStringRep> &xencoding )
Packit df99a1
{
Packit df99a1
  gremainder.resize(size,1);
Packit df99a1
  if(size)
Packit df99a1
    memcpy(remainder,buf,size);
Packit df99a1
  encoding=xencoding;
Packit df99a1
  encodetype=XOTHER;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GStringRep::Unicode::set_remainder( const GP<GStringRep::Unicode> &xremainder )
Packit df99a1
{
Packit df99a1
  if(xremainder)
Packit df99a1
  {
Packit df99a1
    const int size=xremainder->gremainder;
Packit df99a1
    gremainder.resize(size,1);
Packit df99a1
    if(size)
Packit df99a1
      memcpy(remainder,xremainder->remainder,size);
Packit df99a1
    encodetype=xremainder->encodetype;
Packit df99a1
  }
Packit df99a1
  else
Packit df99a1
  {
Packit df99a1
    gremainder.resize(0,1);
Packit df99a1
    encodetype=XUTF8;
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep::Unicode>
Packit df99a1
GStringRep::Unicode::get_remainder( void ) const
Packit df99a1
{
Packit df99a1
  return const_cast<GStringRep::Unicode *>(this);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String 
Packit df99a1
GUTF8String::create(void const * const buf,const unsigned int size,
Packit df99a1
    const EncodeType encodetype, const GUTF8String &encoding)
Packit df99a1
{
Packit df99a1
  return encoding.length()
Packit df99a1
    ?create(buf,size,encodetype)
Packit df99a1
    :create(buf,size,encoding);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String 
Packit df99a1
GUTF8String::create( void const * const buf,
Packit df99a1
  unsigned int size, const EncodeType encodetype )
Packit df99a1
{
Packit df99a1
  GUTF8String retval;
Packit df99a1
  retval.init(GStringRep::Unicode::create(buf,size,encodetype));
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String 
Packit df99a1
GUTF8String::create( void const * const buf,
Packit df99a1
  const unsigned int size, const GP<GStringRep::Unicode> &remainder)
Packit df99a1
{
Packit df99a1
  GUTF8String retval;
Packit df99a1
  retval.init(GStringRep::Unicode::create(buf,size,remainder));
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String 
Packit df99a1
GUTF8String::create( void const * const buf,
Packit df99a1
  const unsigned int size, const GUTF8String &encoding )
Packit df99a1
{
Packit df99a1
  GUTF8String retval;
Packit df99a1
  retval.init(GStringRep::Unicode::create(buf,size,encoding ));
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif