src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

header.go (3192B)


      1 package eventstream
      2 
      3 import (
      4 	"encoding/binary"
      5 	"fmt"
      6 	"io"
      7 )
      8 
      9 // Headers are a collection of EventStream header values.
     10 type Headers []Header
     11 
     12 // Header is a single EventStream Key Value header pair.
     13 type 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.
     20 func (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.
     36 func (hs Headers) Get(name string) Value {
     37 	for i := range hs {
     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.
     46 func (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 
     55 // Clone returns a deep copy of the headers
     56 func (hs Headers) Clone() Headers {
     57 	o := make(Headers, 0, len(hs))
     58 	for _, h := range hs {
     59 		o.Set(h.Name, h.Value)
     60 	}
     61 	return o
     62 }
     63 
     64 func decodeHeaders(r io.Reader) (Headers, error) {
     65 	hs := Headers{}
     66 
     67 	for {
     68 		name, err := decodeHeaderName(r)
     69 		if err != nil {
     70 			if err == io.EOF {
     71 				// EOF while getting header name means no more headers
     72 				break
     73 			}
     74 			return nil, err
     75 		}
     76 
     77 		value, err := decodeHeaderValue(r)
     78 		if err != nil {
     79 			return nil, err
     80 		}
     81 
     82 		hs.Set(name, value)
     83 	}
     84 
     85 	return hs, nil
     86 }
     87 
     88 func decodeHeaderName(r io.Reader) (string, error) {
     89 	var n headerName
     90 
     91 	var err error
     92 	n.Len, err = decodeUint8(r)
     93 	if err != nil {
     94 		return "", err
     95 	}
     96 
     97 	name := n.Name[:n.Len]
     98 	if _, err := io.ReadFull(r, name); err != nil {
     99 		return "", err
    100 	}
    101 
    102 	return string(name), nil
    103 }
    104 
    105 func decodeHeaderValue(r io.Reader) (Value, error) {
    106 	var raw rawValue
    107 
    108 	typ, err := decodeUint8(r)
    109 	if err != nil {
    110 		return nil, err
    111 	}
    112 	raw.Type = valueType(typ)
    113 
    114 	var v Value
    115 
    116 	switch raw.Type {
    117 	case trueValueType:
    118 		v = BoolValue(true)
    119 	case falseValueType:
    120 		v = BoolValue(false)
    121 	case int8ValueType:
    122 		var tv Int8Value
    123 		err = tv.decode(r)
    124 		v = tv
    125 	case int16ValueType:
    126 		var tv Int16Value
    127 		err = tv.decode(r)
    128 		v = tv
    129 	case int32ValueType:
    130 		var tv Int32Value
    131 		err = tv.decode(r)
    132 		v = tv
    133 	case int64ValueType:
    134 		var tv Int64Value
    135 		err = tv.decode(r)
    136 		v = tv
    137 	case bytesValueType:
    138 		var tv BytesValue
    139 		err = tv.decode(r)
    140 		v = tv
    141 	case stringValueType:
    142 		var tv StringValue
    143 		err = tv.decode(r)
    144 		v = tv
    145 	case timestampValueType:
    146 		var tv TimestampValue
    147 		err = tv.decode(r)
    148 		v = tv
    149 	case uuidValueType:
    150 		var tv UUIDValue
    151 		err = tv.decode(r)
    152 		v = tv
    153 	default:
    154 		panic(fmt.Sprintf("unknown value type %d", raw.Type))
    155 	}
    156 
    157 	// Error could be EOF, let caller deal with it
    158 	return v, err
    159 }
    160 
    161 const maxHeaderNameLen = 255
    162 
    163 type headerName struct {
    164 	Len  uint8
    165 	Name [maxHeaderNameLen]byte
    166 }
    167 
    168 func (v headerName) encode(w io.Writer) error {
    169 	if err := binary.Write(w, binary.BigEndian, v.Len); err != nil {
    170 		return err
    171 	}
    172 
    173 	_, err := w.Write(v.Name[:v.Len])
    174 	return err
    175 }