OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
ustring.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
3//
4/// \file
5/// TString (& TUString) implementation (others functions are inline)
6//----------------------------------------------------------------------------
7#include <owl/pch.h>
8#include <owl/defs.h>
9#include <owl/wsyscls.h>
10#include <owl/string.h>
11#include <owl/private/memory.h>
12#include <string.h>
13
14namespace owl {
15
16TUString TUString::Null; // null TAutoStrings reference this object
17
18//
19// Take a wide char string & return an ANSI string in a new'd char[] buffer
20//
21char* TUString::ConvertWtoA(const wchar_t* src, size_t len)
22{
23 size_t size;
24 char* dst;
25#if defined WINELIB
26 //convert from UTF32 (wchar in linux are UTF32) to UTF16 (WCHAR)
27 size_t s = wcslen(src);
28 WCHAR *auxSrc = new WCHAR[s*2]; //maximum possible
29 int i, j;
30 for (i=0, j=0; i<s && src[i]; i++) {
31 if (src[i]<=0xFFFF)
32 auxSrc[j++] = src[i];
33 else { //convert into a surrogate pair
34 wchar_t w=src[i]-0x10000;
35 auxSrc[j++] = (w >> 10) + 0xD800;
36 auxSrc[j++] = (w & 0x3FF)+0xDC00;
37 }
38 }
39 auxSrc[j++] = 0 ;
40 size = WideCharToMultiByte(CP_ACP, 0, auxSrc, len, 0, 0, 0, 0);
41 dst = new char[size + (len != (size_t)-1)]; // room for null if fixed size
42 size = WideCharToMultiByte(CP_ACP, 0, auxSrc, len, dst, size, 0, 0);
43 delete auxSrc;
44#else
45 size = WideCharToMultiByte(CP_ACP, 0, src, static_cast<int>(len), 0, 0, 0, 0);
46 dst = new char[size + (len != (size_t)-1)]; // room for null if fixed size
47 size = WideCharToMultiByte(CP_ACP, 0, src, static_cast<int>(len), dst, static_cast<int>(size), 0, 0);
48#endif
49 if (len != (size_t)-1)
50 dst[size] = 0;
51 return dst;
52}
53
54//
55// Take an ANSI char string & return a wide string in a new'd wchar_t[] buffer
56//
57wchar_t* TUString::ConvertAtoW(const char* src, size_t len)
58{
59 size_t size = MultiByteToWideChar(CP_ACP, 0, src, static_cast<int>(len), 0, 0);
60 wchar_t* dst;
61#if defined WINELIB
62 WCHAR* auxDst = new WCHAR[size + (len != (size_t)-1)];
63 size = MultiByteToWideChar(CP_ACP, 0, src, len, auxDst, size);
64 if (len != (size_t)-1)
65 auxDst[size] = 0;
66
67 //Now convert from UTF16 to UTF32
68 dst = new wchar_t[size + (len != (size_t)-1)];
69 int i, j;
70 for (i=0, j=0; i<size && auxDst[i]; i++) {
71 if (auxDst[i]<0xD800 || auxDst[i]>0xDFFF)
72 dst[j++] = auxDst[i];
73 else { //it's a surrogate pair
74 dst[j++] = 0x10000 + (auxDst[i] - 0xD800) <<10 + (auxDst[i+1] - 0xDC00);
75 i++;
76 }
77 }
78 dst[j] = 0;
79 delete auxDst;
80
81#else
82 dst = new wchar_t[size + (len != (size_t)-1)];
83 size = MultiByteToWideChar(CP_ACP, 0, src, static_cast<int>(len), dst, static_cast<int>(size));
84 if (len != (size_t)-1)
85 dst[size] = 0;
86#endif
87 return dst;
88}
89
91{
92 size_t size = MultiByteToWideChar(CP_ACP, 0, src, -1, 0, 0);
93 wchar_t* pWide = (wchar_t*)alloca(sizeof(wchar_t)*(size+1));
94 size = MultiByteToWideChar(CP_ACP, 0, src, -1, pWide, static_cast<int>(size));
95 pWide[size] = 0;
96 return ::SysAllocString(pWide);
97}
98
99//------------------------------------------------------------------------
100//
101// Change UString to isCopy regardless of current type
102//
103char* TUString::ChangeToCopy()
104{
105 char* dst = 0;
106 const char * src = 0;
107 size_t len = 0;
108 switch (Kind) {
109 case isNull:
110 return 0;
111 case isConst:
112 src = Const;
113 len = strlen(Const);
114 break;
115 case isCopy:
116 return Copy;
117 case isWConst:
119 break;
120 case isWCopy:
122 break;
123 case isBstr:
124 case isExtBstr:
126 break;
127 case isString:
128#if defined(UNICODE)
129 dst = ConvertWtoA(GetOWLString().c_str(), GetOWLString().length());
130#else
131 src = GetOWLString().c_str();
132 len = GetOWLString().length();
133#endif
134 default: //JJH added empty default construct
135 break;
136 }
137 if (!dst)
138 {
139 dst = new char[len+1];
140 memcpy(dst, src, len+1);
141 }
142 Free();
143 Kind = isCopy;
144 Copy = dst;
145 return Copy;
146}
147
148//
149// Change UString to isWCopy regardless of current type
150//
151wchar_t* TUString::ChangeToWCopy()
152{
153 wchar_t* dst = 0;
154 const wchar_t* src = 0;
155 size_t len = 0;
156 switch (Kind) {
157 case isNull:
158 return 0;
159 case isConst:
161 break;
162 case isCopy:
164 break;
165 case isWConst:
166 src = WConst;
168 break;
169 case isWCopy:
170 return WCopy;
171 case isBstr:
172 case isExtBstr:
173 src = Bstr;
175 break;
176 case isString:
177#if defined(UNICODE)
178 src = GetOWLString().c_str();
179 len = GetOWLString().length();
180#else
181 dst = ConvertAtoW(GetOWLString().c_str(), GetOWLString().length());
182#endif
183 }
184 if (!dst) {
185 dst = new wchar_t[len+1];
186 memcpy(dst, src, (len+1) * sizeof(wchar_t));
187 }
188 Free();
189 Kind = isWCopy;
190 WCopy = dst;
191 return WCopy;
192}
193
195{
196 BSTR dst;
197 switch (Kind) {
198 case isNull:
199 return 0;
200 case isConst:
202 break;
203 case isCopy:
205 break;
206 case isWConst:
208 break;
209 case isWCopy:
211 break;
212 case isBstr:
213 case isExtBstr:
214 return Bstr;
215 case isString:
216#if defined(UNICODE)
217 dst = ::SysAllocString(GetOWLString().c_str());
218#else
219 dst = ConvertAtoBSTR(GetOWLString().c_str());
220#endif
221 break;
222 default:
223 CHECK(!"Unexpected Kind of TUString");
224 return 0;
225 }
226 Free();
227 Kind = isBstr;
228 Bstr = dst;
229 return Bstr;
230}
231
232//------------------------------------------------------------------------
233// inline ctors used by Create functions.
234// Note: these are never made public or exported from this unit
235//
236
237//
238inline TUString::TUString(const char & str)
239:
240 Lang(0), Kind(isConst), RefCnt(1), Const(&str)
241{
242}
243
244//
245inline TUString::TUString(char& str)
246:
247 Lang(0),Kind(isCopy), RefCnt(1)
248{
249 Copy = new char[strlen(&str)+1];
250 strcpy(Copy, &str);
251}
252
253
254//
255inline TUString::TUString(const wchar_t& str)
256:
257 Lang(0), Kind(isWConst), RefCnt(1), WConst(&str)
258{
259}
260
261//
262inline TUString::TUString(wchar_t& str)
263:
264 Lang(0), Kind(isWCopy), RefCnt(1)
265{
266 WCopy = new wchar_t[::wcslen(&str)+1];
267 ::wcscpy(WCopy, &str);
268}
269
270//
271inline TUString::TUString(BSTR str, bool loan, TLangId lang)
272:
273 Lang(lang),
274 Kind(loan ? isExtBstr : isBstr),
275 RefCnt(int16(loan ? 2 : 1)),
276 Bstr(str)
277{
278}
279
280//
281inline TUString::TUString(TSysStr& str, bool loan, TLangId lang)
282:
283 Lang(lang),
284 Kind(loan ? isExtBstr : isBstr),
285 RefCnt(int16(loan ? 2 : 1)),
286 Bstr(str.operator BSTR())
287{
288}
289
290//
291//inline void* operator new(size_t, TStringRef** p) {return p;}
292
293//
294inline TUString::TUString(const tstring& str)
295:
296 Lang(0), Kind(isString), RefCnt(1)
297{
298 AllocOWLString(str);
299}
300
301//------------------------------------------------------------------------
302// Static creation, or factory functions return pointers to new UStrings, or
303// pointers to the Null UString
304//
305
306//
307TUString* TUString::Create(const char * str)
308{
309 return str /*&& *str*/ ? new TUString(*str) : &++Null;
310}
311
312//
314{
315 return str /*&& *str*/ ? new TUString(*str) : &++Null;
316}
317
318//
319TUString* TUString::Create(const wchar_t* str)
320{
321 return str /*&& *str*/ ? new TUString(*str) : &++Null;
322}
323
324//
326{
327 return str /*&& *str*/ ? new TUString(*str) : &++Null;
328}
329
330//
332{
333 if (str && TOleAuto::SysStringLen(str))
334 return new TUString(str, loan, lang);
335 if (!loan)
337 return &++Null;
338}
339
340//
342{
343 return Create(str.operator BSTR(), loan, lang);
344}
345
346//
348{
349 return str.length() ? new TUString(str) : &++Null;
350}
351
352//------------------------------------------------------------------------
353//
354//
355
356//
358{
359 if (RefCnt == 1 && Kind != isNull && Kind != isExtBstr)
360 Free();
361 else
362 --*this;
363
364 CONST_CAST(TUString&,s).RefCnt++;
365 return &CONST_CAST(TUString&,s);
366}
367
368//
370{
371 if (s.length() && RefCnt == 1 && Kind != isNull && Kind != isExtBstr)
372 {
373 Free();
374 Kind = isString;
375 AllocOWLString(s);
376 return this;
377 }
378 else
379 {
380 --*this;
381 return Create(s);
382 }
383}
384
385//
387{
388 if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
389 Free();
390 Kind = isConst;
391 Const = s;
392 return this;
393 }
394 else {
395 --*this;
396 return Create(s);
397 }
398}
399
400//
402{
403 if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
404 Free();
405 Kind = isCopy;
406 Copy = new char[strlen(s)+1];
407 strcpy(Copy, s);
408 return this;
409 }
410 else {
411 --*this;
412 return Create(s);
413 }
414}
415
416//
417TUString* TUString::Assign(const wchar_t* s)
418{
419 if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
420 Free();
421 Kind = isWConst;
422 WConst = s;
423 return this;
424 }
425 else {
426 --*this;
427 return Create(s);
428 }
429}
430
431//
433{
434 if (s && *s && RefCnt == 1 && Kind != isNull && Kind != isExtBstr) {
435 Free();
436 Kind = isWCopy;
437 WCopy = new wchar_t[::wcslen(s)+1];
438 ::wcscpy(WCopy, s);
439 return this;
440 }
441 else {
442 --*this;
443 return Create(s);
444 }
445}
446
447//
449{
450 if (RefCnt==1 && Kind != isNull && Kind != isExtBstr) {
451 Free();
452 Kind = isBstr;
453 Bstr = str;
454 Lang = lang;
456 return this;
457 delete this;
458 return &++Null;
459 }
460 else {
461 --*this;
462 return Create(str, false, lang);
463 }
464}
465
466//------------------------------------------------------------------------
467
468//
469TUString::operator const char *() const
470{
471 switch (Kind) {
472 case isNull: return 0;
473 case isConst: return Const;
474 case isCopy: return Copy;
475#if defined(UNICODE)
476 case isString: return CONST_CAST(TUString*,this)->ChangeToCopy();
477#else
478 case isString: return GetOWLString().c_str();
479#endif
480 case isBstr:
481 case isExtBstr: return CONST_CAST(TUString*,this)->ChangeToCopy();
482 case isWConst:
483 case isWCopy: return CONST_CAST(TUString*,this)->ChangeToCopy();
484 default: break; //JJH added empty default construct
485 }
486 return 0; // suppress warning
487}
488
489//
490TUString::operator char*()
491{
492 return ChangeToCopy();
493}
494
495//
496TUString::operator const wchar_t*() const
497{
498 switch (Kind) {
499 case isNull: return 0;
500 case isWConst: return WConst;
501 case isWCopy: return WCopy;
502 case isBstr:
503 case isExtBstr: return Bstr;
504 case isConst:
505 case isCopy:
506#if defined(UNICODE)
507 return CONST_CAST(TUString*,this)->ChangeToWCopy();
508 case isString: return GetOWLString().c_str();
509#else
510 case isString: return CONST_CAST(TUString*,this)->ChangeToWCopy();
511#endif
512 }
513 return 0; // suppress warning
514}
515
516//
517TUString::operator wchar_t*()
518{
519 return ChangeToWCopy();
520}
521
522//------------------------------------------------------------------------
523
524//
525//
526//
528{
529 switch (Kind) {
530 case isNull: return 0;
531 case isWConst: return static_cast<int>(::wcslen(WConst));
532 case isWCopy: return static_cast<int>(::wcslen(WCopy));
533 case isBstr:
534 case isExtBstr: return static_cast<int>(TOleAuto::SysStringLen(Bstr));
535 case isConst: return static_cast<int>(strlen(Const));
536 case isCopy: return static_cast<int>(strlen(Copy));
537 case isString: return static_cast<int>(GetOWLString().length());
538 default: break; //JJH added empty default construct
539}
540 return 0; // suppress warning
541}
542
543//------------------------------------------------------------------------
544
545//
546// Revoke BSTR ownership from this UString, i.e. make this UString relinquish
547//
549{
550 if (Kind != isExtBstr || Bstr != s) // Don't have it anymore
551 return;
552 if (RefCnt == 1) { // We go away. Assume that our envelope knows about this!
553 Kind = isNull;
554 delete this;
555 return;
556 }
557 ChangeToWCopy(); // Make an appropriate copy of it
558}
559
560//
561// Pass BSTR ownership to this UString
562//
564{
565 if (Kind == isExtBstr && Bstr == s) {
566 Kind = isBstr;
567 --*this;
568 }
569 else // Has been overwritten with converted type, don't need anymore
571}
572
573//
574// Free any resources held by this UString. Union & Kind left in random state;
575// must be reinitialized before use.
576//
577void TUString::Free()
578{
579 switch (Kind) {
580 case isCopy: delete[] Copy; break;
581 case isWCopy: delete[] WCopy; break;
582 case isBstr: TOleAuto::SysFreeString(Bstr); break;
583 case isString: GetOWLString().~tstring(); break;
584 default: break; //JJH added empty default construct
585 }
586 Lang = 0;
587//Kind = isNull; // for safety, not really needed
588}
589
590} // OWL namespace
591/* ========================================================================== */
592
#define CHECK(condition)
Definition checks.h:239
static UINT SysStringLen(BSTR)
Definition module.cpp:1244
static HRESULT SysFreeString(BSTR)
Definition module.cpp:1233
System string (BSTR) encapsulation.
Definition string.h:33
Privately used by TString to manage string pointers This is a reference counted union of various stri...
Definition string.h:145
static BSTR ConvertAtoBSTR(const char *src)
Definition ustring.cpp:90
const wchar_t * WConst
Unicode version of Const (Win32)
Definition string.h:224
static char * ConvertWtoA(const wchar_t *src, size_t len=(size_t) -1)
Definition ustring.cpp:21
static TUString * Create(const char *str)
Definition ustring.cpp:307
TLangId Lang
Definition string.h:174
int Length() const
Return appropriate string length.
Definition ustring.cpp:527
TUString * Assign(const TUString &s)
Definition ustring.cpp:357
const char * Const
Passed-in string, NOT owned here, read-only.
Definition string.h:222
BSTR ConvertToBSTR()
Definition ustring.cpp:194
void ReleaseBstr(BSTR s)
Used to unhook if Created with loan==true.
Definition ustring.cpp:563
static wchar_t * ConvertAtoW(const char *src, size_t len=(size_t) -1)
Definition ustring.cpp:57
wchar_t * WCopy
Unicode version of Copy (Win32)
Definition string.h:225
BSTR Bstr
Copy of pointer, owned here.
Definition string.h:226
char * Copy
Local copy, must be deleted, read-write.
Definition string.h:223
void RevokeBstr(BSTR s)
Used to restore if Created with loan==true.
Definition ustring.cpp:548
size_t __stdcall wcslen(const wchar_t *str)
wchar_t *__stdcall wcscpy(wchar_t *dst, const wchar_t *src)
Reliable platform independent header for common memory and string functions.
#define alloca
Definition memory.h:34
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
owl::uint16 TLangId
Holds a language ID, a predefined number that represents a base language and dialect.
Definition lclstrng.h:26
signed short int16
Definition number.h:29
BSTR SysAllocString(const char *str)
Definition string.h:130
std::string tstring
Definition defs.h:79
General definitions used by all ObjectWindows programs.
#define CONST_CAST(targetType, object)
Definition defs.h:273
Definition of class TString, a flexible universal string envelope class.
Classes for window system structure and type encapsulation.