home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / CLASSSRC.PAK / USTRING.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  11KB  |  469 lines

  1. //----------------------------------------------------------------------------
  2. // (C) Copyright 1994 by Borland International, All Rights Reserved
  3. //
  4. // TUString implementation (others functions are inline)
  5. //
  6. //----------------------------------------------------------------------------
  7. #if !defined(_Windows)
  8. # define _Windows      // pretend we are in windows to get the headers we need
  9. #endif
  10. #if !defined(INC_OLE2)
  11. # define INC_OLE2      // Make sure we get Ole2 headers
  12. #endif
  13. #include <osl/ustring.h>
  14. #include <osl/inlines.h>
  15. #include <string.h>
  16.  
  17. TUString TUString::Null;   // null TAutoStrings reference this object
  18.  
  19. #if defined(BI_HAS_WCHAR)
  20. //
  21. // Take a wide char string & return an ANSI string in a new'd char[] buffer
  22. //
  23. char* TUString::ConvertWtoA(const wchar_t* src, size_t len)
  24. {
  25.   size_t size = WideCharToMultiByte(CP_ACP, 0, src, len, 0, 0, 0, 0);
  26.   char* dst = new char[size + (len != -1)];  // room for null if fixed size
  27.   size = WideCharToMultiByte(CP_ACP, 0, src, len, dst, size, 0, 0);
  28.   if (len != -1)
  29.     dst[size] = 0;
  30.   return dst;
  31. }
  32.  
  33. //
  34. // Take an ANSI char string & return a wide string in a new'd wchar_t[] buffer
  35. //
  36. wchar_t* TUString::ConvertAtoW(const char* src, size_t len)
  37. {
  38.   size_t size = MultiByteToWideChar(CP_ACP, 0, src, len, 0, 0);
  39.   wchar_t* dst = new wchar_t[size + (len != -1)];
  40.   size = MultiByteToWideChar(CP_ACP, 0, src, len, dst, size);
  41.   if (len != -1)
  42.     dst[size] = 0;
  43.   return dst;
  44. }
  45. #endif
  46.  
  47. //------------------------------------------------------------------------
  48.  
  49. //
  50. // Change UString to isCopy regardless of current type
  51. //
  52. char* TUString::ChangeToCopy()
  53. {
  54.   char* dst = 0;
  55.   const char far* src;
  56.   int len;
  57.   switch (Kind) {
  58.     case isNull:
  59.       return 0;
  60.     case isConst:
  61.       src = Const;
  62.       len = strlen(Const);
  63.       break;
  64.     case isCopy:
  65.       return Copy;
  66. #if defined(BI_HAS_WCHAR)
  67.     case isWConst:
  68.       dst = ConvertWtoA(WConst);
  69.       break;
  70.     case isWCopy:
  71.       dst = ConvertWtoA(WCopy);
  72.       delete [] WCopy;
  73.       break;
  74. #endif
  75. #if defined(BI_OLECHAR_WIDE)
  76.     case isBstr:
  77.     case isExtBstr:
  78.       dst = ConvertWtoA(Bstr, ::SysStringLen(Bstr));
  79.       break;
  80. #else
  81.     case isBstr:
  82.     case isExtBstr:
  83.       src = Bstr;
  84.       len = ::SysStringLen(Bstr);
  85.       break;
  86. #endif
  87.     case isString:
  88.       src = ((string*)&String)->c_str();
  89.       len = ((string*)&String)->length();
  90.   }
  91.   if (!dst) {
  92.     dst = new char[len+1];
  93.     memcpy(dst, src, len+1);
  94.   }
  95.   if (Kind == isBstr)
  96.     ::SysFreeString(Bstr);
  97.   Kind = isCopy;
  98.   Copy = dst;
  99.   return Copy;
  100. }
  101.  
  102. #if defined(BI_HAS_WCHAR)
  103. //
  104. // Change UString to isWCopy regardless of current type
  105. //
  106. wchar_t* TUString::ChangeToWCopy()
  107. {
  108.   wchar_t* dst = 0;
  109.   const wchar_t* src;
  110.   int len;
  111.   switch (Kind) {
  112.     case isNull:
  113.       return 0;
  114.     case isConst:
  115.       dst = ConvertAtoW(Const);
  116.       break;
  117.     case isCopy:
  118.       dst = ConvertAtoW(Copy);
  119.       delete [] Copy;
  120.       break;
  121.     case isWConst:
  122.       src = WConst;
  123.       len = strlen(WConst);
  124.       break;
  125.     case isWCopy:
  126.       return WCopy;
  127. #if defined(BI_OLECHAR_WIDE)
  128.     case isBstr:
  129.     case isExtBstr:
  130.       src = Bstr;
  131.       len = ::SysStringLen(Bstr);
  132.       if (Kind == isBstr)
  133.         ::SysFreeString(Bstr);
  134.       break;
  135. #else                // This case probably never happens
  136.     case isBstr:
  137.     case isExtBstr:
  138.       dst = ConvertAtoW(Bstr, ::SysStringLen(Bstr));
  139.       if (Kind == isBstr)
  140.         ::SysFreeString(Bstr);
  141.       break;
  142. #endif
  143.     case isString:
  144.       dst = ConvertAtoW(((string*)&String)->c_str(), ((string*)&String)->length());
  145.   }
  146.   if (!dst) {
  147.     dst = new wchar_t[len+1];
  148.     memcpy(dst, src, (len+1) * sizeof(wchar_t));
  149.   }
  150.   Kind = isWCopy;
  151.   WCopy = dst;
  152.   return WCopy;
  153. }
  154. #endif
  155.  
  156. //------------------------------------------------------------------------
  157. // inline ctors used by Create functions
  158.  
  159. inline TUString::TUString(const char far& str)
  160. :
  161.   Kind(isConst), Const(&str), RefCnt(1), Lang(0)
  162. {
  163. }
  164.  
  165. inline TUString::TUString(char& str)
  166. :
  167.   Kind(isCopy), RefCnt(1), Lang(0)
  168. {
  169.   Copy = new char[strlen(&str)+1];
  170.   strcpy(Copy, &str);
  171. }
  172.  
  173. #if defined(BI_HAS_WCHAR)
  174. inline TUString::TUString(const wchar_t& str)
  175. :
  176.   Kind(isWConst), WConst(&str), RefCnt(1), Lang(0)
  177. {
  178. }
  179.   
  180. inline TUString::TUString(wchar_t& str)
  181. :
  182.   Kind(isWCopy), RefCnt(1), Lang(0)
  183. {
  184.   WCopy = new wchar_t[strlen(&str)+1];
  185.   strcpy(WCopy, &str);
  186. }
  187. #endif
  188.  
  189. inline TUString::TUString(BSTR str, bool loan, TLangId lang)
  190. :
  191.   Kind(loan ? isExtBstr : isBstr), Bstr(str), RefCnt(loan ? 2 : 1), Lang(lang)
  192. {
  193. }
  194.  
  195. inline void* operator new(size_t, TStringRef** p) {return p;}
  196.  
  197. inline TUString::TUString(const string& str)
  198. :
  199.   Kind(isString), RefCnt(1), Lang(0)
  200. {
  201.   new(&String) string(str);
  202. }
  203.  
  204. //------------------------------------------------------------------------
  205.  
  206. TUString* TUString::Create(const char far* str)
  207. {
  208.   return str && *str ? new TUString(*str) : &++Null;
  209. }
  210.  
  211. TUString* TUString::Create(char* str)
  212. {
  213.   return str && *str ? new TUString(*str) : &++Null;
  214. }
  215.  
  216. #if defined(BI_HAS_WCHAR)
  217. TUString* TUString::Create(const wchar_t* str)
  218. {
  219.   return str && *str ? new TUString(*str) : &++Null;
  220. }
  221.  
  222. TUString* TUString::Create(wchar_t* str)
  223. {
  224.   return str && *str ? new TUString(*str) : &++Null;
  225. }
  226. #endif
  227.  
  228. TUString* TUString::Create(BSTR str, bool loan, TLangId lang)
  229. {
  230.   if (str && ::SysStringLen(str))
  231.     return new TUString(str, loan, lang);
  232.   if (!loan)
  233.     ::SysFreeString(str);
  234.   return &++Null;
  235. }
  236.  
  237. TUString* TUString::Create(const string& str)
  238. {
  239.   return str.length() ? new TUString(str) : &++Null;
  240. }
  241.  
  242. TUString* TUString::Assign(const TUString& s)
  243. {
  244.   if (RefCnt == 1 && Kind != isNull && Kind != isExtBstr)
  245.     Free();
  246.   else
  247.     --*this;
  248.  
  249.   CONST_CAST(TUString&,s).RefCnt++;
  250.   return &CONST_CAST(TUString&,s);
  251. }
  252.  
  253. TUString* TUString::Assign(const string& s)
  254. {
  255.   if (s.length() && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
  256.     Free();
  257.     Kind = isString;
  258.     new(&String) string(s);
  259.     return this;
  260.   }
  261.   else {
  262.     --*this;
  263.     return Create(s);
  264.   }
  265. }
  266.  
  267. TUString* TUString::Assign(const char far* s)
  268. {
  269.   if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
  270.     Free();
  271.     Kind = isConst;
  272.     Const = s;
  273.     return this;
  274.   }
  275.   else {
  276.     --*this;
  277.     return Create(s);
  278.   }
  279. }
  280.  
  281. TUString* TUString::Assign(char* s)
  282. {
  283.   if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
  284.     Free();
  285.     Kind = isCopy;
  286.     Copy = new char[strlen(s)+1];
  287.     strcpy(Copy, s);
  288.     return this;
  289.   }
  290.   else {
  291.     --*this;
  292.     return Create(s);
  293.   }
  294. }
  295.  
  296. #if defined(BI_HAS_WCHAR)
  297. TUString* TUString::Assign(const wchar_t* s)
  298. {
  299.   if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
  300.     Free();
  301.     Kind = isWConst;
  302.     WConst = s;
  303.     return this;
  304.   }
  305.   else {
  306.     --*this;
  307.     return Create(s);
  308.   }
  309. }
  310.  
  311. TUString* TUString::Assign(wchar_t* s)
  312. {
  313.   if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
  314.     Free();
  315.     Kind = isWCopy;
  316.     WCopy = new wchar_t[strlen(s)+1];
  317.     strcpy(WCopy, s);
  318.     return this;
  319.   }
  320.   else {
  321.     --*this;
  322.     return Create(s);
  323.   }
  324. }
  325. #endif
  326.  
  327. TUString* TUString::Assign(BSTR str, TLangId lang)
  328. {
  329.   if (RefCnt==1 && Kind != isNull && Kind != isExtBstr) {
  330.     Free();
  331.     Kind = isBstr;
  332.     Bstr = str;
  333.     Lang = lang;
  334.     if (Bstr && ::SysStringLen(Bstr))
  335.       return this;
  336.     delete this;
  337.     return &++Null;
  338.   }
  339.   else {
  340.     --*this;
  341.     return Create(str, false, lang);
  342.   }
  343. }
  344.  
  345. TUString::operator const char far*() const
  346. {
  347.   switch (Kind) {
  348.     case isNull:    return 0;
  349.     case isConst:   return Const;
  350.     case isCopy:    return Copy;    
  351.     case isString:  return ((string*)&String)->c_str();
  352. #if defined(BI_OLECHAR_WIDE)
  353.     case isBstr:
  354.     case isExtBstr: return CONST_CAST(TUString*,this)->ChangeToCopy();
  355. #else
  356.     case isBstr:
  357.     case isExtBstr: return Bstr;
  358. #endif
  359.     case isWConst:
  360.     case isWCopy:   return CONST_CAST(TUString*,this)->ChangeToCopy();
  361.   }
  362.   return 0; // suppress warning
  363. }
  364.  
  365. TUString::operator char*()
  366. {
  367.   return ChangeToCopy();
  368. }
  369.  
  370. #if defined(BI_HAS_WCHAR)
  371. TUString::operator const wchar_t*() const
  372. {
  373.   switch (Kind) {
  374.     case isNull:    return 0;
  375.     case isWConst:  return WConst;
  376.     case isWCopy:   return WCopy;    
  377. #if defined(BI_OLECHAR_WIDE)
  378.     case isBstr:
  379.     case isExtBstr: return Bstr;
  380. #else
  381.     case isBstr:
  382.     case isExtBstr: return CONST_CAST(TUString*,this)->ChangeToWCopy();
  383. #endif
  384.     case isConst:
  385.     case isCopy: 
  386.     case isString:  return CONST_CAST(TUString*,this)->ChangeToWCopy();
  387.   }
  388.   return 0; // suppress warning
  389. }
  390.  
  391. TUString::operator wchar_t*()
  392. {
  393.   return ChangeToWCopy();
  394. }
  395. #endif
  396.  
  397. //
  398. // 
  399. //
  400. int TUString::Length() const
  401. {
  402.   switch (Kind) {
  403.     case isNull:    return 0;
  404. #if defined(BI_HAS_WCHAR)
  405.     case isWConst:  return strlen(WConst);
  406.     case isWCopy:   return strlen(WCopy);
  407. #endif
  408.     case isBstr:
  409.     case isExtBstr: return ::SysStringLen(Bstr);
  410.     case isConst:   return strlen(Const);
  411.     case isCopy:    return strlen(Copy);
  412.     case isString:  return ((string*)&String)->length();
  413.   }
  414.   return 0; // suppress warning
  415. }
  416.  
  417. //
  418. // Revokes BSTR ownership from this UString
  419. //
  420. void TUString::RevokeBstr(BSTR s)
  421. {
  422.   if (Kind != isExtBstr || Bstr != s)
  423.     return;
  424.   if (RefCnt == 1) {
  425.     Kind = isNull;
  426.     delete this;
  427.     return;
  428.   }
  429.   Kind = isCopy;
  430. #if defined(BI_OLECHAR_WIDE)
  431.   WCopy = new wchar_t[strlen(s)+1];
  432.   strcpy(WCopy, s);
  433. #else
  434.   Copy = new char[strlen(s)+1];
  435.   strcpy(Copy, s);
  436. #endif
  437. }
  438.  
  439. //
  440. // Passes BSTR ownership to this UString
  441. //
  442. void TUString::ReleaseBstr(BSTR s)
  443. {
  444.   if (Kind == isExtBstr && Bstr == s) {
  445.     Kind = isBstr;
  446.     --*this;
  447.   }
  448.   else       // has been overwritten with converted type
  449.     ::SysFreeString(Bstr);
  450. }
  451.  
  452. //
  453. // Free any resources held by this UString. Union & Kind left in random state;
  454. // must be reinitialized before use.
  455. //
  456. void TUString::Free()
  457. {
  458.   switch (Kind) {
  459.     case isCopy:    delete [] Copy; break;
  460. #if defined(BI_HAS_WCHAR)
  461.     case isWCopy:   delete [] WCopy; break;
  462. #endif
  463.     case isBstr:    ::SysFreeString(Bstr); break;
  464.     case isString:  ((string*)&String)->string::~string();
  465.   }
  466.   Lang = 0;
  467. //Kind = isNull;  // for safety, not really needed
  468. }
  469.