Files
ippserver/packages/ipp/request.go

150 lines
3.2 KiB
Go

package ipp
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
)
type ippMessageHeader struct {
versionNumber versionNumber
operationID OperationID
requestID uint32
}
func (h *ippMessageHeader) unmarshal(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 *ippMessageHeader) marshal() []byte {
b := make([]byte, 0, 8)
buf := bytes.NewBuffer(b)
binary.Write(buf, binary.BigEndian, h.versionNumber)
binary.Write(buf, binary.BigEndian, h.operationID)
binary.Write(buf, binary.BigEndian, h.requestID)
return buf.Bytes()
}
func (h ippMessageHeader) String() string {
return fmt.Sprintf("Version number: %v Operation Id: %v Request Id: %v", h.versionNumber, h.operationID, h.requestID)
}
type AddValuer interface {
addValue(interface{})
}
type Request struct {
a *Attributes
header ippMessageHeader
}
func NewRequest(op OperationID, requestID uint32) *Request {
r := new(Request)
r.header.operationID = op
r.header.requestID = requestID
r.header.versionNumber = 0x0200
r.a = new(Attributes)
return r
}
func (r Request) String() string {
return r.header.String() + "\n" + r.a.String()
}
func (r *Request) UnMarshal(body io.Reader) {
buffbody := bufio.NewReader(body)
r.header.unmarshal(buffbody)
r.a = UnMarshalAttributes(buffbody)
}
func (r *Request) RequestID() uint32 {
return r.header.requestID
}
// Operation returns the operation is of the request.
func (r *Request) Operation() OperationID {
return r.header.operationID
}
func (r *Request) GetAttribute(name string) Attribute {
for _, a := range r.a.operation {
if a.Name() == name {
return a
}
}
for _, a := range r.a.job {
if a.Name() == name {
return a
}
}
for _, a := range r.a.printer {
if a.Name() == name {
return a
}
}
for _, a := range r.a.unsupported {
if a.Name() == name {
return a
}
}
return nil
}
// Marshal converts the request object to a ipp request
func (r *Request) Marshal() []byte {
var buf bytes.Buffer
buf.Write(r.header.marshal())
if len(r.a.operation) > 0 {
buf.WriteByte(byte(operationAttributes))
for _, e := range r.a.operation {
buf.Write(e.marshal())
}
}
if len(r.a.job) > 0 {
buf.WriteByte(byte(jobAttributes))
for _, e := range r.a.job {
buf.Write(e.marshal())
}
}
if len(r.a.printer) > 0 {
buf.WriteByte(byte(printerAttributes))
for _, e := range r.a.printer {
buf.Write(e.marshal())
}
}
buf.WriteByte(byte(endOfAttributes))
return buf.Bytes()
}
// AddPrinterAttribute adds a printer attribute to the request object
func (r *Request) AddPrinterAttribute(a Attribute) error {
if a != nil {
r.a.addAttribute(printerAttributes, a)
return nil
}
return ErrNilAttribute
}
// AddOperatonAttribute adds a operation attribute to the request object
func (r *Request) AddOperatonAttribute(a Attribute) error {
if a != nil {
r.a.addAttribute(operationAttributes, a)
return nil
}
return ErrNilAttribute
}
// AddJobAttribute adds a job attribute to the request object
func (r *Request) AddJobAttribute(a Attribute) error {
if a != nil {
r.a.addAttribute(jobAttributes, a)
return nil
}
return ErrNilAttribute
}