aboutsummaryrefslogtreecommitdiff
path: root/core/encoding
diff options
context:
space:
mode:
authorUsername-Leon <leonardo.temperanza@gmail.com>2025-10-15 15:30:32 +0200
committerUsername-Leon <leonardo.temperanza@gmail.com>2025-10-15 15:30:32 +0200
commit4dd6bb2e871e9b8583a89e62ce36a98d02d48cc3 (patch)
tree25b7599645caf76ebe9136da51e5114006ab93f4 /core/encoding
parente10093bd991334789031df9ed587d27823ca90dd (diff)
parent596066aa0453752f24cc2fa5087fafe2c4686536 (diff)
Merge branch 'master' of https://github.com/LeonardoTemperanza/Odin
Diffstat (limited to 'core/encoding')
-rw-r--r--core/encoding/base32/base32.odin29
-rw-r--r--core/encoding/base32/base32_test.odin228
-rw-r--r--core/encoding/base64/base64.odin16
-rw-r--r--core/encoding/cbor/doc.odin6
-rw-r--r--core/encoding/csv/doc.odin3
-rw-r--r--core/encoding/endian/doc.odin3
-rw-r--r--core/encoding/entity/entity.odin18
-rw-r--r--core/encoding/hex/hex.odin1
-rw-r--r--core/encoding/hxa/doc.odin3
-rw-r--r--core/encoding/ini/ini.odin1
-rw-r--r--core/encoding/json/marshal.odin6
-rw-r--r--core/encoding/json/types.odin21
-rw-r--r--core/encoding/uuid/doc.odin3
-rw-r--r--core/encoding/uuid/legacy/legacy.odin5
-rw-r--r--core/encoding/varint/doc.odin6
-rw-r--r--core/encoding/varint/leb128.odin4
-rw-r--r--core/encoding/xml/doc.odin8
-rw-r--r--core/encoding/xml/xml_reader.odin6
18 files changed, 73 insertions, 294 deletions
diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin
index 2267a872b..34de2ff53 100644
--- a/core/encoding/base32/base32.odin
+++ b/core/encoding/base32/base32.odin
@@ -1,19 +1,20 @@
-// Base32 encoding/decoding implementation as specified in RFC 4648.
-// [[ More; https://www.rfc-editor.org/rfc/rfc4648.html ]]
+/*
+`Base32` encoding and decoding, as specified in [[ RFC 4648; https://www.rfc-editor.org/rfc/rfc4648.html ]].
+
+A secondary param can be used to supply a custom alphabet to `encode` and a matching decoding table to `decode`.
+
+If none is supplied it just uses the standard Base32 alphabet.
+In case your specific version does not use padding, you may
+truncate it from the encoded output.
+
+Error represents errors that can occur during base32 decoding operations.
+As per RFC 4648:
+- Section 3.3: Invalid character handling
+- Section 3.2: Padding requirements
+- Section 6: Base32 encoding specifics (including block size requirements)
+*/
package encoding_base32
-// @note(zh): Encoding utility for Base32
-// A secondary param can be used to supply a custom alphabet to
-// @link(encode) and a matching decoding table to @link(decode).
-// If none is supplied it just uses the standard Base32 alphabet.
-// In case your specific version does not use padding, you may
-// truncate it from the encoded output.
-
-// Error represents errors that can occur during base32 decoding operations.
-// As per RFC 4648:
-// - Section 3.3: Invalid character handling
-// - Section 3.2: Padding requirements
-// - Section 6: Base32 encoding specifics (including block size requirements)
Error :: enum {
None,
Invalid_Character, // Input contains characters outside the specified alphabet
diff --git a/core/encoding/base32/base32_test.odin b/core/encoding/base32/base32_test.odin
deleted file mode 100644
index 07d5c8080..000000000
--- a/core/encoding/base32/base32_test.odin
+++ /dev/null
@@ -1,228 +0,0 @@
-#+test
-package encoding_base32
-
-import "core:testing"
-import "core:bytes"
-
-@(test)
-test_base32_decode_valid :: proc(t: ^testing.T) {
- // RFC 4648 Section 10 - Test vectors
- cases := [?]struct {
- input, expected: string,
- }{
- {"", ""},
- {"MY======", "f"},
- {"MZXQ====", "fo"},
- {"MZXW6===", "foo"},
- {"MZXW6YQ=", "foob"},
- {"MZXW6YTB", "fooba"},
- {"MZXW6YTBOI======", "foobar"},
- }
-
- for c in cases {
- output, err := decode(c.input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.None)
- expected := transmute([]u8)c.expected
- if output != nil {
- testing.expect(t, bytes.equal(output, expected))
- } else {
- testing.expect(t, len(c.expected) == 0)
- }
- }
-}
-
-@(test)
-test_base32_encode :: proc(t: ^testing.T) {
- // RFC 4648 Section 10 - Test vectors
- cases := [?]struct {
- input, expected: string,
- }{
- {"", ""},
- {"f", "MY======"},
- {"fo", "MZXQ===="},
- {"foo", "MZXW6==="},
- {"foob", "MZXW6YQ="},
- {"fooba", "MZXW6YTB"},
- {"foobar", "MZXW6YTBOI======"},
- }
-
- for c in cases {
- output := encode(transmute([]byte)c.input)
- defer delete(output)
- testing.expect(t, output == c.expected)
- }
-}
-
-@(test)
-test_base32_decode_invalid :: proc(t: ^testing.T) {
- // Section 3.3 - Non-alphabet characters
- {
- // Characters outside alphabet
- input := "MZ1W6YTB" // '1' not in alphabet (A-Z, 2-7)
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Invalid_Character)
- }
- {
- // Lowercase not allowed
- input := "mzxq===="
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Invalid_Character)
- }
-
- // Section 3.2 - Padding requirements
- {
- // Padding must only be at end
- input := "MZ=Q===="
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Malformed_Input)
- }
- {
- // Missing padding
- input := "MZXQ" // Should be MZXQ====
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Malformed_Input)
- }
- {
- // Incorrect padding length
- input := "MZXQ=" // Needs 4 padding chars
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Malformed_Input)
- }
- {
- // Too much padding
- input := "MY=========" // Extra padding chars
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Malformed_Input)
- }
-
- // Section 6 - Base32 block size requirements
- {
- // Single character (invalid block)
- input := "M"
- output, err := decode(input)
- if output != nil {
- defer delete(output)
- }
- testing.expect_value(t, err, Error.Invalid_Length)
- }
-}
-
-@(test)
-test_base32_roundtrip :: proc(t: ^testing.T) {
- cases := [?]string{
- "",
- "f",
- "fo",
- "foo",
- "foob",
- "fooba",
- "foobar",
- }
-
- for input in cases {
- encoded := encode(transmute([]byte)input)
- defer delete(encoded)
- decoded, err := decode(encoded)
- if decoded != nil {
- defer delete(decoded)
- }
- testing.expect_value(t, err, Error.None)
- testing.expect(t, bytes.equal(decoded, transmute([]byte)input))
- }
-}
-
-@(test)
-test_base32_custom_alphabet :: proc(t: ^testing.T) {
- custom_enc_table := [32]byte{
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
- 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- }
-
- custom_dec_table: [256]u8
- for i := 0; i < len(custom_enc_table); i += 1 {
- custom_dec_table[custom_enc_table[i]] = u8(i)
- }
-
- /*
- custom_dec_table := [256]u8{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00-0x0f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10-0x1f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20-0x2f
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // 0x30-0x3f ('0'-'9')
- 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 0x40-0x4f ('A'-'O')
- 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50-0x5f ('P'-'V')
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60-0x6f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70-0x7f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80-0x8f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90-0x9f
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0-0xaf
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0-0xbf
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xc0-0xcf
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xd0-0xdf
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0-0xef
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0-0xff
- }
- */
-
- custom_validate :: proc(c: byte) -> bool {
- return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'V') || c == byte(PADDING)
- }
-
- cases := [?]struct {
- input: string,
- enc_expected: string,
- }{
- {"f", "CO======"},
- {"fo", "CPNG===="},
- {"foo", "CPNMU==="},
- }
-
- for c in cases {
- // Test encoding
- encoded := encode(transmute([]byte)c.input, custom_enc_table)
- defer delete(encoded)
- testing.expect(t, encoded == c.enc_expected)
-
- // Test decoding
- decoded, err := decode(encoded, custom_dec_table, custom_validate)
- defer if decoded != nil {
- delete(decoded)
- }
-
- testing.expect_value(t, err, Error.None)
- testing.expect(t, bytes.equal(decoded, transmute([]byte)c.input))
- }
-
- // Test invalid character detection
- {
- input := "WXY=====" // Contains chars not in our alphabet
- output, err := decode(input, custom_dec_table, custom_validate)
- if output != nil {
- delete(output)
- }
- testing.expect_value(t, err, Error.Invalid_Character)
- }
-}
diff --git a/core/encoding/base64/base64.odin b/core/encoding/base64/base64.odin
index 1013a7d0b..2cd7227b5 100644
--- a/core/encoding/base64/base64.odin
+++ b/core/encoding/base64/base64.odin
@@ -1,16 +1,18 @@
+/*
+`Base64` encoding and decoding.
+
+A secondary param can be used to supply a custom alphabet to `encode` and a matching decoding table to `decode`.
+
+If none is supplied it just uses the standard Base64 alphabet.
+In case your specific version does not use padding, you may
+truncate it from the encoded output.
+*/
package encoding_base64
import "core:io"
import "core:mem"
import "core:strings"
-// @note(zh): Encoding utility for Base64
-// A secondary param can be used to supply a custom alphabet to
-// @link(encode) and a matching decoding table to @link(decode).
-// If none is supplied it just uses the standard Base64 alphabet.
-// Incase your specific version does not use padding, you may
-// truncate it from the encoded output.
-
ENC_TABLE := [64]byte {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
diff --git a/core/encoding/cbor/doc.odin b/core/encoding/cbor/doc.odin
index b3fa36130..370c5aaa9 100644
--- a/core/encoding/cbor/doc.odin
+++ b/core/encoding/cbor/doc.odin
@@ -1,5 +1,6 @@
/*
-Package cbor encodes, decodes, marshals and unmarshals types from/into RCF 8949 compatible CBOR binary.
+Encodes and decodes types from/into [[ RCF 8949; https://www.rfc-editor.org/rfc/rfc8949.html ]] compatible `CBOR` binary.
+
Also provided are conversion to and from JSON and the CBOR diagnostic format.
**Allocations:**
@@ -165,5 +166,4 @@ Output:
"str": "Hello, World!"
}
*/
-package encoding_cbor
-
+package encoding_cbor \ No newline at end of file
diff --git a/core/encoding/csv/doc.odin b/core/encoding/csv/doc.odin
index 7abe2be49..50b8e3d1a 100644
--- a/core/encoding/csv/doc.odin
+++ b/core/encoding/csv/doc.odin
@@ -1,6 +1,5 @@
/*
-package csv reads and writes comma-separated values (CSV) files.
-This package supports the format described in [[ RFC 4180; https://tools.ietf.org/html/rfc4180.html ]]
+Reader and writer for comma-separated values (`CSV`) files, per [[ RFC 4180 ; https://tools.ietf.org/html/rfc4180.html ]].
Example:
package main
diff --git a/core/encoding/endian/doc.odin b/core/encoding/endian/doc.odin
index 0b43e3097..7cc9da1b7 100644
--- a/core/encoding/endian/doc.odin
+++ b/core/encoding/endian/doc.odin
@@ -1,6 +1,5 @@
/*
- Package endian implements a simple translation between bytes and numbers with
- specific endian encodings.
+ A simple translation between bytes and numbers with specific endian encodings.
Example:
buf: [100]u8
diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin
index cb8fa8611..28ff58170 100644
--- a/core/encoding/entity/entity.odin
+++ b/core/encoding/entity/entity.odin
@@ -1,13 +1,5 @@
/*
- Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
- Made available under Odin's BSD-3 license.
-
- List of contributors:
- Jeroen van Rijn: Initial implementation.
-*/
-
-/*
- A unicode entity encoder/decoder.
+ Encode and decode `rune`s to/from a Unicode `&entity;`.
This code has several procedures to map unicode runes to/from different textual encodings.
- SGML/XML/HTML entity
@@ -21,6 +13,14 @@
*/
package encoding_unicode_entity
+/*
+ Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
+ Made available under Odin's BSD-3 license.
+
+ List of contributors:
+ Jeroen van Rijn: Initial implementation.
+*/
+
import "core:unicode/utf8"
import "core:unicode"
import "core:strings"
diff --git a/core/encoding/hex/hex.odin b/core/encoding/hex/hex.odin
index c1753003e..318e52ace 100644
--- a/core/encoding/hex/hex.odin
+++ b/core/encoding/hex/hex.odin
@@ -1,3 +1,4 @@
+// Encoding and decoding of hex-encoded binary, e.g. `0x23` -> `#`.
package encoding_hex
import "core:io"
diff --git a/core/encoding/hxa/doc.odin b/core/encoding/hxa/doc.odin
index b696bef7e..902428668 100644
--- a/core/encoding/hxa/doc.odin
+++ b/core/encoding/hxa/doc.odin
@@ -1,5 +1,6 @@
/*
-Implementation of the HxA 3D asset format
+Eskil Steenberg's `HxA` 3D asset interchange format.
+
HxA is a interchangeable graphics asset format.
Designed by Eskil Steenberg. @quelsolaar / eskil 'at' obsession 'dot' se / www.quelsolaar.com
diff --git a/core/encoding/ini/ini.odin b/core/encoding/ini/ini.odin
index c32b1deb5..a119b0f2e 100644
--- a/core/encoding/ini/ini.odin
+++ b/core/encoding/ini/ini.odin
@@ -1,3 +1,4 @@
+// Reader and writer for a variant of the `.ini` file format with `key = value` entries in `[sections]`.
package encoding_ini
import "base:runtime"
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin
index cdb00a354..e563c326a 100644
--- a/core/encoding/json/marshal.odin
+++ b/core/encoding/json/marshal.odin
@@ -176,7 +176,11 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
return .Unsupported_Type
case runtime.Type_Info_Pointer:
- return .Unsupported_Type
+ if v.id == typeid_of(Null) {
+ io.write_string(w, "null") or_return
+ } else {
+ return .Unsupported_Type
+ }
case runtime.Type_Info_Multi_Pointer:
return .Unsupported_Type
diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin
index 41eb21377..1da17a0db 100644
--- a/core/encoding/json/types.odin
+++ b/core/encoding/json/types.odin
@@ -1,14 +1,13 @@
-package encoding_json
-
-import "core:strings"
-
/*
- JSON
+Encoding and decoding JSON in strict `JSON`, [[ JSON5 ; https://json5.org/ ]] and [[ BitSquid ; https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html ]] variants.
+
+Using one of these `Specification`s.
+ JSON
strict JSON
- JSON5
+ JSON5
pure superset of JSON and valid JavaScript
https://json5.org/
-
+
* Object keys may be an ECMAScript 5.1 IdentifierName.
* Objects may have a single trailing comma.
* Arrays may have a single trailing comma.
@@ -21,17 +20,21 @@ import "core:strings"
* Numbers may begin with an explicit plus sign.
* Single and multi-line comments are allowed.
* Additional white space characters are allowed.
-
+
MJSON
pure superset of JSON5, may not be valid JavaScript
https://bitsquid.blogspot.com/2009/10/simplified-json-notation.html
-
+
* All the same features as JSON5 plus extras.
* Assume an object definition at the root level (no need to surround entire file with { } ).
* Commas are optional, using comma insertion rules with newlines.
* Quotes around object keys are optional if the keys are valid identifiers.
* : can be replaced with =
*/
+package encoding_json
+
+import "core:strings"
+
Specification :: enum {
JSON,
JSON5, // https://json5.org/
diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin
index f910c33d8..a5f01ca7c 100644
--- a/core/encoding/uuid/doc.odin
+++ b/core/encoding/uuid/doc.odin
@@ -1,6 +1,5 @@
/*
-package uuid implements Universally Unique Identifiers according to the
-standard originally outlined in RFC 4122 with additions from RFC 9562.
+Universally Unique Identifiers (`UUID`) according to [[ RFC 4122 ; https://tools.ietf.org/html/rfc4122.html ]], with additions from [[ RFC 9562 ; https://tools.ietf.org/html/rfc9562.html ]].
The UUIDs are textually represented and read in the following string format:
`00000000-0000-v000-V000-000000000000`
diff --git a/core/encoding/uuid/legacy/legacy.odin b/core/encoding/uuid/legacy/legacy.odin
index d5f3df617..fe5c88e23 100644
--- a/core/encoding/uuid/legacy/legacy.odin
+++ b/core/encoding/uuid/legacy/legacy.odin
@@ -1,7 +1,6 @@
/*
-package uuid/legacy implements versions 3 and 5 of UUID generation, both of
-which are using hashing algorithms (MD5 and SHA1, respectively) that are known
-these days to no longer be secure.
+Versions 3 and 5 of `UUID` generation, both of which use legacy (`MD5` + `SHA1`) hashes.
+Those are known these days to no longer be secure.
*/
package uuid_legacy
diff --git a/core/encoding/varint/doc.odin b/core/encoding/varint/doc.odin
index a00cfed15..e17faec49 100644
--- a/core/encoding/varint/doc.odin
+++ b/core/encoding/varint/doc.odin
@@ -1,7 +1,5 @@
/*
-Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others.
-
-Author of this Odin package: Jeroen van Rijn
+`LEB128` variable integer encoding and decoding, as used by `DWARF` & `DEX` files.
Example:
package main
@@ -24,4 +22,4 @@ Example:
fmt.printf("Decoded as %v, using %v byte%v\n", decoded_val, decode_size, "" if decode_size == 1 else "s")
}
*/
-package encoding_varint
+package encoding_varint \ No newline at end of file
diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin
index 606c57ba7..876a1ba76 100644
--- a/core/encoding/varint/leb128.odin
+++ b/core/encoding/varint/leb128.odin
@@ -1,3 +1,5 @@
+package encoding_varint
+
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
@@ -6,8 +8,6 @@
Jeroen van Rijn: Initial implementation.
*/
-package encoding_varint
-
// In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file.
// Instead we'll set limits on the values we'll encode/decode
// 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`.
diff --git a/core/encoding/xml/doc.odin b/core/encoding/xml/doc.odin
index 10d9f78be..9030cd400 100644
--- a/core/encoding/xml/doc.odin
+++ b/core/encoding/xml/doc.odin
@@ -1,7 +1,7 @@
/*
-XML 1.0 / 1.1 parser
+A parser for a useful subset of the `XML` specification.
-A from-scratch XML implementation, loosely modelled on the [[ spec; https://www.w3.org/TR/2006/REC-xml11-20060816 ]].
+A from-scratch `XML` implementation, loosely modelled on the [[ spec; https://www.w3.org/TR/2006/REC-xml11-20060816 ]].
Features:
- Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage.
@@ -11,8 +11,8 @@ Caveats:
- We do NOT support HTML in this package, as that may or may not be valid XML.
If it works, great. If it doesn't, that's not considered a bug.
-- We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences.
-- <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options.
+- We do NOT support `UTF-16`. If you have a `UTF-16` XML file, please convert it to `UTF-8` first. Also, our condolences.
+- `<[!ELEMENT` and `<[!ATTLIST` are not supported, and will be either ignored or return an error depending on the parser options.
MAYBE:
- XML writer?
diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin
index 707d2b3f3..621c9c2d0 100644
--- a/core/encoding/xml/xml_reader.odin
+++ b/core/encoding/xml/xml_reader.odin
@@ -1,4 +1,7 @@
+package encoding_xml
/*
+ An XML 1.0 / 1.1 parser
+
2021-2022 Jeroen van Rijn <nom@duclavier.com>.
available under Odin's BSD-3 license.
@@ -6,9 +9,6 @@
- Jeroen van Rijn: Initial implementation.
*/
-package encoding_xml
-// An XML 1.0 / 1.1 parser
-
import "core:bytes"
import "core:encoding/entity"
import "base:intrinsics"