버전

menu_open
Wwise SDK 2024.1.0
AkString.h
이 파일의 문서화 페이지로 가기
1 /*******************************************************************************
2 The content of this file includes portions of the AUDIOKINETIC Wwise Technology
3 released in source code form as part of the SDK installer package.
4 
5 Commercial License Usage
6 
7 Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
8 may use this file in accordance with the end user license agreement provided
9 with the software or, alternatively, in accordance with the terms contained in a
10 written agreement between you and Audiokinetic Inc.
11 
12 Apache License Usage
13 
14 Alternatively, this file may be used under the Apache License, Version 2.0 (the
15 "Apache License"); you may not use this file except in compliance with the
16 Apache License. You may obtain a copy of the Apache License at
17 http://www.apache.org/licenses/LICENSE-2.0.
18 
19 Unless required by applicable law or agreed to in writing, software distributed
20 under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
21 OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
22 the specific language governing permissions and limitations under the License.
23 
24  Copyright (c) 2024 Audiokinetic Inc.
25 *******************************************************************************/
26 #pragma once
27 
31 
32 template<typename TAlloc, typename T_CHAR>
33 class AkStringData : public TAlloc
34 {
35 public:
36  AkStringData() : pStr(NULL), bOwner(false) {}
37  AkStringData(const T_CHAR* in_pStr) : pStr(in_pStr), bOwner(false) {}
39 
40  void Term()
41  {
42  if (pStr && bOwner)
43  {
44  TAlloc::Free((void*)pStr);
45  bOwner = false;
46  }
47  pStr = nullptr;
48  }
49 
51  {
52  if (!bOwner)
53  pStr = nullptr;
54  }
55 
56 protected:
57  const T_CHAR* pStr;
58  bool bOwner;
59 };
60 
61 template<typename TAlloc, typename T_CHAR>
62 class AkStringImpl : public AkStringData<TAlloc, T_CHAR>
63 {};
64 
65 template<typename TAlloc, typename T_CHAR>
66 class AkString: public AkStringImpl<TAlloc, T_CHAR>
67 {
68 private:
71 
72 public:
73  AkString() : AkStringImpl<TAlloc, T_CHAR>() {}
74 
75  template<typename T_CHAR2>
76  AkString(const T_CHAR2* in_pStr) { tImpl::Set(in_pStr); }
77 
78  AkString(const AkString<TAlloc, T_CHAR>& in_other) { tImpl::Set(in_other.Get()); TAlloc::operator=(in_other); }
79 
80  template<typename TAlloc2, typename T_CHAR2>
81  AkString(const AkString<TAlloc2, T_CHAR2>& in_other) { tImpl::Set(in_other.Get()); TAlloc::operator=(in_other); } // if this does not compile it means that both allocation policies are not compatible.
82 
83  // The default assignment behavior is to not create a local copy, unless it is necessary (due to incompatible string types).
84  // Call AllocCopy() if you want to ensure there is a local copy owned by this AkString.
86  {
87  if (tData::pStr && !tData::bOwner)
88  {
89  const T_CHAR* pRefStr = tData::pStr;
90  AkUInt32 uLen = tImpl::Length();
91  if (uLen > 0)
92  {
93  tData::pStr = (T_CHAR*)TAlloc::Alloc((uLen + 1) * sizeof(T_CHAR));
94  if (tData::pStr == NULL)
95  return AK_InsufficientMemory;
96 
97  AKPLATFORM::AkMemCpy((void*)tData::pStr, (void*)pRefStr, ((uLen + 1) * sizeof(T_CHAR)));
98  tData::bOwner = true;
99  }
100  else
101  {
102  tData::pStr = NULL;
103  }
104  }
105  return AK_Success;
106  }
107 
108  // Transfer memory ownership from in_from to this AkString.
110  {
111  tData::Term();
112 
113  TAlloc::TransferMem((void*&) tData::pStr, in_from, (void*)in_from.tData::pStr);
114  in_from.tData::pStr = nullptr;
115 
116  tData::bOwner = in_from.tData::bOwner;
117  in_from.tData::bOwner = false;
118  }
119 
120  const T_CHAR* Get() const
121  {
122  return tData::pStr;
123  }
124 
126  {
127  tImpl::Set(in_rhs.Get());
128  TAlloc::operator=(in_rhs);
129  return *this;
130  }
131 
132  template<typename TAlloc2, typename T_CHAR2>
134  {
135  tImpl::Set(in_rhs.Get());
136  TAlloc::operator=(in_rhs); // if this does not compile it means that both allocation policies are not compatible.
137  return *this;
138  }
139 
140  template<typename T_CHAR2>
141  AkString& operator=(const T_CHAR2* in_pStr)
142  {
143  tImpl::Set(in_pStr);
144  return *this;
145  }
146 };
147 
148 #ifdef AK_SUPPORT_WCHAR
149 template<typename TAlloc>
150 class AkStringImpl <TAlloc, wchar_t> : public AkStringData<TAlloc, wchar_t>
151 {
152 private:
153  typedef AkStringData<TAlloc, wchar_t> tData;
154 
155 public:
156  AkStringImpl() : AkStringData<TAlloc, wchar_t>() {}
157 
158 protected:
159  AKRESULT Set(const char* in_pStr)
160  {
161  tData::Term();
162 
163  if (in_pStr != NULL)
164  {
165  size_t uLen = strlen(in_pStr);
166  if (uLen > 0)
167  {
168  tData::pStr = (wchar_t*)TAlloc::Alloc((uLen + 1) * sizeof(wchar_t));
169  if (tData::pStr == NULL)
170  return AK_InsufficientMemory;
171 
172  AKPLATFORM::AkCharToWideChar(in_pStr, (AkUInt32)(uLen + 1), const_cast<wchar_t*>(tData::pStr));
173  tData::bOwner = true;
174  }
175  else
176  {
177  tData::pStr = NULL;
178  }
179  }
180 
181  return AK_Success;
182  }
183 
184  AKRESULT Set(const wchar_t* in_pStr)
185  {
186  tData::Term();
187  tData::pStr = in_pStr;
188  return AK_Success;
189  }
190 
191 public:
192  AkUInt32 Length() const
193  {
194  if (tData::pStr == nullptr)
195  return 0;
196 
197  return (AkUInt32)wcslen(tData::pStr);
198  }
199 };
200 #endif
201 
202 template<typename TAlloc>
203 class AkStringImpl <TAlloc, char> : public AkStringData<TAlloc, char>
204 {
205 private:
207 
208 public:
209  AkStringImpl() : AkStringData<TAlloc, char>() {}
210 
211 protected:
212  AKRESULT Set(const wchar_t* in_pStr)
213  {
214  tData::Term();
215 
216  if (in_pStr != NULL)
217  {
218  size_t uLen = wcslen(in_pStr);
219  if (uLen > 0)
220  {
221  tData::pStr = (char*)TAlloc::Alloc((uLen + 1) * sizeof(char));
222  if (tData::pStr == NULL)
223  return AK_InsufficientMemory;
224 
225  AKPLATFORM::AkWideCharToChar(in_pStr, (AkUInt32)(uLen + 1), const_cast<char*>(tData::pStr));
226  tData::bOwner = true;
227  }
228  else
229  {
230  tData::pStr = NULL;
231  }
232  }
233 
234  return AK_Success;
235  }
236 
237  AKRESULT Set(const char* in_pStr)
238  {
239  tData::Term();
240  tData::pStr = in_pStr;
241  return AK_Success;
242  }
243 
244 public:
245  AkUInt32 Length() const
246  {
247  if (tData::pStr == nullptr)
248  return 0;
249 
250  return (AkUInt32)strlen(tData::pStr);
251  }
252 };
253 
254 template<typename TAlloc, typename T_CHAR>
256 {
257  AkUInt32 uLen = in_str.Length();
258  if (uLen > 0)
259  {
260  AK::FNVHash32 hash;
261  return hash.Compute(in_str.Get(), uLen * sizeof(T_CHAR));
262  }
263  return 0;
264 }
265 
266 //
267 // AkDbString - A string reference class that stores a hash to a string in a database. If an identical string is found, the reference count in the database is incremented,
268 // so that we do not store duplicate strings. Database can be made multi thread safe by passing in CAkLock for tLock, or AkNonThreaded if concurrent access is not needed.
269 //
270 template<typename TAlloc, typename T_CHAR>
271 class AkDbString : public TAlloc
272 {
273 public:
276 
277  struct Entry
278  {
279  Entry() : refCount(0) {}
280 
283  };
284 
286 
287  struct Instance : public TAlloc
288  {
290  };
291 
292 public:
293 
294  // Must be called to initialize the database.
295  static AKRESULT InitDB()
296  {
297  if (pInstance == NULL)
298  {
299  pInstance = (Instance*)pInstance->TAlloc::Alloc(sizeof(Instance));
300 
301  if (pInstance == nullptr)
302  return AK_Fail;
303 
304  AkPlacementNew(pInstance) Instance();
305 
306  return AK_Success;
307  }
308  else
309  return AK_Fail;
310  }
311 
312  // Term the DB.
313  static void TermDB()
314  {
315  if (pInstance != NULL)
316  {
317  pInstance->~Instance();
318  pInstance->TAlloc::Free(pInstance);
319  pInstance = NULL;
320  }
321  }
322 
323  static const T_CHAR* GetFromHash(AkUInt32 in_uHash)
324  {
325  if (in_uHash != 0)
326  {
327  Entry* pEntry = pInstance->table.Exists(in_uHash);
328 
329  if(pEntry)
330  return pEntry->str.Get();
331  }
332  return NULL;
333  }
334 
335 private:
336 
337  static Instance* pInstance;
338 
339 public:
341  {}
342 
343  AkDbString(const tThis& in_fromDbStr) : m_uHash(0) { Aquire(in_fromDbStr.m_uHash); }
344 
345  // Construct from AkString
346  template<typename TAlloc2, typename T_CHAR2>
347  AkDbString(const AkString<TAlloc2, T_CHAR2>& in_fromStr) : m_uHash(0) { Aquire(in_fromStr); }
348 
349  tThis& operator=(const tThis& in_rhs)
350  {
351  Aquire(in_rhs.m_uHash);
352  return *this;
353  }
354 
355  // Assign from AkString
356  template<typename TAlloc2, typename T_CHAR2>
358  {
359  Aquire(in_rhs);
360  return *this;
361  }
362 
363  // Assign from char string
364  template<typename T_CHAR2>
365  tThis& operator=(const T_CHAR2* in_rhs)
366  {
367  const AkString<TAlloc, T_CHAR2>& convert = in_rhs;
368  Aquire(convert);
369  return *this;
370  }
371 
373  {
374  Release();
375  }
376 
377  const T_CHAR* Get() const
378  {
379  if (pInstance && m_uHash != 0)
380  {
381  Entry* pEntry = pInstance->table.Exists(m_uHash);
382  AKASSERT(pEntry != NULL);
383  return pEntry->str.Get();
384  }
385  return NULL;
386  }
387 
389  {
390  if (pInstance && m_uHash != 0)
391  {
392  Entry* pEntry = pInstance->table.Exists(m_uHash);
393  AKASSERT(pEntry != NULL);
394  return pEntry->str;
395  }
396 
397  return tString();
398  }
399 
400  void Reset()
401  {
402  Release();
403 
404  m_uHash = 0;
405  }
406 
407  AkUInt32 GetHash() const { return m_uHash; }
408 
409 protected:
410 
411  template<typename TAlloc2, typename T_CHAR2>
413  {
414  AKRESULT res = AK_Success;
415 
416  Release();
417 
418  if (pInstance && in_str.Get() != NULL)
419  {
420  m_uHash = AkHash(in_str);
421 
422  Entry* pEntry = pInstance->table.Set(m_uHash);
423  if (pEntry != NULL)
424  {
425  pEntry->refCount++;
426 
427  if (pEntry->str.Get() == NULL)
428  {
429  pEntry->str = in_str;
430  pEntry->str.AllocCopy();
431 
432  if (pEntry->str.Get() == NULL) // Allocation failure
433  {
434  pInstance->table.Unset(m_uHash);
435  m_uHash = 0;
436  res = AK_Fail;
437  }
438  }
439  }
440  else
441  {
442  m_uHash = 0;
443  res = AK_Fail;
444  }
445  }
446  else if (!pInstance)
447  {
448  res = AK_Fail;
449  }
450 
451  return res;
452  }
453 
454  // in_uHash must have come from another AkDbString, and therefore already exist in the DB.
456  {
457  AKRESULT res = AK_Success;
458 
459  Release();
460 
461  if (pInstance && in_uHash != 0)
462  {
463  m_uHash = in_uHash;
464  Entry* pEntry = pInstance->table.Exists(m_uHash);
465  AKASSERT(pEntry != NULL);
466 
467  pEntry->refCount++;
468  AKASSERT(pEntry->str.Get() != NULL);
469  }
470  else if (!pInstance)
471  {
472  res = AK_Fail;
473  }
474 
475  return res;
476  }
477 
478  void Release()
479  {
480  if (m_uHash != 0)
481  {
482 
483  if (pInstance)
484  {
485  tStringTable& table = pInstance->table;
486  typename tStringTable::IteratorEx it = table.FindEx(m_uHash);
487  AKASSERT(it != table.End());//<- Check that DbString was properly constructed.
488  Entry& entry = (*it).item;
489  AKASSERT(entry.refCount > 0);
490 
491  entry.refCount--;
492  if (entry.refCount == 0)
493  {
494  table.Erase(it);
495  }
496  }
497 
498  m_uHash = 0;
499  }
500  }
501 
503 
504 };
505 
506 /// A AkDbWeakString always references a DbString. If the DbString content has been released then the AkDbWeakString will return a null value.
507 /// A AkDbWeakString does not prevent the DbString content to be released.
508 ///
509 template<typename TAlloc, typename T_CHAR>
511 {
512 public:
514 
515 public:
517  : m_uHash(0)
518  {}
519 
521  : m_uHash(in_rhs.m_uHash)
522  {}
523 
524  AkDbWeakString(const _String& in_dbString)
525  {
526  m_uHash = in_dbString.GetHash();
527  }
528 
529  AkDbWeakString& operator=(const _String& in_dbString)
530  {
531  m_uHash = in_dbString.GetHash();
532 
533  return *this;
534  }
535 
537  {
538  m_uHash = in_rhs.m_uHash;
539 
540  return *this;
541  }
542 
543  /// Returns the string content or null if the content does not exist anymore
544  ///
545  const T_CHAR* Get() const
546  {
547  return _String::GetFromHash(m_uHash);
548  }
549 
550 private:
551  AkUInt32 m_uHash;
552 };
553 
554 template<typename TAlloc, typename T_CHAR>
tStringTable table
Definition: AkString.h:289
~AkStringData()
Definition: AkString.h:38
Definition: AkString.h:278
tThis & operator=(const AkString< TAlloc2, T_CHAR2 > &in_rhs)
Definition: AkString.h:357
@ AK_Fail
The operation failed.
Definition: AkTypes.h:137
AkString & operator=(const AkString< TAlloc, T_CHAR > &in_rhs)
Definition: AkString.h:125
Iterator End()
Definition: AkHashList.h:279
AKRESULT Set(const char *in_pStr)
Definition: AkString.h:237
static AKRESULT InitDB()
Definition: AkString.h:295
void Reset()
Definition: AkString.h:400
void Transfer(AkString< TAlloc, T_CHAR > &in_from)
Definition: AkString.h:109
AkStringData(const T_CHAR *in_pStr)
Definition: AkString.h:37
const T_CHAR * Get() const
Definition: AkString.h:377
#define AkPlacementNew(_memory)
AkString< TAlloc, T_CHAR > tString
Definition: AkString.h:275
AKSOUNDENGINE_API void Free(AkMemPoolId in_poolId, void *in_pMemAddress)
AkDbWeakString & operator=(const AkDbWeakString &in_rhs)
Definition: AkString.h:536
AkUInt32 m_uHash
Definition: AkString.h:502
void Release()
Definition: AkString.h:478
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
AkString(const T_CHAR2 *in_pStr)
Definition: AkString.h:76
static void TermDB()
Definition: AkString.h:313
AkUInt32 GetHash() const
Definition: AkString.h:407
const T_CHAR * Get() const
Definition: AkString.h:545
T_ITEM * Exists(T_KEY in_Key)
Definition: AkHashList.h:404
AkString & operator=(const T_CHAR2 *in_pStr)
Definition: AkString.h:141
IteratorEx Erase(const IteratorEx &in_rIter)
Definition: AkHashList.h:494
AkDbWeakString & operator=(const _String &in_dbString)
Definition: AkString.h:529
#define NULL
Definition: AkTypes.h:46
@ AK_Success
The operation was successful.
Definition: AkTypes.h:136
int32_t AkInt32
Signed 32-bit integer
AkUInt32 Length() const
Definition: AkString.h:245
AKSOUNDENGINE_API void Term()
AkStringData()
Definition: AkString.h:36
AkInt32 refCount
Definition: AkString.h:282
static AkForceInline AkUInt32 AkHash(const AkString< TAlloc, T_CHAR > &in_str)
Definition: AkString.h:255
~AkDbString()
Definition: AkString.h:372
tThis & operator=(const T_CHAR2 *in_rhs)
Definition: AkString.h:365
AkDbWeakString(const AkDbWeakString &in_rhs)
Definition: AkString.h:520
AkDbString< TAlloc, T_CHAR > tThis
Definition: AkString.h:274
#define AKASSERT(Condition)
Definition: AkAssert.h:67
AkForceInline void AkMemCpy(void *pDest, const void *pSrc, AkUInt32 uSize)
Platform Independent Helper for memcpy/memmove/memset
AkDbString()
Definition: AkString.h:340
Entry()
Definition: AkString.h:279
const T_CHAR * Get() const
Definition: AkString.h:120
tString str
Definition: AkString.h:281
AkString(const AkString< TAlloc, T_CHAR > &in_other)
Definition: AkString.h:78
void ClearReference()
Definition: AkString.h:50
tString GetString() const
Definition: AkString.h:388
static const T_CHAR * GetFromHash(AkUInt32 in_uHash)
Definition: AkString.h:323
AkDbWeakString(const _String &in_dbString)
Definition: AkString.h:524
AkDbString(const AkString< TAlloc2, T_CHAR2 > &in_fromStr)
Definition: AkString.h:347
AKRESULT Set(const wchar_t *in_pStr)
Definition: AkString.h:212
IteratorEx FindEx(T_KEY in_Key)
Definition: AkHashList.h:307
AkString & operator=(const AkString< TAlloc2, T_CHAR2 > &in_rhs)
Definition: AkString.h:133
AkForceInline AkInt32 AkCharToWideChar(const char *in_pszAnsiString, AkUInt32 in_uiOutBufferSize, void *io_pvUnicodeStringBuffer)
String conversion helper
AKRESULT AllocCopy()
Definition: AkString.h:85
AkDbString< TAlloc, T_CHAR > _String
Definition: AkString.h:513
uint32_t AkUInt32
Unsigned 32-bit integer
tThis & operator=(const tThis &in_rhs)
Definition: AkString.h:349
HashParams::HashType Compute(const void *in_pData, typename HashParams::SizeType in_dataSize)
Definition: AkFNVHash.h:105
@ AK_InsufficientMemory
Memory error.
Definition: AkTypes.h:164
AkForceInline AkInt32 AkWideCharToChar(const wchar_t *in_pszUnicodeString, AkUInt32 in_uiOutBufferSize, char *io_pszAnsiString)
String conversion helper
bool bOwner
Definition: AkString.h:58
AkHashList< AkUInt32, Entry, TAlloc > tStringTable
Definition: AkString.h:285
AKRESULT Aquire(const AkString< TAlloc2, T_CHAR2 > &in_str)
Definition: AkString.h:412
void Term()
Definition: AkString.h:40
#define AkForceInline
Definition: AkTypes.h:63
AkDbString(const tThis &in_fromDbStr)
Definition: AkString.h:343
AkString()
Definition: AkString.h:73
AkString(const AkString< TAlloc2, T_CHAR2 > &in_other)
Definition: AkString.h:81
const T_CHAR * pStr
Definition: AkString.h:57
AKRESULT Aquire(AkUInt32 in_uHash)
Definition: AkString.h:455

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요