1package eventstream 2 3import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7) 8 9// Headers are a collection of EventStream header values. 10type Headers []Header 11 12// Header is a single EventStream Key Value header pair. 13type Header struct { 14 Name string 15 Value Value 16} 17 18// Set associates the name with a value. If the header name already exists in 19// the Headers the value will be replaced with the new one. 20func (hs *Headers) Set(name string, value Value) { 21 var i int 22 for ; i < len(*hs); i++ { 23 if (*hs)[i].Name == name { 24 (*hs)[i].Value = value 25 return 26 } 27 } 28 29 *hs = append(*hs, Header{ 30 Name: name, Value: value, 31 }) 32} 33 34// Get returns the Value associated with the header. Nil is returned if the 35// value does not exist. 36func (hs Headers) Get(name string) Value { 37 for i := 0; i < len(hs); i++ { 38 if h := hs[i]; h.Name == name { 39 return h.Value 40 } 41 } 42 return nil 43} 44 45// Del deletes the value in the Headers if it exists. 46func (hs *Headers) Del(name string) { 47 for i := 0; i < len(*hs); i++ { 48 if (*hs)[i].Name == name { 49 copy((*hs)[i:], (*hs)[i+1:]) 50 (*hs) = (*hs)[:len(*hs)-1] 51 } 52 } 53} 54 55func decodeHeaders(r io.Reader) (Headers, error) { 56 hs := Headers{} 57 58 for { 59 name, err := decodeHeaderName(r) 60 if err != nil { 61 if err == io.EOF { 62 // EOF while getting header name means no more headers 63 break 64 } 65 return nil, err 66 } 67 68 value, err := decodeHeaderValue(r) 69 if err != nil { 70 return nil, err 71 } 72 73 hs.Set(name, value) 74 } 75 76 return hs, nil 77} 78 79func decodeHeaderName(r io.Reader) (string, error) { 80 var n headerName 81 82 var err error 83 n.Len, err = decodeUint8(r) 84 if err != nil { 85 return "", err 86 } 87 88 name := n.Name[:n.Len] 89 if _, err := io.ReadFull(r, name); err != nil { 90 return "", err 91 } 92 93 return string(name), nil 94} 95 96func decodeHeaderValue(r io.Reader) (Value, error) { 97 var raw rawValue 98 99 typ, err := decodeUint8(r) 100 if err != nil { 101 return nil, err 102 } 103 raw.Type = valueType(typ) 104 105 var v Value 106 107 switch raw.Type { 108 case trueValueType: 109 v = BoolValue(true) 110 case falseValueType: 111 v = BoolValue(false) 112 case int8ValueType: 113 var tv Int8Value 114 err = tv.decode(r) 115 v = tv 116 case int16ValueType: 117 var tv Int16Value 118 err = tv.decode(r) 119 v = tv 120 case int32ValueType: 121 var tv Int32Value 122 err = tv.decode(r) 123 v = tv 124 case int64ValueType: 125 var tv Int64Value 126 err = tv.decode(r) 127 v = tv 128 case bytesValueType: 129 var tv BytesValue 130 err = tv.decode(r) 131 v = tv 132 case stringValueType: 133 var tv StringValue 134 err = tv.decode(r) 135 v = tv 136 case timestampValueType: 137 var tv TimestampValue 138 err = tv.decode(r) 139 v = tv 140 case uuidValueType: 141 var tv UUIDValue 142 err = tv.decode(r) 143 v = tv 144 default: 145 panic(fmt.Sprintf("unknown value type %d", raw.Type)) 146 } 147 148 // Error could be EOF, let caller deal with it 149 return v, err 150} 151 152const maxHeaderNameLen = 255 153 154type headerName struct { 155 Len uint8 156 Name [maxHeaderNameLen]byte 157} 158 159func (v headerName) encode(w io.Writer) error { 160 if err := binary.Write(w, binary.BigEndian, v.Len); err != nil { 161 return err 162 } 163 164 _, err := w.Write(v.Name[:v.Len]) 165 return err 166} 167