vrshoot

annotate libs/assimp/BlobIOSystem.h @ 0:b2f14e535253

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