105 lines
2.4 KiB
Go
105 lines
2.4 KiB
Go
// 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)
|
|
}
|