aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-06-23 15:20:37 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-06-23 16:32:48 +0200
commita70635d2f67f29b8d080282f99d2101bca55835f (patch)
treec1103852a474888875111d914e9e329fb3912f09
parent5cb16c4cd1342fed7c4af0715d15d9a724fd36fb (diff)
Most reads now go through buffer for zlib.
-rw-r--r--core/compress/common.odin77
-rw-r--r--core/compress/zlib/zlib.odin4
2 files changed, 66 insertions, 15 deletions
diff --git a/core/compress/common.odin b/core/compress/common.odin
index adea414ea..a4cba2e87 100644
--- a/core/compress/common.odin
+++ b/core/compress/common.odin
@@ -10,6 +10,7 @@ package compress
import "core:io"
import "core:image"
+// import "core:fmt"
// when #config(TRACY_ENABLE, false) { import tracy "shared:odin-tracy" }
@@ -75,12 +76,12 @@ Deflate_Error :: enum {
// General I/O context for ZLIB, LZW, etc.
Context :: struct #packed {
- input: io.Stream,
- input_data: []u8,
+ input: io.Stream,
+ input_data: []u8,
- output: io.Stream,
- output_buf: [dynamic]u8,
- bytes_written: i64,
+ output: io.Stream,
+ output_buf: [dynamic]u8,
+ bytes_written: i64,
/*
If we know the data size, we can optimize the reads and writes.
@@ -93,9 +94,17 @@ Context :: struct #packed {
*/
rolling_hash: u32,
/*
- Could put some useful bools in here.
+ Reserved
*/
- padding: [3]u32,
+ reserved: [2]u32,
+ /*
+ Flags:
+ `input_fully_in_memory` tells us whether we're EOF when `input_data` is empty.
+ `input_refills_from_stream` tells us we can then possibly refill from the stream.
+ */
+ input_fully_in_memory: b8,
+ input_refills_from_stream: b8,
+ reserved_flags: [2]b8,
}
#assert(size_of(Context) == 128);
@@ -123,11 +132,28 @@ Code_Buffer :: struct #packed {
This simplifies end-of-stream handling where bits may be left in the bit buffer.
*/
-read_slice :: #force_inline proc(c: ^Context, size: int) -> (res: []u8, err: io.Error) {
+read_slice :: #force_inline proc(z: ^Context, size: int) -> (res: []u8, err: io.Error) {
when #config(TRACY_ENABLE, false) { tracy.ZoneN("Read Slice"); }
+ if len(z.input_data) >= size {
+ res = z.input_data[:size];
+ z.input_data = z.input_data[size:];
+ return res, .None;
+ }
+
+ if z.input_fully_in_memory {
+ if len(z.input_data) == 0 {
+ return []u8{}, .EOF;
+ } else {
+ return []u8{}, .Short_Buffer;
+ }
+ }
+ // fmt.printf("read_slice of %v bytes fell back to stream.\n", size);
+ /*
+ TODO: Try to refill z.input_data from stream, using packed_data as a guide.
+ */
b := make([]u8, size, context.temp_allocator);
- _, e := c.input->impl_read(b[:]);
+ _, e := z.input->impl_read(b[:]);
if e == .None {
return b, .None;
}
@@ -157,24 +183,45 @@ read_u8 :: #force_inline proc(z: ^Context) -> (res: u8, err: io.Error) {
return 0, e;
}
-peek_data :: #force_inline proc(c: ^Context, $T: typeid) -> (res: T, err: io.Error) {
+peek_data :: #force_inline proc(z: ^Context, $T: typeid) -> (res: T, err: io.Error) {
when #config(TRACY_ENABLE, false) { tracy.ZoneN("Peek Data"); }
+
+ size :: size_of(T);
+
+ if len(z.input_data) >= size {
+ buf := z.input_data[:size];
+ z.input_data = z.input_data[size:];
+ return (^T)(&buf[0])^, .None;
+ }
+
+ if z.input_fully_in_memory {
+ if len(z.input_data) < size {
+ return T{}, .EOF;
+ } else {
+ return T{}, .Short_Buffer;
+ }
+ }
+
// Get current position to read from.
- curr, e1 := c.input->impl_seek(0, .Current);
+ curr, e1 := z.input->impl_seek(0, .Current);
if e1 != .None {
return T{}, e1;
}
- r, e2 := io.to_reader_at(c.input);
+ r, e2 := io.to_reader_at(z.input);
if !e2 {
return T{}, .Empty;
}
- b := make([]u8, size_of(T), context.temp_allocator);
- _, e3 := io.read_at(r, b, curr);
+ when size <= 128 {
+ b: [size]u8;
+ } else {
+ b := make([]u8, size, context.temp_allocator);
+ }
+ _, e3 := io.read_at(r, b[:], curr);
if e3 != .None {
return T{}, .Empty;
}
- res = (^T)(raw_data(b))^;
+ res = (^T)(&b[0])^;
return res, .None;
}
diff --git a/core/compress/zlib/zlib.odin b/core/compress/zlib/zlib.odin
index e6bde8535..a57d202d5 100644
--- a/core/compress/zlib/zlib.odin
+++ b/core/compress/zlib/zlib.odin
@@ -645,6 +645,8 @@ inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false) -
bytes.reader_init(&r, input);
rs := bytes.reader_to_stream(&r);
ctx.input = rs;
+ ctx.input_data = input;
+ ctx.input_fully_in_memory = true;
buf := buf;
ws := bytes.buffer_to_stream(buf);
@@ -662,6 +664,8 @@ inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, cb: ^Code_B
bytes.reader_init(&r, input);
rs := bytes.reader_to_stream(&r);
ctx.input = rs;
+ ctx.input_data = input;
+ ctx.input_fully_in_memory = true;
buf := buf;
ws := bytes.buffer_to_stream(buf);