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 ReadTerminatedString(std::basic_string<C> &out_str,
const C terminator,
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]();
102 TWL_R_TRY(this->ReadBuffer(buf, r_size));
104 for(
size_t i = 0; i < r_size; i++) {
105 if(buf[i] == terminator) {
106 TWL_R_TRY(this->SetAbsoluteOffset(old_offset + i + 1));
107 out_str = std::basic_string<C>(buf, i);
112 TWL_R_TRY(this->SetAbsoluteOffset(old_offset));
113 return ReadNullTerminatedString(out_str, tmp_buf_size * 2);
117 inline Result ReadNullTerminatedString(std::basic_string<C> &out_str,
const size_t tmp_buf_size = 0x200) {
118 return this->ReadTerminatedString(out_str,
static_cast<C
>(0), tmp_buf_size);
122 inline Result WriteString(
const std::basic_string<C> &str) {
123 return this->WriteBuffer(str.c_str(), str.length() *
sizeof(C));
126 inline Result WriteCString(
const char *str) {
127 const auto str_len = std::strlen(str);
128 return this->WriteBuffer(str, str_len);
131 inline Result WriteEnsureAlignmentPadding(
const size_t align,
size_t &out_pad_size) {
137 TWL_R_TRY(this->GetOffset(cur_offset));
138 out_pad_size = util::AlignUp(cur_offset, align) - cur_offset;
140 auto zero_buf =
new u8[out_pad_size]();
145 TWL_R_TRY(this->WriteBuffer(zero_buf, out_pad_size));
150 inline Result WriteEnsureAlignment(
const size_t align) {
152 TWL_R_TRY(this->WriteEnsureAlignmentPadding(align, dummy_size));
157 inline Result WriteVector(
const std::vector<T> &vec) {
158 return this->WriteBuffer(vec.data(), vec.size() *
sizeof(T));
162 inline Result WriteNullTerminatedString(
const std::basic_string<C> &str) {
163 TWL_R_TRY(this->WriteString(str));
164 TWL_R_TRY(this->Write(
static_cast<C
>(0)));
177 constexpr BufferReaderWriter() : buf(
nullptr), buf_size(0), offset(0) {}
179 inline BufferReaderWriter(
const size_t buf_size) : buf(
nullptr), buf_size(0), offset(0) {
180 this->CreateAllocate(buf_size);
183 inline BufferReaderWriter(
void *buf,
const size_t buf_size,
const bool transfer_ownership =
true) : buf(
nullptr), buf_size(0), offset(0) {
184 this->CreateFrom(buf, buf_size, transfer_ownership);
187 BufferReaderWriter(
const BufferReaderWriter&) =
delete;
188 BufferReaderWriter(BufferReaderWriter&&) =
default;
190 void CreateAllocate(
const size_t buf_size);
191 void CreateFrom(
void *buf,
const size_t buf_size,
const bool transfer_ownership =
true);
193 inline void Dispose() {
194 if(this->buf !=
nullptr) {
195 auto del_buf =
reinterpret_cast<u8*
>(this->buf);
204 inline bool IsValid() {
205 return (this->buf !=
nullptr) && (this->buf_size > 0);
208 inline void *GetBuffer() {
212 inline size_t GetBufferSize() {
213 return this->buf_size;
216 Result SetOffset(
const ssize_t offset,
const Whence whence)
override;
218 inline size_t GetBufferOffset() {
222 inline Result GetOffset(
size_t &out_offset)
override {
223 out_offset = this->GetBufferOffset();
227 inline Result GetSize(
size_t &out_size)
override {
228 out_size = this->GetBufferSize();
232 Result ReadBuffer(
void *read_buf,
const size_t read_size)
override;
233 Result WriteBuffer(
const void *write_buf,
const size_t write_size)
override;
242 FileCompression comp;
243 util::LzVersion lz_ver;
249 Result Open(
const FileMode mode,
const FileCompression comp);
252 constexpr File() : mode(FileMode::Invalid), opened(
false), comp(FileCompression::Invalid), lz_ver(util::LzVersion::Invalid), decomp_rw() {}
254 File(
const File&) =
delete;
255 File(File&&) =
default;
257 inline bool IsOpened() {
261 inline constexpr bool IsCompressed() {
262 return (this->comp != FileCompression::Invalid) && (this->comp != FileCompression::None);
265 virtual Result OpenImpl(
const FileMode mode) = 0;
266 virtual Result GetSizeImpl(
size_t &out_size) = 0;
267 virtual Result SetOffsetImpl(
const size_t offset,
const Whence whence) = 0;
268 virtual Result GetOffsetImpl(
size_t &out_offset) = 0;
269 virtual Result ReadBufferImpl(
void *read_buf,
const size_t read_size) = 0;
270 virtual Result WriteBufferImpl(
const void *write_buf,
const size_t write_size) = 0;
271 virtual Result CloseImpl() = 0;
273 inline Result OpenRead(
const FileCompression comp = FileCompression::Auto) {
274 TWL_R_TRY(this->Open(fs::FileMode::Read, comp));
278 inline Result OpenWrite(
const FileCompression comp = FileCompression::None) {
279 TWL_R_TRY(this->Open(fs::FileMode::Write, comp));
283 inline Result GetSize(
size_t &out_size)
override {
284 if(this->IsCompressed()) {
285 out_size = this->decomp_rw.GetBufferSize();
288 TWL_R_TRY(this->GetSizeImpl(out_size));
294 Result SetOffset(
const ssize_t offset,
const Whence whence)
override;
295 Result GetOffset(
size_t &out_offset)
override;
296 Result ReadBuffer(
void *read_buf,
const size_t read_size)
override;
297 Result WriteBuffer(
const void *write_buf,
const size_t write_size)
override;
326 class BufferFile :
public File {
331 constexpr BufferFile() : File(), rw() {}
332 inline BufferFile(
size_t buf_size) : File(), rw(buf_size) {}
333 inline BufferFile(
void *buf,
size_t buf_size,
const bool transfer_ownership =
true) : File(), rw(buf, buf_size, transfer_ownership) {}
335 BufferFile(
const BufferFile&) =
delete;
336 BufferFile(BufferFile&&) =
default;
338 inline void CreateAllocate(
size_t buf_size) {
340 this->rw.CreateAllocate(buf_size);
343 inline void CreateFrom(
void *buf,
size_t buf_size,
const bool transfer_ownership =
true) {
345 this->rw.CreateFrom(buf, buf_size, transfer_ownership);
348 inline void Dispose() {
353 inline bool IsValid() {
354 return this->rw.IsValid();
357 inline void *GetBuffer() {
358 return this->rw.GetBuffer();
361 inline size_t GetBufferSize() {
362 return this->rw.GetBufferSize();
365 Result OpenImpl(
const FileMode mode)
override;
367 inline Result GetSizeImpl(
size_t &out_size)
override {
368 out_size = this->rw.GetBufferSize();
372 Result SetOffsetImpl(
const size_t offset,
const Whence whence)
override;
374 inline Result GetOffsetImpl(
size_t &out_offset)
override {
375 out_offset = this->rw.GetBufferOffset();
379 Result ReadBufferImpl(
void *read_buf,
const size_t read_size)
override;
380 Result WriteBufferImpl(
const void *write_buf,
const size_t write_size)
override;
381 Result CloseImpl()
override;