Files
go-i2p/lib/common/string.go

85 lines
2.2 KiB
Go
Raw Normal View History

2016-02-04 00:54:51 -08:00
package common
import (
"errors"
)
2016-02-05 22:35:37 -08:00
type String []byte
2016-02-04 00:54:51 -08:00
2016-02-06 01:42:47 -08:00
//
// Look up the length of the string, reporting
// errors if the string is invalid or the specified
// length does not match the provided data.
//
func (str String) Length() (int, error) {
if len(str) == 0 {
// log
return 0, errors.New("error parsing string: zero length")
2016-02-04 00:54:51 -08:00
}
2016-02-05 22:00:47 -08:00
length := Integer([]byte{byte(str[0])})
inferred_len := length + 1
str_len := len(str)
if inferred_len > str_len {
// log
return length, errors.New("string parsing warning: string data is shorter than specified by length")
} else if str_len > inferred_len {
//log
return length, errors.New("string parsing warning: string contains data beyond length")
}
return length, nil
}
2016-02-06 01:42:47 -08:00
//
// Return the string data and any errors
// encountered by Length.
//
2016-02-05 22:35:37 -08:00
func (str String) Data() (string, error) {
length, err := str.Length()
if err != nil {
switch err.Error() {
case "error parsing string: zero length":
2016-02-05 22:35:37 -08:00
return "", err
case "string parsing warning: string data is shorter than specified by length":
2016-02-05 22:35:37 -08:00
return string(str[1:]), err
case "string parsing warning: string contains data beyond length":
2016-02-05 22:35:37 -08:00
return string(str[1 : length+1]), err
}
}
2016-02-05 22:35:37 -08:00
return string(str[1:]), nil
}
2016-02-06 01:42:47 -08:00
//
// This function takes an unformatted go string
// and returns a String and any errors encountered
// during the encoding.
//
2016-02-05 22:35:37 -08:00
func ToI2PString(data string) (String, error) {
data_len := len(data)
if data_len >= 256 {
2016-02-05 22:35:37 -08:00
return make([]byte, 0), errors.New("cannot store that much data in I2P string")
}
2016-02-05 22:35:37 -08:00
i2p_string := []byte{byte(data_len)}
i2p_string = append(i2p_string, []byte(data)...)
return String(i2p_string), nil
}
2016-02-04 00:54:51 -08:00
2016-02-06 01:42:47 -08:00
//
// Read a string from a slice of bytes, returning
// any extra data on the end of the slice.
//
2016-02-05 22:35:37 -08:00
func ReadString(data []byte) (String, []byte, error) {
str := String(data)
length, err := String(data).Length()
if err != nil {
switch err.Error() {
case "error parsing string: zero length":
2016-02-05 22:35:37 -08:00
return String{}, make([]byte, 0), err
case "string parsing warning: string data is shorter than specified by length":
2016-02-05 22:35:37 -08:00
return str, make([]byte, 0), err
case "string parsing warning: string contains data beyond length":
2016-02-12 00:21:27 -08:00
return String(str[:length+1]), str[length+1:], nil //err
}
2016-02-04 00:54:51 -08:00
}
2016-02-05 22:35:37 -08:00
return str, make([]byte, 0), nil
2016-02-04 00:54:51 -08:00
}