diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index f94ce70b7..04b0bfdc2 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -177,12 +177,10 @@ decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocato max_output_size := decompress_bound(len(input), model) buf: [dynamic]u8 - if !resize(&buf, max_output_size) { - return "", .Out_Of_Memory - } + resize(&buf, max_output_size) or_return length, result := decompress_slice_to_output_buffer(input, buf[:]) - resize(&buf, length) + resize(&buf, length) or_return return string(buf[:]), result } decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string} @@ -307,12 +305,10 @@ compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := cont max_output_size := compress_bound(len(input)) buf: [dynamic]u8 - if !resize(&buf, max_output_size) { - return {}, .Out_Of_Memory - } + resize(&buf, max_output_size) or_return length, result := compress_string_to_buffer(input, buf[:]) - resize(&buf, length) + resize(&buf, length) or_return return buf[:length], result } compress :: proc{compress_string_to_buffer, compress_string} \ No newline at end of file diff --git a/core/image/common.odin b/core/image/common.odin index 58ff83dd1..ad01f7e6b 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -634,7 +634,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator := buf := bytes.Buffer{} // Can we allocate the return buffer? - if !resize(&buf.buf, bytes_wanted) { + if resize(&buf.buf, bytes_wanted) != nil { delete(buf.buf) return false } @@ -826,7 +826,7 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al buf := bytes.Buffer{} // Can we allocate the return buffer? - if !resize(&buf.buf, bytes_wanted) { + if resize(&buf.buf, bytes_wanted) != nil { delete(buf.buf) return false } @@ -1075,7 +1075,7 @@ apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := con // Can we allocate the return buffer? buf := bytes.Buffer{} bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8) - if !resize(&buf.buf, bytes_wanted) { + if resize(&buf.buf, bytes_wanted) != nil { delete(buf.buf) return false } @@ -1112,7 +1112,7 @@ apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := c // Can we allocate the return buffer? buf := bytes.Buffer{} bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8) - if !resize(&buf.buf, bytes_wanted) { + if resize(&buf.buf, bytes_wanted) != nil { delete(buf.buf) return false } @@ -1147,7 +1147,7 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo // Can we allocate the return buffer? buf := bytes.Buffer{} bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth) - if !resize(&buf.buf, bytes_wanted) { + if resize(&buf.buf, bytes_wanted) != nil { delete(buf.buf) return false } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 91adddafc..caa1e6e8a 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -731,7 +731,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a // We need to create a new image buffer dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8) t := bytes.Buffer{} - if !resize(&t.buf, dest_raw_size) { + if resize(&t.buf, dest_raw_size) != nil { return {}, .Unable_To_Allocate_Or_Resize } @@ -812,7 +812,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a // We need to create a new image buffer dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16) t := bytes.Buffer{} - if !resize(&t.buf, dest_raw_size) { + if resize(&t.buf, dest_raw_size) != nil { return {}, .Unable_To_Allocate_Or_Resize } @@ -1011,7 +1011,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a // We need to create a new image buffer dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8) t := bytes.Buffer{} - if !resize(&t.buf, dest_raw_size) { + if resize(&t.buf, dest_raw_size) != nil { return {}, .Unable_To_Allocate_Or_Resize } @@ -1522,7 +1522,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH bytes_per_channel := depth == 16 ? 2 : 1 num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8) - if !resize(&img.pixels.buf, num_bytes) { + if resize(&img.pixels.buf, num_bytes) != nil { return .Unable_To_Allocate_Or_Resize } @@ -1564,7 +1564,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH if x > 0 && y > 0 { temp: bytes.Buffer temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8) - if !resize(&temp.buf, temp_len) { + if resize(&temp.buf, temp_len) != nil { return .Unable_To_Allocate_Or_Resize } diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 27903c00f..c764178dc 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -53,7 +53,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} // Calculate and allocate maximum size. We'll reclaim space to actually written output at the end. max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be) - if !resize(&output.buf, max_size) { + if resize(&output.buf, max_size) != nil { return .Unable_To_Allocate_Or_Resize } @@ -233,7 +233,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) - if !resize(&img.pixels.buf, bytes_needed) { + if resize(&img.pixels.buf, bytes_needed) != nil { return img, .Unable_To_Allocate_Or_Resize } diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 9fc616804..03ef1a386 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -57,7 +57,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} // Calculate and allocate necessary space. necessary := pixels * img.channels + size_of(image.TGA_Header) - if !resize(&output.buf, necessary) { + if resize(&output.buf, necessary) != nil { return .Unable_To_Allocate_Or_Resize } @@ -292,7 +292,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, nil } - if !resize(&img.pixels.buf, dest_channels * img.width * img.height) { + if resize(&img.pixels.buf, dest_channels * img.width * img.height) != nil { return img, .Unable_To_Allocate_Or_Resize } diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 82b28ae6d..f578a641e 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -289,10 +289,9 @@ reserve_map :: proc(m: ^$T/map[$K]$V, capacity: int, loc := #caller_location) -> Shrinks the capacity of a map down to the current length. */ @builtin -shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool) { +shrink_map :: proc(m: ^$T/map[$K]$V, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) { if m != nil { - err := map_shrink_dynamic((^Raw_Map)(m), map_info(T), loc) - did_shrink = err == nil + return map_shrink_dynamic((^Raw_Map)(m), map_info(T), loc) } return } @@ -315,18 +314,18 @@ delete_key :: proc(m: ^$T/map[$K]$V, key: K) -> (deleted_key: K, deleted_value: @builtin -append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> int { +append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { - return 0 + return 0, nil } when size_of(E) == 0 { array := (^Raw_Dynamic_Array)(array) array.len += 1 - return 1 + return 1, nil } else { if cap(array) < len(array)+1 { cap := 2 * cap(array) + max(8, 1) - _ = reserve(array, cap, loc) + err = reserve(array, cap, loc) // do not 'or_return' here as it could be a partial success } if cap(array)-len(array) > 0 { a := (^Raw_Dynamic_Array)(array) @@ -336,31 +335,31 @@ append_elem :: proc(array: ^$T/[dynamic]$E, arg: E, loc := #caller_location) -> data[a.len] = arg } a.len += 1 - return 1 + return 1, err } - return 0 + return 0, err } } @builtin -append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> int { +append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { - return 0 + return 0, nil } arg_len := len(args) if arg_len <= 0 { - return 0 + return 0, nil } when size_of(E) == 0 { array := (^Raw_Dynamic_Array)(array) array.len += arg_len - return arg_len + return arg_len, nil } else { if cap(array) < len(array)+arg_len { cap := 2 * cap(array) + max(8, arg_len) - _ = reserve(array, cap, loc) + err = reserve(array, cap, loc) // do not 'or_return' here as it could be a partial success } arg_len = min(cap(array)-len(array), arg_len) if arg_len > 0 { @@ -372,13 +371,13 @@ append_elems :: proc(array: ^$T/[dynamic]$E, args: ..E, loc := #caller_location) } a.len += arg_len } - return arg_len + return arg_len, err } } // The append_string built-in procedure appends a string to the end of a [dynamic]u8 like type @builtin -append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> int { +append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { args := transmute([]E)arg return append_elems(array=array, args=args, loc=loc) } @@ -386,9 +385,14 @@ append_elem_string :: proc(array: ^$T/[dynamic]$E/u8, arg: $A/string, loc := #ca // The append_string built-in procedure appends multiple strings to the end of a [dynamic]u8 like type @builtin -append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int) { +append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + n_arg: int for arg in args { - n += append(array = array, args = transmute([]E)(arg), loc = loc) + n_arg, err = append(array = array, args = transmute([]E)(arg), loc = loc) + n += n_arg + if err != nil { + return + } } return } @@ -398,18 +402,18 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ @builtin -append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> int { +append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { - return 0 + return 0, nil } prev_len := len(array) - resize(array, len(array)+1, loc) - return len(array)-prev_len + resize(array, len(array)+1, loc) or_return + return len(array)-prev_len, nil } @builtin -inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool) #no_bounds_check { +inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if array == nil { return } @@ -417,18 +421,17 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle m :: 1 new_size := n + m - if resize(array, new_size, loc) { - when size_of(E) != 0 { - copy(array[index + m:], array[index:]) - array[index] = arg - } - ok = true + resize(array, new_size, loc) or_return + when size_of(E) != 0 { + copy(array[index + m:], array[index:]) + array[index] = arg } + ok = true return } @builtin -inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool) #no_bounds_check { +inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if array == nil { return } @@ -441,18 +444,17 @@ inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #c m := len(args) new_size := n + m - if resize(array, new_size, loc) { - when size_of(E) != 0 { - copy(array[index + m:], array[index:]) - copy(array[index:], args) - } - ok = true + resize(array, new_size, loc) or_return + when size_of(E) != 0 { + copy(array[index + m:], array[index:]) + copy(array[index:], args) } + ok = true return } @builtin -inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool) #no_bounds_check { +inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if array == nil { return } @@ -465,11 +467,10 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string m := len(arg) new_size := n + m - if resize(array, new_size, loc) { - copy(array[index+m:], array[index:]) - copy(array[index:], arg) - ok = true - } + resize(array, new_size, loc) or_return + copy(array[index+m:], array[index:]) + copy(array[index:], arg) + ok = true return } @@ -478,11 +479,12 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string @builtin -assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool) #no_bounds_check { +assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if index < len(array) { array[index] = arg ok = true - } else if resize(array, index+1, loc) { + } else { + resize(array, index+1, loc) or_return array[index] = arg ok = true } @@ -491,11 +493,12 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle @builtin -assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool) #no_bounds_check { +assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if index+len(args) < len(array) { copy(array[index:], args) ok = true - } else if resize(array, index+1+len(args), loc) { + } else { + resize(array, index+1+len(args), loc) or_return copy(array[index:], args) ok = true } @@ -504,13 +507,14 @@ assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #c @builtin -assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool) #no_bounds_check { +assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { if len(args) == 0 { ok = true } else if index+len(args) < len(array) { copy(array[index:], args) ok = true - } else if resize(array, index+1+len(args), loc) { + } else { + resize(array, index+1+len(args), loc) or_return copy(array[index:], args) ok = true } @@ -530,14 +534,14 @@ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) { } @builtin -reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> bool { +reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { if array == nil { - return false + return nil } a := (^Raw_Dynamic_Array)(array) if capacity <= a.cap { - return true + return nil } if a.allocator.procedure == nil { @@ -549,26 +553,26 @@ reserve_dynamic_array :: proc(array: ^$T/[dynamic]$E, capacity: int, loc := #cal new_size := capacity * size_of(E) allocator := a.allocator - new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) - if new_data == nil || err != nil { - return false + new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + if new_data == nil && new_size > 0 { + return .Out_Of_Memory } a.data = raw_data(new_data) a.cap = capacity - return true + return nil } @builtin -resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> bool { +resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { if array == nil { - return false + return nil } a := (^Raw_Dynamic_Array)(array) if length <= a.cap { a.len = max(length, 0) - return true + return nil } if a.allocator.procedure == nil { @@ -580,15 +584,15 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller new_size := length * size_of(E) allocator := a.allocator - new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) - if new_data == nil || err != nil { - return false + new_data := mem_resize(a.data, old_size, new_size, align_of(E), allocator, loc) or_return + if new_data == nil && new_size > 0 { + return .Out_Of_Memory } a.data = raw_data(new_data) a.len = length a.cap = length - return true + return nil } /* @@ -600,7 +604,7 @@ resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, length: int, loc := #caller If `len(array) < new_cap`, then `len(array)` will be left unchanged. */ -shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #caller_location) -> (did_shrink: bool) { +shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) { if array == nil { return } @@ -620,15 +624,12 @@ shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #call old_size := a.cap * size_of(E) new_size := new_cap * size_of(E) - new_data, err := mem_resize(a.data, old_size, new_size, align_of(E), a.allocator, loc) - if err != nil { - return - } + new_data := mem_resize(a.data, old_size, new_size, align_of(E), a.allocator, loc) or_return a.data = raw_data(new_data) a.len = min(new_cap, a.len) a.cap = new_cap - return true + return true, nil } @builtin