mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-01 20:28:15 +00:00
Most reads now go through buffer for zlib.
This commit is contained in:
+62
-15
@@ -10,6 +10,7 @@ package compress
|
|||||||
|
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:image"
|
import "core:image"
|
||||||
|
// import "core:fmt"
|
||||||
|
|
||||||
// when #config(TRACY_ENABLE, false) { import tracy "shared:odin-tracy" }
|
// 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.
|
// General I/O context for ZLIB, LZW, etc.
|
||||||
Context :: struct #packed {
|
Context :: struct #packed {
|
||||||
input: io.Stream,
|
input: io.Stream,
|
||||||
input_data: []u8,
|
input_data: []u8,
|
||||||
|
|
||||||
output: io.Stream,
|
output: io.Stream,
|
||||||
output_buf: [dynamic]u8,
|
output_buf: [dynamic]u8,
|
||||||
bytes_written: i64,
|
bytes_written: i64,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we know the data size, we can optimize the reads and writes.
|
If we know the data size, we can optimize the reads and writes.
|
||||||
@@ -93,9 +94,17 @@ Context :: struct #packed {
|
|||||||
*/
|
*/
|
||||||
rolling_hash: u32,
|
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);
|
#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.
|
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"); }
|
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);
|
b := make([]u8, size, context.temp_allocator);
|
||||||
_, e := c.input->impl_read(b[:]);
|
_, e := z.input->impl_read(b[:]);
|
||||||
if e == .None {
|
if e == .None {
|
||||||
return b, .None;
|
return b, .None;
|
||||||
}
|
}
|
||||||
@@ -157,24 +183,45 @@ read_u8 :: #force_inline proc(z: ^Context) -> (res: u8, err: io.Error) {
|
|||||||
return 0, e;
|
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"); }
|
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.
|
// 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 {
|
if e1 != .None {
|
||||||
return T{}, e1;
|
return T{}, e1;
|
||||||
}
|
}
|
||||||
r, e2 := io.to_reader_at(c.input);
|
r, e2 := io.to_reader_at(z.input);
|
||||||
if !e2 {
|
if !e2 {
|
||||||
return T{}, .Empty;
|
return T{}, .Empty;
|
||||||
}
|
}
|
||||||
b := make([]u8, size_of(T), context.temp_allocator);
|
when size <= 128 {
|
||||||
_, e3 := io.read_at(r, b, curr);
|
b: [size]u8;
|
||||||
|
} else {
|
||||||
|
b := make([]u8, size, context.temp_allocator);
|
||||||
|
}
|
||||||
|
_, e3 := io.read_at(r, b[:], curr);
|
||||||
if e3 != .None {
|
if e3 != .None {
|
||||||
return T{}, .Empty;
|
return T{}, .Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = (^T)(raw_data(b))^;
|
res = (^T)(&b[0])^;
|
||||||
return res, .None;
|
return res, .None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -645,6 +645,8 @@ inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false) -
|
|||||||
bytes.reader_init(&r, input);
|
bytes.reader_init(&r, input);
|
||||||
rs := bytes.reader_to_stream(&r);
|
rs := bytes.reader_to_stream(&r);
|
||||||
ctx.input = rs;
|
ctx.input = rs;
|
||||||
|
ctx.input_data = input;
|
||||||
|
ctx.input_fully_in_memory = true;
|
||||||
|
|
||||||
buf := buf;
|
buf := buf;
|
||||||
ws := bytes.buffer_to_stream(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);
|
bytes.reader_init(&r, input);
|
||||||
rs := bytes.reader_to_stream(&r);
|
rs := bytes.reader_to_stream(&r);
|
||||||
ctx.input = rs;
|
ctx.input = rs;
|
||||||
|
ctx.input_data = input;
|
||||||
|
ctx.input_fully_in_memory = true;
|
||||||
|
|
||||||
buf := buf;
|
buf := buf;
|
||||||
ws := bytes.buffer_to_stream(buf);
|
ws := bytes.buffer_to_stream(buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user