138 lines
3.2 KiB
Go
138 lines
3.2 KiB
Go
package ipp
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type ippRequestHeader struct {
|
|
versionNumber versionNumber
|
|
operationId operationId
|
|
requestId uint32
|
|
}
|
|
|
|
func (h *ippRequestHeader) marshal(byteStream io.Reader) {
|
|
binary.Read(byteStream, binary.BigEndian, &h.versionNumber)
|
|
binary.Read(byteStream, binary.BigEndian, &h.operationId)
|
|
binary.Read(byteStream, binary.BigEndian, &h.requestId)
|
|
}
|
|
|
|
func (h ippRequestHeader) String() string {
|
|
return fmt.Sprintf("Version number: %v Operation Id: %v Request Id: %v", h.versionNumber, h.operationId, h.requestId)
|
|
}
|
|
|
|
type Attribute interface {
|
|
valueTag() tag
|
|
//unmarshal(io.Reader)
|
|
marshal() []byte
|
|
size() int
|
|
}
|
|
|
|
type Request struct {
|
|
header ippRequestHeader
|
|
operationAttributes map[string]Attribute
|
|
jobAttributes map[string]Attribute
|
|
printerAttributes map[string]Attribute
|
|
}
|
|
|
|
func NewRequest() *Request {
|
|
r := new(Request)
|
|
r.operationAttributes = make(map[string]Attribute)
|
|
r.jobAttributes = make(map[string]Attribute)
|
|
r.printerAttributes = make(map[string]Attribute)
|
|
|
|
return r
|
|
}
|
|
|
|
func (r Request) String() string {
|
|
s := r.header.String() + "\n" + " OperationAttributes" + "\n"
|
|
for _, a := range r.operationAttributes {
|
|
s = s + fmt.Sprintf(" %v (%v)\n", a, a.valueTag())
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (r *Request) UnMarshal(body io.Reader) {
|
|
r.header.marshal(body)
|
|
log.Infof("Header %v", r.header)
|
|
var tag tag
|
|
err := binary.Read(body, binary.BigEndian, &tag)
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
log.Infof("got tag - %v", tag)
|
|
|
|
if tag == operationAttributes {
|
|
var lastKeyword *keyWord
|
|
nextoperationattr:
|
|
for tag != endOfAttributes {
|
|
|
|
err = binary.Read(body, binary.BigEndian, &tag)
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
log.Infof("Value tag - %v", tag)
|
|
switch tag {
|
|
case endOfAttributes:
|
|
err = binary.Read(body, binary.BigEndian, &tag)
|
|
if err == io.EOF {
|
|
// No more data
|
|
return
|
|
}
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
log.Infof("got tag - %v", tag)
|
|
err = binary.Read(body, binary.BigEndian, &tag)
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
log.Infof("got tag - %v", tag)
|
|
|
|
break nextoperationattr
|
|
case charsetValueTag:
|
|
c := NewCharSetValue("", "")
|
|
c.unmarshal(body)
|
|
r.operationAttributes[c.name] = c
|
|
log.Infof("%v %v", c.name, c.value)
|
|
case uriValueTag:
|
|
u := newUriValue("", "")
|
|
u.unmarshal(body)
|
|
r.operationAttributes[u.name] = u
|
|
log.Infof("%v %v", u.name, u.value)
|
|
case naturalLanguagageValueTag:
|
|
n := newNaturalLanguagage("", "")
|
|
n.unmarshal(body)
|
|
r.operationAttributes[n.name] = n
|
|
log.Infof("%v %v", n.name, n.value)
|
|
case keyWordValueTag:
|
|
name, value := unmarshalSingleValue(body)
|
|
if name == "" {
|
|
lastKeyword.addValue(value)
|
|
} else {
|
|
k := newKeyWord()
|
|
k.name = name
|
|
k.addValue(value)
|
|
r.operationAttributes[k.name] = k
|
|
lastKeyword = k
|
|
}
|
|
default:
|
|
log.Errorf("Unsupported tag %v", tag)
|
|
|
|
}
|
|
}
|
|
log.Infof("Value tag %v", tag)
|
|
} else {
|
|
log.Error("unexpected tag")
|
|
// TODO Return something sensible here
|
|
|
|
}
|
|
}
|
|
|
|
func (r *Request) RequestId() uint32 {
|
|
return r.header.requestId
|
|
}
|