1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
<html>
<head>
<title>NVIDIA(R) Blast(R) SDK 1.1 API Reference: Serialization (NvBlastExtSerialization)</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<LINK HREF="NVIDIA.css" REL="stylesheet" TYPE="text/css">
</head>
<body bgcolor="#FFFFFF">
<div id="header">
<hr class="first">
<img alt="" src="blast_logo.png">
<br>
<center>
<a class="qindex" href="main.html">Main Page</a>
<!-- <a class="qindex" href="hierarchy.html">Class Hierarchy</a> //-->
<a class="qindex" href="annotated.html">Class List</a>
<a class="qindex" href="functions.html">Class Members</a>
</center>
<hr class="second">
</div>
<!-- Generated by Doxygen 1.5.8 -->
<div class="contents">
<h1><a class="anchor" name="pageextserialization">Serialization (NvBlastExtSerialization) </a></h1><h2><a class="anchor" name="serialization_intro">
Introduction</a></h2>
This extension defines the <a class="el" href="class_nv_1_1_blast_1_1_ext_serialization.html">Nv::Blast::ExtSerialization</a> class, a modular serialization manager which can be extended to handle data types from different Blast™ modules (such as low-level, Tk, and ExtPhysX).<p>
An ExtSerialization manager is created using the global function NvBlastExtSerializationCreate:<p>
(From now on we'll assume we are using the <a class="el" href="namespace_nv_1_1_blast.html">Nv::Blast</a> namespace.)<p>
<div class="fragment"><pre class="fragment">ExtSerialization* ser = <a class="code" href="_nv_blast_ext_serialization_8h.html#9dad7f69d7a72d402c99238ed3c34bfc">NvBlastExtSerializationCreate</a>();
</pre></div><p>
ExtSerialization is capable of loading sets of serializers for different data types and encodings. The NvBlastExtSerialization extension comes with a set of low-level data serializers, with types enumerated in the header <b><a class="el" href="_nv_blast_ext_ll_serialization_8h.html">NvBlastExtLlSerialization.h</a></b>.<p>
<b>The low-level serializers are automatically loaded into an ExtSerialization when it is created.</b><p>
To load serializers for Tk and ExtPhysX assets, you must also load the extensions <a class="el" href="pageexttkserialization.html">BlastTk Serialization (NvBlastExtTkSerialization)</a> and <a class="el" href="pageextpxserialization.html">ExtPhysX Serialization (NvBlastExtPxSerialization)</a>, respectively. See the documentation for those modules.<p>
Each serializer is capable of reading (and writing, if it is not read-only) a single data type in a single encoding (format). Some serializers are read-only, in order to read legacy formats.<p>
The encodings available are enumerated in ExtSerialization::EncodingID. They are currently:<p>
<ul>
<li>CapnProtoBinary - Uses Cap'n Proto's binary serialization format</li><li>Raw - For low-level <a class="el" href="struct_nv_blast_asset.html">NvBlastAsset</a> and <a class="el" href="struct_nv_blast_family.html">NvBlastFamily</a> types, this is simply a memory copy. For Tk and ExtPx assets, this is the deprecated serialization format from Blast™ 1.0.</li></ul>
<p>
<br>
<h2><a class="anchor" name="serialization_ser">
Serialization (writing)</a></h2>
To serialize an object, the serialization manager's write encoding ID must be set to the desired value. By default it is set to EncodingID::CapnProtoBinary, as this is the only encoding which supports writing for all object types (at the present time). When other encodings become available, use ExtSerialization::setSerializationEncoding to set the write encoding to the desired type.<p>
Each serialization module defines the object types it can serialize. ExtSerialization defines the low-level types in <b><a class="el" href="_nv_blast_ext_ll_serialization_8h.html">NvBlastExtLlSerialization.h</a></b>:<p>
<ul>
<li>LlObjectTypeID::Asset - An <a class="el" href="struct_nv_blast_asset.html">NvBlastAsset</a></li><li>LlObjectTypeID::Family - An <a class="el" href="struct_nv_blast_family.html">NvBlastFamily</a></li></ul>
<p>
To serialize an object, for example an <a class="el" href="struct_nv_blast_asset.html">NvBlastAsset</a>, use ExtSerialization::serializeIntoBuffer as follows:<p>
<div class="fragment"><pre class="fragment"><span class="keyword">const</span> <a class="code" href="struct_nv_blast_asset.html">NvBlastAsset</a>* asset = ... <span class="comment">// Given pointer to an NvBlastAsset</span>
<span class="keywordtype">void</span>* buffer;
uint64_t size = ser->serializeIntoBuffer(buffer, asset, LlObjectTypeID::Asset);
</pre></div><p>
If successful, the data is written into a buffer allocated using the NvBlastGlobals allocator, written to the "buffer" parameter, and the size of the buffer written is the return value of the function. If the function returns 0, then serialization was unsuccessful. Notice that the second function parameter is actually a void*, so it requires the last parameter to tell it what object it is serializing. A utility wrapper function is given in <b><a class="el" href="_nv_blast_ext_ll_serialization_8h.html">NvBlastExtLlSerialization.h</a></b> which performs the same operation with an <a class="el" href="struct_nv_blast_asset.html">NvBlastAsset</a>, so one could equivalently use<p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span>* buffer;
uint64_t size = <a class="code" href="_nv_blast_ext_ll_serialization_8h.html#51eaff0f60a0dd3f1ee29618549ae635">NvBlastExtSerializationSerializeAssetIntoBuffer</a>(buffer, *ser, asset);
</pre></div><p>
A corresponding function also exists for <a class="el" href="struct_nv_blast_family.html">NvBlastFamily</a>, as well as other data types supported by other serialization extensions.<p>
This buffer may be written to disk, memory, networked, etc. Since the memory for the buffer is allocated using the allocator in NvBlastGlobals, it may be freed using the same allocator:<p>
<div class="fragment"><pre class="fragment"><a class="code" href="_nv_blast_globals_8h.html#f968d9c2dc2aaeb87f55bbd85488f741">NVBLAST_FREE</a>(buffer)
</pre></div><p>
<br>
<h3><a class="anchor" name="bufferproviders">
Using a Buffer Provider</a></h3>
If you wish to provide the serialization buffer by some means other than the NvBlastGlobals allocator, you may set a "buffer provider" in the serialization manager. A buffer provider is simply a callback that requests a buffer from the user of the necessary size. The user implements the interface ExtSerialization::BufferProvider, and passes a pointer to an instance of one to the serialization manager using ExtSerialization::setBufferProvider.<p>
For example:<p>
<div class="fragment"><pre class="fragment">std::vector<char> growableBuffer;
<span class="keyword">class </span>MyBufferProvider : <span class="keyword">public</span> Nv::Blast::ExtSerialization::BufferProvider
{
<span class="keyword">public</span>:
MyBufferProvider(std::vector<char>& growableBuffer) : m_growableBuffer(growableBuffer) {}
<span class="keyword">virtual</span> <span class="keywordtype">void</span>* requestBuffer(<span class="keywordtype">size_t</span> size)<span class="keyword"> override</span>
<span class="keyword"> </span>{
<span class="keywordflow">if</span> (m_growableBuffer.size() < size)
{
m_growableBuffer.resize(size);
}
<span class="keywordflow">return</span> m_growableBuffer.data();
}
<span class="keyword">private</span>:
std::vector<char>& m_growableBuffer;
} myBufferProvider(growableBuffer);
ser->setBufferProvider(&myBufferProvider);
</pre></div><p>
Passing NULL to setBufferProvider returns the serialization to its default behavior of using the NvBlastGlobals allocator.<p>
<br>
<h2><a class="anchor" name="serialization_deser">
Deserialization (reading)</a></h2>
To deserialize an object, use the ExtSerialization::deserializeFromBuffer method. If you know the type of object in the buffer, you may directly cast the returned pointer to one of that type. For example, if the buffer contains an <a class="el" href="struct_nv_blast_asset.html">NvBlastAsset</a>, use:<p>
<div class="fragment"><pre class="fragment"><span class="keyword">const</span> <span class="keywordtype">void</span>* buffer = ... <span class="comment">// A given buffer, may be read from disk, memory, etc.</span>
<span class="keyword">const</span> uint64_t size = ... <span class="comment">// The buffer's size in bytes</span>
<a class="code" href="struct_nv_blast_asset.html">NvBlastAsset</a>* asset = <span class="keyword">static_cast<</span><a class="code" href="struct_nv_blast_asset.html">NvBlastAsset</a>*<span class="keyword">></span>(ser->deserializeFromBuffer(buffer, size));
</pre></div><p>
This returns a valid pointer if deserialization was successful, or NULL otherwise. If no serializer is loaded which can handle the object type in the stream in its given encoding, it will fail and return NULL.<p>
Again, the memory for the asset is allocated using NvBlastGlobals, so that the asset may be released using<p>
<div class="fragment"><pre class="fragment"><a class="code" href="_nv_blast_globals_8h.html#f968d9c2dc2aaeb87f55bbd85488f741">NVBLAST_FREE</a>(asset);
</pre></div><p>
<br>
<h2><a class="anchor" name="detecting_object_type">
Detecting the Object Type in a Buffer</a></h2>
If you don't know the object type in the buffer, you may use the last (optional) argument in deserializeFromBuffer to return the type:<p>
<div class="fragment"><pre class="fragment">uint32_t objTypeID;
<span class="keywordtype">void</span>* obj = ser->deserializeFromBuffer(buffer, size, &objTypeID);
<a class="code" href="_nv_blast_globals_8h.html#7ac166d3622489e15ed28c5e61b22e0b">NVBLAST_CHECK_ERROR</a>(obj != <span class="keyword">nullptr</span>, <span class="stringliteral">"Object could not be read from buffer."</span>, <span class="keywordflow">return</span>);
<span class="keywordflow">switch</span> (objTypeID)
{
<span class="keywordflow">case</span> LlObjectTypeID::Asset:
handleAssetLoad(static_cast<NvBlastAsset*>(obj));
<span class="keywordflow">break</span>;
<span class="keywordflow">case</span> LlObjectTypeID::Family:
handleFamilyLoad(static_cast<NvBlastFamily*>(obj));
<span class="keywordflow">break</span>;
<span class="keywordflow">default</span>:
<a class="code" href="_nv_blast_globals_8h.html#67129e1adea0a0ed0c08da1b16497da0">NVBLAST_LOG_ERROR</a>(<span class="stringliteral">"Unknown object type "</span>);
}
</pre></div><p>
<br>
<h3><a class="anchor" name="peeking_and_skipping">
Peeking at and Skipping Buffer Data</a></h3>
If a buffer contains multiple objects, you may peek at the buffer to get object information including object type, encoding, and data size, and skip to the next object in the buffer (whether or not you have chosen to read the current object). For example:<p>
<div class="fragment"><pre class="fragment"><span class="keyword">const</span> <span class="keywordtype">void</span>* buffer = ... <span class="comment">// The input buffer</span>
uint64_t size = ... <span class="comment">// The input buffer size</span>
<span class="keywordflow">while</span> (size)
{
uint64_t objTypeID;
<span class="keywordflow">if</span> (!ser->peekHeader(&objTypeID, NULL, NULL, buffer, size)) <span class="comment">// Only reading the object type ID; may pass in NULL for the other header value pointers</span>
{
<span class="keywordflow">break</span>; <span class="comment">// Read error, stop</span>
}
<span class="keywordflow">if</span> (objectShouldBeLoaded(objTypeID)) <span class="comment">// Some function to determine whether or not we want this object</span>
{
<span class="keywordtype">void</span>* obj = ser->deserializeFromBuffer(buffer, size);
<span class="comment">// Handle loaded object ...</span>
}
<span class="comment">// Jump to next object:</span>
buffer = ser->skipObject(size, buffer); <span class="comment">// Updates size as well</span>
}
</pre></div><p>
<br>
<h2><a class="anchor" name="serialization_term">
Cleaning Up</a></h2>
When finished with the serialization manager, it may be released using its release() method:<p>
<div class="fragment"><pre class="fragment">ser->release();
</pre></div><p>
<br>
</div>
<!-- start footer part -->
<div class="footer">
Copyright © 2015-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. <a href="http://www.nvidia.com ">www.nvidia.com</a>
</div>
</body>
</html>
|