|
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
|