home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // (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
- }
-