11 std::shared_ptr<FileHandle> file_handle;
15 util::LzVersion comp_lz_ver;
17 size_t dec_file_offset;
19 size_t dec_file_buf_size;
21 Result LoadDecompressedData();
22 Result SaveCompressedData();
23 Result ReadDecompressedData(
void *read_buf,
const size_t read_size,
size_t &out_read_size);
24 Result WriteDecompressedData(
const void *write_buf,
const size_t write_size);
25 Result ReallocateDecompressedData(
const size_t new_size);
28 BinaryFile() : file_handle(), ok(
false), mode(OpenMode::Read), comp(FileCompression::None), comp_lz_ver(util::LzVersion::LZ10), dec_file_data(
nullptr), dec_file_offset(0), dec_file_size(0) {}
35 Result Open(std::shared_ptr<FileHandle> file_handle,
const std::string &path,
const OpenMode mode,
const FileCompression comp = FileCompression::None);
38 inline bool IsValid() {
39 return this->ok &&
static_cast<bool>(this->file_handle);
42 inline bool IsCompressed() {
43 return this->comp != FileCompression::None;
46 inline constexpr bool CanRead() {
47 return CanReadWithMode(this->mode);
50 inline constexpr bool CanWrite() {
51 return CanWriteWithMode(this->mode);
54 inline Result GetSize(
size_t &out_size) {
55 if(!this->IsValid()) {
56 NTR_R_FAIL(ResultInvalidFile);
59 if(this->IsCompressed()) {
60 out_size = this->dec_file_size;
64 return this->file_handle->GetSize(out_size);
70 Result SetAbsoluteOffset(
const size_t offset);
72 inline Result GetAbsoluteOffset(
size_t &out_offset) {
73 if(!this->IsValid()) {
74 NTR_R_FAIL(ResultInvalidFile);
77 if(this->IsCompressed()) {
78 out_offset = this->dec_file_offset;
82 return this->file_handle->GetOffset(out_offset);
87 if(!this->IsValid()) {
88 NTR_R_FAIL(ResultInvalidFile);
91 if(this->IsCompressed()) {
92 this->dec_file_offset = this->dec_file_size;
97 NTR_R_TRY(this->GetSize(f_size));
98 return this->file_handle->SetOffset(f_size, Position::Begin);
102 inline Result MoveOffset(
const size_t size) {
103 if(!this->IsValid()) {
104 NTR_R_FAIL(ResultInvalidFile);
107 if(this->IsCompressed()) {
108 if((this->dec_file_offset + size) > this->dec_file_buf_size) {
109 NTR_R_TRY(this->ReallocateDecompressedData(this->dec_file_offset + size));
111 this->dec_file_offset += size;
112 if(this->dec_file_offset > this->dec_file_size) {
113 this->dec_file_size = this->dec_file_offset;
118 return this->file_handle->SetOffset(size, Position::Current);
122 Result ReadData(
void *read_buf,
const size_t read_size,
size_t &out_read_size);
124 inline Result ReadDataExact(
void *read_buf,
const size_t read_size) {
125 size_t actual_read_size;
126 NTR_R_TRY(this->ReadData(read_buf, read_size, actual_read_size));
128 if(actual_read_size == read_size) {
132 NTR_R_FAIL(ResultUnexpectedReadSize);
137 inline Result Read(T &out_t) {
138 return this->ReadDataExact(std::addressof(out_t),
sizeof(out_t));
142 inline Result ReadLEB128(T &out_t) {
146 NTR_R_TRY(this->Read(v));
148 out_t = (out_t << 7) | (v & 0x7f);
158 inline Result ReadNullTerminatedString(std::basic_string<C> &out_str,
const size_t tmp_buf_size = 0x200) {
162 NTR_R_TRY(this->GetAbsoluteOffset(old_offset));
164 NTR_R_TRY(this->GetSize(f_size));
165 const auto available_size = f_size - old_offset;
166 if(available_size == 0) {
167 NTR_R_FAIL(ResultEndOfData);
169 const auto r_size = std::min(tmp_buf_size, available_size);
170 auto buf = util::NewArray<C>(r_size);
176 NTR_R_TRY(this->ReadData(buf, r_size, read_size));
178 for(
size_t i = 0; i < read_size; i++) {
179 if(buf[i] ==
static_cast<C
>(0)) {
180 NTR_R_TRY(this->SetAbsoluteOffset(old_offset + i + 1));
181 out_str = std::basic_string<C>(buf, i);
186 NTR_R_TRY(this->SetAbsoluteOffset(old_offset));
187 return ReadNullTerminatedString(out_str, tmp_buf_size * 2);
190 Result WriteData(
const void *write_buf,
const size_t write_size);
193 inline Result WriteString(
const std::basic_string<C> &str) {
194 return this->WriteData(str.c_str(), str.length() *
sizeof(C));
197 inline Result WriteCString(
const char *str) {
198 const auto str_len = std::strlen(str);
199 return this->WriteData(str, str_len);
203 inline Result Write(
const T t) {
204 return this->WriteData(std::addressof(t),
sizeof(t));
207 inline Result WriteEnsureAlignment(
const size_t align,
size_t &out_pad_size) {
209 NTR_R_TRY(this->GetAbsoluteOffset(cur_offset));
210 out_pad_size = util::AlignUp(cur_offset, align) - cur_offset;
212 for(
size_t i = 0; i < out_pad_size; i++) {
213 NTR_R_TRY(this->Write<u8>(0));
219 inline Result WriteVector(
const std::vector<T> &vec) {
220 return this->WriteData(vec.data(), vec.size() *
sizeof(T));
224 inline Result WriteNullTerminatedString(
const std::basic_string<C> &str) {
225 NTR_R_TRY(this->WriteString(str));
226 NTR_R_TRY(this->Write(
static_cast<C
>(0)));