InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StringStorage.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: EricM
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //========================================================================================
23 
24 #ifndef __STRINGSTORAGE__
25 #define __STRINGSTORAGE__
26 
27 #include "BaseType.h"
28 #include "IDThreading.h"
29 
30 const int32 kStringStorageChunk = 32;
31 
32 // Given a requested length (newLength) & currentLength return a padded new size for the buffer.
33 // Performance optimization.
34 // Increase the size of the string by 50% Performance measurements have shown that in the case
35 // of large strings we pay a large penalty in the extra calls to memcpys if the size is increased
36 // by some small chunk size like 16 or 32. For very large strings (as in XML SaveBackwards) this change
37 // resulted in a 50% speed up. [jshankar Aug-5-2003]
38 // If currentLength is zero then default value of kStringChunk is used.
39 inline int32 CalcStringSizeW(int32 newLength, int32 currentLength)
40 {
41  ASSERT(newLength >= 0 && currentLength >= 0);
42  ASSERT(newLength < 128 * 1024 * 1024);
43  ASSERT(currentLength < 128 * 1024 * 1024);
44 
45  int32 myStringChunk = currentLength / 2;
46 
47  // Ensure minimum string chunk size
48  if (myStringChunk < kStringStorageChunk)
49  myStringChunk = kStringStorageChunk;
50 
51  ASSERT(myStringChunk > 0);
52  const int32 calcLength = myStringChunk * ((newLength + myStringChunk -1 ) / myStringChunk);
53  ASSERT(calcLength >= newLength);
54  return calcLength;
55 }
56 
57 
58 
59 int32 CheckTotalUnicodeSavvyStringReferences();
60 
61 
78 {
79 public:
80  // traits
81  typedef int32 size_type;
82 
83  enum {kDefaultLength = 16};
84 
98  static StringStorage *CreateStringStorage(int32 initialLength = kDefaultLength, StringStorage *sourceStr = nil);
99 
100  operator const UTF16TextChar *(void) const;
101  UTF16TextChar operator[](int pos) const;
102 
107  StringStorage * MakeSize(size_type requestedSize);
108 
111  size_type capacity() const;
112 
117  UTF16TextChar * GetBuffer();
121  const UTF16TextChar *ConstBuffer() const;
122 
129  StringStorage * Copy();
134  void Dispose();
135 
139  bool IsUnique() const;
140 
141 
142 #ifdef DEBUG
143 
146  void Validate();
147 
149  static int32 TotalAllocatedMemory();
150 
152  static int32 TotalReferences();
153 #endif
154 
155 
156 protected:
162  StringStorage(int32 initialLength, size_type adjustedLength) ;
163 
170  StringStorage(const StringStorage &srcStorage, size_type initialLength, size_type adjustedLength);
171 
172  int32 fMemorySize; // number of textchars allocated for the buffer
173  int32 fRequestedSize; // number of textchars required for the buffer
174  size_type fReferenceCount; // number of strings that use this buffer
175  UTF16TextChar fFirstCharOfBuffer[1]; // the rest continues and is allocated together in this block
176 
177 private:
178 #ifdef DEBUG
179  // In a multi-threaded environment these stats may not be updated accurately.
180  // Atomic add and subtracts of these stats are required in order to have accurate values.
181  // This would put a great overhead on the performance. Hence, we are not using atomic add and
182  // subtract expecting that these stats need not be accurate.
183  static int32 ts_TotalReferences;
184  static int32 ts_TotalAllocatedMemory;
185 #endif
186 };
187 
188 
189 inline StringStorage::operator const UTF16TextChar *(void) const
190 {
191  return ConstBuffer();
192 }
193 
194 inline UTF16TextChar *StringStorage::GetBuffer()
195 {
196  ASSERT(fReferenceCount == 1);
197  return fFirstCharOfBuffer;
198 }
199 
200 inline const UTF16TextChar *StringStorage::ConstBuffer() const
201 {
202  return fFirstCharOfBuffer;
203 }
204 
205 
206 inline UTF16TextChar StringStorage::operator [] (int pos) const
207 {
208  ASSERT(fRequestedSize > 0);
209  return ConstBuffer()[pos];
210 }
211 
212 
214 {
215  IDThreading::AtomicIncrement(fReferenceCount);
216 #ifdef DEBUG
217  ++ts_TotalReferences;
218 #endif
219  return this;
220 }
221 
222 
223 inline StringStorage::size_type StringStorage::capacity() const
224 {
225  return fMemorySize - 1;
226 }
227 
228 inline bool StringStorage::IsUnique() const
229 {
230  return (fReferenceCount == 1);
231 }
232 
233 #ifdef DEBUG
234 inline int32 StringStorage::TotalReferences()
235 {
236  return ts_TotalReferences;
237 }
238 
239 inline int32 StringStorage::TotalAllocatedMemory()
240 {
241  return ts_TotalAllocatedMemory;
242 }
243 #endif
244 
245 
246 #endif // __STRINGSTORAGE__
247 
248