gwnavruntime/blob/blobbuffer.h Source File

blobbuffer.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
13 #include <string.h>
14 
15 namespace Kaim
16 {
17 
18 
19 class BlobRefInfo
20 {
21 public:
22  BlobRefInfo() { Clear(); }
23 
24  void Clear() { Set(nullptr, nullptr, 0); }
25 
26  void Set(KyUInt32* shallowBlobSizePtr, KyInt32* offsetPtr, KyInt32 blobGlobalOffset)
27  {
28  m_shallowBlobSizePtr = shallowBlobSizePtr;
29  m_offsetPtr = offsetPtr;
30  m_blobGlobalOffset = blobGlobalOffset;
31  }
32 
33  bool IsValid() { return m_shallowBlobSizePtr != nullptr; }
34 
35 public:
36  KyUInt32* m_shallowBlobSizePtr;
37  KyInt32* m_offsetPtr;
38  KyInt32 m_blobGlobalOffset;
39 };
40 
41 
42 /*
43 BlobBuffer is used in conjunction with derivations of BaseBlobBuilder to build Blobs.
44 A given succession of calls to Alloc...() functions must be called twice,
45 once in COUNT mode (the default), once in WRITE mode (set by a call to SwitchToWriteMode()).
46 In COUNT mode (IsWriteMode() == false): Alloc(), AllocArray(), AllocAndCopyArray() do not write to m_buffer memory,
47 they just increment the size needed to fit the Blob.
48 In WRITE mode (IsWriteMode() == true ): Alloc(), AllocArray(), AllocAndCopyArray() do write to m_buffer memory.
49 You should not use BlobBuffer directly, use a derivation of BaseBlobBuilder instead
50 and its accompanying macros: BLOB_SET, BLOB_ARRAY, BLOB_ARRAY_COPY, BLOB_STRING, BLOB_BUILD.
51 */
52 class BlobBuffer
53 {
54  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
55 
56 public:
57  BlobBuffer() : m_offset(0), m_buffer(nullptr) {}
58 
59  /* returns true when BlobBuffer is in write mode */
60  bool IsWriteMode() { return m_buffer != nullptr; }
61 
62  /* In COUNT mode: increment the size by sizeof(T).
63  In WRITE mode: call the T default constructor on the current position in buffer.*/
64  template<class T> T* Alloc();
65 
66  /* In COUNT mode: increment the size by sizeof(T) * count.
67  In WRITE mode: call count times the T default constructor on the current position in buffer. */
68  template<class T> T* AllocArray(BlobArray<T>* blobArray, KyUInt32 count)
69  {
70  return AllocAndCopyArray<T>(blobArray, nullptr, count);
71  }
72 
73  /* In COUNT mode: increment the size by sizeof(T) * count.
74  In WRITE mode: call count times the T default constructor on the current position in buffer. */
75  template<class T> T* AllocAndCopyArray(BlobArray<T>* blobArray, const T* src, KyUInt32 count);
76 
77  template<class T> T* AllocAndCopyReferencedBlob(BlobRef<T>* blobRef, void* srcBlob, KyUInt32 srcBlobDeepSize, KyUInt32 srcBlobShallowSize);
78 
79  template<class T> T* AllocAndCopyReferencedBlobFromBlobHandler(BlobRef<T>* blobRef, const BlobHandler<T>& blobHandler);
80 
81  /* called in BaseBlobBuilder<T>::Build() */
82  void SwitchToWriteMode(BaseBlobHandler& baseBlobHandler, KyUInt32 rootShallowBlobSize, MemoryHeap* heap, KyInt32 memStat);
83 
84  KyUInt32 GetAlignedSize(KyUInt32 size) { return ((size + 4 - 1) / 4) * 4; }
85 
86  template<class T> void BeginBlobRefBuffer(BlobRef<T>* blobRef);
87 
88  void SetBlobRefInfoFromCurrentOffset();
89 
90  void SetBlobRefInfoFromCopiedBlobRef(KyUInt32 shallowBlobSize);
91 
92 public:
93  KyUInt32 m_offset;
94  char* m_buffer;
95  BlobRefInfo m_blobRefInfo;
96 };
97 
98 
99 // --------------------------------- inline implementation ---------------------------------
100 
101 template<class T>
102 T* BlobBuffer::Alloc()
103 {
104  KY_ASSERT(sizeof(T) % 4 == 0);
105 
106  if (IsWriteMode() == false)
107  {
108  m_offset += sizeof(T);
109  return nullptr;
110  }
111 
112  T* ptr = (T*)(m_buffer + m_offset);
113  ::new(ptr) T(); // placement new
114  m_offset += sizeof(T);
115  return ptr;
116 }
117 
118 
119 template<class T>
120 T* BlobBuffer::AllocAndCopyArray(BlobArray<T>* blobArray, const T* src, KyUInt32 count)
121 {
122  KyUInt32 size = sizeof(T) * count;
123  KyUInt32 alignedSize = GetAlignedSize(size);
124  KyUInt32 paddingSize = alignedSize - size;
125 
126  if (IsWriteMode() == false)
127  {
128  m_offset += alignedSize;
129  return nullptr;
130  }
131 
132  if (count == 0)
133  {
134  blobArray->m_count = count;
135  blobArray->m_offset = 0; // force m_offset = 0 when count = 0
136  return nullptr;
137  }
138 
139  // get destArray
140  T* dest = (T*)(m_buffer + m_offset);
141 
142  // initialize blobArray
143  blobArray->m_count = count;
144  blobArray->m_offset = (KyInt32)((char*)dest - (char*)&blobArray->m_offset);
145 
146  if (src != nullptr)
147  {
148  memcpy(dest, src, size);
149  }
150  else
151  {
152  memset(dest, 0, size);
153  // TODO check if this is necessary
154  // call default constructor on each element
155  for (KyUInt32 i = 0; i < count; ++i)
156  ::new(dest + i) T;
157  }
158  for (KyUInt32 i = 0; i < paddingSize; ++i)
159  ((char*)dest)[size + i] = 0;
160 
161  m_offset += alignedSize;
162  return dest;
163 }
164 
165 
166 template<class T>
167 void BlobBuffer::BeginBlobRefBuffer(BlobRef<T>* blobRef)
168 {
169  if (blobRef == nullptr)
170  return;
171  SetBlobRefInfoFromCurrentOffset(); // set the previous BlobRefInfo
172  m_blobRefInfo.Set(&blobRef->m_impl.m_shallowBlobSize, &blobRef->m_impl.m_offset, m_offset);
173 }
174 
175 
176 template<class T>
177 T* BlobBuffer::AllocAndCopyReferencedBlob(BlobRef<T>* blobRef, void* srcBlob, KyUInt32 srcBlobDeepSize, KyUInt32 srcBlobShallowSize)
178 {
179  BeginBlobRefBuffer(blobRef);
180 
181  KyUInt32 alignedSize = GetAlignedSize(srcBlobDeepSize);
182  KyUInt32 paddingSize = alignedSize - srcBlobDeepSize;
183 
184  if (IsWriteMode() == false || srcBlob == nullptr || blobRef == nullptr)
185  {
186  m_offset += alignedSize;
187  SetBlobRefInfoFromCopiedBlobRef(srcBlobShallowSize);
188  return nullptr;
189  }
190 
191  char* dest = m_buffer + m_offset;
192  memcpy(dest, srcBlob, srcBlobDeepSize);
193 
194  // nullify paddingSize
195  for (KyUInt32 i = 0; i < paddingSize; ++i)
196  ((char*)dest)[srcBlobDeepSize + i] = 0;
197 
198  m_offset += alignedSize;
199  SetBlobRefInfoFromCopiedBlobRef(srcBlobShallowSize);
200  return (T*)dest;
201 }
202 
203 
204 template<class T>
205 T* BlobBuffer::AllocAndCopyReferencedBlobFromBlobHandler(BlobRef<T>* blobRef, const BlobHandler<T>& blobHandler)
206 {
207  return AllocAndCopyReferencedBlob(blobRef, (void*)blobHandler.VoidBlob(), blobHandler.GetDeepBlobSize(), blobHandler.GetShallowBlobSize());
208 }
209 
210 
211 
212 }
213 
214 
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
std::int32_t KyInt32
int32_t
Definition: types.h:24