hnakra/protocol/map.go

59 lines
1.4 KiB
Go

package protocol
import "io"
import "fmt"
// Map is a string-to-string map with non-unique keys. Each key can be
// associated with multiple values. This is typically used for things like HTTP
// headers.
type Map map[string] []string
// ReadMap reads a map with a 16-bit length containing strings which have a
// 16-bit size. The length of the map corresponds to how many key/value pairs
// it has, and not how long the map is.
func ReadMap (reader io.Reader) (m Map, err error) {
length, err := ReadU16(reader)
if err != nil { return nil, err }
m = make(Map)
for length > 0 {
key, err := ReadString16(reader)
if err != nil { return m, err }
value, err := ReadString16(reader)
if err != nil { return m, err }
m.Add(key, value)
length --
}
return m, err
}
func (m Map) Serialize (writer io.Writer) (err error) {
if uint(len(m)) > MaxIntOfSize(2) {
panic(fmt.Sprintf("len(%d) cannot fit in U16", len(m)))
}
length := 0
for _, item := range m {
length += len(item)
}
err = WriteU16(writer, uint16(length))
if err != nil { return }
for key, values := range m {
for _, value := range values {
err = WriteString16(writer, key)
if err != nil { return }
err = WriteString16(writer, value)
if err != nil { return }
}}
return
}
// Add adds a value to the map under the specified key.
func (m Map) Add (key, value string) {
m[key] = append(m[key], value)
}