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) }