ReactOS 0.4.15-dev-7136-g77ab709
atlsimpstr.h
Go to the documentation of this file.
1#ifndef __ATLSIMPSTR_H__
2#define __ATLSIMPSTR_H__
3
4#pragma once
5
6#include <atlcore.h>
7#include <atlexcept.h>
8
9#ifdef __RATL__
10 #ifndef _In_count_
11 #define _In_count_(nLength)
12 #endif
13#endif
14
15namespace ATL
16{
17struct CStringData;
18
19// Pure virtual interface
21{
22public:
23
24 virtual ~IAtlStringMgr() {}
25
30 ) = 0;
31
32 virtual void Free(
34 ) = 0;
35
37 CStringData* Reallocate(
41 ) = 0;
42
43 virtual CStringData* GetNilString(void) = 0;
44 virtual IAtlStringMgr* Clone(void) = 0;
45};
46
47
49{
53 long nRefs;
54
55 void* data() noexcept
56 {
57 return (this + 1);
58 }
59
60 void AddRef() noexcept
61 {
62 ATLASSERT(nRefs > 0);
64 }
65
66 void Release() noexcept
67 {
68 ATLASSERT(nRefs != 0);
69
71 {
72 pStringMgr->Free(this);
73 }
74 }
75
76 bool IsLocked() const noexcept
77 {
78 return (nRefs < 0);
79 }
80
81 bool IsShared() const noexcept
82 {
83 return (nRefs > 1);
84 }
85};
86
88 public CStringData
89{
90public:
91 CNilStringData() noexcept
92 {
94 nRefs = 2;
95 nDataLength = 0;
96 nAllocLength = 0;
97 achNil[0] = 0;
98 achNil[1] = 0;
99 }
100
101 void SetManager(_In_ IAtlStringMgr* pMgr) noexcept
102 {
104 pStringMgr = pMgr;
105 }
106
107public:
108 wchar_t achNil[2];
109};
110
111
112template< typename BaseType = char >
114{
115public:
116 typedef char XCHAR;
117 typedef LPSTR PXSTR;
118 typedef LPCSTR PCXSTR;
119 typedef wchar_t YCHAR;
120 typedef LPWSTR PYSTR;
122};
123
124template<>
126{
127public:
128 typedef wchar_t XCHAR;
129 typedef LPWSTR PXSTR;
131 typedef char YCHAR;
132 typedef LPSTR PYSTR;
133 typedef LPCSTR PCYSTR;
134};
135
136template< typename BaseType, bool t_bMFCDLL = false>
138{
139public:
146
147private:
149
150public:
152 {
153 CStringData* pData = pStringMgr->GetNilString();
154 Attach(pData);
155 }
156
158 {
159 CStringData* pSrcData = strSrc.GetData();
160 CStringData* pNewData = CloneData(pSrcData);
161 Attach(pNewData);
162 }
163
165 _In_z_ PCXSTR pszSrc,
166 _Inout_ IAtlStringMgr* pStringMgr)
167 {
168 int nLength = StringLength(pszSrc);
169 CStringData* pData = pStringMgr->Allocate(nLength, sizeof(XCHAR));
170 if (pData == NULL)
172
173 Attach(pData);
176 }
177
179 _In_count_(nLength) const XCHAR* pchSrc,
180 _In_ int nLength,
181 _Inout_ IAtlStringMgr* pStringMgr)
182 {
183 if (pchSrc == NULL && nLength != 0)
185
186 CStringData* pData = pStringMgr->Allocate(nLength, sizeof(XCHAR));
187 if (pData == NULL)
188 {
190 }
191 Attach(pData);
194 }
195
197 {
199 pData->Release();
200 }
201
203 {
204 SetString(pszSrc);
205 return *this;
206 }
207
209 {
211 CStringData* pNewData = strSrc.GetData();
212
213 if (pNewData != pData)
214 {
215 if (!pData->IsLocked() && (pNewData->pStringMgr == pData->pStringMgr))
216 {
217 pNewData = CloneData(pNewData);
218 pData->Release();
219 Attach(pNewData);
220 }
221 else
222 {
223 SetString(strSrc.GetString(), strSrc.GetLength());
224 }
225 }
226
227 return *this;
228 }
229
231 {
232 Append(strSrc);
233 return *this;
234 }
235
237 {
238 Append(pszSrc);
239 return *this;
240 }
241
243 {
244 Append(&ch, 1);
245 return *this;
246 }
247
248 operator PCXSTR() const noexcept
249 {
250 return m_pszData;
251 }
252
253 void Empty() noexcept
254 {
255 CStringData* pOldData = GetData();
256 IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
257 if (pOldData->nDataLength == 0) return;
258
259 if (pOldData->IsLocked())
260 {
261 SetLength(0);
262 }
263 else
264 {
265 pOldData->Release();
266 CStringData* pNewData = pStringMgr->GetNilString();
267 Attach(pNewData);
268 }
269 }
270
271 void Append(
272 _In_count_(nLength) PCXSTR pszSrc,
273 _In_ int nLength)
274 {
275 UINT_PTR nOffset = pszSrc - GetString();
276
277 int nOldLength = GetLength();
278 if (nOldLength < 0)
279 nOldLength = 0;
280
281 ATLASSERT(nLength >= 0);
282
283#if 0 // FIXME: See comment for StringLengthN below.
284 nLength = StringLengthN(pszSrc, nLength);
285 if (!(INT_MAX - nLength >= nOldLength))
286 throw;
287#endif
288
289 int nNewLength = nOldLength + nLength;
290 PXSTR pszBuffer = GetBuffer(nNewLength);
291 if (nOffset <= (UINT_PTR)nOldLength)
292 {
293 pszSrc = pszBuffer + nOffset;
294 }
295 CopyChars(pszBuffer + nOldLength, nLength, pszSrc, nLength);
296 ReleaseBufferSetLength(nNewLength);
297 }
298
299 void Append(_In_z_ PCXSTR pszSrc)
300 {
301 Append(pszSrc, StringLength(pszSrc));
302 }
303
304 void Append(_In_ const CSimpleStringT& strSrc)
305 {
306 Append(strSrc.GetString(), strSrc.GetLength());
307 }
308
310 {
311 SetString(pszSrc, StringLength(pszSrc));
312 }
313
315 _In_ int nLength)
316 {
317 if (nLength == 0)
318 {
319 Empty();
320 }
321 else
322 {
323 UINT nOldLength = GetLength();
324 UINT_PTR nOffset = pszSrc - GetString();
325
326 PXSTR pszBuffer = GetBuffer(nLength);
327 if (nOffset <= nOldLength)
328 {
330 pszBuffer + nOffset, nLength);
331 }
332 else
333 {
334 CopyChars(pszBuffer, GetAllocLength(), pszSrc, nLength);
335 }
337 }
338 }
339
341 {
343 if (pData->IsShared())
344 {
345 // We should fork here
346 Fork(pData->nDataLength);
347 }
348
349 return m_pszData;
350 }
351
352 _Ret_notnull_ _Post_writable_size_(nMinBufferLength + 1) PXSTR GetBuffer(_In_ int nMinBufferLength)
353 {
354 return PrepareWrite(nMinBufferLength);
355 }
356
357 int GetAllocLength() const noexcept
358 {
359 return GetData()->nAllocLength;
360 }
361
362 int GetLength() const noexcept
363 {
364 return GetData()->nDataLength;
365 }
366
367 PXSTR GetString() noexcept
368 {
369 return m_pszData;
370 }
372 {
373 return m_pszData;
374 }
375
376 void ReleaseBufferSetLength(_In_ int nNewLength)
377 {
378 ATLASSERT(nNewLength >= 0);
379 SetLength(nNewLength);
380 }
381
382 void ReleaseBuffer(_In_ int nNewLength = -1)
383 {
384 if (nNewLength < 0)
385 nNewLength = StringLength(m_pszData);
386 ReleaseBufferSetLength(nNewLength);
387 }
388
389 bool IsEmpty() const noexcept
390 {
391 return (GetLength() == 0);
392 }
393
395 {
396 return (reinterpret_cast<CStringData*>(m_pszData) - 1);
397 }
398
400 {
401 IAtlStringMgr* pStringMgr = GetData()->pStringMgr;
402 return (pStringMgr ? pStringMgr->Clone() : NULL);
403 }
404
405public:
407 _In_ const CSimpleStringT& str1,
408 _In_ const CSimpleStringT& str2)
409 {
410 CSimpleStringT s(str1.GetManager());
411 Concatenate(s, str1, str1.GetLength(), str2, str2.GetLength());
412 return s;
413 }
414
416 _In_ const CSimpleStringT& str1,
417 _In_z_ PCXSTR psz2)
418 {
419 CSimpleStringT s(str1.GetManager());
420 Concatenate(s, str1, str1.GetLength(), psz2, StringLength(psz2));
421 return s;
422 }
423
425 _In_z_ PCXSTR psz1,
426 _In_ const CSimpleStringT& str2)
427 {
428 CSimpleStringT s(str2.GetManager());
429 Concatenate(s, psz1, StringLength(psz1), str2, str2.GetLength());
430 return s;
431 }
432
433 static void __cdecl CopyChars(
434 _Out_writes_to_(nDestLen, nChars) XCHAR* pchDest,
435 _In_ size_t nDestLen,
436 _In_reads_opt_(nChars) const XCHAR* pchSrc,
437 _In_ int nChars) noexcept
438 {
439 memcpy(pchDest, pchSrc, nChars * sizeof(XCHAR));
440 }
441
443 _Out_writes_to_(nDestLen, nDestLen) XCHAR* pchDest,
444 _In_ size_t nDestLen,
445 _In_reads_(nChars) const XCHAR* pchSrc,
446 _In_ int nChars) noexcept
447 {
448 memmove(pchDest, pchSrc, nChars * sizeof(XCHAR));
449 }
450
451 static int __cdecl StringLength(_In_opt_z_ const char* psz) noexcept
452 {
453 if (psz == NULL) return 0;
454 return (int)strlen(psz);
455 }
456
457 static int __cdecl StringLength(_In_opt_z_ const wchar_t* psz) noexcept
458 {
459 if (psz == NULL) return 0;
460 return (int)wcslen(psz);
461 }
462
463#if 0 // For whatever reason we do not link with strnlen / wcsnlen. Please investigate!
464 // strnlen / wcsnlen are available in MSVCRT starting Vista+.
465 static int __cdecl StringLengthN(
466 _In_opt_z_count_(sizeInXChar) const char* psz,
467 _In_ size_t sizeInXChar) noexcept
468 {
469 if (psz == NULL) return 0;
470 return (int)strnlen(psz, sizeInXChar);
471 }
472
473 static int __cdecl StringLengthN(
474 _In_opt_z_count_(sizeInXChar) const wchar_t* psz,
475 _In_ size_t sizeInXChar) noexcept
476 {
477 if (psz == NULL) return 0;
478 return (int)wcsnlen(psz, sizeInXChar);
479 }
480#endif
481
482protected:
483 static void __cdecl Concatenate(
484 _Inout_ CSimpleStringT& strResult,
485 _In_count_(nLength1) PCXSTR psz1,
486 _In_ int nLength1,
487 _In_count_(nLength2) PCXSTR psz2,
488 _In_ int nLength2)
489 {
490 int nNewLength = nLength1 + nLength2;
491 PXSTR pszBuffer = strResult.GetBuffer(nNewLength);
492 CopyChars(pszBuffer, nLength1, psz1, nLength1);
493 CopyChars(pszBuffer + nLength1, nLength2, psz2, nLength2);
494 strResult.ReleaseBufferSetLength(nNewLength);
495 }
496
497private:
499 {
500 m_pszData = static_cast<PXSTR>(pData->data());
501 }
502
504 {
505 CStringData* pOldData = GetData();
506 int nOldLength = pOldData->nDataLength;
507 CStringData* pNewData = pOldData->pStringMgr->Clone()->Allocate(nLength, sizeof(XCHAR));
508 if (pNewData == NULL)
509 {
511 }
512 int nCharsToCopy = ((nOldLength < nLength) ? nOldLength : nLength) + 1;
513 CopyChars(PXSTR(pNewData->data()), nCharsToCopy,
514 PCXSTR(pOldData->data()), nCharsToCopy);
515 pNewData->nDataLength = nOldLength;
516 pOldData->Release();
517 Attach(pNewData);
518 }
519
521 {
522 CStringData* pOldData = GetData();
523 int nShared = 1 - pOldData->nRefs;
524 int nTooShort = pOldData->nAllocLength - nLength;
525 if ((nShared | nTooShort) < 0)
526 {
528 }
529
530 return m_pszData;
531 }
533 {
534 CStringData* pOldData = GetData();
535 if (pOldData->nDataLength > nLength)
536 {
537 nLength = pOldData->nDataLength;
538 }
539 if (pOldData->IsShared())
540 {
541 Fork(nLength);
542 //ATLASSERT(FALSE);
543 }
544 else if (pOldData->nAllocLength < nLength)
545 {
546 int nNewLength = pOldData->nAllocLength;
547 if (nNewLength > 1024 * 1024 * 1024)
548 {
549 nNewLength += 1024 * 1024;
550 }
551 else
552 {
553 nNewLength = nNewLength + nNewLength / 2;
554 }
555 if (nNewLength < nLength)
556 {
557 nNewLength = nLength;
558 }
559 Reallocate(nNewLength);
560 }
561 }
562
564 {
565 CStringData* pOldData = GetData();
566 ATLASSERT(pOldData->nAllocLength < nLength);
567 IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
568 if (pOldData->nAllocLength >= nLength || nLength <= 0)
569 {
570 return;
571 }
572 CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR));
573 if (pNewData == NULL)
574 {
576 }
577
578 Attach(pNewData);
579 }
580
582 {
583 ATLASSERT(nLength >= 0);
584 ATLASSERT(nLength <= GetData()->nAllocLength);
585
586 if (nLength < 0 || nLength > GetData()->nAllocLength)
587 {
589 }
590
592 m_pszData[nLength] = 0;
593 }
594
596 {
597 CStringData* pNewData = NULL;
598
599 IAtlStringMgr* pNewStringMgr = pData->pStringMgr->Clone();
600 if (!pData->IsLocked() && (pNewStringMgr == pData->pStringMgr))
601 {
602 pNewData = pData;
603 pNewData->AddRef();
604 }
605 else
606 {
607 pNewData = pNewStringMgr->Allocate(pData->nDataLength, sizeof(XCHAR));
608 if (pNewData == NULL)
609 {
611 }
612
613 pNewData->nDataLength = pData->nDataLength;
614 CopyChars(PXSTR(pNewData->data()), pData->nDataLength + 1,
615 PCXSTR(pData->data()), pData->nDataLength + 1);
616 }
617
618 return pNewData;
619 }
620
621protected:
623 {
625 }
626
628 {
630 }
631};
632
633#ifdef UNICODE
634typedef CSimpleStringT<WCHAR> CSimpleString;
635#else
637#endif
638}
639
640#endif
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define __cdecl
Definition: accygwin.h:79
#define AtlThrow(x)
Definition: atldef.h:20
CNilStringData() noexcept
Definition: atlsimpstr.h:91
void SetManager(_In_ IAtlStringMgr *pMgr) noexcept
Definition: atlsimpstr.h:101
wchar_t achNil[2]
Definition: atlsimpstr.h:108
void Append(_In_count_(nLength) PCXSTR pszSrc, _In_ int nLength)
Definition: atlsimpstr.h:271
CSimpleStringT & operator=(_In_ const CSimpleStringT &strSrc)
Definition: atlsimpstr.h:208
__declspec(noinline) void Fork(_In_ int nLength)
Definition: atlsimpstr.h:503
CSimpleStringT & operator+=(_In_z_ PCXSTR pszSrc)
Definition: atlsimpstr.h:236
CStringData * GetData() const noexcept
Definition: atlsimpstr.h:394
static void __cdecl Concatenate(_Inout_ CSimpleStringT &strResult, _In_count_(nLength1) PCXSTR psz1, _In_ int nLength1, _In_count_(nLength2) PCXSTR psz2, _In_ int nLength2)
Definition: atlsimpstr.h:483
friend CSimpleStringT operator+(_In_ const CSimpleStringT &str1, _In_z_ PCXSTR psz2)
Definition: atlsimpstr.h:415
static CStringData *__cdecl CloneData(_Inout_ CStringData *pData)
Definition: atlsimpstr.h:595
static int __cdecl StringLength(_In_opt_z_ const wchar_t *psz) noexcept
Definition: atlsimpstr.h:457
void Append(_In_ const CSimpleStringT &strSrc)
Definition: atlsimpstr.h:304
CSimpleStringT & operator=(_In_opt_z_ PCXSTR pszSrc)
Definition: atlsimpstr.h:202
void Reallocate(_In_ int nLength)
Definition: atlsimpstr.h:563
CSimpleStringT(_In_z_ PCXSTR pszSrc, _Inout_ IAtlStringMgr *pStringMgr)
Definition: atlsimpstr.h:164
CSimpleStringT & operator+=(XCHAR ch)
Definition: atlsimpstr.h:242
void SetString(_In_reads_opt_(nLength) PCXSTR pszSrc, _In_ int nLength)
Definition: atlsimpstr.h:314
CSimpleStringT(_In_count_(nLength) const XCHAR *pchSrc, _In_ int nLength, _Inout_ IAtlStringMgr *pStringMgr)
Definition: atlsimpstr.h:178
static int __cdecl StringLength(_In_opt_z_ const char *psz) noexcept
Definition: atlsimpstr.h:451
void Attach(_Inout_ CStringData *pData) noexcept
Definition: atlsimpstr.h:498
ChTraitsBase< BaseType >::PCXSTR PCXSTR
Definition: atlsimpstr.h:142
friend CSimpleStringT operator+(_In_ const CSimpleStringT &str1, _In_ const CSimpleStringT &str2)
Definition: atlsimpstr.h:406
~CSimpleStringT() noexcept
Definition: atlsimpstr.h:196
ChTraitsBase< BaseType >::PCYSTR PCYSTR
Definition: atlsimpstr.h:145
static void __cdecl CopyCharsOverlapped(_Out_writes_to_(nDestLen, nDestLen) XCHAR *pchDest, _In_ size_t nDestLen, _In_reads_(nChars) const XCHAR *pchSrc, _In_ int nChars) noexcept
Definition: atlsimpstr.h:442
static void __cdecl CopyChars(_Out_writes_to_(nDestLen, nChars) XCHAR *pchDest, _In_ size_t nDestLen, _In_reads_opt_(nChars) const XCHAR *pchSrc, _In_ int nChars) noexcept
Definition: atlsimpstr.h:433
PCXSTR GetString() const noexcept
Definition: atlsimpstr.h:371
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:389
_Ret_notnull_ _Post_writable_size_(nMinBufferLength+1) PXSTR GetBuffer(_In_ int nMinBufferLength)
Definition: atlsimpstr.h:352
ChTraitsBase< BaseType >::YCHAR YCHAR
Definition: atlsimpstr.h:143
ChTraitsBase< BaseType >::PXSTR PXSTR
Definition: atlsimpstr.h:141
void ReleaseBufferSetLength(_In_ int nNewLength)
Definition: atlsimpstr.h:376
PXSTR PrepareWrite(_In_ int nLength)
Definition: atlsimpstr.h:520
IAtlStringMgr * GetManager() const noexcept
Definition: atlsimpstr.h:399
static void ThrowInvalidArgException()
Definition: atlsimpstr.h:627
int GetAllocLength() const noexcept
Definition: atlsimpstr.h:357
CSimpleStringT(_In_ const CSimpleStringT &strSrc)
Definition: atlsimpstr.h:157
CSimpleStringT(_Inout_ IAtlStringMgr *pStringMgr)
Definition: atlsimpstr.h:151
CSimpleStringT & operator+=(_In_ const CSimpleStringT &strSrc)
Definition: atlsimpstr.h:230
void PrepareWrite2(_In_ int nLength)
Definition: atlsimpstr.h:532
ChTraitsBase< BaseType >::PYSTR PYSTR
Definition: atlsimpstr.h:144
void SetString(_In_opt_z_ PCXSTR pszSrc)
Definition: atlsimpstr.h:309
void Append(_In_z_ PCXSTR pszSrc)
Definition: atlsimpstr.h:299
void ReleaseBuffer(_In_ int nNewLength=-1)
Definition: atlsimpstr.h:382
void SetLength(_In_ int nLength)
Definition: atlsimpstr.h:581
friend CSimpleStringT operator+(_In_z_ PCXSTR psz1, _In_ const CSimpleStringT &str2)
Definition: atlsimpstr.h:424
PXSTR GetString() noexcept
Definition: atlsimpstr.h:367
static void ThrowMemoryException()
Definition: atlsimpstr.h:622
int GetLength() const noexcept
Definition: atlsimpstr.h:362
void Empty() noexcept
Definition: atlsimpstr.h:253
ChTraitsBase< BaseType >::XCHAR XCHAR
Definition: atlsimpstr.h:140
virtual void Free(_Inout_ CStringData *pData)=0
virtual _Ret_maybenull_ _In_ int nCharSize
Definition: atlsimpstr.h:30
virtual CStringData * GetNilString(void)=0
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData)+nAllocLength *nCharSize) CStringData *Reallocate(_Inout_ CStringData *pData
virtual _Ret_maybenull_ _Post_writable_byte_size_(sizeof(CStringData)+nAllocLength *nCharSize) CStringData *Allocate(_In_ int nAllocLength
virtual IAtlStringMgr * Clone(void)=0
virtual _Ret_maybenull_ _In_ int nAllocLength
Definition: atlsimpstr.h:39
virtual ~IAtlStringMgr()
Definition: atlsimpstr.h:24
unsigned short wchar_t
Definition: crtdefs.h:345
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define noinline
Definition: types.h:64
GLdouble s
Definition: gl.h:2039
#define INT_MAX
Definition: limits.h:40
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define _Inout_
Definition: ms_sal.h:378
#define _Ret_maybenull_
Definition: ms_sal.h:529
#define _In_count_(size)
Definition: ms_sal.h:810
#define _In_z_
Definition: ms_sal.h:313
#define _In_opt_z_count_(size)
Definition: ms_sal.h:826
#define _In_opt_z_
Definition: ms_sal.h:314
#define _In_reads_opt_(size)
Definition: ms_sal.h:320
#define _Ret_notnull_
Definition: ms_sal.h:528
#define _In_
Definition: ms_sal.h:308
#define _Out_writes_to_(size, count)
Definition: ms_sal.h:355
#define _In_reads_(size)
Definition: ms_sal.h:319
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
Definition: rosdlgs.h:6
CSimpleStringT< CHAR > CSimpleString
Definition: atlsimpstr.h:636
unsigned int UINT
Definition: ndis.h:50
bool IsLocked() const noexcept
Definition: atlsimpstr.h:76
void * data() noexcept
Definition: atlsimpstr.h:55
bool IsShared() const noexcept
Definition: atlsimpstr.h:81
void AddRef() noexcept
Definition: atlsimpstr.h:60
IAtlStringMgr * pStringMgr
Definition: atlsimpstr.h:50
void Release() noexcept
Definition: atlsimpstr.h:66
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
_In_ DWORD nLength
Definition: wincon.h:473
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:814
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define const
Definition: zconf.h:233