|
|
@ -51,7 +51,7 @@ func (b *Bytes) UnmarshalJSON(input []byte) error { |
|
|
|
|
|
|
|
|
|
|
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
|
|
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
|
|
|
func (b *Bytes) UnmarshalText(input []byte) error { |
|
|
|
func (b *Bytes) UnmarshalText(input []byte) error { |
|
|
|
raw, err := checkText(input) |
|
|
|
raw, err := checkText(input, true) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
@ -73,7 +73,28 @@ func (b Bytes) String() string { |
|
|
|
// determines the required input length. This function is commonly used to implement the
|
|
|
|
// determines the required input length. This function is commonly used to implement the
|
|
|
|
// UnmarshalText method for fixed-size types.
|
|
|
|
// UnmarshalText method for fixed-size types.
|
|
|
|
func UnmarshalFixedText(typname string, input, out []byte) error { |
|
|
|
func UnmarshalFixedText(typname string, input, out []byte) error { |
|
|
|
raw, err := checkText(input) |
|
|
|
raw, err := checkText(input, true) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(raw)/2 != len(out) { |
|
|
|
|
|
|
|
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Pre-verify syntax before modifying out.
|
|
|
|
|
|
|
|
for _, b := range raw { |
|
|
|
|
|
|
|
if decodeNibble(b) == badNibble { |
|
|
|
|
|
|
|
return ErrSyntax |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
hex.Decode(out, raw) |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The
|
|
|
|
|
|
|
|
// length of out determines the required input length. This function is commonly used to
|
|
|
|
|
|
|
|
// implement the UnmarshalText method for fixed-size types.
|
|
|
|
|
|
|
|
func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error { |
|
|
|
|
|
|
|
raw, err := checkText(input, false) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
@ -243,14 +264,15 @@ func bytesHave0xPrefix(input []byte) bool { |
|
|
|
return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') |
|
|
|
return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func checkText(input []byte) ([]byte, error) { |
|
|
|
func checkText(input []byte, wantPrefix bool) ([]byte, error) { |
|
|
|
if len(input) == 0 { |
|
|
|
if len(input) == 0 { |
|
|
|
return nil, nil // empty strings are allowed
|
|
|
|
return nil, nil // empty strings are allowed
|
|
|
|
} |
|
|
|
} |
|
|
|
if !bytesHave0xPrefix(input) { |
|
|
|
if bytesHave0xPrefix(input) { |
|
|
|
|
|
|
|
input = input[2:] |
|
|
|
|
|
|
|
} else if wantPrefix { |
|
|
|
return nil, ErrMissingPrefix |
|
|
|
return nil, ErrMissingPrefix |
|
|
|
} |
|
|
|
} |
|
|
|
input = input[2:] |
|
|
|
|
|
|
|
if len(input)%2 != 0 { |
|
|
|
if len(input)%2 != 0 { |
|
|
|
return nil, ErrOddLength |
|
|
|
return nil, ErrOddLength |
|
|
|
} |
|
|
|
} |
|
|
|