39 virtual Result ReadBuffer(
void *read_buf,
const size_t read_size) = 0;
40 virtual Result WriteBuffer(
const void *write_buf,
const size_t write_size) = 0;
41 virtual Result SetOffset(
const ssize_t offset,
const Whence whence) = 0;
42 virtual Result GetOffset(
size_t &out_offset) = 0;
43 virtual Result GetSize(
size_t &out_size) = 0;
45 inline Result SetAbsoluteOffset(
const size_t offset) {
46 TWL_R_TRY(this->SetOffset(offset, Whence::Begin));
50 inline Result MoveOffset(
const ssize_t offset) {
51 TWL_R_TRY(this->SetOffset(offset, Whence::Current));
56 inline Result Read(T &out_t) {
57 TWL_R_TRY(this->ReadBuffer(std::addressof(out_t),
sizeof(T)));
62 inline Result Write(
const T &t) {
63 TWL_R_TRY(this->WriteBuffer(std::addressof(t),
sizeof(T)));
68 inline Result ReadLEB128(T &out_t) {
72 TWL_R_TRY(this->Read(v));
74 out_t = (out_t << 7) | (v & 0x7F);
84 inline Result ReadNullTerminatedString(std::basic_string<C> &out_str,
const size_t tmp_buf_size = 0x200) {
89 TWL_R_TRY(this->GetOffset(old_offset));
91 TWL_R_TRY(this->GetSize(f_size));
92 const auto available_size = f_size - old_offset;
93 if(available_size == 0) {
94 TWL_R_FAIL(ResultEndOfData);
96 const auto r_size = std::min(tmp_buf_size, available_size);
97 auto buf =
new C[r_size]();
103 TWL_R_TRY(this->ReadBuffer(buf, r_size));
105 for(
size_t i = 0; i < r_size; i++) {
106 if(buf[i] ==
static_cast<C
>(0)) {
107 TWL_R_TRY(this->SetAbsoluteOffset(old_offset + i + 1));
108 out_str = std::basic_string<C>(buf, i);
113 TWL_R_TRY(this->SetAbsoluteOffset(old_offset));
114 return ReadNullTerminatedString(out_str, tmp_buf_size * 2);
118 inline Result WriteString(
const std::basic_string<C> &str) {
119 return this->WriteBuffer(str.c_str(), str.length() *
sizeof(C));
122 inline Result WriteCString(
const char *str) {
123 const auto str_len = std::strlen(str);
124 return this->WriteBuffer(str, str_len);
127 inline Result WriteEnsureAlignmentPadding(
const size_t align,
size_t &out_pad_size) {
133 TWL_R_TRY(this->GetOffset(cur_offset));
134 out_pad_size = util::AlignUp(cur_offset, align) - cur_offset;
136 auto zero_buf =
new u8[out_pad_size]();
141 TWL_R_TRY(this->WriteBuffer(zero_buf, out_pad_size));
146 inline Result WriteEnsureAlignment(
const size_t align) {
148 TWL_R_TRY(this->WriteEnsureAlignmentPadding(align, dummy_size));
153 inline Result WriteVector(
const std::vector<T> &vec) {
154 return this->WriteBuffer(vec.data(), vec.size() *
sizeof(T));
158 inline Result WriteNullTerminatedString(
const std::basic_string<C> &str) {
159 TWL_R_TRY(this->WriteString(str));
160 TWL_R_TRY(this->Write(
static_cast<C
>(0)));
173 constexpr BufferReaderWriter() : buf(
nullptr), buf_size(0), offset(0) {}
175 inline BufferReaderWriter(
const size_t buf_size) : buf(
nullptr), buf_size(0), offset(0) {
176 this->CreateAllocate(buf_size);
179 inline BufferReaderWriter(
void *buf,
const size_t buf_size,
const bool transfer_ownership =
true) : buf(
nullptr), buf_size(0), offset(0) {
180 this->CreateFrom(buf, buf_size, transfer_ownership);
183 BufferReaderWriter(
const BufferReaderWriter&) =
delete;
184 BufferReaderWriter(BufferReaderWriter&&) =
default;
186 void CreateAllocate(
const size_t buf_size);
187 void CreateFrom(
void *buf,
const size_t buf_size,
const bool transfer_ownership =
true);
189 inline void Dispose() {
190 if(this->buf !=
nullptr) {
191 auto del_buf =
reinterpret_cast<u8*
>(this->buf);
200 inline bool IsValid() {
201 return (this->buf !=
nullptr) && (this->buf_size > 0);
204 inline void *GetBuffer() {
208 inline size_t GetBufferSize() {
209 return this->buf_size;
212 Result SetOffset(
const ssize_t offset,
const Whence whence)
override;
214 inline size_t GetBufferOffset() {
218 inline Result GetOffset(
size_t &out_offset)
override {
219 out_offset = this->GetBufferOffset();
223 inline Result GetSize(
size_t &out_size)
override {
224 out_size = this->GetBufferSize();
228 Result ReadBuffer(
void *read_buf,
const size_t read_size)
override;
229 Result WriteBuffer(
const void *write_buf,
const size_t write_size)
override;
238 FileCompression comp;
239 util::LzVersion lz_ver;
245 Result Open(
const FileMode mode,
const FileCompression w_comp = FileCompression::Invalid);
248 constexpr File() : mode(FileMode::Invalid), opened(
false), comp(FileCompression::Invalid), lz_ver(util::LzVersion::Invalid), decomp_rw() {}
250 File(
const File&) =
delete;
251 File(File&&) =
default;
253 inline bool IsOpened() {
257 inline constexpr bool IsCompressed() {
258 return (this->comp != FileCompression::Invalid) && (this->comp != FileCompression::None);
261 virtual Result OpenImpl(
const FileMode mode) = 0;
262 virtual Result GetSizeImpl(
size_t &out_size) = 0;
263 virtual Result SetOffsetImpl(
const size_t offset,
const Whence whence) = 0;
264 virtual Result GetOffsetImpl(
size_t &out_offset) = 0;
265 virtual Result ReadBufferImpl(
void *read_buf,
const size_t read_size) = 0;
266 virtual Result WriteBufferImpl(
const void *write_buf,
const size_t write_size) = 0;
267 virtual Result CloseImpl() = 0;
269 inline Result OpenRead() {
270 TWL_R_TRY(this->Open(fs::FileMode::Read));
274 inline Result OpenWrite(
const FileCompression comp = FileCompression::None) {
275 TWL_R_TRY(this->Open(fs::FileMode::Write, comp));
279 inline Result OpenUpdate() {
280 TWL_R_TRY(this->Open(fs::FileMode::Update));
284 inline Result GetSize(
size_t &out_size)
override {
285 if(this->IsCompressed()) {
286 out_size = this->decomp_rw.GetBufferSize();
289 TWL_R_TRY(this->GetSizeImpl(out_size));
295 Result SetOffset(
const ssize_t offset,
const Whence whence)
override;
296 Result GetOffset(
size_t &out_offset)
override;
297 Result ReadBuffer(
void *read_buf,
const size_t read_size)
override;
298 Result WriteBuffer(
const void *write_buf,
const size_t write_size)
override;
327 class BufferFile :
public File {
332 constexpr BufferFile() : File(), rw() {}
333 inline BufferFile(
size_t buf_size) : File(), rw(buf_size) {}
334 inline BufferFile(
void *buf,
size_t buf_size,
const bool transfer_ownership =
true) : File(), rw(buf, buf_size, transfer_ownership) {}
336 BufferFile(
const BufferFile&) =
delete;
337 BufferFile(BufferFile&&) =
default;
339 inline void CreateAllocate(
size_t buf_size) {
341 this->rw.CreateAllocate(buf_size);
344 inline void CreateFrom(
void *buf,
size_t buf_size,
const bool transfer_ownership =
true) {
346 this->rw.CreateFrom(buf, buf_size, transfer_ownership);
349 inline void Dispose() {
354 inline bool IsValid() {
355 return this->rw.IsValid();
358 inline void *GetBuffer() {
359 return this->rw.GetBuffer();
362 inline size_t GetBufferSize() {
363 return this->rw.GetBufferSize();
366 Result OpenImpl(
const FileMode mode)
override;
368 inline Result GetSizeImpl(
size_t &out_size)
override {
369 out_size = this->rw.GetBufferSize();
373 Result SetOffsetImpl(
const size_t offset,
const Whence whence)
override;
375 inline Result GetOffsetImpl(
size_t &out_offset)
override {
376 out_offset = this->rw.GetBufferOffset();
380 Result ReadBufferImpl(
void *read_buf,
const size_t read_size)
override;
381 Result WriteBufferImpl(
const void *write_buf,
const size_t write_size)
override;
382 Result CloseImpl()
override;