Blame libdjvu/GString.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
// From: Leon Bottou, 1/31/2002
Packit df99a1
// This file has very little to do with my initial implementation.
Packit df99a1
// It has been practically rewritten by Lizardtech for i18n changes.
Packit df99a1
// My original implementation was very small in comparison
Packit df99a1
// <http://prdownloads.sourceforge.net/djvu/DjVu2_2b-src.tgz>.
Packit df99a1
// In my opinion, the duplication of the string classes is a failed
Packit df99a1
// attempt to use the type system to enforce coding policies.
Packit df99a1
// This could be fixed.  But there are better things to do in djvulibre.
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
#include "GThreads.h"
Packit df99a1
#include "debug.h"
Packit df99a1
Packit df99a1
#include <stddef.h>
Packit df99a1
#include <stdlib.h>
Packit df99a1
#include <stdio.h>
Packit df99a1
#include <string.h>
Packit df99a1
#if HAS_WCHAR
Packit df99a1
# include <locale.h>
Packit df99a1
# if !defined(AUTOCONF) || HAVE_WCHAR_H
Packit df99a1
#  include <wchar.h>
Packit df99a1
# endif
Packit df99a1
# if HAS_WCTYPE
Packit df99a1
#  include <wctype.h>
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1
#include <ctype.h>
Packit df99a1
Packit df99a1
#ifndef LC_NUMERIC          //MingW
Packit df99a1
# undef DO_CHANGELOCALE
Packit df99a1
# define LC_NUMERIC 0
Packit df99a1
#endif
Packit df99a1
#ifndef DO_CHANGELOCALE
Packit df99a1
# define DO_CHANGELOCALE 0
Packit df99a1
#endif
Packit df99a1
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
Packit df99a1
GBaseString::~GBaseString() {}
Packit df99a1
GNativeString::~GNativeString() {}
Packit df99a1
GUTF8String::~GUTF8String() {}
Packit df99a1
Packit df99a1
#if !HAS_MBSTATE && HAS_WCHAR
Packit df99a1
// Under some systems, wctomb() and mbtowc() are not thread
Packit df99a1
// safe.  In those cases, wcrtomb and mbrtowc are preferred.
Packit df99a1
// For Solaris, wctomb() and mbtowc() are thread safe, and 
Packit df99a1
// wcrtomb() and mbrtowc() don't exist.
Packit df99a1
Packit df99a1
#define wcrtomb MYwcrtomb
Packit df99a1
#define mbrtowc MYmbrtowc
Packit df99a1
#define mbrlen  MYmbrlen
Packit df99a1
Packit df99a1
static inline int
Packit df99a1
wcrtomb(char *bytes,wchar_t w,mbstate_t *)
Packit df99a1
{
Packit df99a1
  return wctomb(bytes,w);
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline int
Packit df99a1
mbrtowc(wchar_t *w,const char *source, size_t n, mbstate_t *)
Packit df99a1
{
Packit df99a1
  return mbtowc(w,source,n);
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline size_t
Packit df99a1
mbrlen(const char *s, size_t n, mbstate_t *)
Packit df99a1
{
Packit df99a1
  return mblen(s,n);
Packit df99a1
}
Packit df99a1
#endif // !HAS_MBSTATE || HAS_WCHAR
Packit df99a1
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::upcase(void) const
Packit df99a1
{ return tocase(giswupper,gtowupper); }
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::downcase(void) const
Packit df99a1
{ return tocase(giswlower,gtowlower); }
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::create(const unsigned int sz)
Packit df99a1
{
Packit df99a1
  return GStringRep::create(sz,(GStringRep::UTF8 *)0);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::create(const char *s)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.strdup(s);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create(const GP<GStringRep> &s1,const GP<GStringRep> &s2)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create( const GP<GStringRep> &s1,const char *s2)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create( const char *s1, const GP<GStringRep> &s2)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create( const char *s1,const char *s2)
Packit df99a1
{ 
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create(const char *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create(
Packit df99a1
  const uint16_t *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::create(
Packit df99a1
  const uint32_t *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::UTF8 dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::blank(const unsigned int sz) const
Packit df99a1
{
Packit df99a1
   return GStringRep::create(sz,(GStringRep::UTF8 *)0);
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GStringRep::UTF8::isUTF8(void) const
Packit df99a1
{
Packit df99a1
  return true;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::toThis(
Packit df99a1
    const GP<GStringRep> &rep,const GP<GStringRep> &) const
Packit df99a1
{
Packit df99a1
  return rep?(rep->toUTF8(true)):rep;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::create(const char fmt[],va_list& args)
Packit df99a1
{ 
Packit df99a1
  const GP<GStringRep> s(create(fmt));
Packit df99a1
  return (s?(s->vformat(args)):s);
Packit df99a1
}
Packit df99a1
Packit df99a1
#if !HAS_WCHAR
Packit df99a1
Packit df99a1
#define NATIVE_CREATE(x) UTF8::create( x );
Packit df99a1
Packit df99a1
#ifdef LC_ALL
Packit df99a1
#undef LC_ALL
Packit df99a1
#endif
Packit df99a1
#define LC_ALL 0
Packit df99a1
Packit df99a1
class GStringRep::ChangeLocale
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  ChangeLocale(const int,const char *) {}
Packit df99a1
  ~ChangeLocale() {};
Packit df99a1
};
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::NativeToUTF8( const char *s )
Packit df99a1
{
Packit df99a1
  return GStringRep::UTF8::create(s);
Packit df99a1
}
Packit df99a1
Packit df99a1
#else
Packit df99a1
Packit df99a1
#define NATIVE_CREATE(x) Native::create( x );
Packit df99a1
Packit df99a1
// The declaration and implementation of GStringRep::ChangeLocale
Packit df99a1
// Not used in WinCE
Packit df99a1
Packit df99a1
class GStringRep::ChangeLocale
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  ChangeLocale(const int category,const char locale[]);
Packit df99a1
  ~ChangeLocale();
Packit df99a1
private:
Packit df99a1
  GUTF8String locale;
Packit df99a1
  int category;
Packit df99a1
};
Packit df99a1
Packit df99a1
class GStringRep::Native : public GStringRep
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // default constructor
Packit df99a1
  Native(void);
Packit df99a1
  // virtual destructor
Packit df99a1
  virtual ~Native();
Packit df99a1
Packit df99a1
    // Other virtual methods.
Packit df99a1
      // Create an empty string.
Packit df99a1
  virtual GP<GStringRep> blank(const unsigned int sz = 0) const;
Packit df99a1
      // Append a string.
Packit df99a1
  virtual GP<GStringRep> append(const GP<GStringRep> &s2) const;
Packit df99a1
      // Test if Native.
Packit df99a1
  virtual bool isNative(void) const;
Packit df99a1
      // Convert to Native.
Packit df99a1
  virtual GP<GStringRep> toNative(
Packit df99a1
    const EscapeMode escape=UNKNOWN_ESCAPED) const;
Packit df99a1
      // Convert to UTF8.
Packit df99a1
  virtual GP<GStringRep> toUTF8(const bool nothrow=false) const;
Packit df99a1
      // Convert to UTF8.
Packit df99a1
  virtual GP<GStringRep> toThis(
Packit df99a1
     const GP<GStringRep> &rep,const GP<GStringRep> &) const;
Packit df99a1
      // Compare with #s2#.
Packit df99a1
  virtual int cmp(const GP<GStringRep> &s2, const int len=(-1)) const;
Packit df99a1
Packit df99a1
  // Convert strings to numbers.
Packit df99a1
  virtual int toInt(void) const;
Packit df99a1
  virtual long toLong(
Packit df99a1
    const int pos, int &endpos, const int base=10) const;
Packit df99a1
  virtual unsigned long toULong(
Packit df99a1
    const int pos, int &endpos, const int base=10) const;
Packit df99a1
  virtual double toDouble(
Packit df99a1
    const int pos, int &endpos) const;
Packit df99a1
Packit df99a1
    // Create an empty string
Packit df99a1
  static GP<GStringRep> create(const unsigned int sz = 0);
Packit df99a1
Packit df99a1
    // Create a strdup string.
Packit df99a1
  static GP<GStringRep> create(const char *s);
Packit df99a1
Packit df99a1
  // Creates by appending to the current string
Packit df99a1
Packit df99a1
   // Creates with a concat operation.
Packit df99a1
  static GP<GStringRep> create(
Packit df99a1
    const GP<GStringRep> &s1,const GP<GStringRep> &s2;;
Packit df99a1
  static GP<GStringRep> create( const GP<GStringRep> &s1,const char *s2);
Packit df99a1
  static GP<GStringRep> create( const char *s1, const GP<GStringRep> &s2;;
Packit df99a1
  static GP<GStringRep> create(const char *s1,const char *s2);
Packit df99a1
Packit df99a1
    // Create with a strdup and substr operation.
Packit df99a1
  static GP<GStringRep> create(
Packit df99a1
    const char *s,const int start,const int length=(-1));
Packit df99a1
  static GP<GStringRep> create(
Packit df99a1
    const uint16_t *s,const int start,const int length=(-1));
Packit df99a1
  static GP<GStringRep> create(
Packit df99a1
    const uint32_t *s,const int start,const int length=(-1));
Packit df99a1
Packit df99a1
    // Create with an sprintf()
Packit df99a1
  static GP<GStringRep> create_format(const char fmt[],...);
Packit df99a1
  static GP<GStringRep> create(const char fmt[],va_list &args);
Packit df99a1
Packit df99a1
  virtual unsigned char *UCS4toString(
Packit df99a1
    const uint32_t w,unsigned char *ptr, mbstate_t *ps=0) const;
Packit df99a1
Packit df99a1
  // Tests if a string is legally encoded in the current character set.
Packit df99a1
  virtual bool is_valid(void) const;
Packit df99a1
Packit df99a1
  virtual int ncopy(wchar_t * const buf, const int buflen) const;
Packit df99a1
Packit df99a1
  friend class GBaseString;
Packit df99a1
protected:
Packit df99a1
  // Return the next character and increment the source pointer.
Packit df99a1
  virtual uint32_t getValidUCS4(const char *&source) const;
Packit df99a1
};
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(const unsigned int sz)
Packit df99a1
{
Packit df99a1
  return GStringRep::create(sz,(GStringRep::Native *)0);
Packit df99a1
}
Packit df99a1
Packit df99a1
    // Create a strdup string.
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(const char *s)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.strdup(s);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(const GP<GStringRep> &s1,const GP<GStringRep> &s2)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::Native::create( const GP<GStringRep> &s1,const char *s2)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create( const char *s1, const GP<GStringRep> &s2)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(const char *s1,const char *s2)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.concat(s1,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(
Packit df99a1
  const char *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(
Packit df99a1
    const uint16_t *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create(
Packit df99a1
  const uint32_t *s,const int start,const int length)
Packit df99a1
{
Packit df99a1
  GStringRep::Native dummy;
Packit df99a1
  return dummy.substr(s,start,length);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::Native::blank(const unsigned int sz) const
Packit df99a1
{
Packit df99a1
  return GStringRep::create(sz,(GStringRep::Native *)0);
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GStringRep::Native::isNative(void) const
Packit df99a1
{
Packit df99a1
  return true;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::toThis(
Packit df99a1
     const GP<GStringRep> &rep,const GP<GStringRep> &) const
Packit df99a1
{
Packit df99a1
  return rep?(rep->toNative(NOT_ESCAPED)):rep;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::Native::create(const char fmt[],va_list &args)
Packit df99a1
{ 
Packit df99a1
  const GP<GStringRep> s(create(fmt));
Packit df99a1
  return (s?(s->vformat(args)):s);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::Native::ncopy(
Packit df99a1
  wchar_t * const buf, const int buflen ) const
Packit df99a1
{
Packit df99a1
  return toUTF8()->ncopy(buf,buflen);
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::ChangeLocale::ChangeLocale(const int xcategory, const char xlocale[] )
Packit df99a1
  : category(xcategory)
Packit df99a1
{
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
  // This is disabled under UNIX because 
Packit df99a1
  // it does not play nice with MT.
Packit df99a1
  if(xlocale)
Packit df99a1
    {
Packit df99a1
      locale=setlocale(xcategory,0);
Packit df99a1
      if(locale.length() &&(locale!=xlocale))
Packit df99a1
        {
Packit df99a1
          if(locale == setlocale(category,xlocale))
Packit df99a1
            {
Packit df99a1
              locale.empty();
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          locale.empty();
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::ChangeLocale::~ChangeLocale()
Packit df99a1
{
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
  if(locale.length())
Packit df99a1
    {
Packit df99a1
      setlocale(category,(const char *)locale);
Packit df99a1
    }
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString &
Packit df99a1
GNativeString::format(const char fmt[], ... )
Packit df99a1
{
Packit df99a1
  va_list args;
Packit df99a1
  va_start(args, fmt);
Packit df99a1
  return init(GStringRep::Native::create(fmt,args));
Packit df99a1
}
Packit df99a1
Packit df99a1
// Gather the native implementations here. Not used in WinCE.
Packit df99a1
Packit df99a1
GStringRep::Native::Native(void) {}
Packit df99a1
GStringRep::Native::~Native() {}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::append(const GP<GStringRep> &s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    if(s2->isUTF8())
Packit df99a1
    {
Packit df99a1
      G_THROW( ERR_MSG("GStringRep.appendUTF8toNative") );
Packit df99a1
    }
Packit df99a1
    retval=concat(data,s2->data);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep::Native *>(this); 
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::create_format(const char fmt[],...)
Packit df99a1
{
Packit df99a1
  va_list args;
Packit df99a1
  va_start(args, fmt);
Packit df99a1
  return create(fmt,args);
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned char *
Packit df99a1
GStringRep::Native::UCS4toString(
Packit df99a1
  const uint32_t w0,unsigned char *ptr, mbstate_t *ps) const
Packit df99a1
{
Packit df99a1
  return UCS4toNative(w0,ptr,ps);
Packit df99a1
}
Packit df99a1
Packit df99a1
// Convert a UCS4 to a multibyte string in the value bytes.  
Packit df99a1
// The data pointed to by ptr should be long enough to contain
Packit df99a1
// the results with a nill termination.  (Normally 7 characters
Packit df99a1
// is enough.)
Packit df99a1
unsigned char *
Packit df99a1
GStringRep::UCS4toNative(const uint32_t w0,unsigned char *ptr, mbstate_t *ps)
Packit df99a1
{
Packit df99a1
  uint16_t w1;
Packit df99a1
  uint16_t w2=1;
Packit df99a1
  for(int count=(sizeof(wchar_t)==sizeof(w1)) 
Packit df99a1
        ? UCS4toUTF16(w0,w1,w2) : 1;
Packit df99a1
      count;
Packit df99a1
      --count,w1=w2)
Packit df99a1
    {
Packit df99a1
      // wchar_t can be either UCS4 or UCS2
Packit df99a1
      const wchar_t w=(sizeof(wchar_t) == sizeof(w1))?(wchar_t)w1:(wchar_t)w0;
Packit df99a1
      int i=wcrtomb((char *)ptr,w,ps);
Packit df99a1
      if(i<0)
Packit df99a1
        break;
Packit df99a1
      ptr[i]=0;
Packit df99a1
      ptr += i;
Packit df99a1
    }
Packit df99a1
  ptr[0]=0;
Packit df99a1
  return ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::toNative(const EscapeMode escape) const
Packit df99a1
{
Packit df99a1
  if(escape == UNKNOWN_ESCAPED)
Packit df99a1
    G_THROW( ERR_MSG("GStringRep.NativeToNative") );
Packit df99a1
  return const_cast<GStringRep::Native *>(this);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::Native::toUTF8(const bool) const
Packit df99a1
{
Packit df99a1
  unsigned char *buf;
Packit df99a1
  GPBuffer<unsigned char> gbuf(buf,size*6+1);
Packit df99a1
  buf[0]=0;
Packit df99a1
  if(data && size)
Packit df99a1
  {
Packit df99a1
    size_t n=size;
Packit df99a1
    const char *source=data;
Packit df99a1
    mbstate_t ps;
Packit df99a1
    unsigned char *ptr=buf;
Packit df99a1
    //(void)mbrlen(source, n, &ps);
Packit df99a1
    memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
    int i=0;
Packit df99a1
    if(sizeof(wchar_t) == sizeof(uint32_t))
Packit df99a1
      {
Packit df99a1
        wchar_t w = 0;
Packit df99a1
        for(;(n>0)&&((i=mbrtowc(&w,source,n,&ps))>=0); n-=i,source+=i)
Packit df99a1
          {
Packit df99a1
            ptr=UCS4toUTF8((uint32_t)w,ptr);
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
    else
Packit df99a1
      { 
Packit df99a1
        wchar_t w = 0;
Packit df99a1
        for(;(n>0)&&((i=mbrtowc(&w,source,n,&ps))>=0);n-=i,source+=i)
Packit df99a1
          {
Packit df99a1
            uint16_t s[2];
Packit df99a1
            s[0]=w;
Packit df99a1
            uint32_t w0;
Packit df99a1
            if(UTF16toUCS4(w0,s,s+1)<=0)
Packit df99a1
              {
Packit df99a1
                source+=i;
Packit df99a1
                n-=i;
Packit df99a1
                if((n>0)&&((i=mbrtowc(&w,source,n,&ps))>=0))
Packit df99a1
                  {
Packit df99a1
                    s[1]=w;
Packit df99a1
                    if(UTF16toUCS4(w0,s,s+2)<=0)
Packit df99a1
                      {
Packit df99a1
                        i=(-1);
Packit df99a1
                        break;
Packit df99a1
                      }
Packit df99a1
                  }
Packit df99a1
                else
Packit df99a1
                  {
Packit df99a1
                    i=(-1);
Packit df99a1
                    break;
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
            ptr=UCS4toUTF8(w0,ptr);
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
    if(i<0)
Packit df99a1
      {
Packit df99a1
        gbuf.resize(0);
Packit df99a1
      }
Packit df99a1
    else
Packit df99a1
      {
Packit df99a1
        ptr[0]=0;
Packit df99a1
      }
Packit df99a1
  }
Packit df99a1
  return GStringRep::UTF8::create((const char *)buf);
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString
Packit df99a1
GBaseString::UTF8ToNative(
Packit df99a1
  const bool currentlocale,const EscapeMode escape) const
Packit df99a1
{
Packit df99a1
  const char *source=(*this);
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(source && source[0]) 
Packit df99a1
    {
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
      GUTF8String lc_ctype(setlocale(LC_CTYPE,0));
Packit df99a1
      bool repeat;
Packit df99a1
      for(repeat=!currentlocale;;repeat=false)
Packit df99a1
        {
Packit df99a1
#endif
Packit df99a1
          retval=(*this)->toNative((GStringRep::EscapeMode)escape);
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
          if (!repeat || retval || (lc_ctype == setlocale(LC_CTYPE,"")))
Packit df99a1
            break;
Packit df99a1
        }
Packit df99a1
      if(!repeat)
Packit df99a1
        setlocale(LC_CTYPE,(const char *)lc_ctype);
Packit df99a1
#endif
Packit df99a1
    }
Packit df99a1
  return GNativeString(retval);
Packit df99a1
}
Packit df99a1
Packit df99a1
/*MBCS*/
Packit df99a1
GNativeString
Packit df99a1
GBaseString::getUTF82Native( EscapeMode escape ) const
Packit df99a1
{ //MBCS cvt
Packit df99a1
  GNativeString retval;
Packit df99a1
Packit df99a1
  // We don't want to convert this if it 
Packit df99a1
  // already is known to be native...
Packit df99a1
//  if (isNative()) return *this;
Packit df99a1
Packit df99a1
  const size_t slen=length()+1;
Packit df99a1
  if(slen>1)
Packit df99a1
  {
Packit df99a1
    retval=UTF8ToNative(false,escape) ;
Packit df99a1
    if(!retval.length())
Packit df99a1
    {
Packit df99a1
      retval=(const char*)*this;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GBaseString::NativeToUTF8(void) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(length())
Packit df99a1
  {
Packit df99a1
    const char *source=(*this);
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
    GUTF8String lc_ctype=setlocale(LC_CTYPE,0);
Packit df99a1
    bool repeat;
Packit df99a1
    for(repeat=true;;repeat=false)
Packit df99a1
      {
Packit df99a1
#endif
Packit df99a1
        if( (retval=GStringRep::NativeToUTF8(source)) )
Packit df99a1
          if(GStringRep::cmp(retval->toNative(),source))
Packit df99a1
            retval=GStringRep::UTF8::create((unsigned int)0);
Packit df99a1
#if DO_CHANGELOCALE
Packit df99a1
        if(!repeat || retval || (lc_ctype == setlocale(LC_CTYPE,"")))
Packit df99a1
          break;
Packit df99a1
      }
Packit df99a1
    if(!repeat)
Packit df99a1
      setlocale(LC_CTYPE,(const char *)lc_ctype);
Packit df99a1
#endif
Packit df99a1
  }
Packit df99a1
  return GUTF8String(retval);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GBaseString::getNative2UTF8(void) const
Packit df99a1
{ //MBCS cvt
Packit df99a1
Packit df99a1
   // We don't want to do a transform this
Packit df99a1
   // if we already are in the given type.
Packit df99a1
//   if (isUTF8()) return *this;
Packit df99a1
   
Packit df99a1
  const size_t slen=length()+1;
Packit df99a1
  GUTF8String retval;
Packit df99a1
  if(slen > 1)
Packit df99a1
  {
Packit df99a1
    retval=NativeToUTF8();
Packit df99a1
    if(!retval.length())
Packit df99a1
    {
Packit df99a1
      retval=(const char *)(*this);
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
} /*MBCS*/
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::Native::cmp(const GP<GStringRep> &s2,const int len) const
Packit df99a1
{
Packit df99a1
  int retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    if(s2->isUTF8())
Packit df99a1
    {
Packit df99a1
      const GP<GStringRep> r(toUTF8(true));
Packit df99a1
      if(r)
Packit df99a1
      {
Packit df99a1
        retval=GStringRep::cmp(r->data,s2->data,len);
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=cmp(s2->toNative(NOT_ESCAPED),len);
Packit df99a1
      }
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      retval=GStringRep::cmp(data,s2->data,len);
Packit df99a1
    }
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=GStringRep::cmp(data,0,len);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::Native::toInt() const
Packit df99a1
{
Packit df99a1
  return atoi(data);
Packit df99a1
}
Packit df99a1
Packit df99a1
long
Packit df99a1
GStringRep::Native::toLong(
Packit df99a1
  const int pos, int &endpos, const int base) const
Packit df99a1
{
Packit df99a1
   char *edata=0;
Packit df99a1
   const long retval=strtol(data+pos, &edata, base);
Packit df99a1
   if(edata)
Packit df99a1
   {
Packit df99a1
     endpos=(int)((size_t)edata-(size_t)data);
Packit df99a1
   }else
Packit df99a1
   {
Packit df99a1
     endpos=(-1);
Packit df99a1
   }
Packit df99a1
   return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long
Packit df99a1
GStringRep::Native::toULong(
Packit df99a1
  const int pos, int &endpos, const int base) const
Packit df99a1
{
Packit df99a1
   char *edata=0;
Packit df99a1
   const unsigned long retval=strtoul(data+pos, &edata, base);
Packit df99a1
   if(edata)
Packit df99a1
   {
Packit df99a1
     endpos=(int)((size_t)edata-(size_t)data);
Packit df99a1
   }else
Packit df99a1
   {
Packit df99a1
     endpos=(-1);
Packit df99a1
   }
Packit df99a1
   return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
double
Packit df99a1
GStringRep::Native::toDouble(
Packit df99a1
  const int pos, int &endpos) const
Packit df99a1
{
Packit df99a1
   char *edata=0;
Packit df99a1
   const double retval=strtod(data+pos, &edata);
Packit df99a1
   if(edata)
Packit df99a1
   {
Packit df99a1
     endpos=(int)((size_t)edata-(size_t)data);
Packit df99a1
   }else
Packit df99a1
   {
Packit df99a1
     endpos=(-1);
Packit df99a1
   }
Packit df99a1
   return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
uint32_t
Packit df99a1
GStringRep::Native::getValidUCS4(const char *&source) const
Packit df99a1
{
Packit df99a1
  uint32_t retval=0;
Packit df99a1
  int n=(int)((size_t)size+(size_t)data-(size_t)source);
Packit df99a1
  if(source && (n > 0))
Packit df99a1
  {
Packit df99a1
    mbstate_t ps;
Packit df99a1
    //(void)mbrlen(source, n, &ps);
Packit df99a1
    memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
    wchar_t wt;
Packit df99a1
    const int len=mbrtowc(&wt,source,n,&ps); 
Packit df99a1
    if(len>=0)
Packit df99a1
    {
Packit df99a1
      if(sizeof(wchar_t) == sizeof(uint16_t))
Packit df99a1
      {
Packit df99a1
        source+=len;
Packit df99a1
        uint16_t s[2];
Packit df99a1
        s[0]=(uint16_t)wt;
Packit df99a1
        if(UTF16toUCS4(retval,s,s+1)<=0)
Packit df99a1
        {
Packit df99a1
          if((n-=len)>0)
Packit df99a1
          {
Packit df99a1
            const int len=mbrtowc(&wt,source,n,&ps);
Packit df99a1
            if(len>=0)
Packit df99a1
            {
Packit df99a1
              s[1]=(uint16_t)wt;
Packit df99a1
              uint32_t w;
Packit df99a1
              if(UTF16toUCS4(w,s,s+2)>0)
Packit df99a1
              {
Packit df99a1
                source+=len;
Packit df99a1
                retval=w;
Packit df99a1
              }
Packit df99a1
            }
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=(uint32_t)wt;
Packit df99a1
        source++;
Packit df99a1
      } 
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      source++;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
// Tests if a string is legally encoded in the current character set.
Packit df99a1
bool 
Packit df99a1
GStringRep::Native::is_valid(void) const
Packit df99a1
{
Packit df99a1
  bool retval=true;
Packit df99a1
  if(data && size)
Packit df99a1
  {
Packit df99a1
    size_t n=size;
Packit df99a1
    const char *s=data;
Packit df99a1
    mbstate_t ps;
Packit df99a1
    //(void)mbrlen(s, n, &ps);
Packit df99a1
    memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
    do
Packit df99a1
    {
Packit df99a1
      size_t m=mbrlen(s,n,&ps);
Packit df99a1
      if(m > n)
Packit df99a1
      {
Packit df99a1
        retval=false;
Packit df99a1
        break;
Packit df99a1
      }else if(m)
Packit df99a1
      {
Packit df99a1
        s+=m;
Packit df99a1
        n-=m;
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        break;
Packit df99a1
      }
Packit df99a1
    } while(n);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
// These are dummy functions.
Packit df99a1
void 
Packit df99a1
GStringRep::set_remainder(void const * const, const unsigned int,
Packit df99a1
  const EncodeType) {}
Packit df99a1
void 
Packit df99a1
GStringRep::set_remainder(void const * const, const unsigned int,
Packit df99a1
  const GP<GStringRep> &encoding) {}
Packit df99a1
void
Packit df99a1
GStringRep::set_remainder( const GP<GStringRep::Unicode> &) {}
Packit df99a1
Packit df99a1
GP<GStringRep::Unicode>
Packit df99a1
GStringRep::get_remainder( void ) const
Packit df99a1
{
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const char dat)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create(&dat,0,1));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const char *str)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create(str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const unsigned char *str)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create((const char *)str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const uint16_t *str)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create(str,0,-1));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const uint32_t *str)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create(str,0,-1));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const char *dat, unsigned int len)
Packit df99a1
{
Packit df99a1
  init(
Packit df99a1
    GStringRep::Native::create(dat,0,((int)len<0)?(-1):(int)len));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const uint16_t *dat, unsigned int len)
Packit df99a1
{
Packit df99a1
  init(
Packit df99a1
    GStringRep::Native::create(dat,0,((int)len<0)?(-1):(int)len));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const uint32_t *dat, unsigned int len)
Packit df99a1
{
Packit df99a1
  init(
Packit df99a1
    GStringRep::Native::create(dat,0,((int)len<0)?(-1):(int)len));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const GNativeString &str)
Packit df99a1
{
Packit df99a1
  init(str);
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const GBaseString &gs, int from, int len)
Packit df99a1
{
Packit df99a1
  init(
Packit df99a1
    GStringRep::Native::create(gs,from,((int)len<0)?(-1):(int)len));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const int number)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create_format("%d",number));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString::GNativeString(const double number)
Packit df99a1
{
Packit df99a1
  init(GStringRep::Native::create_format("%f",number));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString&
Packit df99a1
GNativeString::operator= (const char str)
Packit df99a1
{ return init(GStringRep::Native::create(&str,0,1)); }
Packit df99a1
Packit df99a1
GNativeString&
Packit df99a1
GNativeString::operator= (const char *str)
Packit df99a1
{ return init(GStringRep::Native::create(str)); }
Packit df99a1
Packit df99a1
GNativeString
Packit df99a1
GBaseString::operator+(const GNativeString &s2) const
Packit df99a1
{
Packit df99a1
  return GStringRep::Native::create(*this,s2);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::NativeToUTF8( const char *s )
Packit df99a1
{
Packit df99a1
  return GStringRep::Native::create(s)->toUTF8();
Packit df99a1
}
Packit df99a1
Packit df99a1
#endif // HAS_WCHAR
Packit df99a1
Packit df99a1
template <class TYPE>
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::create(const unsigned int sz, TYPE *)
Packit df99a1
{
Packit df99a1
  GP<GStringRep> gaddr;
Packit df99a1
  if (sz > 0)
Packit df99a1
  {
Packit df99a1
    GStringRep *addr;
Packit df99a1
    gaddr=(addr=new TYPE);
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
GP<GStringRep>
Packit df99a1
GStringRep::strdup(const char *s) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  const int length=s?strlen(s):0;
Packit df99a1
  if(length>0)
Packit df99a1
  {
Packit df99a1
    retval=blank(length);
Packit df99a1
    char const * const end=s+length;
Packit df99a1
    char *ptr=retval->data;
Packit df99a1
    for(;*s&&(s!=end);ptr++)
Packit df99a1
    {
Packit df99a1
      ptr[0]=s++[0];
Packit df99a1
    }
Packit df99a1
    ptr[0]=0;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::substr(const char *s,const int start,const int len) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s && s[0])
Packit df99a1
  {
Packit df99a1
    const unsigned int length=(start<0 || len<0)?(unsigned int)strlen(s):(unsigned int)(-1);
Packit df99a1
    const char *startptr, *endptr;
Packit df99a1
    if(start<0)
Packit df99a1
    {
Packit df99a1
      startptr=s+length+start;
Packit df99a1
      if(startptr
Packit df99a1
        startptr=s;
Packit df99a1
    }else
Packit df99a1
    { 
Packit df99a1
      startptr=s;
Packit df99a1
      for(const char * const ptr=s+start;(startptr
Packit df99a1
        EMPTY_LOOP;
Packit df99a1
    }
Packit df99a1
    if(len<0)
Packit df99a1
    {
Packit df99a1
      if(s+length+1 < startptr+len)
Packit df99a1
      {
Packit df99a1
        endptr=startptr;
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        endptr=s+length+1+len;
Packit df99a1
      } 
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      endptr=startptr;
Packit df99a1
      for(const char * const ptr=startptr+len;(endptr
Packit df99a1
        EMPTY_LOOP;
Packit df99a1
    }
Packit df99a1
    if(endptr>startptr)
Packit df99a1
    {
Packit df99a1
      retval=blank((size_t)(endptr-startptr));
Packit df99a1
      char *data=retval->data;
Packit df99a1
      for(; (startptr
Packit df99a1
      {
Packit df99a1
        data[0]=startptr[0];
Packit df99a1
      }
Packit df99a1
      data[0]=0;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::substr(const uint16_t *s,const int start,const int len) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s && s[0])
Packit df99a1
  {
Packit df99a1
    uint16_t const *eptr;
Packit df99a1
    if(len<0)
Packit df99a1
    {
Packit df99a1
      for(eptr=s;eptr[0];++eptr)
Packit df99a1
        EMPTY_LOOP;
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      eptr=&(s[len]);
Packit df99a1
    }
Packit df99a1
    s=&s[start];
Packit df99a1
    if((size_t)s<(size_t)eptr)
Packit df99a1
    {
Packit df99a1
      mbstate_t ps;
Packit df99a1
      memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
      unsigned char *buf,*ptr;
Packit df99a1
      GPBuffer<unsigned char> gbuf(buf,(((size_t)eptr-(size_t)s)/2)*3+7);
Packit df99a1
      for(ptr=buf;s[0];)
Packit df99a1
      {
Packit df99a1
        uint32_t w;
Packit df99a1
        int i=UTF16toUCS4(w,s,eptr);
Packit df99a1
        if(i<=0)
Packit df99a1
          break;
Packit df99a1
        s+=i;
Packit df99a1
        ptr=UCS4toString(w,ptr,&ps);
Packit df99a1
      }
Packit df99a1
      ptr[0]=0;
Packit df99a1
      retval = strdup( (const char *)buf );
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::substr(const uint32_t *s,const int start,const int len) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s && s[0])
Packit df99a1
  {
Packit df99a1
    uint32_t const *eptr;
Packit df99a1
    if(len<0)
Packit df99a1
    {
Packit df99a1
      for(eptr=s;eptr[0];++eptr)
Packit df99a1
        EMPTY_LOOP;
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      eptr=&(s[len]);
Packit df99a1
    }
Packit df99a1
    s=&s[start];
Packit df99a1
    if((size_t)s<(size_t)eptr)
Packit df99a1
    {
Packit df99a1
      mbstate_t ps;
Packit df99a1
      memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
      unsigned char *buf,*ptr;
Packit df99a1
      GPBuffer<unsigned char> gbuf(buf,((((size_t)eptr-(size_t)s))/4)*6+7);
Packit df99a1
      for(ptr=buf;s[0];++s)
Packit df99a1
      {
Packit df99a1
        ptr=UCS4toString(s[0],ptr,&ps);
Packit df99a1
      }
Packit df99a1
      ptr[0]=0;
Packit df99a1
      retval = strdup( (const char *)buf );
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::append(const char *s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    retval=concat(data,s2);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep *>(this);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::append(const GP<GStringRep> &s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    if(s2->isNative())
Packit df99a1
    {
Packit df99a1
      G_THROW( ERR_MSG("GStringRep.appendNativeToUTF8") );
Packit df99a1
    }
Packit df99a1
    retval=concat(data,s2->data);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep::UTF8 *>(this); 
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::concat(const char *s1,const char *s2) const
Packit df99a1
{
Packit df99a1
  const int length1=(s1?strlen(s1):0);
Packit df99a1
  const int length2=(s2?strlen(s2):0);
Packit df99a1
  const int length=length1+length2;
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(length>0)
Packit df99a1
  {
Packit df99a1
    retval=blank(length);
Packit df99a1
    GStringRep &r=*retval;
Packit df99a1
    if(length1)
Packit df99a1
    {
Packit df99a1
      strcpy(r.data,s1);
Packit df99a1
      if(length2)
Packit df99a1
        strcat(r.data,s2);
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      strcpy(r.data,s2);
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
const char *GBaseString::nullstr = "";
Packit df99a1
Packit df99a1
void
Packit df99a1
GBaseString::empty( void )
Packit df99a1
{
Packit df99a1
  init(0);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::getbuf(int n) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(n< 0)
Packit df99a1
    n=strlen(data);
Packit df99a1
  if(n>0)
Packit df99a1
  {
Packit df99a1
    retval=blank(n);
Packit df99a1
    char *ndata=retval->data;
Packit df99a1
    strncpy(ndata,data,n);
Packit df99a1
    ndata[n]=0;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
const char *
Packit df99a1
GStringRep::isCharType(bool (*xiswtest)(const unsigned long wc), 
Packit df99a1
                       const char *ptr, 
Packit df99a1
                       const bool reverse) const
Packit df99a1
{
Packit df99a1
  const char *xptr = ptr;
Packit df99a1
  unsigned long w=getValidUCS4(xptr);
Packit df99a1
  if(ptr != xptr)
Packit df99a1
    {
Packit df99a1
      if (sizeof(wchar_t) == 2)
Packit df99a1
        w &= 0xffff;
Packit df99a1
      if (reverse ^ xiswtest(w))
Packit df99a1
        ptr = xptr;
Packit df99a1
    }
Packit df99a1
  return ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::nextCharType(
Packit df99a1
  bool (*xiswtest)(const unsigned long wc), const int from, const int len,
Packit df99a1
  const bool reverse) const
Packit df99a1
{
Packit df99a1
  // We want to return the position of the next
Packit df99a1
  // non white space starting from the #from#
Packit df99a1
  // location.  isspace should work in any locale
Packit df99a1
  // so we should only need to do this for the non-
Packit df99a1
  // native locales (UTF8)
Packit df99a1
  int retval;
Packit df99a1
  if(from
Packit df99a1
  {
Packit df99a1
    retval=from;
Packit df99a1
    const char * ptr = data+from;
Packit df99a1
    for( const char * const eptr=ptr+((len<0)?(size-from):len);
Packit df99a1
      (ptr
Packit df99a1
    {
Packit df99a1
       // Skip characters that fail the isCharType test
Packit df99a1
      char const * const xptr=isCharType(xiswtest,ptr,!reverse);
Packit df99a1
      if(xptr == ptr)
Packit df99a1
        break;
Packit df99a1
      ptr=xptr;
Packit df99a1
    }
Packit df99a1
    retval=(int)((size_t)ptr-(size_t)data);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=size;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GStringRep::giswspace(const unsigned long w)
Packit df99a1
{
Packit df99a1
#if HAS_WCTYPE
Packit df99a1
  return !!iswspace((wchar_t)w);
Packit df99a1
#else
Packit df99a1
  return (w & ~0xff) ? false : !!isspace((int)(w & 0xff));
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GStringRep::giswupper(const unsigned long w)
Packit df99a1
{
Packit df99a1
#if HAS_WCTYPE
Packit df99a1
  return !!iswupper((wchar_t)w);
Packit df99a1
#else
Packit df99a1
  return (w & ~0xff) ? false : !!isupper((int)(w & 0xff));
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GStringRep::giswlower(const unsigned long w)
Packit df99a1
{
Packit df99a1
#if HAS_WCTYPE
Packit df99a1
  return !!iswlower((wchar_t)w);
Packit df99a1
#else
Packit df99a1
  return (w & ~0xff) ? false : !!islower((int)(w & 0xff));
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long
Packit df99a1
GStringRep::gtowupper(const unsigned long w)
Packit df99a1
{
Packit df99a1
#if HAS_WCTYPE
Packit df99a1
  return (unsigned long)towupper((wchar_t)w);
Packit df99a1
#else
Packit df99a1
  return (w&~0xff) ? w : (unsigned long)toupper(w & 0xff);
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long
Packit df99a1
GStringRep::gtowlower(const unsigned long w)
Packit df99a1
{
Packit df99a1
#if HAS_WCTYPE
Packit df99a1
  return (unsigned long)towlower((wchar_t)w);
Packit df99a1
#else
Packit df99a1
  return (w&~0xff) ? w : (unsigned long)tolower(w & 0xff);
Packit df99a1
#endif
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::tocase(
Packit df99a1
  bool (*xiswcase)(const unsigned long wc),
Packit df99a1
  unsigned long (*xtowcase)(const unsigned long wc)) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  char const * const eptr=data+size;
Packit df99a1
  char const *ptr=data;
Packit df99a1
  while(ptr
Packit df99a1
  {
Packit df99a1
    char const * const xptr=isCharType(xiswcase,ptr,false);
Packit df99a1
    if(ptr == xptr)
Packit df99a1
      break;
Packit df99a1
    ptr=xptr;
Packit df99a1
  }
Packit df99a1
  if(ptr
Packit df99a1
  {
Packit df99a1
    const int n=(int)((size_t)ptr-(size_t)data);
Packit df99a1
    unsigned char *buf;
Packit df99a1
    GPBuffer<unsigned char> gbuf(buf,n+(1+size-n)*6);
Packit df99a1
    if(n>0)
Packit df99a1
    {
Packit df99a1
      strncpy((char *)buf,data,n);
Packit df99a1
    }
Packit df99a1
    unsigned char *buf_ptr=buf+n;
Packit df99a1
    for(char const *ptr=data+n;ptr
Packit df99a1
    {
Packit df99a1
      char const * const xptr=ptr;
Packit df99a1
      const unsigned long w=getValidUCS4(ptr);
Packit df99a1
      if(ptr == xptr)
Packit df99a1
        break;
Packit df99a1
      if(xiswcase(w))
Packit df99a1
      {
Packit df99a1
        const int len=(int)((size_t)ptr-(size_t)xptr);
Packit df99a1
        strncpy((char *)buf_ptr,xptr,len);
Packit df99a1
        buf_ptr+=len;
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        mbstate_t ps;
Packit df99a1
        memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
        buf_ptr=UCS4toString(xtowcase(w),buf_ptr,&ps);
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
    buf_ptr[0]=0;
Packit df99a1
    retval=substr((const char *)buf,0,(int)((size_t)buf_ptr-(size_t)buf));
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep *>(this);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
// Returns a copy of this string with characters used in XML escaped as follows:
Packit df99a1
//      '<'  -->  "<"
Packit df99a1
//      '>'  -->  ">"
Packit df99a1
//      '&'  -->  "&"
Packit df99a1
//      '\'' -->  "'"
Packit df99a1
//      '\"' -->  """
Packit df99a1
//  Also escapes characters 0x00 through 0x1f and 0x7e through 0x7f.
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::toEscaped( const bool tosevenbit ) const
Packit df99a1
{
Packit df99a1
  bool modified=false;
Packit df99a1
  char *ret;
Packit df99a1
  GPBuffer<char> gret(ret,size*7);
Packit df99a1
  ret[0]=0;
Packit df99a1
  char *retptr=ret;
Packit df99a1
  char const *start=data;
Packit df99a1
  char const *s=start;
Packit df99a1
  char const *last=s;
Packit df99a1
  GP<GStringRep> special;
Packit df99a1
  for(unsigned long w;(w=getValidUCS4(s));last=s)  
Packit df99a1
    // Whoever wrote this for statement should be __complete_here__
Packit df99a1
  {
Packit df99a1
    char const *ss=0;
Packit df99a1
    switch(w)
Packit df99a1
    {
Packit df99a1
    case '<':
Packit df99a1
      ss="<";
Packit df99a1
      break;
Packit df99a1
    case '>':
Packit df99a1
      ss=">";
Packit df99a1
      break;
Packit df99a1
    case '&':
Packit df99a1
      ss="&";
Packit df99a1
      break;
Packit df99a1
    case '\47':
Packit df99a1
      ss="'";
Packit df99a1
      break;
Packit df99a1
    case '\42':
Packit df99a1
      ss=""";
Packit df99a1
      break;
Packit df99a1
    default:
Packit df99a1
      if((w<' ')||(w>=0x7e && (tosevenbit || (w < 0x80))))
Packit df99a1
      {
Packit df99a1
        special=toThis(UTF8::create_format("&#%lu;",w));
Packit df99a1
        ss=special->data;
Packit df99a1
      }
Packit df99a1
      break;
Packit df99a1
    }
Packit df99a1
    if(ss)
Packit df99a1
    {
Packit df99a1
      modified=true;
Packit df99a1
      if(s!=start)
Packit df99a1
      {
Packit df99a1
        size_t len=(size_t)last-(size_t)start;
Packit df99a1
        strncpy(retptr,start,len);
Packit df99a1
        retptr+=len;
Packit df99a1
        start=s;
Packit df99a1
      }
Packit df99a1
      if(ss[0])
Packit df99a1
      {
Packit df99a1
        size_t len=strlen(ss);
Packit df99a1
        strcpy(retptr,ss);
Packit df99a1
        retptr+=len;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(modified)
Packit df99a1
  {
Packit df99a1
    strcpy(retptr,start);
Packit df99a1
    retval=strdup( ret );
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep *>(this);
Packit df99a1
  }
Packit df99a1
//  DEBUG_MSG( "Escaped string is '" << ret << "'\n" );
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
static const GMap<GUTF8String,GUTF8String> &
Packit df99a1
BasicMap( void )
Packit df99a1
{
Packit df99a1
  static GMap<GUTF8String,GUTF8String> Basic;
Packit df99a1
  if (! Basic.size())
Packit df99a1
    {
Packit df99a1
      Basic["lt"]   = GUTF8String('<');
Packit df99a1
      Basic["gt"]   = GUTF8String('>');
Packit df99a1
      Basic["amp"]  = GUTF8String('&';;
Packit df99a1
      Basic["apos"] = GUTF8String('\47');
Packit df99a1
      Basic["quot"] = GUTF8String('\42');
Packit df99a1
    }
Packit df99a1
  return Basic;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::fromEscaped( const GMap<GUTF8String,GUTF8String> ConvMap ) const
Packit df99a1
{
Packit df99a1
  GUTF8String ret;                  // Build output string here
Packit df99a1
  int start_locn = 0;           // Beginning of substring to skip
Packit df99a1
  int amp_locn;                 // Location of a found ampersand
Packit df99a1
Packit df99a1
  while( (amp_locn = search( '&', start_locn )) > -1 )
Packit df99a1
  {
Packit df99a1
      // Found the next apostrophe
Packit df99a1
      // Locate the closing semicolon
Packit df99a1
    const int semi_locn = search( ';', amp_locn );
Packit df99a1
      // No closing semicolon, exit and copy
Packit df99a1
      //  the rest of the string.
Packit df99a1
    if( semi_locn < 0 )
Packit df99a1
      break;
Packit df99a1
    ret += substr( start_locn, amp_locn - start_locn );
Packit df99a1
    int const len = semi_locn - amp_locn - 1;
Packit df99a1
    if(len)
Packit df99a1
    {
Packit df99a1
      GUTF8String key = substr( amp_locn+1, len);
Packit df99a1
      //DEBUG_MSG( "key = '" << key << "'\n" );
Packit df99a1
      char const * s=key;
Packit df99a1
      if( s[0] == '#')
Packit df99a1
      {
Packit df99a1
        unsigned long value;
Packit df99a1
        char *ptr=0;
Packit df99a1
        if(s[1] == 'x' || s[1] == 'X')
Packit df99a1
        {
Packit df99a1
          value=strtoul((char const *)(s+2),&ptr,16);
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          value=strtoul((char const *)(s+1),&ptr,10);
Packit df99a1
        }
Packit df99a1
        if(ptr)
Packit df99a1
        {
Packit df99a1
          unsigned char utf8char[7];
Packit df99a1
          unsigned char const * const end=GStringRep::UCS4toUTF8(value,utf8char);
Packit df99a1
          ret+=GUTF8String((char const *)utf8char,(size_t)end-(size_t)utf8char);
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          ret += substr( amp_locn, semi_locn - amp_locn + 1 );
Packit df99a1
        }
Packit df99a1
      }else
Packit df99a1
      {  
Packit df99a1
        GPosition map_entry = ConvMap.contains( key );
Packit df99a1
        if( map_entry )
Packit df99a1
        {                           // Found in the conversion map, substitute
Packit df99a1
          ret += ConvMap[map_entry];
Packit df99a1
        } else
Packit df99a1
        {
Packit df99a1
          static const GMap<GUTF8String,GUTF8String> &Basic = BasicMap();
Packit df99a1
          GPosition map_entry = Basic.contains( key );
Packit df99a1
          if ( map_entry )
Packit df99a1
          {
Packit df99a1
            ret += Basic[map_entry];
Packit df99a1
          }else
Packit df99a1
          {
Packit df99a1
            ret += substr( amp_locn, len+2 );
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      ret += substr( amp_locn, len+2 );
Packit df99a1
    }
Packit df99a1
    start_locn = semi_locn + 1;
Packit df99a1
//    DEBUG_MSG( "ret = '" << ret << "'\n" );
Packit df99a1
  }
Packit df99a1
Packit df99a1
                                // Copy the end of the string to the output
Packit df99a1
  ret += substr( start_locn, length()-start_locn );
Packit df99a1
Packit df99a1
//  DEBUG_MSG( "Unescaped string is '" << ret << "'\n" );
Packit df99a1
  return (ret == *this)?(*this):ret;
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::fromEscaped(void) const
Packit df99a1
{
Packit df99a1
  const GMap<GUTF8String,GUTF8String> nill;
Packit df99a1
  return fromEscaped(nill);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::setat(int n, char ch) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(n<0)
Packit df99a1
    n+=size;
Packit df99a1
  if (n < 0 || n>size) 
Packit df99a1
    GBaseString::throw_illegal_subscript();
Packit df99a1
  if(ch == data[n])
Packit df99a1
  {
Packit df99a1
    retval=const_cast<GStringRep *>(this);
Packit df99a1
  }else if(!ch)
Packit df99a1
  {
Packit df99a1
    retval=getbuf(n);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    retval=getbuf((n
Packit df99a1
    retval->data[n]=ch;
Packit df99a1
    if(n == size)
Packit df99a1
      retval->data[n+1]=0;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
#if defined(AUTOCONF) && defined(HAVE_VSNPRINTF)
Packit df99a1
# define USE_VSNPRINTF vsnprintf
Packit df99a1
#elif defined(_WIN32) && !defined(__CYGWIN32__)
Packit df99a1
# define USE_VSNPRINTF _vsnprintf
Packit df99a1
#elif defined(linux)
Packit df99a1
# define USE_VSNPRINTF vsnprintf
Packit df99a1
#endif
Packit df99a1
 
Packit df99a1
GUTF8String &
Packit df99a1
GUTF8String::format(const char fmt[], ... )
Packit df99a1
{
Packit df99a1
  va_list args;
Packit df99a1
  va_start(args, fmt);
Packit df99a1
  return init(GStringRep::UTF8::create(fmt,args));
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::create_format(const char fmt[],...)
Packit df99a1
{
Packit df99a1
  va_list args;
Packit df99a1
  va_start(args, fmt);
Packit df99a1
  return create(fmt,args);
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::vformat(va_list args) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(size)
Packit df99a1
  {
Packit df99a1
    char const * const fmt=data;
Packit df99a1
    int buflen=32768;
Packit df99a1
    char *buffer;
Packit df99a1
    GPBuffer<char> gbuffer(buffer,buflen);
Packit df99a1
    ChangeLocale locale(LC_NUMERIC,(isNative()?0:"C"));
Packit df99a1
    // Format string
Packit df99a1
#ifdef USE_VSNPRINTF
Packit df99a1
    while(USE_VSNPRINTF(buffer, buflen, fmt, args)<0)
Packit df99a1
      {
Packit df99a1
        gbuffer.resize(0);
Packit df99a1
        gbuffer.resize(buflen+32768);
Packit df99a1
      }
Packit df99a1
    va_end(args);
Packit df99a1
#else
Packit df99a1
    buffer[buflen-1] = 0;
Packit df99a1
    vsprintf(buffer, fmt, args);
Packit df99a1
    va_end(args);
Packit df99a1
    if (buffer[buflen-1])
Packit df99a1
      {
Packit df99a1
        // This isn't as fatal since it is on the stack, but we
Packit df99a1
        // definitely should stop the current operation.
Packit df99a1
        G_THROW( ERR_MSG("GString.overwrite") );
Packit df99a1
      }
Packit df99a1
#endif
Packit df99a1
    retval=strdup((const char *)buffer);
Packit df99a1
  }
Packit df99a1
  // Go altering the string
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::search(char c, int from) const
Packit df99a1
{
Packit df99a1
  if (from<0)
Packit df99a1
    from += size;
Packit df99a1
  int retval=(-1);
Packit df99a1
  if (from>=0 && from
Packit df99a1
  {
Packit df99a1
    char const *const s = strchr(data+from,c);
Packit df99a1
    if(s)
Packit df99a1
      retval=(int)((size_t)s-(size_t)data);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::search(char const *ptr, int from) const
Packit df99a1
{
Packit df99a1
  if(from<0)
Packit df99a1
  {
Packit df99a1
    from+=size;
Packit df99a1
    if(from<0)
Packit df99a1
      G_THROW( ERR_MSG("GString.bad_subscript") );
Packit df99a1
  }
Packit df99a1
  int retval=(-1);
Packit df99a1
  if (from>=0 && from
Packit df99a1
  {
Packit df99a1
    char const *const s = strstr(data+from,ptr);
Packit df99a1
    if(s)
Packit df99a1
      retval=(int)((size_t)s-(size_t)data);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::rsearch(char c, int from) const
Packit df99a1
{
Packit df99a1
  if(from<0)
Packit df99a1
  {
Packit df99a1
    from+=size;
Packit df99a1
    if(from<0)
Packit df99a1
      G_THROW( ERR_MSG("GString.bad_subscript") );
Packit df99a1
  }
Packit df99a1
  int retval=(-1);
Packit df99a1
  if ((from>=0) && (from
Packit df99a1
  {
Packit df99a1
    char const *const s = strrchr(data+from,c);
Packit df99a1
    if(s)
Packit df99a1
      retval=(int)((size_t)s-(size_t)data);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::rsearch(char const *ptr, int from) const
Packit df99a1
{
Packit df99a1
  if(from<0)
Packit df99a1
  {
Packit df99a1
    from+=size;
Packit df99a1
    if(from<0)
Packit df99a1
      G_THROW( ERR_MSG("GString.bad_subscript") );
Packit df99a1
  }
Packit df99a1
  int retval=(-1);
Packit df99a1
  for(int loc=from;(loc=search(ptr,loc)) >= 0;++loc)
Packit df99a1
    retval=loc;
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::contains(const char accept[],int from) const
Packit df99a1
{
Packit df99a1
  if(from<0)
Packit df99a1
  {
Packit df99a1
    from+=size;
Packit df99a1
    if(from<0)
Packit df99a1
      G_THROW( ERR_MSG("GString.bad_subscript") );
Packit df99a1
  }
Packit df99a1
  int retval=(-1);
Packit df99a1
  if (accept && accept[0] && from>=0 && from
Packit df99a1
  {
Packit df99a1
    char const * const src = data+from;
Packit df99a1
    char const *ptr=strpbrk(src,accept);
Packit df99a1
    if(ptr)
Packit df99a1
    {
Packit df99a1
      retval=(int)(ptr-src)+from;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::rcontains(const char accept[],int from) const
Packit df99a1
{
Packit df99a1
  int retval=(-1);
Packit df99a1
  while((from=contains(accept,from)) >= 0)
Packit df99a1
  {
Packit df99a1
    retval=from++;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GBaseString::is_int(void) const
Packit df99a1
{
Packit df99a1
  bool isLong=!!ptr;
Packit df99a1
  if(isLong)
Packit df99a1
  {
Packit df99a1
    int endpos;
Packit df99a1
    (*this)->toLong(0,endpos);
Packit df99a1
    if(endpos>=0)
Packit df99a1
    {
Packit df99a1
      isLong=((*this)->nextNonSpace(endpos) == (int)length());
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return isLong;
Packit df99a1
}
Packit df99a1
Packit df99a1
bool
Packit df99a1
GBaseString::is_float(void) const
Packit df99a1
{
Packit df99a1
  bool isDouble=!!ptr;
Packit df99a1
  if(isDouble)
Packit df99a1
  {
Packit df99a1
    int endpos;
Packit df99a1
    (*this)->toDouble(0,endpos);
Packit df99a1
    if(endpos>=0)
Packit df99a1
    {
Packit df99a1
      isDouble=((*this)->nextNonSpace(endpos) == (int)length());
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return isDouble;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned int 
Packit df99a1
hash(const GBaseString &str)
Packit df99a1
{
Packit df99a1
  unsigned int x = 0;
Packit df99a1
  const char *s = (const char*)str;
Packit df99a1
  while (*s) 
Packit df99a1
    x = x ^ (x<<6) ^ (unsigned char)(*s++);
Packit df99a1
  return x;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
GBaseString::throw_illegal_subscript()
Packit df99a1
{
Packit df99a1
  G_THROW( ERR_MSG("GString.bad_subscript") );
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned char *
Packit df99a1
GStringRep::UTF8::UCS4toString(
Packit df99a1
  const uint32_t w0,unsigned char *ptr, mbstate_t *) const
Packit df99a1
{
Packit df99a1
  return UCS4toUTF8(w0,ptr);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::UTF8::ncopy(wchar_t * const buf, const int buflen ) const
Packit df99a1
{
Packit df99a1
  int retval=(-1);
Packit df99a1
  if(buf && buflen)
Packit df99a1
    {
Packit df99a1
      buf[0]=0;
Packit df99a1
      if(data[0])
Packit df99a1
	{
Packit df99a1
          const size_t length=strlen(data);
Packit df99a1
          const unsigned char * const eptr=(const unsigned char *)(data+length);
Packit df99a1
	  wchar_t *r=buf;
Packit df99a1
	  wchar_t const * const rend=buf+buflen;
Packit df99a1
          for(const unsigned char *s=(const unsigned char *)data;
Packit df99a1
              (r
Packit df99a1
            {
Packit df99a1
              const uint32_t w0=UTF8toUCS4(s,eptr);
Packit df99a1
              uint16_t w1;
Packit df99a1
              uint16_t w2=1;
Packit df99a1
              for(int count=(sizeof(wchar_t)==sizeof(w1))
Packit df99a1
                    ?UCS4toUTF16(w0,w1,w2):1;
Packit df99a1
                  count&&(r
Packit df99a1
                  --count,w1=w2,++r)
Packit df99a1
		{
Packit df99a1
		  r[0]=(sizeof(wchar_t) == sizeof(w1))?(wchar_t)w1:(wchar_t)w0;
Packit df99a1
		}
Packit df99a1
            }
Packit df99a1
	  if(r
Packit df99a1
            {
Packit df99a1
              r[0]=0;
Packit df99a1
              retval=((size_t)r-(size_t)buf)/sizeof(wchar_t);
Packit df99a1
            }
Packit df99a1
	}
Packit df99a1
      else
Packit df99a1
	{
Packit df99a1
	  retval=0;
Packit df99a1
	}
Packit df99a1
    }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::UTF8::toNative(const EscapeMode escape) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(data[0])
Packit df99a1
  {
Packit df99a1
    const size_t length=strlen(data);
Packit df99a1
    const unsigned char * const eptr=(const unsigned char *)(data+length);
Packit df99a1
    unsigned char *buf;
Packit df99a1
    GPBuffer<unsigned char> gbuf(buf,12*length+12); 
Packit df99a1
    unsigned char *r=buf;
Packit df99a1
    mbstate_t ps;
Packit df99a1
    memset(&ps,0,sizeof(mbstate_t));
Packit df99a1
    for(const unsigned char *s=(const unsigned char *)data;(s
Packit df99a1
      {
Packit df99a1
        const unsigned char * const s0 = s;
Packit df99a1
        const uint32_t w0=UTF8toUCS4(s,eptr);
Packit df99a1
        if (s == s0)
Packit df99a1
          {
Packit df99a1
            s += 1;
Packit df99a1
            *r++ = '?';
Packit df99a1
          }
Packit df99a1
        else
Packit df99a1
          {
Packit df99a1
            const unsigned char * const r0 = r;
Packit df99a1
            r=UCS4toNative(w0,r,&ps);
Packit df99a1
            if(r == r0)
Packit df99a1
              {
Packit df99a1
                if (escape == IS_ESCAPED)
Packit df99a1
                  {
Packit df99a1
                    sprintf((char *)r,"&#%lu;",(unsigned long)w0);
Packit df99a1
                    r += strlen((char *)r);
Packit df99a1
                  }
Packit df99a1
                else
Packit df99a1
                  {
Packit df99a1
                    *r++ = '?';
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
      }
Packit df99a1
    r[0]=0;
Packit df99a1
    retval = NATIVE_CREATE( (const char *)buf );
Packit df99a1
  } 
Packit df99a1
  else
Packit df99a1
  {
Packit df99a1
    retval = NATIVE_CREATE( (unsigned int)0 );
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8::toUTF8(const bool nothrow) const
Packit df99a1
{
Packit df99a1
  if(!nothrow)
Packit df99a1
    G_THROW( ERR_MSG("GStringRep.UTF8ToUTF8") );
Packit df99a1
  return const_cast<GStringRep::UTF8 *>(this);
Packit df99a1
}
Packit df99a1
Packit df99a1
// Tests if a string is legally encoded in the current character set.
Packit df99a1
bool 
Packit df99a1
GStringRep::UTF8::is_valid(void) const
Packit df99a1
{
Packit df99a1
  bool retval=true;
Packit df99a1
  if(data && size)
Packit df99a1
  {
Packit df99a1
    const unsigned char * const eptr=(const unsigned char *)(data+size);
Packit df99a1
    for(const unsigned char *s=(const unsigned char *)data;(s
Packit df99a1
    {
Packit df99a1
      const unsigned char * const r=s;
Packit df99a1
      (void)UTF8toUCS4(s,eptr);
Packit df99a1
      if(r == s)
Packit df99a1
      {
Packit df99a1
        retval=false;
Packit df99a1
        break;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline uint32_t
Packit df99a1
add_char(uint32_t const U, unsigned char const * const r)
Packit df99a1
{
Packit df99a1
  uint32_t const C=r[0];
Packit df99a1
  return ((C|0x3f) == 0xbf)?((U<<6)|(C&0x3f)):0;
Packit df99a1
}
Packit df99a1
Packit df99a1
uint32_t
Packit df99a1
GStringRep::UTF8toUCS4(
Packit df99a1
  unsigned char const *&s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  uint32_t U=0;
Packit df99a1
  unsigned char const *r=s;
Packit df99a1
  if(r < eptr)
Packit df99a1
  {
Packit df99a1
    uint32_t const C1=r++[0];
Packit df99a1
    if(C1&0x80)
Packit df99a1
    {
Packit df99a1
      if(r < eptr)
Packit df99a1
      {
Packit df99a1
        U=C1;
Packit df99a1
        if((U=((C1&0x40)?add_char(U,r++):0)))
Packit df99a1
        {
Packit df99a1
          if(C1&0x20)
Packit df99a1
          {
Packit df99a1
            if(r < eptr)
Packit df99a1
            {
Packit df99a1
              if((U=add_char(U,r++)))
Packit df99a1
              {
Packit df99a1
                if(C1&0x10)
Packit df99a1
                {
Packit df99a1
                  if(r < eptr)
Packit df99a1
                  {
Packit df99a1
                    if((U=add_char(U,r++)))
Packit df99a1
                    {
Packit df99a1
                      if(C1&0x8)
Packit df99a1
                      {
Packit df99a1
                        if(r < eptr)
Packit df99a1
                        {
Packit df99a1
                          if((U=add_char(U,r++)))
Packit df99a1
                          {
Packit df99a1
                            if(C1&0x4)
Packit df99a1
                            {
Packit df99a1
                              if(r < eptr)
Packit df99a1
                              {
Packit df99a1
                                if((U=((!(C1&0x2))?(add_char(U,r++)&0x7fffffff):0)))
Packit df99a1
                                {
Packit df99a1
                                  s=r;
Packit df99a1
                                }else
Packit df99a1
                                {
Packit df99a1
                                  U=(unsigned int)(-1)-s++[0];
Packit df99a1
                                }
Packit df99a1
                              }else
Packit df99a1
                              {
Packit df99a1
                                U=0;
Packit df99a1
                              }
Packit df99a1
                            }else if((U=((U&0x4000000)?0:(U&0x3ffffff))))
Packit df99a1
                            {
Packit df99a1
                              s=r;
Packit df99a1
                            }
Packit df99a1
                          }else
Packit df99a1
                          {
Packit df99a1
                            U=(unsigned int)(-1)-s++[0];
Packit df99a1
                          }
Packit df99a1
                        }else
Packit df99a1
                        {
Packit df99a1
                          U=0;
Packit df99a1
                        }
Packit df99a1
                      }else if((U=((U&0x200000)?0:(U&0x1fffff))))
Packit df99a1
                      {
Packit df99a1
                        s=r;
Packit df99a1
                      }
Packit df99a1
                    }else
Packit df99a1
                    {
Packit df99a1
                      U=(unsigned int)(-1)-s++[0];
Packit df99a1
                    }
Packit df99a1
                  }else
Packit df99a1
                  {
Packit df99a1
                    U=0;
Packit df99a1
                  }
Packit df99a1
                }else if((U=((U&0x10000)?0:(U&0xffff))))
Packit df99a1
                {
Packit df99a1
                  s=r;
Packit df99a1
                }
Packit df99a1
              }else
Packit df99a1
              {
Packit df99a1
                U=(unsigned int)(-1)-s++[0];
Packit df99a1
              }
Packit df99a1
            }else
Packit df99a1
            {
Packit df99a1
              U=0;
Packit df99a1
            }
Packit df99a1
          }else if((U=((U&0x800)?0:(U&0x7ff))))
Packit df99a1
          {
Packit df99a1
            s=r;
Packit df99a1
          }
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          U=(unsigned int)(-1)-s++[0];
Packit df99a1
        }
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        U=0;
Packit df99a1
      }
Packit df99a1
    }else if((U=C1))
Packit df99a1
    {
Packit df99a1
      s=r;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return U;
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned char *
Packit df99a1
GStringRep::UCS4toUTF8(const uint32_t w,unsigned char *ptr)
Packit df99a1
{
Packit df99a1
  if(w <= 0x7f)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)w;
Packit df99a1
  }
Packit df99a1
  else if(w <= 0x7ff)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)((w>>6)|0xC0);
Packit df99a1
    *ptr++ = (unsigned char)((w|0x80)&0xBF);
Packit df99a1
  }
Packit df99a1
  else if(w <= 0xFFFF)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)((w>>12)|0xE0);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>6)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)((w|0x80)&0xBF);
Packit df99a1
  }
Packit df99a1
  else if(w <= 0x1FFFFF)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)((w>>18)|0xF0);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>12)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>6)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)((w|0x80)&0xBF);
Packit df99a1
  }
Packit df99a1
  else if(w <= 0x3FFFFFF)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)((w>>24)|0xF8);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>18)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>12)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>6)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)((w|0x80)&0xBF);
Packit df99a1
  }
Packit df99a1
  else if(w <= 0x7FFFFFFF)
Packit df99a1
  {
Packit df99a1
    *ptr++ = (unsigned char)((w>>30)|0xFC);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>24)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>18)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>12)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)(((w>>6)|0x80)&0xBF);
Packit df99a1
    *ptr++ = (unsigned char)((w|0x80)&0xBF);
Packit df99a1
  }
Packit df99a1
  else
Packit df99a1
  { 
Packit df99a1
    *ptr++ = '?';
Packit df99a1
  }
Packit df99a1
  return ptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
   // Creates with a concat operation.
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::concat( const char *s1, const GP<GStringRep> &s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    retval=toThis(s2);
Packit df99a1
    if(s1 && s1[0])
Packit df99a1
    {
Packit df99a1
      if(retval)
Packit df99a1
      {
Packit df99a1
        retval=concat(s1,retval->data);
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=strdup(s1);
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }else if(s1 && s1[0])
Packit df99a1
  {
Packit df99a1
    retval=strdup(s1);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
   // Creates with a concat operation.
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::concat( const GP<GStringRep> &s1,const char *s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> retval;
Packit df99a1
  if(s1)
Packit df99a1
  {
Packit df99a1
    retval=toThis(s1);
Packit df99a1
    if(s2 && s2[0])
Packit df99a1
    {
Packit df99a1
      if(retval)
Packit df99a1
      {
Packit df99a1
        retval=retval->append(s2);
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=strdup(s2);
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }else if(s2 && s2[0])
Packit df99a1
  {
Packit df99a1
    retval=strdup(s2);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep> 
Packit df99a1
GStringRep::concat(const GP<GStringRep> &s1,const GP<GStringRep> &s2) const
Packit df99a1
{ 
Packit df99a1
  GP<GStringRep> retval; 
Packit df99a1
  if(s1)
Packit df99a1
  {
Packit df99a1
    retval=toThis(s1,s2);
Packit df99a1
    if(retval && s2)
Packit df99a1
    {
Packit df99a1
      retval=retval->append(toThis(s2));
Packit df99a1
    }
Packit df99a1
  }else if(s2)
Packit df99a1
  {
Packit df99a1
    retval=toThis(s2);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::GStringRep(void)
Packit df99a1
{
Packit df99a1
  size=0;
Packit df99a1
  data=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::~GStringRep()
Packit df99a1
{
Packit df99a1
  if(data)
Packit df99a1
  {
Packit df99a1
    data[0]=0;
Packit df99a1
    ::operator delete(data);
Packit df99a1
  }
Packit df99a1
  data=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
GStringRep::UTF8::UTF8(void) {}
Packit df99a1
Packit df99a1
GStringRep::UTF8::~UTF8() {}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::cmp(const char *s1,const int len) const
Packit df99a1
{
Packit df99a1
  return cmp(data,s1,len);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::cmp(const char *s1, const char *s2,const int len)
Packit df99a1
{
Packit df99a1
  return (len
Packit df99a1
   ?((s1&&s1[0])
Packit df99a1
      ?((s2&&s2[0])
Packit df99a1
        ?((len>0)
Packit df99a1
          ?strncmp(s1,s2,len)
Packit df99a1
          :strcmp(s1,s2))
Packit df99a1
        :1)
Packit df99a1
      :((s2&&s2[0])?(-1):0))
Packit df99a1
   :0);
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::cmp(const GP<GStringRep> &s1, const GP<GStringRep> &s2,
Packit df99a1
  const int len )
Packit df99a1
{
Packit df99a1
  return (s1?(s1->cmp(s2,len)):cmp(0,(s2?(s2->data):0),len));
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::cmp(const GP<GStringRep> &s1, const char *s2, 
Packit df99a1
  const int len )
Packit df99a1
{
Packit df99a1
  return cmp((s1?s1->data:0),s2,len);
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::cmp(const char *s1, const GP<GStringRep> &s2,
Packit df99a1
  const int len )
Packit df99a1
{
Packit df99a1
  return cmp(s1,(s2?(s2->data):0),len);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::UTF8::cmp(const GP<GStringRep> &s2,const int len) const
Packit df99a1
{
Packit df99a1
  int retval;
Packit df99a1
  if(s2)
Packit df99a1
  {
Packit df99a1
    if(s2->isNative())
Packit df99a1
    {
Packit df99a1
      GP<GStringRep> r(s2->toUTF8(true));
Packit df99a1
      if(r)
Packit df99a1
      {
Packit df99a1
        retval=GStringRep::cmp(data,r->data,len);
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        retval=-(s2->cmp(toNative(NOT_ESCAPED),len));
Packit df99a1
      }
Packit df99a1
    }else
Packit df99a1
    {
Packit df99a1
      retval=GStringRep::cmp(data,s2->data,len);
Packit df99a1
    }
Packit df99a1
  }else
Packit df99a1
  { 
Packit df99a1
    retval=GStringRep::cmp(data,0,len);
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
} 
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::UTF8::toInt() const
Packit df99a1
{
Packit df99a1
  int endpos;
Packit df99a1
  return (int)toLong(0,endpos);
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline long
Packit df99a1
Cstrtol(char *data,char **edata, const int base)
Packit df99a1
{
Packit df99a1
  GStringRep::ChangeLocale locale(LC_NUMERIC,"C");
Packit df99a1
  while (data && *data==' ') data++;
Packit df99a1
  return strtol(data,edata,base);
Packit df99a1
}
Packit df99a1
Packit df99a1
long 
Packit df99a1
GStringRep::UTF8::toLong(
Packit df99a1
  const int pos, int &endpos, const int base) const
Packit df99a1
{
Packit df99a1
  char *edata=0;
Packit df99a1
  long retval=Cstrtol(data+pos,&edata, base);
Packit df99a1
  if(edata)
Packit df99a1
  {
Packit df99a1
    endpos=edata-data;
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    GP<GStringRep> ptr = GStringRep::UTF8::create();
Packit df99a1
    endpos=(-1);
Packit df99a1
    ptr=ptr->strdup(data+pos);
Packit df99a1
    if(ptr)
Packit df99a1
      ptr=ptr->toNative(NOT_ESCAPED);
Packit df99a1
    if(ptr)
Packit df99a1
    {
Packit df99a1
      int xendpos;
Packit df99a1
      retval=ptr->toLong(0,xendpos,base);
Packit df99a1
      if(xendpos> 0)
Packit df99a1
      {
Packit df99a1
        endpos=(int)size;
Packit df99a1
        ptr=ptr->strdup(data+xendpos);
Packit df99a1
        if(ptr)
Packit df99a1
        {
Packit df99a1
          ptr=ptr->toUTF8(true);
Packit df99a1
          if(ptr)
Packit df99a1
          {
Packit df99a1
            endpos-=(int)(ptr->size);
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline unsigned long
Packit df99a1
Cstrtoul(char *data,char **edata, const int base)
Packit df99a1
{
Packit df99a1
  GStringRep::ChangeLocale locale(LC_NUMERIC,"C");
Packit df99a1
  while (data && *data==' ') data++;
Packit df99a1
  return strtoul(data,edata,base);
Packit df99a1
}
Packit df99a1
Packit df99a1
unsigned long 
Packit df99a1
GStringRep::UTF8::toULong(
Packit df99a1
  const int pos, int &endpos, const int base) const
Packit df99a1
{
Packit df99a1
  char *edata=0;
Packit df99a1
  unsigned long retval=Cstrtoul(data+pos,&edata, base);
Packit df99a1
  if(edata)
Packit df99a1
  {
Packit df99a1
    endpos=edata-data;
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    GP<GStringRep> ptr = GStringRep::UTF8::create();
Packit df99a1
    endpos=(-1);
Packit df99a1
    ptr=ptr->strdup(data+pos);
Packit df99a1
    if(ptr)
Packit df99a1
      ptr=ptr->toNative(NOT_ESCAPED);
Packit df99a1
    if(ptr)
Packit df99a1
    {
Packit df99a1
      int xendpos;
Packit df99a1
      retval=ptr->toULong(0,xendpos,base);
Packit df99a1
      if(xendpos> 0)
Packit df99a1
      {
Packit df99a1
        endpos=(int)size;
Packit df99a1
        ptr=ptr->strdup(data+xendpos);
Packit df99a1
        if(ptr)
Packit df99a1
        {
Packit df99a1
          ptr=ptr->toUTF8(true);
Packit df99a1
          if(ptr)
Packit df99a1
          {
Packit df99a1
            endpos-=(int)(ptr->size);
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
static inline double
Packit df99a1
Cstrtod(char *data,char **edata)
Packit df99a1
{
Packit df99a1
  GStringRep::ChangeLocale locale(LC_NUMERIC,"C");
Packit df99a1
  while (data && *data==' ') data++;
Packit df99a1
  return strtod(data,edata);
Packit df99a1
}
Packit df99a1
Packit df99a1
double
Packit df99a1
GStringRep::UTF8::toDouble(const int pos, int &endpos) const
Packit df99a1
{
Packit df99a1
  char *edata=0;
Packit df99a1
  double retval=Cstrtod(data+pos,&edata);
Packit df99a1
  if(edata)
Packit df99a1
  {
Packit df99a1
    endpos=edata-data;
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    GP<GStringRep> ptr = GStringRep::UTF8::create();
Packit df99a1
    endpos=(-1);
Packit df99a1
    ptr=ptr->strdup(data+pos);
Packit df99a1
    if(ptr)
Packit df99a1
      ptr=ptr->toNative(NOT_ESCAPED);
Packit df99a1
    if(ptr)
Packit df99a1
    {
Packit df99a1
      int xendpos;
Packit df99a1
      retval=ptr->toDouble(0,xendpos);
Packit df99a1
      if(xendpos >= 0)
Packit df99a1
      {
Packit df99a1
        endpos=(int)size;
Packit df99a1
        ptr=ptr->strdup(data+xendpos);
Packit df99a1
        if(ptr)
Packit df99a1
        {
Packit df99a1
          ptr=ptr->toUTF8(true);
Packit df99a1
          if(ptr)
Packit df99a1
          {
Packit df99a1
            endpos-=(int)(ptr->size);
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::getUCS4(uint32_t &w, const int from) const
Packit df99a1
{
Packit df99a1
  int retval;
Packit df99a1
  if(from>=size)
Packit df99a1
  {
Packit df99a1
    w=0;
Packit df99a1
    retval=size;
Packit df99a1
  }else if(from<0)
Packit df99a1
  {
Packit df99a1
    w=(unsigned int)(-1);
Packit df99a1
    retval=(-1);
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    const char *source=data+from;
Packit df99a1
    w=getValidUCS4(source);
Packit df99a1
    retval=(int)((size_t)source-(size_t)data);
Packit df99a1
  } 
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
uint32_t
Packit df99a1
GStringRep::UTF8::getValidUCS4(const char *&source) const
Packit df99a1
{
Packit df99a1
  return GStringRep::UTF8toUCS4((const unsigned char *&)source,data+size);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::nextNonSpace(const int from,const int len) const
Packit df99a1
{
Packit df99a1
  return nextCharType(giswspace,from,len,true);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::nextSpace(const int from,const int len) const
Packit df99a1
{
Packit df99a1
  return nextCharType(giswspace,from,len,false);
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::nextChar(const int from) const
Packit df99a1
{
Packit df99a1
  char const * xptr=data+from;
Packit df99a1
  (void)getValidUCS4(xptr);
Packit df99a1
  return (int)((size_t)xptr-(size_t)data);
Packit df99a1
}
Packit df99a1
Packit df99a1
int 
Packit df99a1
GStringRep::firstEndSpace(int from,const int len) const
Packit df99a1
{
Packit df99a1
  const int xsize=(len<0)?size:(from+len);
Packit df99a1
  const int ysize=(size
Packit df99a1
  int retval=ysize;
Packit df99a1
  while(from
Packit df99a1
  {
Packit df99a1
    from=nextNonSpace(from,ysize-from);
Packit df99a1
    if(from < size)
Packit df99a1
    {
Packit df99a1
      const int r=nextSpace(from,ysize-from);
Packit df99a1
      // If a character isn't legal, then it will return
Packit df99a1
      // tru for both nextSpace and nextNonSpace.
Packit df99a1
      if(r == from)
Packit df99a1
      {
Packit df99a1
        from++;
Packit df99a1
      }else
Packit df99a1
      {
Packit df99a1
        from=retval=r;
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::UCS4toUTF16(
Packit df99a1
  const uint32_t w,uint16_t &w1, uint16_t &w2)
Packit df99a1
{
Packit df99a1
  int retval;
Packit df99a1
  if(w<0x10000)
Packit df99a1
  {
Packit df99a1
    w1=(uint16_t)w;
Packit df99a1
    w2=0;
Packit df99a1
    retval=1;
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    w1=(uint16_t)((((w-0x10000)>>10)&0x3ff)+0xD800);
Packit df99a1
    w2=(uint16_t)((w&0x3ff)+0xDC00);
Packit df99a1
    retval=2;
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
int
Packit df99a1
GStringRep::UTF16toUCS4(
Packit df99a1
  uint32_t &U,uint16_t const * const s,void const * const eptr)
Packit df99a1
{
Packit df99a1
  int retval=0;
Packit df99a1
  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
        retval=1;
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))&&((U=(0x10000+((W1&0x3ff)<<10))|(W2&0x3ff))))
Packit df99a1
        {
Packit df99a1
          retval=2;
Packit df99a1
        }else
Packit df99a1
        {
Packit df99a1
          retval=(-1);
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
//bcr
Packit df99a1
Packit df99a1
GUTF8String&
Packit df99a1
GUTF8String::operator+= (char ch)
Packit df99a1
{
Packit df99a1
  return init(
Packit df99a1
    GStringRep::UTF8::create((const char*)*this,
Packit df99a1
    GStringRep::UTF8::create(&ch,0,1)));
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String&
Packit df99a1
GUTF8String::operator+= (const char *str)
Packit df99a1
{
Packit df99a1
  return init(GStringRep::UTF8::create(*this,str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String&
Packit df99a1
GUTF8String::operator+= (const GBaseString &str)
Packit df99a1
{
Packit df99a1
  return init(GStringRep::UTF8::create(*this,str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::substr(int from, int len) const
Packit df99a1
{ return GUTF8String(*this, from, len); }
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::operator+(const GBaseString &s2) const
Packit df99a1
{ return GStringRep::UTF8::create(*this,s2); }
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::operator+(const GUTF8String &s2) const
Packit df99a1
{ return GStringRep::UTF8::create(*this,s2); }
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::operator+(const char    *s2) const
Packit df99a1
{ return GStringRep::UTF8::create(*this,s2); }
Packit df99a1
Packit df99a1
char *
Packit df99a1
GUTF8String::getbuf(int n)
Packit df99a1
{
Packit df99a1
  if(ptr)
Packit df99a1
    init((*this)->getbuf(n));
Packit df99a1
  else if(n>0)
Packit df99a1
    init(GStringRep::UTF8::create(n));
Packit df99a1
  else
Packit df99a1
    init(0);
Packit df99a1
  return ptr?((*this)->data):0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
GUTF8String::setat(const int n, const char ch)
Packit df99a1
{
Packit df99a1
  if((!n)&&(!ptr))
Packit df99a1
  {
Packit df99a1
    init(GStringRep::UTF8::create(&ch,0,1));
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    init((*this)->setat(CheckSubscript(n),ch));
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<GStringRep>
Packit df99a1
GStringRep::UTF8ToNative( const char *s, const EscapeMode escape )
Packit df99a1
{
Packit df99a1
  return GStringRep::UTF8::create(s)->toNative(escape);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const char dat)
Packit df99a1
{ init(GStringRep::UTF8::create(&dat,0,1)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const GUTF8String &fmt, va_list &args)
Packit df99a1
{ 
Packit df99a1
  if (fmt.ptr)
Packit df99a1
    init(fmt->vformat(args));
Packit df99a1
  else 
Packit df99a1
    init(fmt); 
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const char *str)
Packit df99a1
{ init(GStringRep::UTF8::create(str)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const unsigned char *str)
Packit df99a1
{ init(GStringRep::UTF8::create((const char *)str)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const uint16_t *str)
Packit df99a1
{ init(GStringRep::UTF8::create(str,0,-1)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const uint32_t *str)
Packit df99a1
{ init(GStringRep::UTF8::create(str,0,-1)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const char *dat, unsigned int len)
Packit df99a1
{ init(GStringRep::UTF8::create(dat,0,((int)len<0)?(-1):(int)len)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const uint16_t *dat, unsigned int len)
Packit df99a1
{ init(GStringRep::UTF8::create(dat,0,((int)len<0)?(-1):(int)len)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const uint32_t *dat, unsigned int len)
Packit df99a1
{ init(GStringRep::UTF8::create(dat,0,((int)len<0)?(-1):(int)len)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const GBaseString &gs, int from, int len)
Packit df99a1
{ init(GStringRep::UTF8::create(gs,from,((int)len<0)?(-1):(int)len)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const int number)
Packit df99a1
{ init(GStringRep::UTF8::create_format("%d",number)); }
Packit df99a1
Packit df99a1
GUTF8String::GUTF8String(const double number)
Packit df99a1
{ init(GStringRep::UTF8::create_format("%f",number)); }
Packit df99a1
Packit df99a1
GUTF8String& GUTF8String::operator= (const char str)
Packit df99a1
{ return init(GStringRep::UTF8::create(&str,0,1)); }
Packit df99a1
Packit df99a1
GUTF8String& GUTF8String::operator= (const char *str)
Packit df99a1
{ return init(GStringRep::UTF8::create(str)); }
Packit df99a1
Packit df99a1
GUTF8String GBaseString::operator+(const GUTF8String &s2) const
Packit df99a1
{ return GStringRep::UTF8::create(*this,s2); }
Packit df99a1
Packit df99a1
#if HAS_WCHAR
Packit df99a1
GUTF8String
Packit df99a1
GNativeString::operator+(const GUTF8String &s2) const
Packit df99a1
{
Packit df99a1
  if (ptr)
Packit df99a1
    return GStringRep::UTF8::create((*this)->toUTF8(true),s2);
Packit df99a1
  else
Packit df99a1
    return GStringRep::UTF8::create((*this),s2);
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
GUTF8String::operator+(const GNativeString &s2) const
Packit df99a1
{
Packit df99a1
  GP<GStringRep> g = s2;
Packit df99a1
  if (s2.ptr)
Packit df99a1
    g = s2->toUTF8(true);
Packit df99a1
  return GStringRep::UTF8::create(*this,g);
Packit df99a1
}
Packit df99a1
Packit df99a1
GUTF8String
Packit df99a1
operator+(const char    *s1, const GUTF8String &s2)
Packit df99a1
{ return GStringRep::UTF8::create(s1,s2); }
Packit df99a1
Packit df99a1
#if HAS_WCHAR
Packit df99a1
GNativeString
Packit df99a1
operator+(const char    *s1, const GNativeString &s2)
Packit df99a1
{ return GStringRep::Native::create(s1,s2); }
Packit df99a1
Packit df99a1
GNativeString&
Packit df99a1
GNativeString::operator+= (char ch)
Packit df99a1
{
Packit df99a1
  char s[2]; s[0]=ch; s[1]=0;
Packit df99a1
  return init(GStringRep::Native::create((const char*)*this, s));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString&
Packit df99a1
GNativeString::operator+= (const char *str)
Packit df99a1
{
Packit df99a1
  return init(GStringRep::Native::create(*this,str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString&
Packit df99a1
GNativeString::operator+= (const GBaseString &str)
Packit df99a1
{
Packit df99a1
  return init(GStringRep::Native::create(*this,str));
Packit df99a1
}
Packit df99a1
Packit df99a1
GNativeString
Packit df99a1
GNativeString::operator+(const GBaseString &s2) const
Packit df99a1
{ return GStringRep::Native::create(*this,s2); }
Packit df99a1
Packit df99a1
GNativeString
Packit df99a1
GNativeString::operator+(const GNativeString &s2) const
Packit df99a1
{ return GStringRep::Native::create(*this,s2); }
Packit df99a1
Packit df99a1
GNativeString
Packit df99a1
GNativeString::operator+(const char    *s2) const
Packit df99a1
{ return GStringRep::Native::create(*this,s2); }
Packit df99a1
Packit df99a1
char *
Packit df99a1
GNativeString::getbuf(int n)
Packit df99a1
{
Packit df99a1
  if(ptr)
Packit df99a1
    init((*this)->getbuf(n));
Packit df99a1
  else if(n>0)
Packit df99a1
    init(GStringRep::Native::create(n));
Packit df99a1
  else
Packit df99a1
    init(0);
Packit df99a1
  return ptr?((*this)->data):0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
GNativeString::setat(const int n, const char ch)
Packit df99a1
{
Packit df99a1
  if((!n)&&(!ptr))
Packit df99a1
  {
Packit df99a1
    init(GStringRep::Native::create(&ch,0,1));
Packit df99a1
  }else
Packit df99a1
  {
Packit df99a1
    init((*this)->setat(CheckSubscript(n),ch));
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
#endif
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