Add integer attribute type.
Merges some common code between integer and enum.
Enum can now bw a set.
Add valuer must take a interface{} in addValue since it can be different types.
This commit is contained in:
@@ -1,23 +1,18 @@
|
|||||||
package ipp
|
package ipp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type enum struct {
|
type enum struct {
|
||||||
name string
|
name string
|
||||||
value int32
|
values []int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnum(name string, value int32) *enum {
|
func NewEnum(name string, values ...int32) *enum {
|
||||||
e := new(enum)
|
e := new(enum)
|
||||||
e.name = name
|
e.name = name
|
||||||
e.value = value
|
e.values = values
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,32 +21,21 @@ func (e enum) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e enum) String() string {
|
func (e enum) String() string {
|
||||||
return e.name + ":" + fmt.Sprint(e.value)
|
return e.name + ":" + fmt.Sprint(e.values)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *enum) valueTag() tag {
|
func (e *enum) valueTag() tag {
|
||||||
return enumValueTag
|
return enumValueTag
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *enum) unmarshal(byteStream io.Reader) {
|
func (e *enum) size() int {
|
||||||
log.Warn("Unmarshal of enum is not implemented yet")
|
return 9 + len(e.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *enum) addValue(v interface{}) {
|
||||||
|
i.values = append(i.values, v.(int32))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *enum) marshal() []byte {
|
func (e *enum) marshal() []byte {
|
||||||
l := 3 + len(e.name) + 6
|
return marshalInteger(enumValueTag, e.name, e.values)
|
||||||
b := make([]byte, 0, l)
|
|
||||||
buf := bytes.NewBuffer(b)
|
|
||||||
buf.WriteByte(byte(enumValueTag))
|
|
||||||
binary.Write(buf, binary.BigEndian, uint16(len(e.name)))
|
|
||||||
buf.WriteString(e.name)
|
|
||||||
binary.Write(buf, binary.BigEndian, uint16(4))
|
|
||||||
binary.Write(buf, binary.BigEndian, e.value)
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *enum) size() int {
|
|
||||||
l := 1 + 4 // The attribute tag + 2 lengths
|
|
||||||
l += len(e.name)
|
|
||||||
l += 4
|
|
||||||
return l
|
|
||||||
}
|
}
|
||||||
|
|||||||
67
packages/ipp/integer.go
Normal file
67
packages/ipp/integer.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package ipp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type integer struct {
|
||||||
|
name string
|
||||||
|
values []int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInteger(name string, values ...int32) *integer {
|
||||||
|
e := new(integer)
|
||||||
|
e.name = name
|
||||||
|
e.values = values
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i integer) Name() string {
|
||||||
|
return i.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i integer) String() string {
|
||||||
|
return i.name + ":" + fmt.Sprint(i.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *integer) valueTag() tag {
|
||||||
|
return integerValueTag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *integer) size() int {
|
||||||
|
return 9 + len(i.name) // The attribute tag + 2 lengths
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *integer) addValue(v interface{}) {
|
||||||
|
i.values = append(i.values, v.(int32))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *integer) marshal() []byte {
|
||||||
|
return marshalInteger(integerValueTag, i.name, i.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalInteger(t tag, name string, values []int32) []byte {
|
||||||
|
l := 9 + len(name)
|
||||||
|
b := make([]byte, 0, l)
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
buf.WriteByte(byte(integerValueTag))
|
||||||
|
binary.Write(buf, binary.BigEndian, uint16(len(name)))
|
||||||
|
buf.WriteString(name)
|
||||||
|
binary.Write(buf, binary.BigEndian, uint16(4))
|
||||||
|
binary.Write(buf, binary.BigEndian, values[0])
|
||||||
|
for _, v := range values[1:] {
|
||||||
|
buf.WriteByte(byte(integerValueTag))
|
||||||
|
binary.Write(buf, binary.BigEndian, uint16(0))
|
||||||
|
binary.Write(buf, binary.BigEndian, uint16(4))
|
||||||
|
binary.Write(buf, binary.BigEndian, v)
|
||||||
|
}
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalSingleInteger(byteStream io.Reader) (string, int32) {
|
||||||
|
name, data := unmarshalSingleAttribute(byteStream)
|
||||||
|
return name, int32(binary.BigEndian.Uint32(data))
|
||||||
|
}
|
||||||
38
packages/ipp/integer_test.go
Normal file
38
packages/ipp/integer_test.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package ipp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnMarshalSinglePositiveInteger(T *testing.T) {
|
||||||
|
testdata := []byte{
|
||||||
|
0x00, 0x04,
|
||||||
|
0x66, 0x6c, 0x6f, 0x70, //flop
|
||||||
|
0x00, 0x04,
|
||||||
|
0x00, 0x0, 0x0, 0x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(testdata)
|
||||||
|
|
||||||
|
n, v := unmarshalSingleInteger(buf)
|
||||||
|
assert.Equal(T, "flop", n, "Should be equal")
|
||||||
|
assert.Equal(T, int32(4), v, "Should be equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnMarshalSingleNegativeInteger(T *testing.T) {
|
||||||
|
testdata := []byte{
|
||||||
|
0x00, 0x04,
|
||||||
|
0x66, 0x6c, 0x6f, 0x70, //flop
|
||||||
|
0x00, 0x04,
|
||||||
|
0xff, 0xff, 0xff, 0xfc,
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(testdata)
|
||||||
|
|
||||||
|
n, v := unmarshalSingleInteger(buf)
|
||||||
|
assert.Equal(T, "flop", n, "Should be equal")
|
||||||
|
assert.Equal(T, int32(-4), v, "Should be equal")
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ func (k *keyWord) marshal() []byte {
|
|||||||
return k.sos.marshal()
|
return k.sos.marshal()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *keyWord) addValue(v string) {
|
func (k *keyWord) addValue(v interface{}) {
|
||||||
k.sos.AddValue(v)
|
k.sos.AddValue(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,19 @@ func (v versionNumber) String() string {
|
|||||||
return fmt.Sprintf("%x.%x", vn&0xff00>>8, vn&0x00ff)
|
return fmt.Sprintf("%x.%x", vn&0xff00>>8, vn&0x00ff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unmarshalSingleAttribute(byteStream io.Reader) (string, []byte) {
|
||||||
|
var length uint16
|
||||||
|
binary.Read(byteStream, binary.BigEndian, &length)
|
||||||
|
attributeName := make([]byte, length)
|
||||||
|
if length > 0 {
|
||||||
|
binary.Read(byteStream, binary.BigEndian, attributeName)
|
||||||
|
}
|
||||||
|
binary.Read(byteStream, binary.BigEndian, &length)
|
||||||
|
attributeValue := make([]byte, length)
|
||||||
|
binary.Read(byteStream, binary.BigEndian, attributeValue)
|
||||||
|
return string(attributeName), attributeValue
|
||||||
|
}
|
||||||
|
|
||||||
func unmarshalSingleValue(byteStream io.Reader) (string, string) {
|
func unmarshalSingleValue(byteStream io.Reader) (string, string) {
|
||||||
var length uint16
|
var length uint16
|
||||||
binary.Read(byteStream, binary.BigEndian, &length)
|
binary.Read(byteStream, binary.BigEndian, &length)
|
||||||
@@ -137,7 +150,7 @@ type attributes struct {
|
|||||||
job []Attribute
|
job []Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *attributes) String() string{
|
func (a *attributes) String() string {
|
||||||
s := " OperationAttributes" + "\n"
|
s := " OperationAttributes" + "\n"
|
||||||
for _, a := range a.operation {
|
for _, a := range a.operation {
|
||||||
s = s + fmt.Sprintf(" %v (%v)\n", a, a.valueTag())
|
s = s + fmt.Sprintf(" %v (%v)\n", a, a.valueTag())
|
||||||
@@ -231,6 +244,26 @@ func UnMarshalAttributues(body io.Reader) *attributes {
|
|||||||
lastAddValuer = m
|
lastAddValuer = m
|
||||||
}
|
}
|
||||||
log.Debugf("%v : %v", name, value)
|
log.Debugf("%v : %v", name, value)
|
||||||
|
case integerValueTag:
|
||||||
|
name, value := unmarshalSingleInteger(body)
|
||||||
|
if name == "" {
|
||||||
|
lastAddValuer.addValue(value)
|
||||||
|
} else {
|
||||||
|
i := NewInteger(name, value)
|
||||||
|
a.addAttribute(currentAttributeGroup, i)
|
||||||
|
lastAddValuer = i
|
||||||
|
}
|
||||||
|
log.Debugf("%v : %v", name, value)
|
||||||
|
case enumValueTag:
|
||||||
|
name, value := unmarshalSingleInteger(body)
|
||||||
|
if name == "" {
|
||||||
|
lastAddValuer.addValue(value)
|
||||||
|
} else {
|
||||||
|
e := NewEnum(name, value)
|
||||||
|
a.addAttribute(currentAttributeGroup, e)
|
||||||
|
lastAddValuer = e
|
||||||
|
}
|
||||||
|
log.Debugf("%v : %v", name, value)
|
||||||
case jobAttributes:
|
case jobAttributes:
|
||||||
log.Debug("Start job attributes")
|
log.Debug("Start job attributes")
|
||||||
currentAttributeGroup = jobAttributes
|
currentAttributeGroup = jobAttributes
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ func (m *mimeMediaType) marshal() []byte {
|
|||||||
return m.sos.marshal()
|
return m.sos.marshal()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mimeMediaType) addValue(v string) {
|
func (m *mimeMediaType) addValue(v interface{}) {
|
||||||
m.sos.AddValue(v)
|
m.sos.AddValue(v.(string))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (h ippMessageHeader) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AddValuer interface {
|
type AddValuer interface {
|
||||||
addValue(string)
|
addValue(interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user