gwnavruntime/blob/blobbuffer.h Source File

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