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
00030
00031
00032 #include <vlCore/VirtualFile.hpp>
00033 #include <vlCore/FileSystem.hpp>
00034 #include <vlCore/Log.hpp>
00035 #include <vlCore/Say.hpp>
00036 #include <vlCore/CRC32CheckSum.hpp>
00037
00038 using namespace vl;
00039
00040
00041 ref<VirtualFile> vl::locateFile(const String& path) { return defFileSystem()->locateFile(path); }
00042
00043 unsigned int VirtualFile::crc32()
00044 {
00045 unsigned int sum = 0;
00046
00047 if ( open(OM_ReadOnly) )
00048 {
00049 CRC32CheckSum check_sum;
00050 sum = check_sum.compute(this);
00051 close();
00052 }
00053
00054 return sum;
00055 }
00056
00057 MD5CheckSum VirtualFile::md5()
00058 {
00059 MD5CheckSum check_sum;
00060 if ( open(OM_ReadOnly) )
00061 {
00062 check_sum.compute(this);
00063 close();
00064 }
00065 return check_sum;
00066 }
00067
00068 long long VirtualFile::peek(void* buffer, long long byte_count)
00069 {
00070 if ( !isOpen() )
00071 {
00072 Log::error("VirtualFile::peek(): the file is closed.\n");
00073 return 0;
00074 }
00075 long long pos = position();
00076 long long read_bytes = read(buffer, byte_count);
00077 if ( !seekSet( pos ) )
00078 Log::error("VirtualFile::peek() called on a non seek-able VirtualFile.\n");
00079 return read_bytes;
00080 }
00081
00082 long long VirtualFile::read(void* buffer, long long byte_count)
00083 {
00084 if (byte_count > 0)
00085 return read_Implementation(buffer, byte_count);
00086 else
00087 return 0;
00088 }
00089
00090 long long VirtualFile::write(const void* buffer, long long byte_count)
00091 {
00092 if (byte_count > 0)
00093 return write_Implementation(buffer, byte_count);
00094 else
00095 return 0;
00096 }
00097
00098 long long VirtualFile::position() const
00099 {
00100 return position_Implementation();
00101 }
00102
00103 bool VirtualFile::seekSet(long long offset)
00104 {
00105 if (offset < 0)
00106 {
00107 Log::error( Say("VirtualFile::seekSet(%n): invalid offset.\n") << offset);
00108 seekSet_Implementation(0);
00109 return false;
00110 }
00111 if (offset > size() )
00112 {
00113 Log::error( Say("VirtualFile::seekSet(%n): invalid offset past end of stream.\n") << offset);
00114 seekSet_Implementation(size());
00115 return false;
00116 }
00117
00118 return seekSet_Implementation(offset);
00119 }
00120
00121 bool VirtualFile::seekCur(long long offset)
00122 {
00123 return seekSet( position() + offset );
00124 }
00125
00126 bool VirtualFile::seekEnd(long long offset)
00127 {
00128 return seekSet( size() + offset );
00129 }
00130
00131 long long VirtualFile::load(std::vector<char>& data)
00132 {
00133 data.resize( (size_t)size() );
00134 if (data.size())
00135 return load(&data[0], data.size());
00136 else
00137 return 0;
00138 }
00139
00140 long long VirtualFile::load(void* buffer, long long max)
00141 {
00142 if (max<0)
00143 max = size();
00144 if ( open(OM_ReadOnly) )
00145 {
00146 long long bytes = read(buffer,max);
00147 close();
00148 return bytes;
00149 }
00150 else
00151 {
00152 Log::error( Say("Cannot load file '%s'.\n") << path() );
00153 return 0;
00154 }
00155 }
00156
00157
00158
00159 double VirtualFile::readDouble(bool little_endian_data)
00160 {
00161 double data = 0;
00162 read64(&data, little_endian_data);
00163 return data;
00164 }
00165
00166 float VirtualFile::readFloat(bool little_endian_data)
00167 {
00168 float data = 0;
00169 read32(&data, little_endian_data);
00170 return data;
00171 }
00172
00173 unsigned long long VirtualFile::readUInt64(bool little_endian_data)
00174 {
00175 unsigned long long data = 0;
00176 read64(&data, little_endian_data);
00177 return data;
00178 }
00179
00180 long long VirtualFile::readSInt64(bool little_endian_data)
00181 {
00182 long long data = 0;
00183 read64(&data, little_endian_data);
00184 return data;
00185 }
00186
00187 unsigned int VirtualFile::readUInt32(bool little_endian_data)
00188 {
00189 unsigned long data = 0;
00190 read32(&data, little_endian_data);
00191 return data;
00192 }
00193
00194 int VirtualFile::readSInt32(bool little_endian_data)
00195 {
00196 int data = 0;
00197 read32(&data, little_endian_data);
00198 return data;
00199 }
00200
00201 unsigned short VirtualFile::readUInt16(bool little_endian_data)
00202 {
00203 unsigned short data = 0;
00204 read16(&data, little_endian_data);
00205 return data;
00206 }
00207
00208 short VirtualFile::readSInt16(bool little_endian_data)
00209 {
00210 short data = 0;
00211 read16(&data, little_endian_data);
00212 return data;
00213 }
00214
00215 unsigned char VirtualFile::readUInt8()
00216 {
00217 unsigned char data = 0;
00218 read(&data, 1);
00219 return data;
00220 }
00221
00222 char VirtualFile::readSInt8()
00223 {
00224 char data = 0;
00225 read(&data, 1);
00226 return data;
00227 }
00228
00229
00230
00231 long long VirtualFile::readDouble(double* buffer, long long count, bool little_endian_data)
00232 {
00233 return read64(buffer, count, little_endian_data);
00234 }
00235
00236 long long VirtualFile::readFloat(float* buffer, long long count, bool little_endian_data)
00237 {
00238 return read32(buffer, count, little_endian_data);
00239 }
00240
00241 long long VirtualFile::readUInt64(unsigned long long* buffer, long long count, bool little_endian_data)
00242 {
00243 return read64(buffer, count, little_endian_data);
00244 }
00245
00246 long long VirtualFile::readSInt64(long long* buffer, long long count, bool little_endian_data)
00247 {
00248 return read64(buffer, count, little_endian_data);
00249 }
00250
00251 long long VirtualFile::readUInt32(unsigned int* buffer, long long count, bool little_endian_data)
00252 {
00253 return read32(buffer, count, little_endian_data);
00254 }
00255
00256 long long VirtualFile::readSInt32(int* buffer, long long count, bool little_endian_data)
00257 {
00258 return read32(buffer, count, little_endian_data);
00259 }
00260
00261 long long VirtualFile::readUInt16(unsigned short* buffer, long long count, bool little_endian_data)
00262 {
00263 return read16(buffer, count, little_endian_data);
00264 }
00265
00266 long long VirtualFile::readSInt16(short* buffer, long long count, bool little_endian_data)
00267 {
00268 return read16(buffer, count, little_endian_data);
00269 }
00270
00271 long long VirtualFile::readUInt8(unsigned char* buffer, long long count)
00272 {
00273 return read(buffer, count);
00274 }
00275
00276 long long VirtualFile::readSInt8(char* buffer, long long count)
00277 {
00278 return read(buffer, count);
00279 }
00280
00281
00282
00283 long long VirtualFile::writeDouble(double data, bool little_endian_data)
00284 {
00285 return write64(&data, little_endian_data);
00286 }
00287
00288 long long VirtualFile::writeFloat(float data, bool little_endian_data)
00289 {
00290 return write32(&data, little_endian_data);
00291 }
00292
00293 long long VirtualFile::writeUInt64(unsigned long long data, bool little_endian_data)
00294 {
00295 return write64(&data, little_endian_data);
00296 }
00297
00298 long long VirtualFile::writeSInt64(long long data, bool little_endian_data)
00299 {
00300 return write64(&data, little_endian_data);
00301 }
00302
00303 long long VirtualFile::writeUInt32(unsigned int data, bool little_endian_data)
00304 {
00305 return write32(&data, little_endian_data);
00306 }
00307
00308 long long VirtualFile::writeSInt32(int data, bool little_endian_data)
00309 {
00310 return write32(&data, little_endian_data);
00311 }
00312
00313 long long VirtualFile::writeUInt16(unsigned short data, bool little_endian_data)
00314 {
00315 return write16(&data, little_endian_data);
00316 }
00317
00318 long long VirtualFile::writeSInt16(short data, bool little_endian_data)
00319 {
00320 return write16(&data, little_endian_data);
00321 }
00322
00323 long long VirtualFile::writeUInt8(unsigned char data)
00324 {
00325 return write(&data, 1);
00326 }
00327
00328 long long VirtualFile::writeSInt8(char data)
00329 {
00330 return write(&data, 1);
00331 }
00332
00333
00334
00335 long long VirtualFile::writeDouble(const double* buffer, long long count, bool little_endian_data)
00336 {
00337 return write64(buffer, count, little_endian_data);
00338 }
00339
00340 long long VirtualFile::writeFloat(const float* buffer, long long count, bool little_endian_data)
00341 {
00342 return write32(buffer, count, little_endian_data);
00343 }
00344
00345 long long VirtualFile::writeUInt64(const unsigned long long* buffer, long long count, bool little_endian_data)
00346 {
00347 return write64(buffer, count, little_endian_data);
00348 }
00349
00350 long long VirtualFile::writeSInt64(const long long* buffer, long long count, bool little_endian_data)
00351 {
00352 return write64(buffer, count, little_endian_data);
00353 }
00354
00355 long long VirtualFile::writeUInt32(const unsigned int* buffer, long long count, bool little_endian_data)
00356 {
00357 return write32(buffer, count, little_endian_data);
00358 }
00359
00360 long long VirtualFile::writeSInt32(const int* buffer, long long count, bool little_endian_data)
00361 {
00362 return write32(buffer, count, little_endian_data);
00363 }
00364
00365 long long VirtualFile::writeUInt16(const unsigned short* buffer, long long count, bool little_endian_data)
00366 {
00367 return write16(buffer, count, little_endian_data);
00368 }
00369
00370 long long VirtualFile::writeSInt16(const short* buffer, long long count, bool little_endian_data)
00371 {
00372 return write16(buffer, count, little_endian_data);
00373 }
00374
00375 long long VirtualFile::writeUInt8(const unsigned char* buffer, long long count)
00376 {
00377 return write(buffer, count);
00378 }
00379
00380 long long VirtualFile::writeSInt8(const char* buffer, long long count)
00381 {
00382 return write(buffer, count);
00383 }
00384
00385
00386
00387 long long VirtualFile::write64(const void* buffer, long long count, bool little_endian_data)
00388 {
00389 unsigned short bet = 0x00FF;
00390 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00391 if (little_endian_cpu != little_endian_data)
00392 {
00393 long long ret = 0;
00394 for(long long i=0; i<count; ++i)
00395 ret += write64( (char*)buffer+i*8, little_endian_data );
00396 return ret;
00397 }
00398 else
00399 return write(buffer, 8*count);
00400 }
00401
00402 long long VirtualFile::write32(const void* buffer, long long count, bool little_endian_data)
00403 {
00404 unsigned short bet = 0x00FF;
00405 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00406 if (little_endian_cpu != little_endian_data)
00407 {
00408 long long ret = 0;
00409 for(long long i=0; i<count; ++i)
00410 ret += write32( (char*)buffer+i*4, little_endian_data );
00411 return ret;
00412 }
00413 else
00414 return write(buffer, 4*count);
00415 }
00416
00417 long long VirtualFile::write16(const void* buffer, long long count, bool little_endian_data)
00418 {
00419 unsigned short bet = 0x00FF;
00420 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00421 if (little_endian_cpu != little_endian_data)
00422 {
00423 long long ret = 0;
00424 for(long long i=0; i<count; ++i)
00425 ret += write16( (char*)buffer+i*2, little_endian_data );
00426 return ret;
00427 }
00428 else
00429 return write(buffer, 2*count);
00430 }
00431
00432 long long VirtualFile::read64(void* buffer, long long count, bool little_endian_data)
00433 {
00434 long long ret = read(buffer, 8*count);
00435 unsigned short bet = 0x00FF;
00436 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00437 if ( little_endian_cpu != little_endian_data )
00438 {
00439 char* bytes = (char*)buffer;
00440 for(int i=0; i<count; ++i, bytes+=8)
00441 {
00442 char tmp;
00443 tmp = bytes[0]; bytes[0] = bytes[7]; bytes[7] = tmp;
00444 tmp = bytes[1]; bytes[1] = bytes[6]; bytes[6] = tmp;
00445 tmp = bytes[2]; bytes[2] = bytes[5]; bytes[5] = tmp;
00446 tmp = bytes[3]; bytes[3] = bytes[4]; bytes[4] = tmp;
00447 }
00448 }
00449 return ret;
00450 }
00451
00452 long long VirtualFile::read32(void* buffer, long long count, bool little_endian_data)
00453 {
00454 long long ret = read(buffer, 4*count);
00455 unsigned short bet = 0x00FF;
00456 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00457 if ( little_endian_cpu != little_endian_data )
00458 {
00459 char* bytes = (char*)buffer;
00460 for(int i=0; i<count; ++i, bytes+=4)
00461 {
00462 char tmp;
00463 tmp = bytes[0]; bytes[0] = bytes[3]; bytes[3] = tmp;
00464 tmp = bytes[1]; bytes[1] = bytes[2]; bytes[2] = tmp;
00465 }
00466 }
00467 return ret;
00468 }
00469
00470 long long VirtualFile::read16(void* buffer, long long count, bool little_endian_data)
00471 {
00472 long long ret = read(buffer, 2*count);
00473 unsigned short bet = 0x00FF;
00474 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00475 if ( little_endian_cpu != little_endian_data )
00476 {
00477 char* bytes = (char*)buffer;
00478 for(int i=0; i<count; ++i, bytes+=2)
00479 {
00480 char tmp = bytes[0]; bytes[0] = bytes[1]; bytes[1] = tmp;
00481 }
00482 }
00483 return ret;
00484 }
00485
00486 long long VirtualFile::write64(const void* buffer, bool little_endian_data)
00487 {
00488 unsigned short bet = 0x00FF;
00489 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00490 long long dummy = *(long long*)buffer;
00491 char* byte = (char*)&dummy;
00492 if (little_endian_cpu != little_endian_data)
00493 {
00494 char tmp;
00495 tmp = byte[0]; byte[0] = byte[7]; byte[7] = tmp;
00496 tmp = byte[1]; byte[1] = byte[6]; byte[6] = tmp;
00497 tmp = byte[2]; byte[2] = byte[5]; byte[5] = tmp;
00498 tmp = byte[3]; byte[3] = byte[4]; byte[4] = tmp;
00499 }
00500 return write(byte, 8);
00501 }
00502
00503 long long VirtualFile::write32(const void* buffer, bool little_endian_data)
00504 {
00505 unsigned short bet = 0x00FF;
00506 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00507 int dummy = *(int*)buffer;
00508 char* byte = (char*)&dummy;
00509 if (little_endian_cpu != little_endian_data)
00510 {
00511 char tmp;
00512 tmp = byte[0]; byte[0] = byte[3]; byte[3] = tmp;
00513 tmp = byte[1]; byte[1] = byte[2]; byte[2] = tmp;
00514 }
00515 return write(byte, 4);
00516 }
00517
00518 long long VirtualFile::write16(const void* buffer, bool little_endian_data)
00519 {
00520 unsigned short bet = 0x00FF;
00521 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00522 short dummy = *(short*)buffer;
00523 char* byte = (char*)&dummy;
00524 if (little_endian_cpu != little_endian_data)
00525 {
00526 char tmp = byte[0]; byte[0] = byte[1]; byte[1] = tmp;
00527 }
00528 return write(byte, 2);
00529 }
00530
00531 long long VirtualFile::read64(void* buffer, bool little_endian_data)
00532 {
00533 char* bytes = (char*)buffer;
00534 long long ret = read(bytes, 8);
00535 unsigned short bet = 0x00FF;
00536 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00537 if ( little_endian_cpu != little_endian_data )
00538 {
00539 char tmp;
00540 tmp = bytes[0]; bytes[0] = bytes[7]; bytes[7] = tmp;
00541 tmp = bytes[1]; bytes[1] = bytes[6]; bytes[6] = tmp;
00542 tmp = bytes[2]; bytes[2] = bytes[5]; bytes[5] = tmp;
00543 tmp = bytes[3]; bytes[3] = bytes[4]; bytes[4] = tmp;
00544 }
00545 return ret;
00546 }
00547
00548 long long VirtualFile::read32(void* buffer, bool little_endian_data)
00549 {
00550 char* bytes = (char*)buffer;
00551 long long ret = read(bytes, 4);
00552 unsigned short bet = 0x00FF;
00553 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00554 if ( little_endian_cpu != little_endian_data )
00555 {
00556 char tmp;
00557 tmp = bytes[0]; bytes[0] = bytes[3]; bytes[3] = tmp;
00558 tmp = bytes[1]; bytes[1] = bytes[2]; bytes[2] = tmp;
00559 }
00560 return ret;
00561 }
00562
00563 long long VirtualFile::read16(void* buffer, bool little_endian_data)
00564 {
00565 char* bytes = (char*)buffer;
00566 long long ret = read(bytes, 2);
00567 unsigned short bet = 0x00FF;
00568 bool little_endian_cpu = ((unsigned char*)&bet)[0] == 0xFF;
00569 if ( little_endian_cpu != little_endian_data )
00570 {
00571 char tmp = bytes[0]; bytes[0] = bytes[1]; bytes[1] = tmp;
00572 }
00573 return ret;
00574 }
00575