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.
|
|
|
|
//
|
2016-02-05 02:23:11 -08:00
|
|
|
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])})
|
2016-02-05 02:23:11 -08:00
|
|
|
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) {
|
2016-02-05 02:23:11 -08:00
|
|
|
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
|
2016-02-05 02:23:11 -08:00
|
|
|
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
|
2016-02-05 02:23:11 -08:00
|
|
|
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 02:23:11 -08:00
|
|
|
}
|
|
|
|
}
|
2016-02-05 22:35:37 -08:00
|
|
|
return string(str[1:]), nil
|
2016-02-05 02:23:11 -08:00
|
|
|
}
|
|
|
|
|
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) {
|
2016-02-05 02:23:11 -08:00
|
|
|
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 02:23:11 -08:00
|
|
|
}
|
2016-02-05 22:35:37 -08:00
|
|
|
i2p_string := []byte{byte(data_len)}
|
|
|
|
i2p_string = append(i2p_string, []byte(data)...)
|
2016-02-05 02:23:11 -08:00
|
|
|
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) {
|
2016-02-05 02:23:11 -08:00
|
|
|
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
|
2016-02-05 02:23:11 -08:00
|
|
|
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
|
2016-02-05 02:23:11 -08:00
|
|
|
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-05 02:23:11 -08:00
|
|
|
}
|
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
|
|
|
}
|