CLimitReadFile.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #include "CLimitReadFile.h"
  5. #include "irrString.h"
  6. namespace irr
  7. {
  8. namespace io
  9. {
  10. CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long pos,
  11. long areaSize, const io::path& name)
  12. : Filename(name), AreaStart(0), AreaEnd(0), Pos(0),
  13. File(alreadyOpenedFile)
  14. {
  15. #ifdef _DEBUG
  16. setDebugName("CLimitReadFile");
  17. #endif
  18. if (File)
  19. {
  20. File->grab();
  21. AreaStart = pos;
  22. AreaEnd = AreaStart + areaSize;
  23. }
  24. }
  25. CLimitReadFile::~CLimitReadFile()
  26. {
  27. if (File)
  28. File->drop();
  29. }
  30. //! returns how much was read
  31. s32 CLimitReadFile::read(void* buffer, u32 sizeToRead)
  32. {
  33. #if 1
  34. if (0 == File)
  35. return 0;
  36. s32 r = AreaStart + Pos;
  37. s32 toRead = core::s32_min(AreaEnd, r + sizeToRead) - core::s32_max(AreaStart, r);
  38. if (toRead < 0)
  39. return 0;
  40. File->seek(r);
  41. r = File->read(buffer, toRead);
  42. Pos += r;
  43. return r;
  44. #else
  45. const long pos = File->getPos();
  46. if (pos >= AreaEnd)
  47. return 0;
  48. if (pos + (long)sizeToRead >= AreaEnd)
  49. sizeToRead = AreaEnd - pos;
  50. return File->read(buffer, sizeToRead);
  51. #endif
  52. }
  53. //! changes position in file, returns true if successful
  54. bool CLimitReadFile::seek(long finalPos, bool relativeMovement)
  55. {
  56. #if 1
  57. Pos = core::s32_clamp(finalPos + (relativeMovement ? Pos : 0 ), 0, AreaEnd - AreaStart);
  58. return true;
  59. #else
  60. const long pos = File->getPos();
  61. if (relativeMovement)
  62. {
  63. if (pos + finalPos > AreaEnd)
  64. finalPos = AreaEnd - pos;
  65. }
  66. else
  67. {
  68. finalPos += AreaStart;
  69. if (finalPos > AreaEnd)
  70. return false;
  71. }
  72. return File->seek(finalPos, relativeMovement);
  73. #endif
  74. }
  75. //! returns size of file
  76. long CLimitReadFile::getSize() const
  77. {
  78. return AreaEnd - AreaStart;
  79. }
  80. //! returns where in the file we are.
  81. long CLimitReadFile::getPos() const
  82. {
  83. #if 1
  84. return Pos;
  85. #else
  86. return File->getPos() - AreaStart;
  87. #endif
  88. }
  89. //! returns name of file
  90. const io::path& CLimitReadFile::getFileName() const
  91. {
  92. return Filename;
  93. }
  94. IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize)
  95. {
  96. return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName);
  97. }
  98. } // end namespace io
  99. } // end namespace irr