mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-20 21:35:19 +00:00
Add API for creating custom version 8 UUIDs
This commit is contained in:
89
core/encoding/uuid/stamping.odin
Normal file
89
core/encoding/uuid/stamping.odin
Normal file
@@ -0,0 +1,89 @@
|
||||
package uuid
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
/*
|
||||
Stamp a 128-bit integer as being a valid version 8 UUID.
|
||||
|
||||
Per the specification, all version 8 UUIDs are either for experimental or
|
||||
vendor-specific purposes. This procedure allows for converting arbitrary data
|
||||
into custom UUIDs.
|
||||
|
||||
Inputs:
|
||||
- integer: Any integer type.
|
||||
|
||||
Returns:
|
||||
- result: A valid version 8 UUID.
|
||||
*/
|
||||
stamp_v8_int :: proc(#any_int integer: u128) -> (result: Identifier) {
|
||||
result = transmute(Identifier)cast(u128be)integer
|
||||
|
||||
result[VERSION_BYTE_INDEX] &= 0x0F
|
||||
result[VERSION_BYTE_INDEX] |= 0x80
|
||||
|
||||
result[VARIANT_BYTE_INDEX] &= 0x3F
|
||||
result[VARIANT_BYTE_INDEX] |= 0x80
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
Stamp an array of 16 bytes as being a valid version 8 UUID.
|
||||
|
||||
Per the specification, all version 8 UUIDs are either for experimental or
|
||||
vendor-specific purposes. This procedure allows for converting arbitrary data
|
||||
into custom UUIDs.
|
||||
|
||||
Inputs:
|
||||
- array: An array of 16 bytes.
|
||||
|
||||
Returns:
|
||||
- result: A valid version 8 UUID.
|
||||
*/
|
||||
stamp_v8_array :: proc(array: [16]u8) -> (result: Identifier) {
|
||||
result = transmute(Identifier)array
|
||||
|
||||
result[VERSION_BYTE_INDEX] &= 0x0F
|
||||
result[VERSION_BYTE_INDEX] |= 0x80
|
||||
|
||||
result[VARIANT_BYTE_INDEX] &= 0x3F
|
||||
result[VARIANT_BYTE_INDEX] |= 0x80
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
Stamp a slice of bytes as being a valid version 8 UUID.
|
||||
|
||||
If the slice is less than 16 bytes long, the data available will be used.
|
||||
If it is longer than 16 bytes, only the first 16 will be used.
|
||||
|
||||
This procedure does not modify the underlying slice.
|
||||
|
||||
Per the specification, all version 8 UUIDs are either for experimental or
|
||||
vendor-specific purposes. This procedure allows for converting arbitrary data
|
||||
into custom UUIDs.
|
||||
|
||||
Inputs:
|
||||
- slice: A slice of bytes.
|
||||
|
||||
Returns:
|
||||
- result: A valid version 8 UUID.
|
||||
*/
|
||||
stamp_v8_slice :: proc(slice: []u8) -> (result: Identifier) {
|
||||
runtime.mem_copy_non_overlapping(&result, &slice[0], min(16, len(slice)))
|
||||
|
||||
result[VERSION_BYTE_INDEX] &= 0x0F
|
||||
result[VERSION_BYTE_INDEX] |= 0x80
|
||||
|
||||
result[VARIANT_BYTE_INDEX] &= 0x3F
|
||||
result[VARIANT_BYTE_INDEX] |= 0x80
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
stamp_v8 :: proc {
|
||||
stamp_v8_int,
|
||||
stamp_v8_array,
|
||||
stamp_v8_slice,
|
||||
}
|
||||
@@ -18,7 +18,13 @@ test_version_and_variant :: proc(t: ^testing.T) {
|
||||
v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "")
|
||||
v6 := uuid.generate_v6()
|
||||
v7 := uuid.generate_v7()
|
||||
v8 := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512)
|
||||
|
||||
_v8_array: [16]u8 = 0xff
|
||||
v8_int := uuid.stamp_v8(max(u128))
|
||||
v8_array := uuid.stamp_v8(_v8_array)
|
||||
v8_slice := uuid.stamp_v8(_v8_array[:])
|
||||
|
||||
v8_hash := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512)
|
||||
|
||||
testing.expect_value(t, uuid.version(v1), 1)
|
||||
testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122)
|
||||
@@ -32,8 +38,16 @@ test_version_and_variant :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122)
|
||||
testing.expect_value(t, uuid.version(v7), 7)
|
||||
testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122)
|
||||
testing.expect_value(t, uuid.version(v8), 8)
|
||||
testing.expect_value(t, uuid.variant(v8), uuid.Variant_Type.RFC_4122)
|
||||
|
||||
testing.expect_value(t, uuid.version(v8_int), 8)
|
||||
testing.expect_value(t, uuid.variant(v8_int), uuid.Variant_Type.RFC_4122)
|
||||
testing.expect_value(t, uuid.version(v8_array), 8)
|
||||
testing.expect_value(t, uuid.variant(v8_array), uuid.Variant_Type.RFC_4122)
|
||||
testing.expect_value(t, uuid.version(v8_slice), 8)
|
||||
testing.expect_value(t, uuid.variant(v8_slice), uuid.Variant_Type.RFC_4122)
|
||||
|
||||
testing.expect_value(t, uuid.version(v8_hash), 8)
|
||||
testing.expect_value(t, uuid.variant(v8_hash), uuid.Variant_Type.RFC_4122)
|
||||
}
|
||||
|
||||
@(test)
|
||||
|
||||
Reference in New Issue
Block a user