home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
CLASSSRC.PAK
/
USTRING.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
11KB
|
469 lines
//----------------------------------------------------------------------------
// (C) Copyright 1994 by Borland International, All Rights Reserved
//
// TUString implementation (others functions are inline)
//
//----------------------------------------------------------------------------
#if !defined(_Windows)
# define _Windows // pretend we are in windows to get the headers we need
#endif
#if !defined(INC_OLE2)
# define INC_OLE2 // Make sure we get Ole2 headers
#endif
#include <osl/ustring.h>
#include <osl/inlines.h>
#include <string.h>
TUString TUString::Null; // null TAutoStrings reference this object
#if defined(BI_HAS_WCHAR)
//
// Take a wide char string & return an ANSI string in a new'd char[] buffer
//
char* TUString::ConvertWtoA(const wchar_t* src, size_t len)
{
size_t size = WideCharToMultiByte(CP_ACP, 0, src, len, 0, 0, 0, 0);
char* dst = new char[size + (len != -1)]; // room for null if fixed size
size = WideCharToMultiByte(CP_ACP, 0, src, len, dst, size, 0, 0);
if (len != -1)
dst[size] = 0;
return dst;
}
//
// Take an ANSI char string & return a wide string in a new'd wchar_t[] buffer
//
wchar_t* TUString::ConvertAtoW(const char* src, size_t len)
{
size_t size = MultiByteToWideChar(CP_ACP, 0, src, len, 0, 0);
wchar_t* dst = new wchar_t[size + (len != -1)];
size = MultiByteToWideChar(CP_ACP, 0, src, len, dst, size);
if (len != -1)
dst[size] = 0;
return dst;
}
#endif
//------------------------------------------------------------------------
//
// Change UString to isCopy regardless of current type
//
char* TUString::ChangeToCopy()
{
char* dst = 0;
const char far* src;
int len;
switch (Kind) {
case isNull:
return 0;
case isConst:
src = Const;
len = strlen(Const);
break;
case isCopy:
return Copy;
#if defined(BI_HAS_WCHAR)
case isWConst:
dst = ConvertWtoA(WConst);
break;
case isWCopy:
dst = ConvertWtoA(WCopy);
delete [] WCopy;
break;
#endif
#if defined(BI_OLECHAR_WIDE)
case isBstr:
case isExtBstr:
dst = ConvertWtoA(Bstr, ::SysStringLen(Bstr));
break;
#else
case isBstr:
case isExtBstr:
src = Bstr;
len = ::SysStringLen(Bstr);
break;
#endif
case isString:
src = ((string*)&String)->c_str();
len = ((string*)&String)->length();
}
if (!dst) {
dst = new char[len+1];
memcpy(dst, src, len+1);
}
if (Kind == isBstr)
::SysFreeString(Bstr);
Kind = isCopy;
Copy = dst;
return Copy;
}
#if defined(BI_HAS_WCHAR)
//
// Change UString to isWCopy regardless of current type
//
wchar_t* TUString::ChangeToWCopy()
{
wchar_t* dst = 0;
const wchar_t* src;
int len;
switch (Kind) {
case isNull:
return 0;
case isConst:
dst = ConvertAtoW(Const);
break;
case isCopy:
dst = ConvertAtoW(Copy);
delete [] Copy;
break;
case isWConst:
src = WConst;
len = strlen(WConst);
break;
case isWCopy:
return WCopy;
#if defined(BI_OLECHAR_WIDE)
case isBstr:
case isExtBstr:
src = Bstr;
len = ::SysStringLen(Bstr);
if (Kind == isBstr)
::SysFreeString(Bstr);
break;
#else // This case probably never happens
case isBstr:
case isExtBstr:
dst = ConvertAtoW(Bstr, ::SysStringLen(Bstr));
if (Kind == isBstr)
::SysFreeString(Bstr);
break;
#endif
case isString:
dst = ConvertAtoW(((string*)&String)->c_str(), ((string*)&String)->length());
}
if (!dst) {
dst = new wchar_t[len+1];
memcpy(dst, src, (len+1) * sizeof(wchar_t));
}
Kind = isWCopy;
WCopy = dst;
return WCopy;
}
#endif
//------------------------------------------------------------------------
// inline ctors used by Create functions
inline TUString::TUString(const char far& str)
:
Kind(isConst), Const(&str), RefCnt(1), Lang(0)
{
}
inline TUString::TUString(char& str)
:
Kind(isCopy), RefCnt(1), Lang(0)
{
Copy = new char[strlen(&str)+1];
strcpy(Copy, &str);
}
#if defined(BI_HAS_WCHAR)
inline TUString::TUString(const wchar_t& str)
:
Kind(isWConst), WConst(&str), RefCnt(1), Lang(0)
{
}
inline TUString::TUString(wchar_t& str)
:
Kind(isWCopy), RefCnt(1), Lang(0)
{
WCopy = new wchar_t[strlen(&str)+1];
strcpy(WCopy, &str);
}
#endif
inline TUString::TUString(BSTR str, bool loan, TLangId lang)
:
Kind(loan ? isExtBstr : isBstr), Bstr(str), RefCnt(loan ? 2 : 1), Lang(lang)
{
}
inline void* operator new(size_t, TStringRef** p) {return p;}
inline TUString::TUString(const string& str)
:
Kind(isString), RefCnt(1), Lang(0)
{
new(&String) string(str);
}
//------------------------------------------------------------------------
TUString* TUString::Create(const char far* str)
{
return str && *str ? new TUString(*str) : &++Null;
}
TUString* TUString::Create(char* str)
{
return str && *str ? new TUString(*str) : &++Null;
}
#if defined(BI_HAS_WCHAR)
TUString* TUString::Create(const wchar_t* str)
{
return str && *str ? new TUString(*str) : &++Null;
}
TUString* TUString::Create(wchar_t* str)
{
return str && *str ? new TUString(*str) : &++Null;
}
#endif
TUString* TUString::Create(BSTR str, bool loan, TLangId lang)
{
if (str && ::SysStringLen(str))
return new TUString(str, loan, lang);
if (!loan)
::SysFreeString(str);
return &++Null;
}
TUString* TUString::Create(const string& str)
{
return str.length() ? new TUString(str) : &++Null;
}
TUString* TUString::Assign(const TUString& s)
{
if (RefCnt == 1 && Kind != isNull && Kind != isExtBstr)
Free();
else
--*this;
CONST_CAST(TUString&,s).RefCnt++;
return &CONST_CAST(TUString&,s);
}
TUString* TUString::Assign(const string& s)
{
if (s.length() && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isString;
new(&String) string(s);
return this;
}
else {
--*this;
return Create(s);
}
}
TUString* TUString::Assign(const char far* s)
{
if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isConst;
Const = s;
return this;
}
else {
--*this;
return Create(s);
}
}
TUString* TUString::Assign(char* s)
{
if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isCopy;
Copy = new char[strlen(s)+1];
strcpy(Copy, s);
return this;
}
else {
--*this;
return Create(s);
}
}
#if defined(BI_HAS_WCHAR)
TUString* TUString::Assign(const wchar_t* s)
{
if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isWConst;
WConst = s;
return this;
}
else {
--*this;
return Create(s);
}
}
TUString* TUString::Assign(wchar_t* s)
{
if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isWCopy;
WCopy = new wchar_t[strlen(s)+1];
strcpy(WCopy, s);
return this;
}
else {
--*this;
return Create(s);
}
}
#endif
TUString* TUString::Assign(BSTR str, TLangId lang)
{
if (RefCnt==1 && Kind != isNull && Kind != isExtBstr) {
Free();
Kind = isBstr;
Bstr = str;
Lang = lang;
if (Bstr && ::SysStringLen(Bstr))
return this;
delete this;
return &++Null;
}
else {
--*this;
return Create(str, false, lang);
}
}
TUString::operator const char far*() const
{
switch (Kind) {
case isNull: return 0;
case isConst: return Const;
case isCopy: return Copy;
case isString: return ((string*)&String)->c_str();
#if defined(BI_OLECHAR_WIDE)
case isBstr:
case isExtBstr: return CONST_CAST(TUString*,this)->ChangeToCopy();
#else
case isBstr:
case isExtBstr: return Bstr;
#endif
case isWConst:
case isWCopy: return CONST_CAST(TUString*,this)->ChangeToCopy();
}
return 0; // suppress warning
}
TUString::operator char*()
{
return ChangeToCopy();
}
#if defined(BI_HAS_WCHAR)
TUString::operator const wchar_t*() const
{
switch (Kind) {
case isNull: return 0;
case isWConst: return WConst;
case isWCopy: return WCopy;
#if defined(BI_OLECHAR_WIDE)
case isBstr:
case isExtBstr: return Bstr;
#else
case isBstr:
case isExtBstr: return CONST_CAST(TUString*,this)->ChangeToWCopy();
#endif
case isConst:
case isCopy:
case isString: return CONST_CAST(TUString*,this)->ChangeToWCopy();
}
return 0; // suppress warning
}
TUString::operator wchar_t*()
{
return ChangeToWCopy();
}
#endif
//
//
//
int TUString::Length() const
{
switch (Kind) {
case isNull: return 0;
#if defined(BI_HAS_WCHAR)
case isWConst: return strlen(WConst);
case isWCopy: return strlen(WCopy);
#endif
case isBstr:
case isExtBstr: return ::SysStringLen(Bstr);
case isConst: return strlen(Const);
case isCopy: return strlen(Copy);
case isString: return ((string*)&String)->length();
}
return 0; // suppress warning
}
//
// Revokes BSTR ownership from this UString
//
void TUString::RevokeBstr(BSTR s)
{
if (Kind != isExtBstr || Bstr != s)
return;
if (RefCnt == 1) {
Kind = isNull;
delete this;
return;
}
Kind = isCopy;
#if defined(BI_OLECHAR_WIDE)
WCopy = new wchar_t[strlen(s)+1];
strcpy(WCopy, s);
#else
Copy = new char[strlen(s)+1];
strcpy(Copy, s);
#endif
}
//
// Passes BSTR ownership to this UString
//
void TUString::ReleaseBstr(BSTR s)
{
if (Kind == isExtBstr && Bstr == s) {
Kind = isBstr;
--*this;
}
else // has been overwritten with converted type
::SysFreeString(Bstr);
}
//
// Free any resources held by this UString. Union & Kind left in random state;
// must be reinitialized before use.
//
void TUString::Free()
{
switch (Kind) {
case isCopy: delete [] Copy; break;
#if defined(BI_HAS_WCHAR)
case isWCopy: delete [] WCopy; break;
#endif
case isBstr: ::SysFreeString(Bstr); break;
case isString: ((string*)&String)->string::~string();
}
Lang = 0;
//Kind = isNull; // for safety, not really needed
}