// Copyright 2021, Henrik Sölver henrik.solver@gmail.com // SPDX-License-Identifier: BSD-3-Clause package ipp import ( "bufio" "encoding/binary" ) // SetOfStrings is the strings attribute type SetOfStrings struct { name string values []string vTag tag } // NewSetOfStrings creates a new strings attribute func NewSetOfStrings(name string, t tag, values []string) *SetOfStrings { s := new(SetOfStrings) s.name = name s.vTag = t s.values = values //make([]string, 0) return s } func (s SetOfStrings) String() string { r := s.name + " :" for _, v := range s.values { r = r + " " + v } return r } func (s *SetOfStrings) valueTag() tag { return s.vTag } func (s *SetOfStrings) unmarshal(byteStream *bufio.Reader, valueTag tag) error { var length uint16 s.vTag = valueTag s.values = make([]string, 0, 1) binary.Read(byteStream, binary.BigEndian, &length) name := make([]byte, length) if length > 0 { binary.Read(byteStream, binary.BigEndian, name) } s.name = string(name) binary.Read(byteStream, binary.BigEndian, &length) for length > 0 { valueBytes := make([]byte, length) err := binary.Read(byteStream, binary.BigEndian, valueBytes) if err != nil { return err } s.values = append(s.values, string(valueBytes)) next, err := byteStream.Peek(3) if err != nil { break } if next[0] != byte(valueTag) || next[1] != 0x00 || next[2] != 0x00 { break } // Remove the value tag with the zero length from the stream byteStream.Discard(3) binary.Read(byteStream, binary.BigEndian, &length) } return nil } func (s *SetOfStrings) marshal() []byte { l := 5 + len(s.name) + len(s.values[0]) for i := range s.values[1:] { l += 5 + len(s.values[i+1]) } res := make([]byte, l) p := 0 res[p] = byte(s.vTag) p++ binary.BigEndian.PutUint16(res[p:p+2], uint16(len(s.name))) p += 2 copy(res[p:], []byte(s.name)) p += len(s.name) binary.BigEndian.PutUint16(res[p:p+2], uint16(len(s.values[0]))) p += 2 copy(res[p:], []byte(s.values[0])) p += len(s.values[0]) for i := range s.values[1:] { res[p] = byte(s.vTag) p++ binary.BigEndian.PutUint16(res[p:p+2], uint16(0)) p = p + 2 binary.BigEndian.PutUint16(res[p:p+2], uint16(len(s.values[i+1]))) p = p + 2 copy(res[p:], []byte(s.values[i+1])) p += len(s.values[i+1]) } return res } // AddValue adds a new sring to the set func (s *SetOfStrings) AddValue(v string) { s.values = append(s.values, v) }