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 "capnp/serialize.h"
00032 #include "NvBlastExtInputStream.h"
00033 #include "NvBlastExtOutputStream.h"
00034 #include "NvBlastArray.h"
00035 #include "NvBlastExtSerialization.h"
00036
00037
00038 namespace Nv
00039 {
00040 namespace Blast
00041 {
00042
00043 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00044 class ExtSerializationCAPN
00045 {
00046 public:
00047 static TObject* deserializeFromBuffer(const unsigned char* input, uint64_t size);
00048 static TObject* deserializeFromStream(std::istream& inputStream);
00049
00050 static uint64_t serializationBufferSize(const TObject* object);
00051
00052 static bool serializeIntoBuffer(const TObject* object, unsigned char* buffer, uint64_t maxSize, uint64_t& usedSize);
00053 static bool serializeIntoBuffer(const TObject *object, unsigned char*& buffer, uint64_t& size, ExtSerialization::BufferProvider* bufferProvider = nullptr, uint64_t offset = 0);
00054 static bool serializeIntoStream(const TObject* object, std::ostream& outputStream);
00055
00056 private:
00057
00058 static bool serializeIntoBuilder(TSerializationBuilder& objectBuilder, const TObject* object);
00059 static bool serializeIntoMessage(capnp::MallocMessageBuilder& message, const TObject* object);
00060 static TObject* deserializeFromStreamReader(capnp::InputStreamMessageReader& message);
00061 };
00062
00063
00064 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00065 TObject* ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::deserializeFromBuffer(const unsigned char* input, uint64_t size)
00066 {
00067 kj::ArrayPtr<const unsigned char> source(input, size);
00068
00069 kj::ArrayInputStream inputStream(source);
00070
00071 Nv::Blast::Array<uint64_t>::type scratch(static_cast<uint32_t>(size));
00072 kj::ArrayPtr<capnp::word> scratchArray((capnp::word*) scratch.begin(), size);
00073
00074 capnp::InputStreamMessageReader message(inputStream, capnp::ReaderOptions(), scratchArray);
00075
00076 return deserializeFromStreamReader(message);
00077 }
00078
00079
00080 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00081 TObject* ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::deserializeFromStream(std::istream& inputStream)
00082 {
00083 ExtInputStream readStream(inputStream);
00084
00085 capnp::InputStreamMessageReader message(readStream);
00086
00087 return deserializeFromStreamReader(message);
00088 }
00089
00090
00091 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00092 uint64_t ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializationBufferSize(const TObject* object)
00093 {
00094 capnp::MallocMessageBuilder message;
00095
00096 bool result = serializeIntoMessage(message, object);
00097
00098 if (result == false)
00099 {
00100 return 0;
00101 }
00102
00103 return computeSerializedSizeInWords(message) * sizeof(uint64_t);
00104 }
00105
00106
00107 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00108 bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoBuffer(const TObject* object, unsigned char* buffer, uint64_t maxSize, uint64_t& usedSize)
00109 {
00110 capnp::MallocMessageBuilder message;
00111
00112 bool result = serializeIntoMessage(message, object);
00113
00114 if (result == false)
00115 {
00116 usedSize = 0;
00117 return false;
00118 }
00119
00120 uint64_t messageSize = computeSerializedSizeInWords(message) * sizeof(uint64_t);
00121
00122 if (maxSize < messageSize)
00123 {
00124 NVBLAST_LOG_ERROR("When attempting to serialize into an existing buffer, the provided buffer was too small.");
00125 usedSize = 0;
00126 return false;
00127 }
00128
00129 kj::ArrayPtr<unsigned char> outputBuffer(buffer, maxSize);
00130 kj::ArrayOutputStream outputStream(outputBuffer);
00131
00132 capnp::writeMessage(outputStream, message);
00133
00134 usedSize = messageSize;
00135 return true;
00136 }
00137
00138
00139 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00140 bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoBuffer(const TObject *object, unsigned char*& buffer, uint64_t& size, ExtSerialization::BufferProvider* bufferProvider, uint64_t offset)
00141 {
00142 capnp::MallocMessageBuilder message;
00143
00144 bool result = serializeIntoMessage(message, object);
00145
00146 if (result == false)
00147 {
00148 buffer = nullptr;
00149 size = 0;
00150 return false;
00151 }
00152
00153 const uint64_t blockSize = computeSerializedSizeInWords(message) * sizeof(uint64_t);
00154
00155 size = blockSize + offset;
00156
00157 buffer = static_cast<unsigned char *>(bufferProvider != nullptr ? bufferProvider->requestBuffer(size) : NVBLAST_ALLOC(size));
00158
00159 kj::ArrayPtr<unsigned char> outputBuffer(buffer + offset, blockSize);
00160 kj::ArrayOutputStream outputStream(outputBuffer);
00161
00162 capnp::writeMessage(outputStream, message);
00163
00164 return true;
00165 }
00166
00167
00168 template<typename TObject, typename TSerializationReader, typename TSerializationBuilder>
00169 bool ExtSerializationCAPN<TObject, TSerializationReader, TSerializationBuilder>::serializeIntoStream(const TObject* object, std::ostream& outputStream)
00170 {
00171 capnp::MallocMessageBuilder message;
00172
00173 bool result = serializeIntoMessage(message, object);
00174
00175 if (result == false)
00176 {
00177 return false;
00178 }
00179
00180 ExtOutputStream blastOutputStream(outputStream);
00181
00182 writeMessage(blastOutputStream, message);
00183
00184 return true;
00185 }
00186
00187 }
00188 }