mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-13 13:53:43 +00:00
Change strings.Builder to be distinct [dynamic]byte from a struct wrapper
This commit is contained in:
@@ -207,7 +207,7 @@ encode :: encode_into
|
||||
encode_into_bytes :: proc(v: Value, flags := ENCODE_SMALL, allocator := context.allocator, temp_allocator := context.temp_allocator, loc := #caller_location) -> (data: []byte, err: Encode_Error) {
|
||||
b := strings.builder_make(allocator, loc) or_return
|
||||
encode_into_builder(&b, v, flags, temp_allocator) or_return
|
||||
return b.buf[:], nil
|
||||
return b[:], nil
|
||||
}
|
||||
|
||||
// Encodes the CBOR value into binary CBOR written to the given builder.
|
||||
@@ -396,7 +396,7 @@ _decode_bytes :: proc(d: Decoder, add: Add, type: Major = .Bytes, allocator := c
|
||||
if iter_n == -1 {
|
||||
return nil, .Nested_Indefinite_Length
|
||||
}
|
||||
reserve(&buf.buf, len(buf.buf) + iter_cap) or_return
|
||||
reserve(&buf, len(buf) + iter_cap) or_return
|
||||
io.copy_n(buf_stream, d.reader, i64(iter_n)) or_return
|
||||
|
||||
case .Other:
|
||||
@@ -411,12 +411,12 @@ _decode_bytes :: proc(d: Decoder, add: Add, type: Major = .Bytes, allocator := c
|
||||
io.copy_n(buf_stream, d.reader, i64(n)) or_return
|
||||
}
|
||||
|
||||
v = buf.buf[:]
|
||||
v = buf[:]
|
||||
|
||||
// Write zero byte so this can be converted to cstring.
|
||||
strings.write_byte(&buf, 0)
|
||||
|
||||
if .Shrink_Excess in d.flags { shrink(&buf.buf) }
|
||||
if .Shrink_Excess in d.flags { shrink(&buf) }
|
||||
return
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ _encode_map :: proc(e: Encoder, m: Map) -> (err: Encode_Error) {
|
||||
ke.writer = strings.to_stream(&buf)
|
||||
|
||||
encode(ke, entry.entry.key) or_return
|
||||
entry.encoded_key = buf.buf[:]
|
||||
entry.encoded_key = buf[:]
|
||||
}
|
||||
|
||||
// Sort lexicographic on the bytes of the key.
|
||||
|
||||
@@ -58,7 +58,7 @@ marshal_into_bytes :: proc(v: any, flags := ENCODE_SMALL, allocator := context.a
|
||||
return
|
||||
}
|
||||
|
||||
return b.buf[:], nil
|
||||
return b[:], nil
|
||||
}
|
||||
|
||||
// Marshals the given value into a CBOR byte stream written to the given builder.
|
||||
@@ -379,7 +379,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er
|
||||
|
||||
err := _encode_u64(e, u64(len(str)), .Text)
|
||||
assert(err == nil)
|
||||
res[9] = u8(len(builder.buf))
|
||||
res[9] = u8(len(builder))
|
||||
assert(res[9] < 10)
|
||||
return
|
||||
}
|
||||
@@ -476,7 +476,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er
|
||||
key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index))
|
||||
key_builder := strings.builder_make(0, 8, e.temp_allocator) or_return
|
||||
marshal_into(Encoder{e.flags, strings.to_stream(&key_builder), e.temp_allocator}, any{ key, info.key.id }) or_return
|
||||
append(&entries, Encoded_Entry{ &key_builder.buf, bucket_index }) or_return
|
||||
append(&entries, Encoded_Entry{ (^[dynamic]byte)(&key_builder), bucket_index }) or_return
|
||||
}
|
||||
|
||||
slice.sort_by_cmp(entries[:], proc(a, b: Encoded_Entry) -> slice.Ordering {
|
||||
@@ -555,7 +555,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er
|
||||
|
||||
key_builder := strings.builder_make(e.temp_allocator) or_return
|
||||
err_conv(_encode_text(Encoder{e.flags, strings.to_stream(&key_builder), e.temp_allocator}, fname)) or_return
|
||||
append(&entries, Name{key_builder.buf[:], i}) or_return
|
||||
append(&entries, Name{key_builder[:], i}) or_return
|
||||
}
|
||||
|
||||
// Sort lexicographic on the bytes of the key.
|
||||
|
||||
@@ -311,7 +311,7 @@ tag_base64_unmarshal :: proc(_: ^Tag_Implementation, d: Decoder, _: Tag_Number,
|
||||
b64_decode_into(strings.to_stream(&builder), bytes) or_return
|
||||
|
||||
raw := (^cstring)(v.data)
|
||||
raw^ = cstring(raw_data(builder.buf))
|
||||
raw^ = cstring(raw_data(builder))
|
||||
} else {
|
||||
raw := (^string)(v.data)
|
||||
raw^ = string(b64_decode(bytes) or_return)
|
||||
|
||||
@@ -146,8 +146,8 @@ marshal :: proc(v: any, opt: Marshal_Options = {}, allocator := context.allocato
|
||||
opt := opt
|
||||
marshal_to_builder(&b, v, &opt) or_return
|
||||
|
||||
if len(b.buf) != 0 {
|
||||
data = b.buf[:]
|
||||
if len(b) != 0 {
|
||||
data = b[:]
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
||||
@@ -161,7 +161,7 @@ decode :: proc(data: []byte, allocator := context.allocator) -> (blk: ^Block, re
|
||||
@(require_results)
|
||||
encode :: proc(label: string, data: []byte, newline := false, allocator := context.allocator) -> (res: []byte, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
sanitize_sb := proc(sb: ^strings.Builder) {
|
||||
buf := sb.buf[:]
|
||||
buf := sb[:]
|
||||
b, l := raw_data(buf), len(buf)
|
||||
crypto.zero_explicit(b, l)
|
||||
strings.builder_destroy(sb)
|
||||
|
||||
@@ -120,11 +120,11 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
switch header.format {
|
||||
// Compressed binary
|
||||
case .P4:
|
||||
header_buf := data.buf[:]
|
||||
header_buf := data[:]
|
||||
pixels := img.pixels.buf[:]
|
||||
|
||||
p4_buffer_size := (img.width / 8 + 1) * img.height
|
||||
reserve(&data.buf, len(header_buf) + p4_buffer_size)
|
||||
reserve(&data, len(header_buf) + p4_buffer_size)
|
||||
|
||||
// we build up a byte value until it is completely filled
|
||||
// or we reach the end the row
|
||||
@@ -138,39 +138,39 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
b |= (v << bit)
|
||||
|
||||
if bit == 0 {
|
||||
append(&data.buf, b)
|
||||
append(&data, b)
|
||||
b = 0
|
||||
}
|
||||
}
|
||||
|
||||
if b != 0 {
|
||||
append(&data.buf, b)
|
||||
append(&data, b)
|
||||
b = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Simple binary
|
||||
case .P5, .P6, .P7, .Pf, .PF:
|
||||
header_buf := data.buf[:]
|
||||
header_buf := data[:]
|
||||
pixels := img.pixels.buf[:]
|
||||
|
||||
resize(&data.buf, len(header_buf) + len(pixels))
|
||||
mem.copy(raw_data(data.buf[len(header_buf):]), raw_data(pixels), len(pixels))
|
||||
resize(&data, len(header_buf) + len(pixels))
|
||||
mem.copy(raw_data(data[len(header_buf):]), raw_data(pixels), len(pixels))
|
||||
|
||||
// convert from native endianness
|
||||
if img.depth == 16 {
|
||||
pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):])
|
||||
pixels := mem.slice_data_cast([]u16be, data[len(header_buf):])
|
||||
for &p in pixels {
|
||||
p = u16be(transmute(u16) p)
|
||||
}
|
||||
} else if header.format in PFM {
|
||||
if header.little_endian {
|
||||
pixels := mem.slice_data_cast([]f32le, data.buf[len(header_buf):])
|
||||
pixels := mem.slice_data_cast([]f32le, data[len(header_buf):])
|
||||
for &p in pixels {
|
||||
p = f32le(transmute(f32) p)
|
||||
}
|
||||
} else {
|
||||
pixels := mem.slice_data_cast([]f32be, data.buf[len(header_buf):])
|
||||
pixels := mem.slice_data_cast([]f32be, data[len(header_buf):])
|
||||
for &p in pixels {
|
||||
p = f32be(transmute(f32) p)
|
||||
}
|
||||
@@ -183,9 +183,9 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
for y in 0 ..< img.height {
|
||||
for x in 0 ..< img.width {
|
||||
i := y * img.width + x
|
||||
append(&data.buf, '0' if pixels[i] == 0 else '1')
|
||||
append(&data, '0' if pixels[i] == 0 else '1')
|
||||
}
|
||||
append(&data.buf, '\n')
|
||||
append(&data, '\n')
|
||||
}
|
||||
|
||||
// Token ASCII
|
||||
@@ -220,14 +220,14 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
}
|
||||
|
||||
case:
|
||||
return data.buf[:], .Invalid_Image_Depth
|
||||
return data[:], .Invalid_Image_Depth
|
||||
}
|
||||
|
||||
case:
|
||||
return data.buf[:], .Invalid_Format
|
||||
return data[:], .Invalid_Format
|
||||
}
|
||||
|
||||
return data.buf[:], Format_Error.None
|
||||
return data[:], Format_Error.None
|
||||
}
|
||||
|
||||
parse_header :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) {
|
||||
@@ -405,7 +405,7 @@ _parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (head
|
||||
return
|
||||
}
|
||||
|
||||
if len(tupltype.buf) == 0 {
|
||||
if len(tupltype) == 0 {
|
||||
fmt.sbprint(&tupltype, value)
|
||||
} else {
|
||||
fmt.sbprint(&tupltype, "", value)
|
||||
|
||||
@@ -188,7 +188,7 @@ debug :: proc(contents: ..Debuggable, location := #caller_location) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
b: strings.Builder
|
||||
b.buf.allocator = context.temp_allocator
|
||||
b.allocator = context.temp_allocator
|
||||
|
||||
strings.write_string(&b, "[nbio] ")
|
||||
|
||||
|
||||
@@ -19,9 +19,8 @@ A dynamic byte buffer / string builder with helper procedures
|
||||
The dynamic array is wrapped inside the struct to be more opaque
|
||||
You can use `fmt.sbprint*` procedures with a `^strings.Builder` directly
|
||||
*/
|
||||
Builder :: struct {
|
||||
buf: [dynamic]byte,
|
||||
}
|
||||
Builder :: distinct [dynamic]byte
|
||||
|
||||
/*
|
||||
Produces an empty Builder
|
||||
|
||||
@@ -35,7 +34,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_make_none :: proc(allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
return Builder{buf=make([dynamic]byte, allocator, loc) or_return }, nil
|
||||
return Builder(make([dynamic]byte, allocator, loc) or_return), nil
|
||||
}
|
||||
/*
|
||||
Produces a Builder with specified length and capacity `len`.
|
||||
@@ -51,7 +50,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_make_len :: proc(len: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
return Builder{buf=make([dynamic]byte, len, allocator, loc) or_return }, nil
|
||||
return Builder(make([dynamic]byte, len, allocator, loc) or_return), nil
|
||||
}
|
||||
/*
|
||||
Produces a Builder with specified length `len` and capacity `cap`.
|
||||
@@ -68,7 +67,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
return Builder{buf=make([dynamic]byte, len, cap, allocator, loc) or_return }, nil
|
||||
return Builder(make([dynamic]byte, len, cap, allocator, loc) or_return), nil
|
||||
}
|
||||
/*
|
||||
Produces a String Builder
|
||||
@@ -116,7 +115,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
b.buf = make([dynamic]byte, allocator, loc) or_return
|
||||
b^ = make(Builder, allocator, loc) or_return
|
||||
return b, nil
|
||||
}
|
||||
/*
|
||||
@@ -135,7 +134,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
b.buf = make([dynamic]byte, len, allocator, loc) or_return
|
||||
b^ = make(Builder, len, allocator, loc) or_return
|
||||
return b, nil
|
||||
}
|
||||
/*
|
||||
@@ -153,7 +152,7 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
builder_init_len_cap :: proc(b: ^Builder, len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
b.buf = make([dynamic]byte, len, cap, allocator, loc) or_return
|
||||
b^ = make(Builder, len, cap, allocator, loc) or_return
|
||||
return b, nil
|
||||
}
|
||||
// Overload simple `builder_init_*` with or without len / ap parameters
|
||||
@@ -173,7 +172,7 @@ _builder_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byt
|
||||
}
|
||||
return
|
||||
case .Size:
|
||||
n = i64(len(b.buf))
|
||||
n = i64(len(b))
|
||||
return
|
||||
case .Destroy:
|
||||
builder_destroy(b)
|
||||
@@ -215,8 +214,8 @@ Inputs:
|
||||
- b: A pointer to the Builder
|
||||
*/
|
||||
builder_destroy :: proc(b: ^Builder) {
|
||||
delete(b.buf)
|
||||
b.buf = nil
|
||||
delete(b^)
|
||||
b^ = nil
|
||||
}
|
||||
/*
|
||||
Reserves the Builder byte buffer to a specific capacity, when it's higher than before
|
||||
@@ -226,7 +225,7 @@ Inputs:
|
||||
- cap: The desired capacity for the Builder's buffer
|
||||
*/
|
||||
builder_grow :: proc(b: ^Builder, cap: int) {
|
||||
reserve(&b.buf, cap)
|
||||
reserve(b, cap)
|
||||
}
|
||||
/*
|
||||
Clears the Builder byte buffer content (sets len to zero)
|
||||
@@ -235,7 +234,7 @@ Inputs:
|
||||
- b: A pointer to the Builder
|
||||
*/
|
||||
builder_reset :: proc(b: ^Builder) {
|
||||
clear(&b.buf)
|
||||
clear(b)
|
||||
}
|
||||
/*
|
||||
Creates a Builder from a slice of bytes with the same slice length as its capacity. Used in fmt.bprint*
|
||||
@@ -268,15 +267,13 @@ Output:
|
||||
|
||||
*/
|
||||
builder_from_bytes :: proc(backing: []byte) -> (res: Builder) {
|
||||
return Builder{
|
||||
buf = transmute([dynamic]byte)runtime.Raw_Dynamic_Array{
|
||||
data = raw_data(backing),
|
||||
len = 0,
|
||||
cap = len(backing),
|
||||
allocator = runtime.Allocator{
|
||||
procedure = runtime.nil_allocator_proc,
|
||||
data = nil,
|
||||
},
|
||||
return transmute(Builder)runtime.Raw_Dynamic_Array{
|
||||
data = raw_data(backing),
|
||||
len = 0,
|
||||
cap = len(backing),
|
||||
allocator = runtime.Allocator{
|
||||
procedure = runtime.nil_allocator_proc,
|
||||
data = nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -293,7 +290,7 @@ Returns:
|
||||
- res: The contents of the Builder's buffer, as a string
|
||||
*/
|
||||
to_string :: proc(b: Builder) -> (res: string) {
|
||||
return string(b.buf[:])
|
||||
return string(b[:])
|
||||
}
|
||||
/*
|
||||
Appends a trailing null byte after the end of the current Builder byte buffer and then casts it to a cstring
|
||||
@@ -307,9 +304,9 @@ Returns:
|
||||
- res: A cstring of the Builder's buffer
|
||||
*/
|
||||
unsafe_to_cstring :: proc(b: ^Builder, loc := #caller_location) -> (res: cstring) {
|
||||
append(&b.buf, 0, loc)
|
||||
pop(&b.buf)
|
||||
return cstring(raw_data(b.buf))
|
||||
append(b, 0, loc)
|
||||
pop(b)
|
||||
return cstring(raw_data(b^))
|
||||
}
|
||||
/*
|
||||
Appends a trailing null byte after the end of the current Builder byte buffer and then casts it to a cstring
|
||||
@@ -322,15 +319,15 @@ Returns:
|
||||
- err: An optional allocator error if one occured, `nil` otherwise
|
||||
*/
|
||||
to_cstring :: proc(b: ^Builder, loc := #caller_location) -> (res: cstring, err: runtime.Allocator_Error) #optional_allocator_error {
|
||||
n := append(&b.buf, 0, loc) or_return
|
||||
n := append(b, 0, loc) or_return
|
||||
if n != 1 {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
pop(&b.buf)
|
||||
pop(b)
|
||||
#no_bounds_check {
|
||||
assert(b.buf[len(b.buf)] == 0)
|
||||
assert(b[len(b)] == 0)
|
||||
}
|
||||
return cstring(raw_data(b.buf)), nil
|
||||
return cstring(raw_data(b^)), nil
|
||||
}
|
||||
/*
|
||||
Returns the length of the Builder's buffer, in bytes
|
||||
@@ -342,7 +339,7 @@ Returns:
|
||||
- res: The length of the Builder's buffer
|
||||
*/
|
||||
builder_len :: proc(b: Builder) -> (res: int) {
|
||||
return len(b.buf)
|
||||
return len(b)
|
||||
}
|
||||
/*
|
||||
Returns the capacity of the Builder's buffer, in bytes
|
||||
@@ -354,7 +351,7 @@ Returns:
|
||||
- res: The capacity of the Builder's buffer
|
||||
*/
|
||||
builder_cap :: proc(b: Builder) -> (res: int) {
|
||||
return cap(b.buf)
|
||||
return cap(b)
|
||||
}
|
||||
/*
|
||||
The free space left in the Builder's buffer, in bytes
|
||||
@@ -366,7 +363,7 @@ Returns:
|
||||
- res: The available space left in the Builder's buffer
|
||||
*/
|
||||
builder_space :: proc(b: Builder) -> (res: int) {
|
||||
return cap(b.buf) - len(b.buf)
|
||||
return cap(b) - len(b)
|
||||
}
|
||||
/*
|
||||
Appends a byte to the Builder and returns the number of bytes appended
|
||||
@@ -398,9 +395,9 @@ Output:
|
||||
|
||||
*/
|
||||
write_byte :: proc(b: ^Builder, x: byte, loc := #caller_location) -> (n: int) {
|
||||
n0 := len(b.buf)
|
||||
append(&b.buf, x, loc)
|
||||
n1 := len(b.buf)
|
||||
n0 := len(b)
|
||||
append(b, x, loc)
|
||||
n1 := len(b)
|
||||
return n1-n0
|
||||
}
|
||||
/*
|
||||
@@ -428,9 +425,9 @@ Returns:
|
||||
- n: The number of bytes appended
|
||||
*/
|
||||
write_bytes :: proc(b: ^Builder, x: []byte, loc := #caller_location) -> (n: int) {
|
||||
n0 := len(b.buf)
|
||||
append(&b.buf, ..x, loc=loc)
|
||||
n1 := len(b.buf)
|
||||
n0 := len(b)
|
||||
append(b, ..x, loc=loc)
|
||||
n1 := len(b)
|
||||
return n1-n0
|
||||
}
|
||||
/*
|
||||
@@ -529,9 +526,9 @@ Output:
|
||||
|
||||
*/
|
||||
write_string :: proc(b: ^Builder, s: string, loc := #caller_location) -> (n: int) {
|
||||
n0 := len(b.buf)
|
||||
append(&b.buf, s, loc)
|
||||
n1 := len(b.buf)
|
||||
n0 := len(b)
|
||||
append(b, s, loc)
|
||||
n1 := len(b)
|
||||
return n1-n0
|
||||
}
|
||||
/*
|
||||
@@ -544,12 +541,12 @@ Returns:
|
||||
- r: The last byte in the Builder or 0 if empty
|
||||
*/
|
||||
pop_byte :: proc(b: ^Builder) -> (r: byte) {
|
||||
if len(b.buf) == 0 {
|
||||
if len(b) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
r = b.buf[len(b.buf)-1]
|
||||
d := (^runtime.Raw_Dynamic_Array)(&b.buf)
|
||||
r = b[len(b)-1]
|
||||
d := (^runtime.Raw_Dynamic_Array)(b)
|
||||
d.len = max(d.len-1, 0)
|
||||
return
|
||||
}
|
||||
@@ -564,12 +561,12 @@ Returns:
|
||||
- width: The rune width or 0 if the builder was empty
|
||||
*/
|
||||
pop_rune :: proc(b: ^Builder) -> (r: rune, width: int) {
|
||||
if len(b.buf) == 0 {
|
||||
if len(b) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
r, width = utf8.decode_last_rune(b.buf[:])
|
||||
d := (^runtime.Raw_Dynamic_Array)(&b.buf)
|
||||
r, width = utf8.decode_last_rune(b[:])
|
||||
d := (^runtime.Raw_Dynamic_Array)(b)
|
||||
d.len = max(d.len-width, 0)
|
||||
return
|
||||
}
|
||||
@@ -892,7 +889,7 @@ builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_lo
|
||||
if len(old) == 0 {
|
||||
// NOTE(bill): reserve the necessary memory
|
||||
found := 0
|
||||
for i := 0; i <= len(b.buf); i += len(new)+1 {
|
||||
for i := 0; i <= len(b); i += len(new)+1 {
|
||||
if n > 0 && found == n {
|
||||
break
|
||||
}
|
||||
@@ -901,29 +898,29 @@ builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_lo
|
||||
if found == 0 {
|
||||
return
|
||||
}
|
||||
reserve(&b.buf, len(b.buf) + len(new)*found) or_return
|
||||
reserve(b, len(b) + len(new)*found) or_return
|
||||
|
||||
|
||||
for i := 0; i <= len(b.buf); i += len(new)+1 {
|
||||
for i := 0; i <= len(b); i += len(new)+1 {
|
||||
if n > 0 && replaced == n {
|
||||
break
|
||||
}
|
||||
|
||||
resize(&b.buf, len(b.buf)+len(new), loc) or_return
|
||||
copy(b.buf[i+len(new):], b.buf[i:])
|
||||
copy(b.buf[i:], new)
|
||||
resize(b, len(b)+len(new), loc) or_return
|
||||
copy(b[i+len(new):], b[i:])
|
||||
copy(b[i:], new)
|
||||
replaced += 1
|
||||
}
|
||||
} else {
|
||||
if len(new) > len(old) {
|
||||
// NOTE(bill): reserve the necessary memory
|
||||
found := 0
|
||||
for i := 0; i < len(b.buf); /**/ {
|
||||
for i := 0; i < len(b); /**/ {
|
||||
if n > 0 && found == n {
|
||||
break
|
||||
}
|
||||
|
||||
j := index(string(b.buf[i:]), old)
|
||||
j := index(string(b[i:]), old)
|
||||
if j < 0 {
|
||||
break
|
||||
}
|
||||
@@ -933,24 +930,24 @@ builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_lo
|
||||
if found == 0 {
|
||||
return
|
||||
}
|
||||
reserve(&b.buf, len(b.buf) + (len(new)-len(old))*found) or_return
|
||||
reserve(b, len(b) + (len(new)-len(old))*found) or_return
|
||||
}
|
||||
|
||||
for i := 0; i < len(b.buf); /**/ {
|
||||
for i := 0; i < len(b); /**/ {
|
||||
if n > 0 && replaced == n {
|
||||
break
|
||||
}
|
||||
|
||||
j := index(string(b.buf[i:]), old)
|
||||
j := index(string(b[i:]), old)
|
||||
if j < 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(new) > len(old) {
|
||||
resize(&b.buf, len(b.buf) + len(new)-len(old)) or_return
|
||||
resize(b, len(b) + len(new)-len(old)) or_return
|
||||
}
|
||||
|
||||
cur := b.buf[i+j:]
|
||||
cur := b[i+j:]
|
||||
src := cur[len(old):]
|
||||
dst := cur[len(new):]
|
||||
copy(dst, src)
|
||||
@@ -961,7 +958,7 @@ builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_lo
|
||||
replaced += 1
|
||||
|
||||
if len(new) < len(old) {
|
||||
resize(&b.buf, len(b.buf) + len(new)-len(old)) or_return
|
||||
resize(b, len(b) + len(new)-len(old)) or_return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ _os_version :: proc (allocator: runtime.Allocator, loc := #caller_location) -> (
|
||||
build = string(cstring(raw_data(build_buf[:])))
|
||||
}
|
||||
ws(&b, " (build ")
|
||||
build_start := len(b.buf)
|
||||
build_start := len(b)
|
||||
ws(&b, build)
|
||||
res.release = string(b.buf[build_start:][:len(build)])
|
||||
res.release = string(b[build_start:][:len(build)])
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -65,7 +65,7 @@ _os_version :: proc (allocator: runtime.Allocator, loc := #caller_location) -> (
|
||||
|
||||
release_i := strings.builder_len(b)
|
||||
strings.write_string(&b, string(cstring(&uts.release[0])))
|
||||
release_str := string(b.buf[release_i:])
|
||||
release_str := string(b[release_i:])
|
||||
|
||||
res.full = strings.to_string(b)
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ begin :: proc(s: ^State, id: u64, builder: ^strings.Builder) {
|
||||
end(s)
|
||||
}
|
||||
s.id = id
|
||||
s.selection = {len(builder.buf), 0}
|
||||
s.selection = {len(builder), 0}
|
||||
s.builder = builder
|
||||
update_time(s)
|
||||
undo_clear(s, &s.undo)
|
||||
@@ -118,7 +118,7 @@ update_time :: proc(s: ^State) {
|
||||
// setup the builder, selection and undo|redo state once allowing to retain selection
|
||||
setup_once :: proc(s: ^State, builder: ^strings.Builder) {
|
||||
s.builder = builder
|
||||
s.selection = { len(builder.buf), 0 }
|
||||
s.selection = { len(builder), 0 }
|
||||
undo_clear(s, &s.undo)
|
||||
undo_clear(s, &s.redo)
|
||||
}
|
||||
@@ -126,8 +126,8 @@ setup_once :: proc(s: ^State, builder: ^strings.Builder) {
|
||||
// returns true when the builder had content to be cleared
|
||||
// clear builder&selection and the undo|redo stacks
|
||||
clear_all :: proc(s: ^State) -> (cleared: bool) {
|
||||
if s.builder != nil && len(s.builder.buf) > 0 {
|
||||
clear(&s.builder.buf)
|
||||
if s.builder != nil && len(s.builder) > 0 {
|
||||
clear(s.builder)
|
||||
s.selection = {}
|
||||
cleared = true
|
||||
}
|
||||
@@ -142,7 +142,7 @@ undo_state_push :: proc(s: ^State, undo: ^[dynamic]^Undo_State) -> mem.Allocator
|
||||
if s.builder == nil {
|
||||
return nil
|
||||
}
|
||||
text := string(s.builder.buf[:])
|
||||
text := string(s.builder[:])
|
||||
item := (^Undo_State)(mem.alloc(size_of(Undo_State) + len(text), align_of(Undo_State), s.undo_text_allocator) or_return)
|
||||
item.selection = s.selection
|
||||
item.len = len(text)
|
||||
@@ -234,13 +234,13 @@ input_rune :: proc(s: ^State, r: rune) {
|
||||
insert :: proc(s: ^State, at: int, text: string) -> int {
|
||||
undo_check(s)
|
||||
if s.builder != nil {
|
||||
if ok, _ := inject_at(&s.builder.buf, at, text); !ok {
|
||||
n := cap(s.builder.buf) - len(s.builder.buf)
|
||||
if ok, _ := inject_at(s.builder, at, text); !ok {
|
||||
n := cap(s.builder) - len(s.builder)
|
||||
assert(n < len(text))
|
||||
for is_continuation_byte(text[n]) {
|
||||
n -= 1
|
||||
}
|
||||
if ok2, _ := inject_at(&s.builder.buf, at, text[:n]); !ok2 {
|
||||
if ok2, _ := inject_at(s.builder, at, text[:n]); !ok2 {
|
||||
n = 0
|
||||
}
|
||||
return n
|
||||
@@ -254,7 +254,7 @@ insert :: proc(s: ^State, at: int, text: string) -> int {
|
||||
remove :: proc(s: ^State, lo, hi: int) {
|
||||
undo_check(s)
|
||||
if s.builder != nil {
|
||||
remove_range(&s.builder.buf, lo, hi)
|
||||
remove_range(s.builder, lo, hi)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,8 +269,8 @@ has_selection :: proc(s: ^State) -> bool {
|
||||
sorted_selection :: proc(s: ^State) -> (lo, hi: int) {
|
||||
lo = min(s.selection[0], s.selection[1])
|
||||
hi = max(s.selection[0], s.selection[1])
|
||||
lo = clamp(lo, 0, len(s.builder.buf) if s.builder != nil else 0)
|
||||
hi = clamp(hi, 0, len(s.builder.buf) if s.builder != nil else 0)
|
||||
lo = clamp(lo, 0, len(s.builder) if s.builder != nil else 0)
|
||||
hi = clamp(hi, 0, len(s.builder) if s.builder != nil else 0)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ translate_position :: proc(s: ^State, t: Translation) -> int {
|
||||
|
||||
buf: []byte
|
||||
if s.builder != nil {
|
||||
buf = s.builder.buf[:]
|
||||
buf = s.builder[:]
|
||||
}
|
||||
pos := clamp(s.selection[0], 0, len(buf))
|
||||
|
||||
@@ -400,7 +400,7 @@ delete_to :: proc(s: ^State, t: Translation) {
|
||||
current_selected_text :: proc(s: ^State) -> string {
|
||||
lo, hi := sorted_selection(s)
|
||||
if s.builder != nil {
|
||||
return string(s.builder.buf[lo:hi])
|
||||
return string(s.builder[lo:hi])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -481,7 +481,7 @@ perform_command :: proc(s: ^State, cmd: Command) {
|
||||
case .Cut: cut(s)
|
||||
case .Copy: copy(s)
|
||||
case .Paste: paste(s)
|
||||
case .Select_All: s.selection = {len(s.builder.buf) if s.builder != nil else 0, 0}
|
||||
case .Select_All: s.selection = {len(s.builder) if s.builder != nil else 0, 0}
|
||||
case .Backspace: delete_to(s, .Left)
|
||||
case .Delete: delete_to(s, .Right)
|
||||
case .Delete_Word_Left: delete_to(s, .Word_Left)
|
||||
|
||||
2
vendor/microui/microui.odin
vendored
2
vendor/microui/microui.odin
vendored
@@ -996,7 +996,7 @@ textbox_raw :: proc(ctx: ^Context, textbuf: []u8, textlen: ^int, id: Id, r: Rect
|
||||
if ctx.focus_id == id {
|
||||
/* create a builder backed by the user's buffer */
|
||||
builder := strings.builder_from_bytes(textbuf)
|
||||
non_zero_resize(&builder.buf, textlen^)
|
||||
non_zero_resize(&builder, textlen^)
|
||||
ctx.textbox_state.builder = &builder
|
||||
if ctx.textbox_state.id != u64(id) {
|
||||
ctx.textbox_state.id = u64(id)
|
||||
|
||||
Reference in New Issue
Block a user