data

package
v0.1.59999 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 11 Imported by: 7

README

data

-- import "github.com/go-i2p/common/data"

data.svg

Package data implements common data structures used in higher level structures.

Usage

const BITS_PER_BYTE = 8

BITS_PER_BYTE is the number of bits in a byte, used for bit shift calculations Cross-Ref: integer.go

const DATE_SIZE = 8

DATE_SIZE is the length in bytes of an I2P Date. Cross-Ref: date.go

const KEY_VAL_INTEGER_LENGTH = 1

KEY_VAL_INTEGER_LENGTH is the length in bytes for encoding key and value lengths in I2P mappings Cross-Ref: mapping.go

const MAPPING_EQUALS_DELIMITER = 0x3d

MAPPING_EQUALS_DELIMITER is the ASCII character '=' (0x3d) used to separate keys from values in I2P mappings Cross-Ref: mapping.go

const MAPPING_MIN_SIZE = 3

MAPPING_MIN_SIZE is the minimum size in bytes for a valid I2P mapping (2-byte length field + at least 1 byte data) Cross-Ref: mapping.go

const MAPPING_SEMICOLON_DELIMITER = 0x3b

MAPPING_SEMICOLON_DELIMITER is the ASCII character ';' (0x3b) used to separate key-value pairs in I2P mappings Cross-Ref: mapping.go

const MAPPING_SIZE_FIELD_LENGTH = 2

MAPPING_SIZE_FIELD_LENGTH is the length in bytes of the mapping size field in I2P mappings Cross-Ref: mapping.go

const MAX_INTEGER_SIZE = 8

MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes. Cross-Ref: integer.go

const STRING_MAX_SIZE = 255

STRING_MAX_SIZE is the maximum number of bytes that can be stored in an I2P string Cross-Ref: string.go

var (
	ErrZeroLength            = fmt.Errorf("error parsing string: zero length")
	ErrDataTooShort          = fmt.Errorf("string parsing warning: string data is shorter than specified by length")
	ErrDataTooLong           = fmt.Errorf("string parsing warning: string contains data beyond length")
	ErrLengthMismatch        = fmt.Errorf("error reading I2P string, length does not match data")
	ErrMappingLengthMismatch = fmt.Errorf("warning parsing mapping: mapping length exceeds provided data")
)
func PrintErrors
func PrintErrors(errs []error)

PrintErrors prints a formatted list of errors to the console. Used in: errors.go

func WrapErrors
func WrapErrors(errs []error) error

WrapErrors compiles a slice of errors and returns them wrapped together as a single error. Used in: errors.go

type Date
type Date [8]byte

Date is the represenation of an I2P Date.

https://geti2p.net/spec/common-structures#date

func DateFromTime
func DateFromTime(t time.Time) (date *Date, err error)

DateFromTime takes a time.Time and returns a data.Date

func NewDate
func NewDate(data []byte) (date *Date, remainder []byte, err error)

NewDate creates a new Date from []byte using ReadDate. Returns a pointer to Date unlike ReadDate.

func ReadDate
func ReadDate(data []byte) (date Date, remainder []byte, err error)

ReadDate creates a Date from []byte using the first DATE_SIZE bytes. Any data after DATE_SIZE is returned as a remainder.

func (Date) Bytes
func (i Date) Bytes() []byte

Bytes returns the raw []byte content of a Date.

func (Date) Int
func (i Date) Int() int

Int returns the Date as a Go integer.

func (Date) Time
func (date Date) Time() (date_time time.Time)

Time takes the value stored in date as an 8 byte big-endian integer representing the number of milliseconds since the beginning of unix time and converts it to a Go time.Time struct.

type Hash
type Hash [32]byte

Hash is the represenation of an I2P Hash.

https://geti2p.net/spec/common-structures#hash

func HashData
func HashData(data []byte) (h Hash)

HashData returns the SHA256 sum of a []byte input as Hash.

func HashReader
func HashReader(r io.Reader) (h Hash, err error)

HashReader returns the SHA256 sum from all data read from an io.Reader. return error if one occurs while reading from reader

func (Hash) Bytes
func (h Hash) Bytes() [32]byte

Bytes returns the raw []byte content of a Hash.

type I2PString
type I2PString []byte

I2PString is the representation of an I2P String.

https://geti2p.net/spec/common-structures#string

func ReadI2PString
func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error)

ReadI2PString returns I2PString from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func ToI2PString
func ToI2PString(data string) (str I2PString, err error)

ToI2PString converts a Go string to an I2PString. Returns error if the string exceeds STRING_MAX_SIZE.

func (I2PString) Data
func (str I2PString) Data() (data string, err error)

Data returns the I2PString content as a string trimmed to the specified length and not including the length byte. Returns error encountered by Length.

func (I2PString) Length
func (str I2PString) Length() (length int, err error)

Length returns the length specified in the first byte. Returns error if the specified does not match the actual length or the string is otherwise invalid.

type Integer
type Integer []byte

Integer is the represenation of an I2P Integer.

https://geti2p.net/spec/common-structures#integer

func NewInteger
func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error)

NewInteger creates a new Integer from []byte using ReadInteger. Deprecated: Use ReadInteger and take address if pointer needed. This function will be removed in v2.0. Returns a pointer to Integer unlike ReadInteger.

func NewIntegerFromInt
func NewIntegerFromInt(value int, size int) (integer *Integer, err error)

NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte length.

func ReadInteger
func ReadInteger(bytes []byte, size int) (Integer, []byte)

ReadInteger returns an Integer from a []byte of specified length. The remaining bytes after the specified length are also returned.

func (Integer) Bytes
func (i Integer) Bytes() []byte

Bytes returns the raw []byte content of an Integer.

func (Integer) Int
func (i Integer) Int() int

Int returns the Integer as a Go integer

type Mapping
type Mapping struct {
}

Mapping is the represenation of an I2P Mapping.

https://geti2p.net/spec/common-structures#mapping

func GoMapToMapping
func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error)

GoMapToMapping converts a Go map of unformatted strings to *Mapping.

func NewMapping
func NewMapping(bytes []byte) (values *Mapping, remainder []byte, err []error)

NewMapping creates a new *Mapping from []byte using ReadMapping. Returns a pointer to Mapping unlike ReadMapping.

func ReadMapping
func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)

ReadMapping returns Mapping from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func ValuesToMapping
func ValuesToMapping(values MappingValues) *Mapping

ValuesToMapping creates a *Mapping using MappingValues. The values are sorted in the order defined in mappingOrder.

func (*Mapping) Data
func (mapping *Mapping) Data() []byte

Data returns a Mapping in its []byte form.

func (*Mapping) HasDuplicateKeys
func (mapping *Mapping) HasDuplicateKeys() bool

HasDuplicateKeys returns true if two keys in a mapping are identical.

func (Mapping) Values
func (mapping Mapping) Values() MappingValues

Values returns the values contained in a Mapping as MappingValues.

type MappingValues
type MappingValues [][2]I2PString

MappingValues represents the parsed key value pairs inside of an I2P Mapping.

func ReadMappingValues
func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error)

ReadMappingValues returns *MappingValues from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func (MappingValues) Get
func (m MappingValues) Get(key I2PString) I2PString

Get retrieves the value for a given key from MappingValues.

data

github.com/go-i2p/common/data

go-i2p template file

Documentation

Overview

Package data implements I2P common data structures according to specification version 0.9.67.

This package provides fundamental data types used throughout the I2P network protocol, including safe constructors and validators to prevent common programming errors.

Overview

The data package contains low-level I2P data structures that are building blocks for higher-level protocol components:

  • Integer: Variable-length big-endian integers
  • I2PString: Length-prefixed UTF-8 strings (max 255 bytes)
  • Date: 64-bit millisecond timestamps (rolls over in 2106)
  • Hash: 32-byte SHA-256 hashes
  • Mapping: Key-value property maps
  • MappingValues: Type-safe key-value pair collections

Safe Constructors

All types provide safe constructors that validate input and return errors rather than panicking or producing invalid data:

// Integer construction with validation
i, err := data.NewIntegerFromBytes(someBytes)
if err != nil {
    return err
}
value, err := i.IntSafe()  // Returns error instead of defaulting to 0

// String construction with UTF-8 validation
str, err := data.NewI2PString("hello")
if err != nil {
    return err
}
content, err := str.DataSafe()  // Safe accessor with error handling

// Hash construction from bytes
hash, err := data.NewHashFromSlice(hashBytes)
if err != nil {
    return err
}

// Date construction with validation
date, err := data.NewDateFromUnix(timestamp)
if err != nil {
    return err
}

Zero-Value Safety

All types provide methods to check for zero/invalid values:

if integer.IsZero() {
    // Handle zero integer
}

if hash.IsZero() {
    // Handle zero hash
}

if date.IsZero() {
    // Handle undefined date
}

Validation

Types provide Validate() and IsValid() methods for checking integrity:

// Validate mapping structure and all key-value pairs
if err := mapping.Validate(); err != nil {
    return err
}

// Boolean validation check
if !mapping.IsValid() {
    return errors.New("invalid mapping")
}

Encoding and Decoding

The package provides safe integer encoding with overflow checks:

// Encode with size validation
encoded, err := data.EncodeIntN(12345, 4)  // validates value fits in 4 bytes
if err != nil {
    return err
}

// Decode with length validation
decoded, err := data.DecodeIntN(encoded)
if err != nil {
    return err
}

Stream Parsing

Many types support stream-oriented parsing for efficient multi-value reads:

hash1, remaining, err := data.ReadHash(data)
if err != nil {
    return err
}
hash2, remaining, err := data.ReadHash(remaining)
// ... continue parsing

Best Practices

  • Always use safe constructors (NewXxx) for untrusted input
  • Check IsValid() or Validate() after parsing from bytes
  • Use safe accessor methods (xxxSafe) when error handling is critical
  • Validate sizes before encoding to prevent DoS attacks

Specification

Reference: https://geti2p.net/spec/common-structures

This implementation follows I2P specification version 0.9.67 and provides backward-compatible safe constructors while maintaining the existing API.

Package data implements I2P common data structures.

Index

Constants

View Source
const BITS_PER_BYTE = 8

BITS_PER_BYTE is the number of bits in a byte, used for bit shift calculations Cross-Ref: integer.go

View Source
const DATE_SIZE = 8

DATE_SIZE is the length in bytes of an I2P Date. Cross-Ref: date.go

View Source
const KEY_VAL_INTEGER_LENGTH = 1

KEY_VAL_INTEGER_LENGTH is the length in bytes for encoding key and value lengths in I2P mappings Cross-Ref: mapping.go

View Source
const MAPPING_EQUALS_DELIMITER = 0x3d

MAPPING_EQUALS_DELIMITER is the ASCII character '=' (0x3d) used to separate keys from values in I2P mappings Cross-Ref: mapping.go

View Source
const MAPPING_MIN_SIZE = 2

MAPPING_MIN_SIZE is the minimum size in bytes for a valid I2P mapping (2-byte size field; size=0 is valid) Cross-Ref: mapping.go

View Source
const MAPPING_SEMICOLON_DELIMITER = 0x3b

MAPPING_SEMICOLON_DELIMITER is the ASCII character ';' (0x3b) used to separate key-value pairs in I2P mappings Cross-Ref: mapping.go

View Source
const MAPPING_SIZE_FIELD_LENGTH = 2

MAPPING_SIZE_FIELD_LENGTH is the length in bytes of the mapping size field in I2P mappings Cross-Ref: mapping.go

View Source
const MAX_INTEGER_SIZE = 8

MAX_INTEGER_SIZE is the maximum length of an I2P integer in bytes. Cross-Ref: integer.go

View Source
const MAX_MAPPING_DATA_SIZE = 65535

MAX_MAPPING_DATA_SIZE is the maximum number of bytes in a mapping's data payload. Per the I2P spec: "Total length limit is 65535 bytes, plus the 2 byte size field, or 65537 total." Cross-Ref: mapping_values.go

View Source
const MAX_MAPPING_PAIRS = 1000

MAX_MAPPING_PAIRS is the maximum number of key-value pairs allowed in a single mapping. This prevents infinite loops when parsing malformed mappings. Cross-Ref: mapping_values.go

View Source
const STRING_MAX_SIZE = 255

STRING_MAX_SIZE is the maximum number of bytes that can be stored in an I2P string Cross-Ref: string.go

Variables

View Source
var (
	ErrZeroLength               = fmt.Errorf("error parsing string: zero length")
	ErrDataTooShort             = fmt.Errorf("string parsing warning: string data is shorter than specified by length")
	ErrDataTooLong              = fmt.Errorf("string parsing warning: string contains data beyond length")
	ErrLengthMismatch           = fmt.Errorf("error reading I2P string, length does not match data")
	ErrMappingLengthMismatch    = fmt.Errorf("warning parsing mapping: mapping length exceeds provided data")
	ErrMappingExpectedEquals    = fmt.Errorf("mapping format violation, expected =")
	ErrMappingExpectedSemicolon = fmt.Errorf("mapping format violation, expected ;")
)
View Source
var ZeroHash = Hash{}

ZeroHash represents an all-zeros hash (not a valid SHA256 of any data).

Functions

func DecodeInt16 added in v0.0.6

func DecodeInt16(data [2]byte) int16

DecodeInt16 decodes a 2-byte big-endian array to an int16 value.

Example:

value := data.DecodeInt16([2]byte{251, 46})
// value = -1234

func DecodeInt32 added in v0.0.6

func DecodeInt32(data [4]byte) int32

DecodeInt32 decodes a 4-byte big-endian array to an int32 value.

Example:

value := data.DecodeInt32([4]byte{255, 254, 29, 192})
// value = -123456

func DecodeInt64 added in v0.0.6

func DecodeInt64(data [8]byte) int64

DecodeInt64 decodes an 8-byte big-endian array to an int64 value.

Example:

value := data.DecodeInt64([8]byte{255, 255, 255, 255, 248, 164, 50, 235})
// value = -123456789

func DecodeIntN added in v0.0.6

func DecodeIntN(data []byte) (int, error)

DecodeIntN decodes a variable-length byte slice to an integer.

Parameters:

  • data: The byte slice to decode (1-8 bytes, big-endian)

Returns:

  • int: The decoded integer value
  • error: Error if data is empty or too large

Example:

value, err := data.DecodeIntN([]byte{4, 210})
// value = 1234, err = nil

func DecodeUint16 added in v0.0.6

func DecodeUint16(data [2]byte) uint16

DecodeUint16 decodes a 2-byte big-endian array to a uint16 value.

Example:

value := data.DecodeUint16([2]byte{4, 210})
// value = 1234

func DecodeUint32 added in v0.0.6

func DecodeUint32(data [4]byte) uint32

DecodeUint32 decodes a 4-byte big-endian array to a uint32 value.

Example:

value := data.DecodeUint32([4]byte{0, 1, 226, 64})
// value = 123456

func DecodeUint64 added in v0.0.6

func DecodeUint64(data [8]byte) uint64

DecodeUint64 decodes an 8-byte big-endian array to a uint64 value.

Example:

value := data.DecodeUint64([8]byte{0, 0, 0, 0, 7, 91, 205, 21})
// value = 123456789

func EncodeInt16 added in v0.0.6

func EncodeInt16(value int16) [2]byte

EncodeInt16 encodes an int16 value to a 2-byte big-endian array. This is a Go interop convenience function; I2P uses unsigned integers exclusively. Callers should ensure the value is non-negative when targeting I2P wire formats.

Example:

bytes := data.EncodeInt16(-1234)

func EncodeInt32 added in v0.0.6

func EncodeInt32(value int32) [4]byte

EncodeInt32 encodes an int32 value to a 4-byte big-endian array. This is a Go interop convenience function; I2P uses unsigned integers exclusively. Callers should ensure the value is non-negative when targeting I2P wire formats.

Example:

bytes := data.EncodeInt32(-123456)

func EncodeInt64 added in v0.0.6

func EncodeInt64(value int64) [8]byte

EncodeInt64 encodes an int64 value to an 8-byte big-endian array. This is a Go interop convenience function; I2P uses unsigned integers exclusively. Callers should ensure the value is non-negative when targeting I2P wire formats.

Example:

bytes := data.EncodeInt64(-123456789)

func EncodeIntN added in v0.0.6

func EncodeIntN(value, size int) ([]byte, error)

EncodeIntN encodes an integer to a variable-length byte slice. This is for cases where size checking is needed. Use the fixed-size Encode* functions when the size is known at compile time.

Parameters:

  • value: The integer value to encode (must be non-negative)
  • size: The number of bytes to use (1-8)

Returns:

  • []byte: The encoded value as a big-endian byte slice
  • error: Error if value is negative, size is invalid, or value doesn't fit

Example:

bytes, err := data.EncodeIntN(1234, 2)
// bytes = [4, 210], err = nil

func EncodeUint16 added in v0.0.6

func EncodeUint16(value uint16) [2]byte

EncodeUint16 encodes a uint16 value to a 2-byte big-endian array. This is a convenience function for creating fixed-size integers without error handling.

Example:

bytes := data.EncodeUint16(1234)
// bytes = [4, 210] (0x04D2 in big endian)

func EncodeUint32 added in v0.0.6

func EncodeUint32(value uint32) [4]byte

EncodeUint32 encodes a uint32 value to a 4-byte big-endian array. This is a convenience function for creating fixed-size integers without error handling.

Example:

bytes := data.EncodeUint32(123456)
// bytes = [0, 1, 226, 64] (0x0001E240 in big endian)

func EncodeUint64 added in v0.0.6

func EncodeUint64(value uint64) [8]byte

EncodeUint64 encodes a uint64 value to an 8-byte big-endian array. This is a convenience function for creating fixed-size integers without error handling.

Example:

bytes := data.EncodeUint64(123456789)

func PrintErrors

func PrintErrors(errs []error)

PrintErrors prints a formatted list of errors to the console. Used in: errors.go

func WrapErrors

func WrapErrors(errs []error) error

WrapErrors compiles a slice of errors and returns them wrapped together as a single error. Used in: errors.go

Types

type Date

type Date [8]byte

Date is the represenation of an I2P Date.

https://geti2p.net/spec/common-structures#date

func DateFromTime

func DateFromTime(t time.Time) (date *Date, err error)

DateFromTime takes a time.Time and returns a data.Date. Returns error if the time is before the Unix epoch (January 1, 1970).

func NewDate

func NewDate(data []byte) (date *Date, remainder []byte, err error)

NewDate creates a new Date from []byte using ReadDate. Returns a pointer to Date unlike ReadDate.

func NewDateFromMillis added in v0.1.0

func NewDateFromMillis(millis int64) (*Date, error)

NewDateFromMillis creates a Date from milliseconds since epoch with validation. Returns error if milliseconds is negative.

func NewDateFromUnix added in v0.1.0

func NewDateFromUnix(timestamp int64) (*Date, error)

NewDateFromUnix creates a Date from a Unix timestamp (seconds) with validation. Returns error if timestamp is negative or exceeds maximum safe value.

func ReadDate

func ReadDate(data []byte) (date Date, remainder []byte, err error)

ReadDate creates a Date from []byte using the first DATE_SIZE bytes. Any data after DATE_SIZE is returned as a remainder.

func (Date) Bytes

func (i Date) Bytes() []byte

Bytes returns the raw []byte content of a Date.

func (Date) Int

func (i Date) Int() int

Int returns the Date as a Go integer. WARNING: For Date values >= 2^63 ms since epoch, this method returns 0 because the unsigned I2P Date value exceeds Go's signed int range. Use Date.Time() for reliable, full-range date handling.

func (Date) IsValid added in v0.1.5

func (d Date) IsValid() bool

IsValid returns true if the Date represents a defined (non-zero) time.

func (Date) IsZero added in v0.1.0

func (d Date) IsZero() bool

IsZero returns true if the date represents zero time (undefined/null). According to I2P spec, a date value of 0 means undefined or null.

func (Date) Time

func (date Date) Time() (date_time time.Time)

Time takes the value stored in date as an 8 byte big-endian integer representing the number of milliseconds since the beginning of unix time and converts it to a Go time.Time struct. Uses unsigned decoding to correctly handle the full range of I2P Date values.

If the unsigned millisecond value exceeds math.MaxInt64 (high bit set), Time returns the zero time.Time{}, since Go's time.UnixMilli cannot represent such large values. Callers should check for zero time if working with dates that may have the high bit set.

func (Date) Validate added in v0.1.5

func (d Date) Validate() error

Validate checks that the Date is structurally valid. A Date is always 8 bytes (fixed-size array), so the only validation is whether it represents a non-zero (defined) time. Returns nil if the Date is valid (non-zero).

type Hash

type Hash [32]byte

Hash is the represenation of an I2P Hash.

https://geti2p.net/spec/common-structures#hash

func HashData

func HashData(data []byte) (h Hash)

HashData returns the SHA256 sum of a []byte input as Hash.

func HashReader

func HashReader(r io.Reader) (h Hash, err error)

HashReader returns the SHA256 sum from all data read from an io.Reader. return error if one occurs while reading from reader

func NewHash added in v0.1.0

func NewHash(hashBytes [32]byte) Hash

NewHash creates a Hash from a 32-byte array. This is the preferred way to construct a Hash from known bytes.

func NewHashFromSlice added in v0.1.0

func NewHashFromSlice(data []byte) (Hash, error)

NewHashFromSlice creates a Hash from a byte slice with validation. Returns error if the slice is not exactly 32 bytes.

func ReadHash added in v0.1.0

func ReadHash(data []byte) (Hash, []byte, error)

ReadHash reads a 32-byte hash from data and returns remaining bytes.

func (Hash) Bytes

func (h Hash) Bytes() [32]byte

Bytes returns the raw []byte content of a Hash.

func (Hash) Equal added in v0.1.0

func (h Hash) Equal(other Hash) bool

Equal returns true if two hashes are identical.

func (Hash) IsValid added in v0.1.5

func (h Hash) IsValid() bool

IsValid returns true if the Hash contains a non-zero value.

func (Hash) IsZero added in v0.1.0

func (h Hash) IsZero() bool

IsZero returns true if the hash is all zeros. Note: This is not the same as the SHA256 of empty data.

func (Hash) String added in v0.1.0

func (h Hash) String() string

String returns the hash as a hexadecimal string for debugging.

func (Hash) Validate added in v0.1.5

func (h Hash) Validate() error

Validate checks that the Hash is non-zero. A Hash is always exactly 32 bytes (fixed-size array), so the only semantic validation is whether it contains a meaningful (non-zero) value.

type I2PString

type I2PString []byte

I2PString is the representation of an I2P String.

https://geti2p.net/spec/common-structures#string

func NewI2PString added in v0.1.0

func NewI2PString(content string) (I2PString, error)

NewI2PString creates a validated I2PString from a Go string. Returns error if the string exceeds STRING_MAX_SIZE (255 bytes). This is the preferred constructor for creating I2PStrings from Go strings.

func NewI2PStringFromBytes added in v0.1.0

func NewI2PStringFromBytes(data []byte) (I2PString, error)

NewI2PStringFromBytes creates an I2PString from raw bytes with validation. Validates that the length prefix matches the actual data length. This is the preferred constructor for creating I2PStrings from byte slices.

func ReadI2PString

func ReadI2PString(data []byte) (str I2PString, remainder []byte, err error)

ReadI2PString returns I2PString from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func ToI2PString

func ToI2PString(data string) (str I2PString, err error)

ToI2PString converts a Go string to an I2PString. Returns error if the string exceeds STRING_MAX_SIZE. Deprecated: Use NewI2PString instead for better clarity and consistency.

func (I2PString) Data

func (str I2PString) Data() (data string, err error)

Data returns the I2PString content as a string trimmed to the specified length and not including the length byte. Returns error encountered by Length.

func (I2PString) DataSafe added in v0.1.0

func (str I2PString) DataSafe() (string, error)

DataSafe returns the I2PString content with strict validation. Unlike Data(), this fails fast on any inconsistency. Returns error if the I2PString structure is invalid.

func (I2PString) IsValid added in v0.1.0

func (str I2PString) IsValid() bool

IsValid checks if the I2PString has a valid structure. Returns true if the length byte matches the actual data length.

func (I2PString) Length

func (str I2PString) Length() (length int, err error)

Length returns the length specified in the first byte. Returns error if the specified does not match the actual length or the string is otherwise invalid.

func (I2PString) Validate added in v0.1.5

func (str I2PString) Validate() error

Validate checks that the I2PString is structurally valid. Returns an error describing the first issue found, or nil if valid.

type Integer

type Integer []byte

Integer is the represenation of an I2P Integer.

https://geti2p.net/spec/common-structures#integer

func NewInteger

func NewInteger(bytes []byte, size int) (integer *Integer, remainder []byte, err error)

NewInteger creates a new Integer from []byte using ReadInteger. Deprecated: Use ReadInteger and take address if pointer needed. This function will be removed in v2.0. Returns a pointer to Integer unlike ReadInteger.

func NewIntegerFromBytes added in v0.1.0

func NewIntegerFromBytes(bytes []byte) (Integer, error)

NewIntegerFromBytes creates a validated Integer from a byte slice. Returns error if bytes is empty or exceeds maximum integer size. This is the recommended safe constructor for creating Integers from raw bytes.

func NewIntegerFromInt

func NewIntegerFromInt(value, size int) (integer *Integer, err error)

NewIntegerFromInt creates a new Integer from a Go integer of a specified []byte length.

func ReadInteger

func ReadInteger(bytes []byte, size int) (Integer, []byte)

ReadInteger returns an Integer from a []byte of specified length. The remaining bytes after the specified length are also returned. Size must be between 1 and MAX_INTEGER_SIZE (8) inclusive.

func (Integer) Bytes

func (i Integer) Bytes() []byte

Bytes returns the raw []byte content of an Integer.

func (Integer) Int

func (i Integer) Int() int

Int returns the Integer as a Go integer. Returns 0 if conversion fails. WARNING: For 8-byte values >= 2^63, this method returns 0 because the unsigned I2P Integer exceeds Go's signed int range. Use UintSafe() for the full unsigned range.

func (Integer) IntSafe added in v0.1.0

func (i Integer) IntSafe() (int, error)

IntSafe returns the Integer as a Go int with error handling. Unlike Int(), this method returns an error instead of defaulting to 0. Use this method when you need to distinguish between actual zero values and errors. WARNING: For 8-byte values >= 2^63, this returns an error because the unsigned I2P Integer exceeds Go's signed int range. Use UintSafe() for the full unsigned range.

func (Integer) IsValid added in v0.1.5

func (i Integer) IsValid() bool

IsValid returns true if the Integer has a valid byte length per the I2P spec. Valid Integers are 1–8 bytes (inclusive). Nil or empty Integers are invalid.

func (Integer) IsZero added in v0.1.0

func (i Integer) IsZero() bool

IsZero returns true if the integer represents a valid zero value. All bytes in the integer must be 0x00 for this to return true. Returns false for nil or empty Integers, since a zero-length Integer is invalid per the I2P spec (Integers must be 1–8 bytes). Use IsValid() to check whether an Integer has valid length before calling IsZero().

func (Integer) UintSafe added in v0.1.5

func (i Integer) UintSafe() (uint64, error)

UintSafe returns the Integer as a Go uint64 with error handling. This method correctly handles unsigned integers per the I2P spec, which defines Integer as "an unsigned integer." Values with the high bit set are returned correctly as large positive values, unlike Int()/IntSafe() which may wrap negative for 8-byte values >= 2^63.

func (Integer) Validate added in v0.1.5

func (i Integer) Validate() error

Validate checks that the Integer is structurally valid per the I2P spec. Returns an error if the Integer is empty or exceeds the maximum size of 8 bytes.

type Mapping

type Mapping struct {
	// contains filtered or unexported fields
}

Mapping is the represenation of an I2P Mapping.

https://geti2p.net/spec/common-structures#mapping

func GoMapToMapping

func GoMapToMapping(gomap map[string]string) (mapping *Mapping, err error)

GoMapToMapping converts a Go map to a Mapping. The Go map iteration order is intentionally non-deterministic; the resulting Mapping is always sorted by Java String.compareTo() order via ValuesToMapping(), so the output IS deterministic and suitable for use in signed structures.

func NewMapping

func NewMapping(bytes []byte) (values *Mapping, remainder []byte, err []error)

NewMapping creates a new *Mapping from []byte using ReadMapping. Returns a pointer to Mapping unlike ReadMapping.

func ReadMapping

func ReadMapping(bytes []byte) (mapping Mapping, remainder []byte, err []error)

ReadMapping returns Mapping from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func ValuesToMapping

func ValuesToMapping(values MappingValues) (*Mapping, error)

ValuesToMapping creates a *Mapping using MappingValues. The values are sorted in the order defined in mappingOrder. Returns error if the total mapping data exceeds the maximum size (65535 bytes).

func (*Mapping) Data

func (mapping *Mapping) Data() []byte

Data returns a Mapping in its []byte form. Returns nil if the mapping is not properly initialized or any key-value pair is invalid. Callers should check for nil to detect serialization failures; use Validate() for details. The size field is recalculated from the serialized pairs to ensure consistency. Data returns the wire format bytes for this Mapping. Deprecated: Use DataSafe() for production serialization paths to ensure proper error handling. This method returns nil on error instead of returning an error, violating the project's error handling contract.

func (*Mapping) DataSafe added in v0.1.6

func (mapping *Mapping) DataSafe() ([]byte, error)

DataSafe returns the wire format bytes for this Mapping with proper error reporting. This is the recommended method for production code that needs serialization with guaranteed error handling. Returns error if validation fails or serialization cannot proceed. Empty or uninitialized mappings return the wire encoding for an empty mapping (0x00, 0x00).

func (*Mapping) HasDuplicateKeys

func (mapping *Mapping) HasDuplicateKeys() (bool, error)

HasDuplicateKeys returns true if two keys in a mapping are identical. Returns error if any key in the mapping is invalid.

func (*Mapping) IsValid added in v0.1.0

func (mapping *Mapping) IsValid() bool

IsValid returns true if the Mapping is properly initialized and valid.

func (*Mapping) ToGoMap added in v0.1.5

func (mapping *Mapping) ToGoMap() (map[string]string, error)

ToGoMap converts a Mapping to a Go map[string]string. Returns an error if any key or value cannot be extracted.

func (*Mapping) Validate added in v0.1.0

func (mapping *Mapping) Validate() error

Validate checks if the Mapping is properly initialized and all key-value pairs are valid.

func (Mapping) Values

func (mapping Mapping) Values() MappingValues

Values returns the values contained in a Mapping as MappingValues.

type MappingValues

type MappingValues [][2]I2PString

MappingValues represents the parsed key value pairs inside of an I2P Mapping.

func NewMappingValues added in v0.1.0

func NewMappingValues(capacity int) MappingValues

NewMappingValues creates a new empty MappingValues with optional initial capacity. This is the safe way to construct MappingValues for building mappings programmatically.

Parameters:

  • capacity: Optional initial capacity hint (0 for default)

Returns:

  • MappingValues: Empty mapping values ready for use

Example:

mv := data.NewMappingValues(10) // Pre-allocate space for 10 pairs
mv, err := mv.Add("key1", "value1")
if err != nil {
    return err
}

func ReadMappingValues

func ReadMappingValues(remainder []byte, map_length Integer) (values *MappingValues, remainder_bytes []byte, errs []error)

ReadMappingValues returns *MappingValues from a []byte. The remaining bytes after the specified length are also returned. Returns a list of errors that occurred during parsing.

func (MappingValues) Add added in v0.1.0

func (mv MappingValues) Add(key, value string) (MappingValues, error)

Add appends a new key-value pair to the MappingValues. Both key and value are validated as I2P strings before adding.

Parameters:

  • key: The key string (max 255 bytes)
  • value: The value string (max 255 bytes)

Returns:

  • MappingValues: Updated mapping values with the new pair
  • error: Error if key or value validation fails

Example:

mv := data.NewMappingValues(0)
mv, err := mv.Add("host", "127.0.0.1")
if err != nil {
    return err
}
mv, err = mv.Add("port", "7654")

func (MappingValues) Get

func (m MappingValues) Get(key I2PString) I2PString

Get retrieves the value for a given key from MappingValues.

func (MappingValues) IsValid added in v0.1.0

func (mv MappingValues) IsValid() bool

IsValid returns true if all key-value pairs in MappingValues are valid. This is a convenience wrapper around Validate().

Example:

if !mv.IsValid() {
    return errors.New("invalid mapping values")
}

func (MappingValues) Validate added in v0.1.0

func (mv MappingValues) Validate() error

Validate checks if all key-value pairs in MappingValues are valid. This ensures all I2PStrings are properly formatted.

Returns:

  • error: Error if any key or value is invalid, nil otherwise

Example:

if err := mv.Validate(); err != nil {
    return fmt.Errorf("invalid mapping values: %w", err)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL