vrshoot

view libs/assimp/BlobIOSystem.h @ 1:e7ca128b8713

looks nice :)
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Feb 2014 00:35:22 +0200
parents
children
line source
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
6 Copyright (c) 2006-2012, assimp team
8 All rights reserved.
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
42 /** @file Provides cheat implementations for IOSystem and IOStream to
43 * redirect exporter output to a blob chain.*/
45 #ifndef AI_BLOBIOSYSTEM_H_INCLUDED
46 #define AI_BLOBIOSYSTEM_H_INCLUDED
48 namespace Assimp {
49 class BlobIOSystem;
51 // --------------------------------------------------------------------------------------------
52 /** Redirect IOStream to a blob */
53 // --------------------------------------------------------------------------------------------
54 class BlobIOStream : public IOStream
55 {
56 public:
58 BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
59 : buffer()
60 , cur_size()
61 , file_size()
62 , cursor()
63 , initial(initial)
64 , file(file)
65 , creator(creator)
66 {
67 }
70 virtual ~BlobIOStream();
72 public:
74 // -------------------------------------------------------------------
75 aiExportDataBlob* GetBlob()
76 {
77 aiExportDataBlob* blob = new aiExportDataBlob();
78 blob->size = file_size;
79 blob->data = buffer;
81 buffer = NULL;
83 return blob;
84 }
87 public:
90 // -------------------------------------------------------------------
91 virtual size_t Read(void* pvBuffer,
92 size_t pSize,
93 size_t pCount)
94 {
95 return 0;
96 }
98 // -------------------------------------------------------------------
99 virtual size_t Write(const void* pvBuffer,
100 size_t pSize,
101 size_t pCount)
102 {
103 pSize *= pCount;
104 if (cursor + pSize > cur_size) {
105 Grow(cursor + pSize);
106 }
108 memcpy(buffer+cursor, pvBuffer, pSize);
109 cursor += pSize;
111 file_size = std::max(file_size,cursor);
112 return pCount;
113 }
115 // -------------------------------------------------------------------
116 virtual aiReturn Seek(size_t pOffset,
117 aiOrigin pOrigin)
118 {
119 switch(pOrigin)
120 {
121 case aiOrigin_CUR:
122 cursor += pOffset;
124 case aiOrigin_END:
125 cursor = file_size - pOffset;
127 case aiOrigin_SET:
128 cursor = pOffset;
129 break;
131 default:
132 return AI_FAILURE;
133 }
135 if (cursor > file_size) {
136 Grow(cursor);
137 }
139 file_size = std::max(cursor,file_size);
140 return AI_SUCCESS;
141 }
143 // -------------------------------------------------------------------
144 virtual size_t Tell() const
145 {
146 return cursor;
147 }
149 // -------------------------------------------------------------------
150 virtual size_t FileSize() const
151 {
152 return file_size;
153 }
155 // -------------------------------------------------------------------
156 virtual void Flush()
157 {
158 // ignore
159 }
163 private:
165 // -------------------------------------------------------------------
166 void Grow(size_t need = 0)
167 {
168 // 1.5 and phi are very heap-friendly growth factors (the first
169 // allows for frequent re-use of heap blocks, the second
170 // forms a fibonacci sequence with similar characteristics -
171 // since this heavily depends on the heap implementation
172 // and other factors as well, i'll just go with 1.5 since
173 // it is quicker to compute).
174 size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
176 const uint8_t* const old = buffer;
177 buffer = new uint8_t[new_size];
179 if (old) {
180 memcpy(buffer,old,cur_size);
181 delete[] old;
182 }
184 cur_size = new_size;
185 }
187 private:
189 uint8_t* buffer;
190 size_t cur_size,file_size, cursor, initial;
192 const std::string file;
193 BlobIOSystem* const creator;
194 };
197 #define AI_BLOBIO_MAGIC "$blobfile"
199 // --------------------------------------------------------------------------------------------
200 /** Redirect IOSystem to a blob */
201 // --------------------------------------------------------------------------------------------
202 class BlobIOSystem : public IOSystem
203 {
205 friend class BlobIOStream;
206 typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
208 public:
210 BlobIOSystem()
211 {
212 }
214 virtual ~BlobIOSystem()
215 {
216 BOOST_FOREACH(BlobEntry& blobby, blobs) {
217 delete blobby.second;
218 }
219 }
221 public:
223 // -------------------------------------------------------------------
224 const char* GetMagicFileName() const
225 {
226 return AI_BLOBIO_MAGIC;
227 }
230 // -------------------------------------------------------------------
231 aiExportDataBlob* GetBlobChain()
232 {
233 // one must be the master
234 aiExportDataBlob* master = NULL, *cur;
235 BOOST_FOREACH(const BlobEntry& blobby, blobs) {
236 if (blobby.first == AI_BLOBIO_MAGIC) {
237 master = blobby.second;
238 break;
239 }
240 }
241 if (!master) {
242 DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
243 return NULL;
244 }
246 master->name.Set("");
248 cur = master;
249 BOOST_FOREACH(const BlobEntry& blobby, blobs) {
250 if (blobby.second == master) {
251 continue;
252 }
254 cur->next = blobby.second;
255 cur = cur->next;
257 // extract the file extension from the file written
258 const std::string::size_type s = blobby.first.find_first_of('.');
259 cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
260 }
262 // give up blob ownership
263 blobs.clear();
264 return master;
265 }
267 public:
269 // -------------------------------------------------------------------
270 virtual bool Exists( const char* pFile) const {
271 return created.find(std::string(pFile)) != created.end();
272 }
275 // -------------------------------------------------------------------
276 virtual char getOsSeparator() const {
277 return '/';
278 }
281 // -------------------------------------------------------------------
282 virtual IOStream* Open(const char* pFile,
283 const char* pMode)
284 {
285 if (pMode[0] != 'w') {
286 return NULL;
287 }
289 created.insert(std::string(pFile));
290 return new BlobIOStream(this,std::string(pFile));
291 }
293 // -------------------------------------------------------------------
294 virtual void Close( IOStream* pFile)
295 {
296 delete pFile;
297 }
299 private:
301 // -------------------------------------------------------------------
302 void OnDestruct(const std::string& filename, BlobIOStream* child)
303 {
304 // we don't know in which the files are closed, so we
305 // can't reliably say that the first must be the master
306 // file ...
307 blobs.push_back( BlobEntry(filename,child->GetBlob()) );
308 }
310 private:
311 std::set<std::string> created;
312 std::vector< BlobEntry > blobs;
313 };
316 // --------------------------------------------------------------------------------------------
317 BlobIOStream :: ~BlobIOStream()
318 {
319 creator->OnDestruct(file,this);
320 delete[] buffer;
321 }
324 } // end Assimp
326 #endif