mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 14:18:47 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -9,6 +9,7 @@ package poly1305
|
||||
import "core:crypto"
|
||||
import field "core:crypto/_fiat/field_poly1305"
|
||||
import "core:encoding/endian"
|
||||
import "core:math/bits"
|
||||
import "core:mem"
|
||||
|
||||
// KEY_SIZE is the Poly1305 key size in bytes.
|
||||
@@ -50,7 +51,7 @@ verify :: proc(tag, msg, key: []byte) -> bool {
|
||||
Context :: struct {
|
||||
_r: field.Tight_Field_Element,
|
||||
_a: field.Tight_Field_Element,
|
||||
_s: field.Tight_Field_Element,
|
||||
_s: [2]u64,
|
||||
_buffer: [_BLOCK_SIZE]byte,
|
||||
_leftover: int,
|
||||
_is_initialized: bool,
|
||||
@@ -66,11 +67,12 @@ init :: proc(ctx: ^Context, key: []byte) {
|
||||
// r = le_bytes_to_num(key[0..15])
|
||||
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
|
||||
tmp_lo := endian.unchecked_get_u64le(key[0:]) & 0x0ffffffc0fffffff
|
||||
tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0xffffffc0ffffffc
|
||||
tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0x0ffffffc0ffffffc
|
||||
field.fe_from_u64s(&ctx._r, tmp_lo, tmp_hi)
|
||||
|
||||
// s = le_bytes_to_num(key[16..31])
|
||||
field.fe_from_bytes(&ctx._s, key[16:32], 0)
|
||||
ctx._s[0] = endian.unchecked_get_u64le(key[16:])
|
||||
ctx._s[1] = endian.unchecked_get_u64le(key[24:])
|
||||
|
||||
// a = 0
|
||||
field.fe_zero(&ctx._a)
|
||||
@@ -138,14 +140,20 @@ final :: proc(ctx: ^Context, dst: []byte) {
|
||||
_blocks(ctx, ctx._buffer[:], true)
|
||||
}
|
||||
|
||||
// a += s
|
||||
field.fe_add(field.fe_relax_cast(&ctx._a), &ctx._a, &ctx._s) // _a unreduced
|
||||
field.fe_carry(&ctx._a, field.fe_relax_cast(&ctx._a)) // _a reduced
|
||||
|
||||
// return num_to_16_le_bytes(a)
|
||||
// a += s (NOT mod p)
|
||||
tmp: [32]byte = ---
|
||||
field.fe_to_bytes(&tmp, &ctx._a)
|
||||
copy_slice(dst, tmp[0:16])
|
||||
|
||||
c: u64
|
||||
lo := endian.unchecked_get_u64le(tmp[0:])
|
||||
hi := endian.unchecked_get_u64le(tmp[8:])
|
||||
|
||||
lo, c = bits.add_u64(lo, ctx._s[0], 0)
|
||||
hi, _ = bits.add_u64(hi, ctx._s[1], c)
|
||||
|
||||
// return num_to_16_le_bytes(a)
|
||||
endian.unchecked_put_u64le(dst[0:], lo)
|
||||
endian.unchecked_put_u64le(dst[8:], hi)
|
||||
}
|
||||
|
||||
// reset sanitizes the Context. The Context must be re-initialized to
|
||||
|
||||
@@ -177,7 +177,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
|
||||
}
|
||||
defer file.nodes = file.nodes[:node_count]
|
||||
|
||||
for node_idx in 0..<header.internal_node_count {
|
||||
for _ in 0..<header.internal_node_count {
|
||||
node := &file.nodes[node_count]
|
||||
type := read_value(r, Node_Type) or_return
|
||||
if type > max(Node_Type) {
|
||||
|
||||
@@ -246,7 +246,6 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
opt_write_end(w, opt, ']') or_return
|
||||
|
||||
case runtime.Type_Info_Enumerated_Array:
|
||||
index := runtime.type_info_base(info.index).variant.(runtime.Type_Info_Enum)
|
||||
opt_write_start(w, opt, '[') or_return
|
||||
for i in 0..<info.count {
|
||||
opt_write_iteration(w, opt, i) or_return
|
||||
@@ -299,14 +298,14 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
|
||||
// check for string type
|
||||
{
|
||||
v := any{key, info.key.id}
|
||||
ti := runtime.type_info_base(type_info_of(v.id))
|
||||
a := any{v.data, ti.id}
|
||||
kv := any{key, info.key.id}
|
||||
kti := runtime.type_info_base(type_info_of(kv.id))
|
||||
ka := any{kv.data, kti.id}
|
||||
name: string
|
||||
|
||||
#partial switch info in ti.variant {
|
||||
#partial switch info in kti.variant {
|
||||
case runtime.Type_Info_String:
|
||||
switch s in a {
|
||||
switch s in ka {
|
||||
case string: name = s
|
||||
case cstring: name = string(s)
|
||||
}
|
||||
@@ -336,13 +335,13 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
|
||||
// check for string type
|
||||
{
|
||||
v := any{key, info.key.id}
|
||||
ti := runtime.type_info_base(type_info_of(v.id))
|
||||
a := any{v.data, ti.id}
|
||||
kv := any{key, info.key.id}
|
||||
kti := runtime.type_info_base(type_info_of(kv.id))
|
||||
ka := any{kv.data, kti.id}
|
||||
|
||||
#partial switch info in ti.variant {
|
||||
#partial switch info in kti.variant {
|
||||
case runtime.Type_Info_String:
|
||||
switch s in a {
|
||||
switch s in ka {
|
||||
case string: name = s
|
||||
case cstring: name = string(s)
|
||||
}
|
||||
|
||||
@@ -483,9 +483,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
|
||||
|
||||
mem.zero_slice(elem_backing)
|
||||
if err := unmarshal_value(p, map_backing_value); err != nil {
|
||||
if uerr := unmarshal_value(p, map_backing_value); uerr != nil {
|
||||
delete(key, p.allocator)
|
||||
return err
|
||||
return uerr
|
||||
}
|
||||
|
||||
key_ptr := rawptr(&key)
|
||||
|
||||
@@ -199,8 +199,8 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
for x in 0 ..< img.width {
|
||||
i := y * img.width + x
|
||||
for c in 0 ..< img.channels {
|
||||
i := i * img.channels + c
|
||||
fmt.sbprintf(&data, "%i ", pixels[i])
|
||||
j := i * img.channels + c
|
||||
fmt.sbprintf(&data, "%i ", pixels[j])
|
||||
}
|
||||
fmt.sbprint(&data, "\n")
|
||||
}
|
||||
@@ -213,8 +213,8 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
for x in 0 ..< img.width {
|
||||
i := y * img.width + x
|
||||
for c in 0 ..< img.channels {
|
||||
i := i * img.channels + c
|
||||
fmt.sbprintf(&data, "%i ", pixels[i])
|
||||
j := i * img.channels + c
|
||||
fmt.sbprintf(&data, "%i ", pixels[j])
|
||||
}
|
||||
fmt.sbprint(&data, "\n")
|
||||
}
|
||||
@@ -283,7 +283,7 @@ _parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Er
|
||||
current_field := 0
|
||||
current_value := header_fields[0]
|
||||
|
||||
parse_loop: for d, i in data[SIG_LENGTH:] {
|
||||
parse_loop: for d in data[SIG_LENGTH:] {
|
||||
length += 1
|
||||
|
||||
// handle comments
|
||||
@@ -728,4 +728,4 @@ _register :: proc() {
|
||||
_ = destroy(img)
|
||||
}
|
||||
image.register(.NetPBM, loader, destroyer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ init_from_f64 :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), val: f64) {
|
||||
}
|
||||
|
||||
init_from_parts :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), integer, fraction: Backing) {
|
||||
i, f := math.modf(val)
|
||||
x.i = fraction
|
||||
x.i &= 1<<Fraction_Width - 1
|
||||
x.i |= integer
|
||||
|
||||
+15
-50
@@ -83,11 +83,7 @@ free :: proc(ptr: rawptr, allocator := context.allocator, loc := #caller_locatio
|
||||
}
|
||||
|
||||
free_with_size :: proc(ptr: rawptr, byte_count: int, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
if ptr == nil || allocator.procedure == nil {
|
||||
return nil
|
||||
}
|
||||
_, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, byte_count, loc)
|
||||
return err
|
||||
return runtime.mem_free_with_size(ptr, byte_count, allocator, loc)
|
||||
}
|
||||
|
||||
free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
@@ -130,19 +126,19 @@ query_info :: proc(pointer: rawptr, allocator: Allocator, loc := #caller_locatio
|
||||
|
||||
|
||||
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return free_with_size(raw_data(str), len(str), allocator, loc)
|
||||
return runtime.delete_string(str, allocator, loc)
|
||||
}
|
||||
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return free((^byte)(str), allocator, loc)
|
||||
return runtime.delete_cstring(str, allocator, loc)
|
||||
}
|
||||
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {
|
||||
return free_with_size(raw_data(array), cap(array)*size_of(E), array.allocator, loc)
|
||||
return runtime.delete_dynamic_array(array, loc)
|
||||
}
|
||||
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
|
||||
return free_with_size(raw_data(array), len(array)*size_of(E), allocator, loc)
|
||||
return runtime.delete_slice(array, allocator, loc)
|
||||
}
|
||||
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) -> Allocator_Error {
|
||||
return runtime.map_free_dynamic(transmute(Raw_Map)m, runtime.map_info(T), loc)
|
||||
return runtime.delete_map(m, loc)
|
||||
}
|
||||
|
||||
|
||||
@@ -161,71 +157,40 @@ new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location)
|
||||
}
|
||||
@(require_results)
|
||||
new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) {
|
||||
data := alloc_bytes(size_of(T), alignment, allocator, loc) or_return
|
||||
t = (^T)(raw_data(data))
|
||||
return
|
||||
return runtime.new_aligned(T, alignment, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) {
|
||||
backing := alloc_bytes(size_of(T), align_of(T), allocator, loc) or_return
|
||||
t = (^T)(raw_data(backing))
|
||||
if t != nil {
|
||||
t^ = data
|
||||
return t, nil
|
||||
}
|
||||
return nil, .Out_Of_Memory
|
||||
return runtime.new_clone(data, allocator, loc)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (slice: T, err: Allocator_Error) {
|
||||
runtime.make_slice_error_loc(loc, len)
|
||||
data := alloc_bytes(size_of(E)*len, alignment, allocator, loc) or_return
|
||||
if data == nil && size_of(E) != 0 {
|
||||
return
|
||||
}
|
||||
slice = transmute(T)Raw_Slice{raw_data(data), len}
|
||||
return
|
||||
return runtime.make_aligned(T, len, alignment, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
|
||||
return make_aligned(T, len, align_of(E), allocator, loc)
|
||||
return runtime.make_slice(T, len, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
|
||||
return make_dynamic_array_len_cap(T, 0, 16, allocator, loc)
|
||||
return runtime.make_dynamic_array(T, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
|
||||
return make_dynamic_array_len_cap(T, len, len, allocator, loc)
|
||||
return runtime.make_dynamic_array(T, len, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) {
|
||||
runtime.make_dynamic_array_error_loc(loc, len, cap)
|
||||
data := alloc_bytes(size_of(E)*cap, align_of(E), allocator, loc) or_return
|
||||
s := Raw_Dynamic_Array{raw_data(data), len, cap, allocator}
|
||||
if data == nil && size_of(E) != 0 {
|
||||
s.len, s.cap = 0, 0
|
||||
}
|
||||
array = transmute(T)s
|
||||
return
|
||||
return runtime.make_dynamic_array(T, len, cap, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = 1<<runtime.MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> (m: T, err: Allocator_Error) {
|
||||
runtime.make_map_expr_error_loc(loc, cap)
|
||||
context.allocator = allocator
|
||||
|
||||
err = reserve_map(&m, cap, loc)
|
||||
return
|
||||
return runtime.make_map(T, cap, allocator, loc)
|
||||
}
|
||||
@(require_results)
|
||||
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) {
|
||||
runtime.make_slice_error_loc(loc, len)
|
||||
data := alloc_bytes(size_of(E)*len, align_of(E), allocator, loc) or_return
|
||||
if data == nil && size_of(E) != 0 {
|
||||
return
|
||||
}
|
||||
mp = cast(T)raw_data(data)
|
||||
return
|
||||
return runtime.make_multi_pointer(T, len, allocator, loc)
|
||||
}
|
||||
|
||||
make :: proc{
|
||||
|
||||
@@ -45,6 +45,8 @@ copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawpt
|
||||
intrinsics.mem_copy_non_overlapping(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
compare :: proc "contextless" (a, b: []byte) -> int {
|
||||
res := compare_byte_ptrs(raw_data(a), raw_data(b), min(len(a), len(b)))
|
||||
if res == 0 && len(a) != len(b) {
|
||||
|
||||
+2
-2
@@ -119,9 +119,9 @@ aton :: proc(address_and_maybe_port: string, family: Address_Family, allow_decim
|
||||
}
|
||||
|
||||
a: [4]u8 = ---
|
||||
for v, i in buf {
|
||||
for v, j in buf {
|
||||
if v > 255 { return {}, false }
|
||||
a[i] = u8(v)
|
||||
a[j] = u8(v)
|
||||
}
|
||||
return IP4_Address(a), true
|
||||
|
||||
|
||||
@@ -816,7 +816,6 @@ parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator
|
||||
|
||||
dq_sz :: 4
|
||||
hn_sz := skip_hostname(response, cur_idx) or_return
|
||||
dns_query := mem.slice_data_cast([]u16be, response[cur_idx+hn_sz:cur_idx+hn_sz+dq_sz])
|
||||
|
||||
cur_idx += hn_sz + dq_sz
|
||||
}
|
||||
|
||||
@@ -85,11 +85,9 @@ _get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator :
|
||||
append(&recs, record)
|
||||
|
||||
case .CNAME:
|
||||
|
||||
hostname := strings.clone(string(r.Data.CNAME))
|
||||
record := DNS_Record_CNAME{
|
||||
base = base_record,
|
||||
host_name = hostname,
|
||||
host_name = strings.clone(string(r.Data.CNAME)),
|
||||
}
|
||||
append(&recs, record)
|
||||
|
||||
@@ -107,10 +105,9 @@ _get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator :
|
||||
}
|
||||
|
||||
case .NS:
|
||||
hostname := strings.clone(string(r.Data.NS))
|
||||
record := DNS_Record_NS{
|
||||
base = base_record,
|
||||
host_name = hostname,
|
||||
host_name = strings.clone(string(r.Data.NS)),
|
||||
}
|
||||
append(&recs, record)
|
||||
|
||||
|
||||
@@ -161,11 +161,10 @@ recv_any :: proc(socket: Any_Socket, buf: []byte) -> (
|
||||
) {
|
||||
switch socktype in socket {
|
||||
case TCP_Socket:
|
||||
bytes_read, err := recv_tcp(socktype, buf)
|
||||
return bytes_read, nil, err
|
||||
bytes_read, err = recv_tcp(socktype, buf)
|
||||
return
|
||||
case UDP_Socket:
|
||||
bytes_read, endpoint, err := recv_udp(socktype, buf)
|
||||
return bytes_read, endpoint, err
|
||||
return recv_udp(socktype, buf)
|
||||
case: panic("Not supported")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,6 @@ Type :: struct {
|
||||
// .Bit_Set - <=2 types: 0=element type, 1=underlying type (Underlying_Type flag will be set)
|
||||
// .Simd_Vector - 1 type: 0=element
|
||||
// .Relative_Pointer - 2 types: 0=pointer type, 1=base integer
|
||||
// .Relative_Slice - 2 types: 0=slice type, 1=base integer
|
||||
// .Multi_Pointer - 1 type: 0=element
|
||||
// .Matrix - 1 type: 0=element
|
||||
// .Soa_Pointer - 1 type: 0=element
|
||||
|
||||
@@ -643,7 +643,7 @@ align_switch_stmt :: proc(p: ^Printer, index: int) {
|
||||
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
|
||||
|
||||
//find all the switch cases that are one lined
|
||||
for line, line_index in p.lines[brace_line + 1:] {
|
||||
for line in p.lines[brace_line + 1:] {
|
||||
|
||||
case_found := false
|
||||
colon_found := false
|
||||
@@ -716,7 +716,7 @@ align_enum :: proc(p: ^Printer, index: int) {
|
||||
|
||||
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
|
||||
|
||||
for line, line_index in p.lines[brace_line + 1:] {
|
||||
for line in p.lines[brace_line + 1:] {
|
||||
length := 0
|
||||
|
||||
for format_token, i in line.format_tokens {
|
||||
@@ -880,7 +880,7 @@ align_comments :: proc(p: ^Printer) {
|
||||
|
||||
length := 0
|
||||
|
||||
for format_token, i in line.format_tokens {
|
||||
for format_token in line.format_tokens {
|
||||
if format_token.kind == .Comment {
|
||||
current_info.length = max(current_info.length, length)
|
||||
current_info.end = line_index
|
||||
|
||||
@@ -1462,9 +1462,9 @@ visit_binary_expr :: proc(p: ^Printer, binary: ^ast.Binary_Expr) {
|
||||
}
|
||||
|
||||
either_implicit_selector := false
|
||||
if _, ok := binary.left.derived.(^ast.Implicit_Selector_Expr); ok {
|
||||
if _, lok := binary.left.derived.(^ast.Implicit_Selector_Expr); lok {
|
||||
either_implicit_selector = true
|
||||
} else if _, ok := binary.right.derived.(^ast.Implicit_Selector_Expr); ok {
|
||||
} else if _, rok := binary.right.derived.(^ast.Implicit_Selector_Expr); rok {
|
||||
either_implicit_selector = true
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@ General_Error :: enum u32 {
|
||||
|
||||
Timeout,
|
||||
|
||||
Broken_Pipe,
|
||||
|
||||
// Indicates that an attempt to retrieve a file's size was made, but the
|
||||
// file doesn't have a size.
|
||||
No_Size,
|
||||
|
||||
Invalid_File,
|
||||
Invalid_Dir,
|
||||
Invalid_Path,
|
||||
@@ -51,6 +57,8 @@ error_string :: proc(ferr: Error) -> string {
|
||||
case .Not_Exist: return "file does not exist"
|
||||
case .Closed: return "file already closed"
|
||||
case .Timeout: return "i/o timeout"
|
||||
case .Broken_Pipe: return "Broken pipe"
|
||||
case .No_Size: return "file has no definite size"
|
||||
case .Invalid_File: return "invalid file"
|
||||
case .Invalid_Dir: return "invalid directory"
|
||||
case .Invalid_Path: return "invalid path"
|
||||
|
||||
+35
-11
@@ -87,26 +87,50 @@ read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator) -
|
||||
|
||||
read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (data: []byte, err: Error) {
|
||||
size: int
|
||||
has_size := true
|
||||
if size64, err := file_size(f); err == nil {
|
||||
if i64(int(size64)) != size64 {
|
||||
size = int(size64)
|
||||
}
|
||||
} else if err == .No_Size {
|
||||
has_size = false
|
||||
} else {
|
||||
return
|
||||
}
|
||||
size += 1 // for EOF
|
||||
|
||||
// TODO(bill): Is this correct logic?
|
||||
total: int
|
||||
data = make([]byte, size, allocator) or_return
|
||||
for {
|
||||
n: int
|
||||
n, err = read(f, data[total:])
|
||||
total += n
|
||||
if err != nil {
|
||||
if err == .EOF {
|
||||
err = nil
|
||||
if has_size {
|
||||
total: int
|
||||
data = make([]byte, size, allocator) or_return
|
||||
for {
|
||||
n: int
|
||||
n, err = read(f, data[total:])
|
||||
total += n
|
||||
if err != nil {
|
||||
if err == .EOF {
|
||||
err = nil
|
||||
}
|
||||
data = data[:total]
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buffer: [1024]u8
|
||||
out_buffer := make([dynamic]u8, 0, 0, allocator)
|
||||
total := 0
|
||||
for {
|
||||
n: int = ---
|
||||
n, err = read(f, buffer[:])
|
||||
total += n
|
||||
append_elems(&out_buffer, ..buffer[:total])
|
||||
if err != nil {
|
||||
if err == .EOF || err == .Broken_Pipe {
|
||||
err = nil
|
||||
}
|
||||
data = out_buffer[:total]
|
||||
return
|
||||
}
|
||||
data = data[:total]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,6 +434,9 @@ _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) {
|
||||
|
||||
_file_size :: proc(f: ^File) -> (n: i64, err: Error) {
|
||||
length: win32.LARGE_INTEGER
|
||||
if f.impl.kind == .Pipe {
|
||||
return 0, .No_Size
|
||||
}
|
||||
handle := _handle(f)
|
||||
if !win32.GetFileSizeEx(handle, &length) {
|
||||
err = _get_platform_error()
|
||||
@@ -766,7 +769,6 @@ _is_dir :: proc(path: string) -> bool {
|
||||
_file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
f := (^File)(stream_data)
|
||||
ferr: Error
|
||||
i: int
|
||||
switch mode {
|
||||
case .Read:
|
||||
n, ferr = _read(f, p)
|
||||
|
||||
@@ -456,6 +456,7 @@ foreign libc {
|
||||
@(link_name="fstat64") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int ---
|
||||
@(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t ---
|
||||
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---
|
||||
@(link_name="fsync") _unix_fsync :: proc(handle: Handle) -> c.int ---
|
||||
|
||||
@(link_name="fdopendir$INODE64") _unix_fdopendir_amd64 :: proc(fd: Handle) -> Dir ---
|
||||
@(link_name="readdir_r$INODE64") _unix_readdir_r_amd64 :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
|
||||
@@ -565,8 +566,8 @@ fchmod :: proc(fd: Handle, mode: u16) -> Errno {
|
||||
return cast(Errno)_unix_fchmod(fd, mode)
|
||||
}
|
||||
|
||||
close :: proc(fd: Handle) -> bool {
|
||||
return _unix_close(fd) == 0
|
||||
close :: proc(fd: Handle) -> Errno {
|
||||
return cast(Errno)_unix_close(fd)
|
||||
}
|
||||
|
||||
// If you read or write more than `SSIZE_MAX` bytes, most darwin implementations will return `EINVAL`
|
||||
@@ -894,6 +895,10 @@ access :: proc(path: string, mask: int) -> bool {
|
||||
return _unix_access(cstr, mask) == 0
|
||||
}
|
||||
|
||||
flush :: proc(fd: Handle) -> Errno {
|
||||
return cast(Errno)_unix_fsync(fd)
|
||||
}
|
||||
|
||||
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
|
||||
path_str := strings.clone_to_cstring(key, context.temp_allocator)
|
||||
|
||||
@@ -878,7 +878,7 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
|
||||
s = s[1:]
|
||||
fallthrough
|
||||
case 'i', 'I':
|
||||
n := common_prefix_len_ignore_case(s, "infinity")
|
||||
n = common_prefix_len_ignore_case(s, "infinity")
|
||||
if 3 < n && n < 8 { // "inf" or "infinity"
|
||||
n = 3
|
||||
}
|
||||
|
||||
@@ -809,7 +809,7 @@ _split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocato
|
||||
n = l
|
||||
}
|
||||
|
||||
res := make([]string, n, allocator, loc) or_return
|
||||
res = make([]string, n, allocator, loc) or_return
|
||||
for i := 0; i < n-1; i += 1 {
|
||||
_, w := utf8.decode_rune_in_string(s)
|
||||
res[i] = s[:w]
|
||||
|
||||
@@ -18,8 +18,8 @@ init_os_version :: proc () {
|
||||
fd, errno := linux.open("/etc/os-release", {.RDONLY}, {})
|
||||
assert(errno == .NONE, "Failed to read /etc/os-release")
|
||||
defer {
|
||||
errno := linux.close(fd)
|
||||
assert(errno == .NONE, "Failed to close the file descriptor")
|
||||
cerrno := linux.close(fd)
|
||||
assert(cerrno == .NONE, "Failed to close the file descriptor")
|
||||
}
|
||||
os_release_buf: [2048]u8
|
||||
n, read_errno := linux.read(fd, os_release_buf[:])
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
package linux
|
||||
|
||||
/*
|
||||
|
||||
@@ -324,6 +324,7 @@ foreign kernel32 {
|
||||
lpName: LPCWSTR,
|
||||
) -> HANDLE ---
|
||||
ResetEvent :: proc(hEvent: HANDLE) -> BOOL ---
|
||||
SetEvent :: proc(hEvent: HANDLE) -> BOOL ---
|
||||
WaitForMultipleObjects :: proc(
|
||||
nCount: DWORD,
|
||||
lpHandles: ^HANDLE,
|
||||
@@ -545,6 +546,10 @@ FILE_MAP_RESERVE :: DWORD(0x80000000)
|
||||
FILE_MAP_TARGETS_INVALID :: DWORD(0x40000000)
|
||||
FILE_MAP_LARGE_PAGES :: DWORD(0x20000000)
|
||||
|
||||
// Flags for `SetFileCompletionNotificationModes`.
|
||||
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS :: 0x1
|
||||
FILE_SKIP_SET_EVENT_ON_HANDLE :: 0x2
|
||||
|
||||
PAGE_NOACCESS :: 0x01
|
||||
PAGE_READONLY :: 0x02
|
||||
PAGE_READWRITE :: 0x04
|
||||
|
||||
@@ -3,9 +3,24 @@ package sys_windows
|
||||
foreign import "system:Ole32.lib"
|
||||
|
||||
//objbase.h
|
||||
// Note(Dragos): https://learn.microsoft.com/en-us/windows/win32/api/objbase/ne-objbase-coinit makes you believe that MULTITHREADED == 3. That is wrong. See definition of objbase.h
|
||||
/*
|
||||
typedef enum tagCOINIT
|
||||
{
|
||||
COINIT_APARTMENTTHREADED = 0x2, // Apartment model
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
|
||||
// These constants are only valid on Windows NT 4.0
|
||||
COINIT_MULTITHREADED = COINITBASE_MULTITHREADED,
|
||||
COINIT_DISABLE_OLE1DDE = 0x4, // Don't use DDE for Ole1 support.
|
||||
COINIT_SPEED_OVER_MEMORY = 0x8, // Trade memory for speed.
|
||||
#endif // DCOM
|
||||
} COINIT;
|
||||
*/
|
||||
// Where COINITBASE_MULTITHREADED == 0x00
|
||||
COINIT :: enum DWORD {
|
||||
APARTMENTTHREADED = 0x2,
|
||||
MULTITHREADED,
|
||||
MULTITHREADED = 0,
|
||||
DISABLE_OLE1DDE = 0x4,
|
||||
SPEED_OVER_MEMORY = 0x8,
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
package sys_windows
|
||||
|
||||
// Define flags to be used with the WSAAsyncSelect() call.
|
||||
FD_READ :: 0x01
|
||||
FD_WRITE :: 0x02
|
||||
FD_OOB :: 0x04
|
||||
FD_ACCEPT :: 0x08
|
||||
FD_CONNECT :: 0x10
|
||||
FD_CLOSE :: 0x20
|
||||
FD_READ :: 0x01
|
||||
FD_WRITE :: 0x02
|
||||
FD_OOB :: 0x04
|
||||
FD_ACCEPT :: 0x08
|
||||
FD_CONNECT :: 0x10
|
||||
FD_CLOSE :: 0x20
|
||||
FD_MAX_EVENTS :: 10
|
||||
|
||||
INADDR_LOOPBACK :: 0x7f000001
|
||||
@@ -24,10 +24,10 @@ POLLERR :: 0x0001
|
||||
POLLHUP :: 0x0002
|
||||
POLLNVAL :: 0x0004
|
||||
|
||||
WSA_POLLFD::struct{
|
||||
fd:SOCKET,
|
||||
events:c_short,
|
||||
revents:c_short,
|
||||
WSA_POLLFD :: struct{
|
||||
fd: SOCKET,
|
||||
events: c_short,
|
||||
revents: c_short,
|
||||
}
|
||||
|
||||
WSANETWORKEVENTS :: struct {
|
||||
@@ -37,16 +37,43 @@ WSANETWORKEVENTS :: struct {
|
||||
|
||||
WSAEVENT :: HANDLE
|
||||
|
||||
WSAID_ACCEPTEX :: GUID{0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
WSAID_ACCEPTEX :: GUID{0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
WSAID_GETACCEPTEXSOCKADDRS :: GUID{0xb5367df2, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
|
||||
WSAID_CONNECTX :: GUID{0x25a207b9, 0xddf3, 0x4660, {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
|
||||
|
||||
SIO_GET_EXTENSION_FUNCTION_POINTER :: IOC_INOUT | IOC_WS2 | 6
|
||||
IOC_OUT :: 0x40000000
|
||||
IOC_IN :: 0x80000000
|
||||
|
||||
IOC_OUT :: 0x40000000
|
||||
IOC_IN :: 0x80000000
|
||||
IOC_INOUT :: (IOC_IN | IOC_OUT)
|
||||
IOC_WS2 :: 0x08000000
|
||||
IOC_WS2 :: 0x08000000
|
||||
|
||||
SO_UPDATE_ACCEPT_CONTEXT :: 28683
|
||||
|
||||
LPFN_CONNECTEX :: #type proc "system" (
|
||||
s: SOCKET,
|
||||
sockaddr: ^SOCKADDR_STORAGE_LH,
|
||||
namelen: c_int,
|
||||
lpSendBuffer: PVOID,
|
||||
dwSendDataLength: DWORD,
|
||||
lpdwBytesSent: LPDWORD,
|
||||
lpOverlapped: LPOVERLAPPED,
|
||||
) -> BOOL
|
||||
|
||||
LPFN_ACCEPTEX :: #type proc "system" (
|
||||
sListenSocket: SOCKET,
|
||||
sAcceptSocket: SOCKET,
|
||||
lpOutputBuffer: PVOID,
|
||||
dwReceiveDataLength: DWORD,
|
||||
dwLocalAddressLength: DWORD,
|
||||
dwRemoteAddressLength: DWORD,
|
||||
lpdwBytesReceived: LPDWORD,
|
||||
lpOverlapped: LPOVERLAPPED,
|
||||
) -> BOOL
|
||||
|
||||
/*
|
||||
Example Load:
|
||||
load_accept_ex :: proc(listener: SOCKET, fn_acceptex: rawptr) {
|
||||
load_accept_ex :: proc(listener: SOCKET, fn_acceptex: ^LPFN_ACCEPTEX) {
|
||||
bytes: u32
|
||||
guid_accept_ex := WSAID_ACCEPTEX
|
||||
rc := WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_accept_ex, size_of(guid_accept_ex),
|
||||
|
||||
@@ -128,7 +128,7 @@ parse_qt_linguist_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTI
|
||||
|
||||
num_plurals: int
|
||||
for {
|
||||
numerus_id := xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) or_break
|
||||
xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) or_break
|
||||
num_plurals += 1
|
||||
}
|
||||
|
||||
|
||||
+13
-28
@@ -45,18 +45,18 @@ accept_ranges := [5]Accept_Range{
|
||||
{0x80, 0x8f},
|
||||
}
|
||||
|
||||
accept_sizes := [256]u8{
|
||||
0x00..=0x7f = 0xf0,
|
||||
0x80..=0xc1 = 0xf1,
|
||||
0xc2..=0xdf = 0x02,
|
||||
0xe0 = 0x13,
|
||||
0xe1..=0xec = 0x03,
|
||||
0xed = 0x23,
|
||||
0xee..=0xef = 0x03,
|
||||
0xf0 = 0x34,
|
||||
0xf1..=0xf3 = 0x04,
|
||||
0xf4 = 0x44,
|
||||
0xf5..=0xff = 0xf1,
|
||||
accept_sizes := [256]u8{
|
||||
0x00..=0x7f = 0xf0, // ascii, size 1
|
||||
0x80..=0xc1 = 0xf1, // invalid, size 1
|
||||
0xc2..=0xdf = 0x02, // accept 1, size 2
|
||||
0xe0 = 0x13, // accept 1, size 3
|
||||
0xe1..=0xec = 0x03, // accept 0, size 3
|
||||
0xed = 0x23, // accept 2, size 3
|
||||
0xee..=0xef = 0x03, // accept 0, size 3
|
||||
0xf0 = 0x34, // accept 3, size 4
|
||||
0xf1..=0xf3 = 0x04, // accept 0, size 4
|
||||
0xf4 = 0x44, // accept 4, size 4
|
||||
0xf5..=0xff = 0xf1, // ascii, size 1
|
||||
}
|
||||
|
||||
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
|
||||
@@ -385,7 +385,7 @@ full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
x := _first[b[0]]
|
||||
x := accept_sizes[b[0]]
|
||||
if n >= int(x & 7) {
|
||||
return true
|
||||
}
|
||||
@@ -403,18 +403,3 @@ full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
|
||||
full_rune_in_string :: proc "contextless" (s: string) -> bool {
|
||||
return full_rune_in_bytes(transmute([]byte)s)
|
||||
}
|
||||
|
||||
|
||||
_first := [256]u8{
|
||||
0x00..=0x7f = 0xf0, // ascii, size 1
|
||||
0x80..=0xc1 = 0xf1, // invalid, size 1
|
||||
0xc2..=0xdf = 0x02, // accept 1, size 2
|
||||
0xe0 = 0x13, // accept 1, size 3
|
||||
0xe1..=0xec = 0x03, // accept 0, size 3
|
||||
0xed = 0x23, // accept 2, size 3
|
||||
0xee..=0xef = 0x03, // accept 0, size 3
|
||||
0xf0 = 0x34, // accept 3, size 4
|
||||
0xf1..=0xf3 = 0x04, // accept 0, size 4
|
||||
0xf4 = 0x44, // accept 4, size 4
|
||||
0xf5..=0xff = 0xf1, // ascii, size 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user