Add integer and range of integer attributes. #10
@@ -1,23 +1,18 @@
|
||||
package ipp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type enum struct {
|
||||
name string
|
||||
value int32
|
||||
name string
|
||||
values []int32
|
||||
}
|
||||
|
||||
func NewEnum(name string, value int32) *enum {
|
||||
func NewEnum(name string, values ...int32) *enum {
|
||||
e := new(enum)
|
||||
e.name = name
|
||||
e.value = value
|
||||
e.values = values
|
||||
return e
|
||||
}
|
||||
|
||||
@@ -26,32 +21,21 @@ func (e enum) Name() 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 {
|
||||
return enumValueTag
|
||||
}
|
||||
|
||||
func (e *enum) unmarshal(byteStream io.Reader) {
|
||||
log.Warn("Unmarshal of enum is not implemented yet")
|
||||
func (e *enum) size() int {
|
||||
return 9 + len(e.name)
|
||||
}
|
||||
|
||||
func (i *enum) addValue(v interface{}) {
|
||||
i.values = append(i.values, v.(int32))
|
||||
}
|
||||
|
||||
func (e *enum) marshal() []byte {
|
||||
l := 3 + len(e.name) + 6
|
||||
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
|
||||
return marshalInteger(enumValueTag, e.name, e.values)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
func (k *keyWord) addValue(v string) {
|
||||
k.sos.AddValue(v)
|
||||
func (k *keyWord) addValue(v interface{}) {
|
||||
k.sos.AddValue(v.(string))
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,19 @@ func (v versionNumber) String() string {
|
||||
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) {
|
||||
var length uint16
|
||||
binary.Read(byteStream, binary.BigEndian, &length)
|
||||
@@ -137,7 +150,7 @@ type attributes struct {
|
||||
job []Attribute
|
||||
}
|
||||
|
||||
func (a *attributes) String() string{
|
||||
func (a *attributes) String() string {
|
||||
s := " OperationAttributes" + "\n"
|
||||
for _, a := range a.operation {
|
||||
s = s + fmt.Sprintf(" %v (%v)\n", a, a.valueTag())
|
||||
@@ -231,6 +244,36 @@ func UnMarshalAttributues(body io.Reader) *attributes {
|
||||
lastAddValuer = m
|
||||
}
|
||||
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 rangeOfIntegerValueTag:
|
||||
name, value := unmarshalSingleRangeOfInteger(body)
|
||||
if name == "" {
|
||||
lastAddValuer.addValue(value)
|
||||
} else {
|
||||
r := NewRangeOfInteger(name, value)
|
||||
a.addAttribute(currentAttributeGroup, r)
|
||||
lastAddValuer = r
|
||||
}
|
||||
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:
|
||||
log.Debug("Start job attributes")
|
||||
currentAttributeGroup = jobAttributes
|
||||
|
||||
@@ -31,6 +31,6 @@ func (m *mimeMediaType) marshal() []byte {
|
||||
return m.sos.marshal()
|
||||
}
|
||||
|
||||
func (m *mimeMediaType) addValue(v string) {
|
||||
m.sos.AddValue(v)
|
||||
func (m *mimeMediaType) addValue(v interface{}) {
|
||||
m.sos.AddValue(v.(string))
|
||||
}
|
||||
|
||||
55
packages/ipp/rangeofinteger.go
Normal file
55
packages/ipp/rangeofinteger.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package ipp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type IRange struct {
|
||||
lower int32
|
||||
upper int32
|
||||
}
|
||||
|
||||
type rangeOfInteger struct {
|
||||
name string
|
||||
values []IRange
|
||||
}
|
||||
|
||||
func NewRangeOfInteger(name string, values ...IRange) *rangeOfInteger {
|
||||
r := new(rangeOfInteger)
|
||||
r.name = name
|
||||
r.values = values
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *rangeOfInteger) Name() string {
|
||||
return r.name
|
||||
}
|
||||
|
||||
func (r rangeOfInteger) String() string {
|
||||
return r.name + ":" + fmt.Sprint(r.values)
|
||||
}
|
||||
|
||||
func (r *rangeOfInteger) valueTag() tag {
|
||||
return rangeOfIntegerValueTag
|
||||
}
|
||||
|
||||
func (r *rangeOfInteger) marshal() []byte {
|
||||
log.Error("marshal rangeOfInteger is not implemented yet")
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func (r *rangeOfInteger) addValue(v interface{}) {
|
||||
r.values = append(r.values, v.(IRange))
|
||||
}
|
||||
|
||||
func unmarshalSingleRangeOfInteger(byteStream io.Reader) (string, IRange) {
|
||||
name, data := unmarshalSingleAttribute(byteStream)
|
||||
var r IRange
|
||||
r.lower = int32(binary.BigEndian.Uint32(data[0:4]))
|
||||
r.upper = int32(binary.BigEndian.Uint32(data[4:8]))
|
||||
return name, r
|
||||
}
|
||||
24
packages/ipp/rangeofinteger_test.go
Normal file
24
packages/ipp/rangeofinteger_test.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package ipp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnMarshalSingleRange(T *testing.T) {
|
||||
testdata := []byte{
|
||||
0x00, 0x04,
|
||||
0x66, 0x6c, 0x6f, 0x70, //flop
|
||||
0x00, 0x08,
|
||||
0x00, 0x0, 0x0, 0x4, 0x00, 0x0, 0x0, 0x5,
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(testdata)
|
||||
|
||||
n, v := unmarshalSingleRangeOfInteger(buf)
|
||||
assert.Equal(T, "flop", n, "Should be equal")
|
||||
assert.Equal(T, int32(4), v.lower, "Should be equal")
|
||||
assert.Equal(T, int32(5), v.upper, "Should be equal")
|
||||
}
|
||||
@@ -33,7 +33,7 @@ func (h ippMessageHeader) String() string {
|
||||
}
|
||||
|
||||
type AddValuer interface {
|
||||
addValue(string)
|
||||
addValue(interface{})
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
|
||||
Reference in New Issue
Block a user