diff --git a/stream/mts/meta/meta.go b/stream/mts/meta/meta.go index 66790315..4b5cf8e9 100644 --- a/stream/mts/meta/meta.go +++ b/stream/mts/meta/meta.go @@ -49,9 +49,9 @@ const ( ) var ( - errKeyAbsent = errors.New("Key does not exist in map") - errNoHeader = errors.New("Metadata string does not contain header") - errInvalidHeader = errors.New("Metadata string does not contain valid header") + errKeyAbsent = errors.New("Key does not exist in map") + errInvalidMeta = errors.New("Invalid metadata given") + errUnexpectedMetaFormat = errors.New("Unexpected meta format") ) // Metadata provides functionality for the storage and encoding of metadata @@ -164,14 +164,11 @@ func (m *Data) Encode() []byte { return m.enc } -// ReadFrom extracts a value from a metadata string d, for the given key. If the -// key is not present in the metadata string, an error is returned. If the -// metadata header is not present in the string, an error is returned. -func Extract(key string, d []byte) (string, error) { - if d[0] != 0 { - return "", errNoHeader - } else if d[0] == 0 && binary.BigEndian.Uint16(d[2:headSize]) != uint16(len(d[headSize:])) { - return "", errInvalidHeader +// Get returns the value for the given key in d. +func Get(key string, d []byte) (string, error) { + err := checkMeta(d) + if err != nil { + return "", err } d = d[headSize:] entries := strings.Split(string(d), "\t") @@ -183,3 +180,30 @@ func Extract(key string, d []byte) (string, error) { } return "", errKeyAbsent } + +// GetAll returns metadata keys and values from d. +func GetAll(d []byte) ([][2]string, error) { + err := checkMeta(d) + if err != nil { + return nil, err + } + d = d[headSize:] + entries := strings.Split(string(d), "\t") + all := make([][2]string, len(entries)) + for i, entry := range entries { + kv := strings.Split(entry, "=") + if len(kv) != 2 { + return nil, errUnexpectedMetaFormat + } + copy(all[i][:], kv) + } + return all, nil +} + +// checkHeader checks that a valid metadata header exists in the given data. +func checkMeta(d []byte) error { + if len(d) == 0 || d[0] != 0 || binary.BigEndian.Uint16(d[2:headSize]) != uint16(len(d[headSize:])) { + return errInvalidMeta + } + return nil +} diff --git a/stream/mts/meta/meta_test.go b/stream/mts/meta/meta_test.go index e1f9f3b7..459b9912 100644 --- a/stream/mts/meta/meta_test.go +++ b/stream/mts/meta/meta_test.go @@ -136,9 +136,9 @@ func TestEncode(t *testing.T) { } } -// TestReadFrom checks that we can correctly obtain a value for a partiular key +// TestGetFrom checks that we can correctly obtain a value for a partiular key // from a string of metadata using the ReadFrom func. -func TestReadFrom(t *testing.T) { +func TestGetFrom(t *testing.T) { tstMeta := append([]byte{0x00, 0x10, 0x00, 0x12}, "loc=a,b,c\tts=12345"...) tests := []struct { @@ -156,7 +156,7 @@ func TestReadFrom(t *testing.T) { } for _, test := range tests { - got, err := Extract(test.key, []byte(tstMeta)) + got, err := Get(test.key, []byte(tstMeta)) if err != nil { t.Errorf("Unexpected err: %v\n", err) } @@ -165,3 +165,26 @@ func TestReadFrom(t *testing.T) { } } } + +// TestGetAll checks that meta.GetAll can correctly get all metadata +// from descriptor data. +func TestGetAll(t *testing.T) { + tstMeta := append([]byte{0x00, 0x10, 0x00, 0x12}, "loc=a,b,c\tts=12345"...) + want := [][2]string{ + { + "loc", + "a,b,c", + }, + { + "ts", + "12345", + }, + } + got, err := GetAll(tstMeta) + if err != nil { + t.Errorf("Unexpected error: %v\n", err) + } + if !reflect.DeepEqual(got, want) { + t.Errorf("Did not get expected out. \nGot : %v, \nWant: %v\n", got, want) + } +}