Files
ippserver/packages/ipp/setofstrings.go
2021-11-27 15:47:03 +00:00

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)
}