package uuid
import "core:crypto"
import "core:io"
import "core:mem"
UUID_SIZE :: 16
UUID :: distinct [UUID_SIZE]byte
generate :: proc() -> (u: UUID) #no_bounds_check {
crypto.rand_bytes(u[:])
u[6] = (u[6] & 0x0f) | (4 << 4)
u[8] = (u[8] & (0xff >> 2) | (0x02 << 6))
return u
}
to_string :: proc(dst: []byte, u: UUID) #no_bounds_check {
u := u
assert(len(dst) >= 36, "dst not big enough for UUID")
hex(dst[0:8], u[0:4])
dst[8] = '-'
hex(dst[9:13], u[4:6])
dst[13] = '-'
hex(dst[14:18], u[6:8])
dst[18] = '-'
hex(dst[19:23], u[8:10])
dst[23] = '-'
hex(dst[24:], u[10:])
}
clone_to_string :: proc(
u: UUID,
allocator := context.allocator,
) -> (
str: string,
err: mem.Allocator_Error,
) {
buf := make([]byte, 36, allocator) or_return
to_string(buf, u)
str = string(buf)
delete(buf)
return
}
write :: proc(dst: io.Writer, u: UUID, n_written: ^int = nil) -> (int, io.Error) {
buf: [36]byte
to_string(buf[:], u)
return io.write(dst, buf[:], n_written)
}
@(private)
HEXTABLE := [16]byte {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f',
}
@(private)
hex :: proc(dst, src: []byte) #no_bounds_check {
i := 0
for v in src {
dst[i] = HEXTABLE[v >> 4]
dst[i + 1] = HEXTABLE[v & 0x0f]
i += 2
}
}