00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #pragma once
00030
00031 #include "NvBlastExtSerialization.h"
00032
00033 #include <cstring>
00034
00035 #define ExtSerializerBoilerplate(_name, _description, _objectTypeID, _encodingID) \
00036 virtual const char* getName() const override { return _name; } \
00037 virtual const char* getDescription() const override { return _description; } \
00038 virtual uint32_t getObjectTypeID() const override { return _objectTypeID; } \
00039 virtual uint32_t getEncodingID() const override { return _encodingID; }
00040
00041
00042 #define ExtSerializerReadOnly(_name) \
00043 virtual bool isReadOnly() const override { return true; } \
00044 virtual uint64_t serializeIntoBuffer \
00045 ( \
00046 void*& buffer, \
00047 ExtSerialization::BufferProvider& bufferProvider, \
00048 const void* object, \
00049 uint64_t offset = 0 \
00050 ) override \
00051 { \
00052 NVBLAST_LOG_WARNING(#_name "::serializeIntoBuffer: ExtPxAsset_RAW serializer is read-only."); \
00053 NV_UNUSED(buffer); \
00054 NV_UNUSED(bufferProvider); \
00055 NV_UNUSED(object); \
00056 NV_UNUSED(offset); \
00057 return 0; \
00058 }
00059
00060
00061 #define ExtSerializerDefaultFactoryAndRelease(_classname) \
00062 static ExtSerializer* create() \
00063 { \
00064 return NVBLAST_NEW(_classname) (); \
00065 } \
00066 virtual void release() override \
00067 { \
00068 NVBLAST_DELETE(this, _classname); \
00069 }
00070
00071
00072 namespace Nv
00073 {
00074 namespace Blast
00075 {
00076
00080 class ExtSerializer
00081 {
00082 public:
00083 virtual ~ExtSerializer() {}
00084
00088 virtual const char* getName() const = 0;
00089
00093 virtual const char* getDescription() const = 0;
00094
00098 virtual uint32_t getObjectTypeID() const = 0;
00099
00103 virtual uint32_t getEncodingID() const = 0;
00104
00110 virtual bool isReadOnly() const { return false; }
00111
00119 virtual void* deserializeFromBuffer(const void* buffer, uint64_t size) = 0;
00120
00130 virtual uint64_t serializeIntoBuffer(void*& buffer, ExtSerialization::BufferProvider& bufferProvider, const void* object, uint64_t offset = 0) = 0;
00131
00135 virtual void release() = 0;
00136 };
00137
00138
00142 class ExtSerializationInternal : public ExtSerialization
00143 {
00144 public:
00149 virtual bool registerSerializer(ExtSerializer& serializer) = 0;
00150 virtual bool unregisterSerializer(ExtSerializer& serializer) = 0;
00151
00160 virtual ExtSerializer* findSerializer(uint32_t objectTypeID, uint32_t encodingID) = 0;
00161
00163 enum { HeaderSize = 128 };
00164 };
00165
00166
00167 template<typename Factory, size_t N>
00168 size_t ExtSerializationLoadSet(Nv::Blast::ExtSerializationInternal& serialization, Factory(&factories)[N])
00169 {
00170 size_t count = 0;
00171
00172 for (auto f : factories)
00173 {
00174 Nv::Blast::ExtSerializer* serializer = f();
00175 if (serializer != nullptr)
00176 {
00177 if (serialization.registerSerializer(*serializer))
00178 {
00179 ++count;
00180 }
00181 else
00182 {
00183 NVBLAST_LOG_ERROR("Nv::Blast::ExtSerializationLoadSet: failed to register serailizer:");
00184 NVBLAST_LOG_ERROR(serializer->getName());
00185 serializer->release();
00186 }
00187 }
00188 else
00189 {
00190 NVBLAST_LOG_ERROR("Nv::Blast::ExtSerializationLoadSet: failed to create serailizer.");
00191 }
00192 }
00193
00194 return count;
00195 }
00196
00197
00198 class ExtIStream
00199 {
00200 public:
00201 enum Flags
00202 {
00203 LittleEndian = (1 << 0),
00204 Fail = (1 << 1)
00205 };
00206
00207 ExtIStream(const void* buffer, size_t size) : m_buf(reinterpret_cast<const char*>(buffer)), m_flags(0)
00208 {
00209 m_cur = m_buf;
00210 m_end = m_buf + size;
00211 const uint16_t x = LittleEndian;
00212 m_flags = *reinterpret_cast<const char*>(&x);
00213 }
00214
00215 bool advance(ptrdiff_t diff)
00216 {
00217 m_cur += diff;
00218 if (m_cur < m_buf)
00219 {
00220 m_cur = m_buf;
00221 m_flags |= Fail;
00222 return false;
00223 }
00224 else
00225 if (m_cur > m_end)
00226 {
00227 m_cur = m_end;
00228 m_flags |= Fail;
00229 return false;
00230 }
00231 return true;
00232 }
00233
00234 const void* view()
00235 {
00236 return m_cur;
00237 }
00238
00239 bool read(void* buffer, size_t size)
00240 {
00241 if (!canRead(size)) return false;
00242 std::memcpy(buffer, m_cur, size);
00243 m_cur += size;
00244 return true;
00245 }
00246
00247 size_t tellg() const { return m_cur - m_buf; }
00248 size_t left() const { return m_end - m_cur; }
00249
00250 bool eof() const { return m_cur >= m_end; }
00251 bool fail() const { return (m_flags & Fail) != 0; }
00252
00253 private:
00254 const char* m_buf;
00255 const char* m_cur;
00256 const char* m_end;
00257 uint32_t m_flags;
00258
00259 bool isLittleEndian() const { return (m_flags & LittleEndian) != 0; }
00260
00261 bool canRead(size_t size) const { return m_cur + size <= m_end; }
00262
00263 template<typename T>
00264 friend ExtIStream& operator >> (ExtIStream& s, T& x);
00265 };
00266
00267 template<typename T>
00268 NV_INLINE ExtIStream& operator >> (ExtIStream& s, T& x)
00269 {
00270 if (s.canRead(sizeof(T)))
00271 {
00272 if (s.isLittleEndian())
00273 {
00274 x = *reinterpret_cast<const T*>(s.m_cur);
00275 s.m_cur += sizeof(T);
00276 }
00277 else
00278 {
00279 char* b = reinterpret_cast<char*>(&x) + sizeof(T);
00280 for (size_t n = sizeof(T); n--;) *--b = *s.m_cur++;
00281 }
00282 }
00283 else
00284 {
00285 s.m_flags |= ExtIStream::Fail;
00286 }
00287 return s;
00288 }
00289
00290 }
00291 }