diff --git a/backend/vendor/github.com/enetx/g/bytes_compdecomp.go b/backend/vendor/github.com/enetx/g/bytes_compdecomp.go new file mode 100644 index 00000000..93af3da8 --- /dev/null +++ b/backend/vendor/github.com/enetx/g/bytes_compdecomp.go @@ -0,0 +1,128 @@ +package g + +import ( + "bytes" + "compress/flate" + "compress/gzip" + "compress/zlib" + "io" +) + +type ( + // A struct that wraps Bytes for compression. + bcompress struct{ bytes Bytes } + + // A struct that wraps Bytes for decompression. + bdecompress struct{ bytes Bytes } +) + +// Compress returns a bcompress struct wrapping the given Bytes. +func (bs Bytes) Compress() bcompress { return bcompress{bs} } + +// Decompress returns a bdecompress struct wrapping the given Bytes. +func (bs Bytes) Decompress() bdecompress { return bdecompress{bs} } + +// Zlib compresses the wrapped Bytes using the zlib compression algorithm and +// returns the compressed data as Bytes. +func (c bcompress) Zlib() Bytes { + buffer := new(bytes.Buffer) + writer := zlib.NewWriter(buffer) + + _, _ = writer.Write(c.bytes) + _ = writer.Flush() + _ = writer.Close() + + return buffer.Bytes() +} + +// Zlib decompresses the wrapped Bytes using the zlib compression algorithm and +// returns the decompressed data as a Result[Bytes]. +func (d bdecompress) Zlib() Result[Bytes] { + reader, err := zlib.NewReader(bytes.NewReader(d.bytes)) + if err != nil { + return Err[Bytes](err) + } + + defer reader.Close() + + buffer := new(bytes.Buffer) + if _, err := io.Copy(buffer, reader); err != nil { + return Err[Bytes](err) + } + + return Ok(Bytes(buffer.Bytes())) +} + +// Gzip compresses the wrapped Bytes using the gzip compression format and +// returns the compressed data as Bytes. +func (c bcompress) Gzip() Bytes { + buffer := new(bytes.Buffer) + writer := gzip.NewWriter(buffer) + + _, _ = writer.Write(c.bytes) + _ = writer.Flush() + _ = writer.Close() + + return buffer.Bytes() +} + +// Gzip decompresses the wrapped Bytes using the gzip compression format and +// returns the decompressed data as a Result[Bytes]. +func (d bdecompress) Gzip() Result[Bytes] { + reader, err := gzip.NewReader(bytes.NewReader(d.bytes)) + if err != nil { + return Err[Bytes](err) + } + + defer reader.Close() + + buffer := new(bytes.Buffer) + if _, err := io.Copy(buffer, reader); err != nil { + return Err[Bytes](err) + } + + return Ok(Bytes(buffer.Bytes())) +} + +// Flate compresses the wrapped Bytes using the flate (deflate) compression +// algorithm and returns the compressed data as Bytes. +// It accepts an optional compression level. If no level is provided, it +// defaults to 7. The level is clamped to the valid flate range [-2, 9] to +// avoid an invalid-level error that would otherwise return a nil writer and +// panic on use. +func (c bcompress) Flate(level ...int) Bytes { + buffer := new(bytes.Buffer) + + l := 7 + if len(level) != 0 { + l = level[0] + } + + if l < flate.HuffmanOnly { + l = flate.HuffmanOnly + } else if l > flate.BestCompression { + l = flate.BestCompression + } + + writer, _ := flate.NewWriter(buffer, l) + + _, _ = writer.Write(c.bytes) + _ = writer.Flush() + _ = writer.Close() + + return buffer.Bytes() +} + +// Flate decompresses the wrapped Bytes using the flate (deflate) compression +// algorithm and returns the decompressed data as a Result[Bytes]. +func (d bdecompress) Flate() Result[Bytes] { + reader := flate.NewReader(bytes.NewReader(d.bytes)) + defer reader.Close() + + buffer := new(bytes.Buffer) + if _, err := io.Copy(buffer, reader); err != nil { + return Err[Bytes](err) + } + + return Ok(Bytes(buffer.Bytes())) +} diff --git a/backend/vendor/github.com/enetx/g/bytes_encdec.go b/backend/vendor/github.com/enetx/g/bytes_encdec.go new file mode 100644 index 00000000..8df5f751 --- /dev/null +++ b/backend/vendor/github.com/enetx/g/bytes_encdec.go @@ -0,0 +1,344 @@ +package g + +import ( + "encoding/base64" + "encoding/hex" + "html" + "net/url" + "strconv" + + json "encoding/json/v2" +) + +type ( + // A struct that wraps Bytes for encoding. + bencode struct{ bytes Bytes } + + // A struct that wraps Bytes for decoding. + bdecode struct{ bytes Bytes } +) + +// Encode returns a bencode struct wrapping the given Bytes. +func (bs Bytes) Encode() bencode { return bencode{bs} } + +// Decode returns a bdecode struct wrapping the given Bytes. +func (bs Bytes) Decode() bdecode { return bdecode{bs} } + +// Base64 encodes the wrapped Bytes using standard Base64 (with padding). +func (e bencode) Base64() Bytes { + out := make(Bytes, base64.StdEncoding.EncodedLen(len(e.bytes))) + base64.StdEncoding.Encode(out, e.bytes) + return out +} + +// Base64Raw encodes the wrapped Bytes using standard Base64 without padding. +func (e bencode) Base64Raw() Bytes { + out := make(Bytes, base64.RawStdEncoding.EncodedLen(len(e.bytes))) + base64.RawStdEncoding.Encode(out, e.bytes) + return out +} + +// Base64URL encodes the wrapped Bytes using URL-safe Base64 (with padding). +func (e bencode) Base64URL() Bytes { + out := make(Bytes, base64.URLEncoding.EncodedLen(len(e.bytes))) + base64.URLEncoding.Encode(out, e.bytes) + return out +} + +// Base64RawURL encodes the wrapped Bytes using URL-safe Base64 without padding. +func (e bencode) Base64RawURL() Bytes { + out := make(Bytes, base64.RawURLEncoding.EncodedLen(len(e.bytes))) + base64.RawURLEncoding.Encode(out, e.bytes) + return out +} + +// Base64 decodes the wrapped Bytes as standard Base64 (with padding) and returns Result[Bytes]. +func (d bdecode) Base64() Result[Bytes] { + out := make(Bytes, base64.StdEncoding.DecodedLen(len(d.bytes))) + n, err := base64.StdEncoding.Decode(out, d.bytes) + if err != nil { + return Err[Bytes](err) + } + + return Ok(out[:n]) +} + +// Base64Raw decodes the wrapped Bytes as standard Base64 without padding and returns Result[Bytes]. +func (d bdecode) Base64Raw() Result[Bytes] { + out := make(Bytes, base64.RawStdEncoding.DecodedLen(len(d.bytes))) + n, err := base64.RawStdEncoding.Decode(out, d.bytes) + if err != nil { + return Err[Bytes](err) + } + + return Ok(out[:n]) +} + +// Base64URL decodes the wrapped Bytes as URL-safe Base64 (with padding) and returns Result[Bytes]. +func (d bdecode) Base64URL() Result[Bytes] { + out := make(Bytes, base64.URLEncoding.DecodedLen(len(d.bytes))) + n, err := base64.URLEncoding.Decode(out, d.bytes) + if err != nil { + return Err[Bytes](err) + } + + return Ok(out[:n]) +} + +// Base64RawURL decodes the wrapped Bytes as URL-safe Base64 without padding and returns Result[Bytes]. +func (d bdecode) Base64RawURL() Result[Bytes] { + out := make(Bytes, base64.RawURLEncoding.DecodedLen(len(d.bytes))) + n, err := base64.RawURLEncoding.Decode(out, d.bytes) + if err != nil { + return Err[Bytes](err) + } + + return Ok(out[:n]) +} + +// Hex hex-encodes the wrapped Bytes and returns the result as Bytes. +func (e bencode) Hex() Bytes { + out := make(Bytes, hex.EncodedLen(len(e.bytes))) + hex.Encode(out, e.bytes) + return out +} + +// Hex hex-decodes the wrapped Bytes and returns the decoded result as Result[Bytes]. +func (d bdecode) Hex() Result[Bytes] { + out := make(Bytes, hex.DecodedLen(len(d.bytes))) + n, err := hex.Decode(out, d.bytes) + if err != nil { + return Err[Bytes](err) + } + + return Ok(out[:n]) +} + +// XOR encodes the wrapped Bytes using XOR cipher with the given key. +// +// Warning: a repeating-key XOR cipher is not a security primitive and provides +// no real confidentiality. Use it only for lightweight obfuscation, never to +// protect secrets. +func (e bencode) XOR(key Bytes) Bytes { + if len(key) == 0 { + return e.bytes.Clone() + } + + out := make(Bytes, len(e.bytes)) + for i, b := range e.bytes { + out[i] = b ^ key[i%len(key)] + } + + return out +} + +// XOR decodes the wrapped Bytes using XOR cipher with the given key. +func (d bdecode) XOR(key Bytes) Bytes { return d.bytes.Encode().XOR(key) } + +// Binary converts the wrapped Bytes to its binary representation as Bytes. +func (e bencode) Binary() Bytes { + var b Builder + b.Grow(e.bytes.Len() * 8) + + for _, c := range e.bytes { + for bit := 7; bit >= 0; bit-- { + b.WriteByte('0' + (c>>uint(bit))&1) + } + } + + return b.String().Bytes() +} + +// Binary converts the wrapped binary Bytes back to raw Bytes as Result[Bytes]. +func (d bdecode) Binary() Result[Bytes] { + if len(d.bytes)%8 != 0 { + return Err[Bytes](ErrInvalidBinaryLength) + } + + out := make(Bytes, 0, len(d.bytes)/8) + + for i := 0; i+8 <= len(d.bytes); i += 8 { + var b byte + for j := range 8 { + c := d.bytes[i+j] + if c != '0' && c != '1' { + return Err[Bytes](ErrInvalidBinaryDigit) + } + b = b<<1 | (c - '0') + } + + out = append(out, b) + } + + return Ok(out) +} + +// JSON encodes the wrapped Bytes as a JSON string using encoding/json/v2 and +// returns the result as Result[Bytes]. +// +// The bytes are treated as text, mirroring String.Encode().JSON. +// +// v2 semantics: Bytes containing invalid UTF-8 yield Err — use Base64/Hex +// encoding for arbitrary binary data. +// Unlike encoding/json v1, the output does not HTML-escape '<', '>', '&' or the +// line separators U+2028/U+2029 — they are emitted raw. Escape the output +// yourself before embedding it in HTML or