File.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * Copyright (c) 2006-2021 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "File.h"
  21. namespace love
  22. {
  23. namespace filesystem
  24. {
  25. love::Type File::type("File", &Object::type);
  26. File::~File()
  27. {
  28. }
  29. FileData *File::read(int64 size)
  30. {
  31. bool isopen = isOpen();
  32. if (!isopen && !open(MODE_READ))
  33. throw love::Exception("Could not read file %s.", getFilename().c_str());
  34. int64 max = getSize();
  35. int64 cur = tell();
  36. size = (size == ALL) ? max : size;
  37. if (size < 0)
  38. throw love::Exception("Invalid read size.");
  39. // Clamping because the file offset may be in a weird position.
  40. if (cur < 0)
  41. cur = 0;
  42. else if (cur > max)
  43. cur = max;
  44. if (cur + size > max)
  45. size = max - cur;
  46. FileData *fileData = new FileData(size, getFilename());
  47. int64 bytesRead = read(fileData->getData(), size);
  48. if (bytesRead < 0 || (bytesRead == 0 && bytesRead != size))
  49. {
  50. delete fileData;
  51. throw love::Exception("Could not read from file.");
  52. }
  53. if (bytesRead < size)
  54. {
  55. FileData *tmpFileData = new FileData(bytesRead, getFilename());
  56. memcpy(tmpFileData->getData(), fileData->getData(), (size_t) bytesRead);
  57. fileData->release();
  58. fileData = tmpFileData;
  59. }
  60. if (!isopen)
  61. close();
  62. return fileData;
  63. }
  64. bool File::write(const Data *data, int64 size)
  65. {
  66. return write(data->getData(), (size == ALL) ? data->getSize() : size);
  67. }
  68. std::string File::getExtension() const
  69. {
  70. const std::string &filename = getFilename();
  71. std::string::size_type idx = filename.rfind('.');
  72. if (idx != std::string::npos)
  73. return filename.substr(idx+1);
  74. else
  75. return std::string();
  76. }
  77. bool File::getConstant(const char *in, Mode &out)
  78. {
  79. return modes.find(in, out);
  80. }
  81. bool File::getConstant(Mode in, const char *&out)
  82. {
  83. return modes.find(in, out);
  84. }
  85. std::vector<std::string> File::getConstants(Mode)
  86. {
  87. return modes.getNames();
  88. }
  89. bool File::getConstant(const char *in, BufferMode &out)
  90. {
  91. return bufferModes.find(in, out);
  92. }
  93. bool File::getConstant(BufferMode in, const char *&out)
  94. {
  95. return bufferModes.find(in, out);
  96. }
  97. std::vector<std::string> File::getConstants(BufferMode)
  98. {
  99. return bufferModes.getNames();
  100. }
  101. StringMap<File::Mode, File::MODE_MAX_ENUM>::Entry File::modeEntries[] =
  102. {
  103. { "c", MODE_CLOSED },
  104. { "r", MODE_READ },
  105. { "w", MODE_WRITE },
  106. { "a", MODE_APPEND },
  107. };
  108. StringMap<File::Mode, File::MODE_MAX_ENUM> File::modes(File::modeEntries, sizeof(File::modeEntries));
  109. StringMap<File::BufferMode, File::BUFFER_MAX_ENUM>::Entry File::bufferModeEntries[] =
  110. {
  111. { "none", BUFFER_NONE },
  112. { "line", BUFFER_LINE },
  113. { "full", BUFFER_FULL },
  114. };
  115. StringMap<File::BufferMode, File::BUFFER_MAX_ENUM> File::bufferModes(File::bufferModeEntries, sizeof(File::bufferModeEntries));
  116. } // filesystem
  117. } // love