OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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.