Initial commit
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user