package ipp import ( "encoding/binary" "fmt" "io" ) // References // https://tools.ietf.org/html/rfc8010 // https://tools.ietf.org/html/rfc8011 // Defined value tags // from rfc8010 type tag uint8 const ( // attribute group tags beginAttribute tag = 0x00 operationAttributes tag = 0x01 jobAttributes tag = 0x02 endOfAttributes tag = 0x03 printerAttributes tag = 0x04 unsupportedAttributes tag = 0x05 // Out of band unsupportedValueTag tag = 0x10 unknownValueTag tag = 0x12 noValueValueTag tag = 0x13 // Integer values integerValueTag tag = 0x21 booleanValueTag tag = 0x22 enumValueTag tag = 0x23 // octetString Tags octetStringValueTag tag = 0x30 dateTimeValueTag tag = 0x31 resolutionValueTag tag = 0x32 rangeOfIntegerValueTag tag = 0x33 begCollectionValueTag tag = 0x34 textWithLanguageValueTag tag = 0x35 nameWithLanguageValueTag tag = 0x36 endCollectionValueTag tag = 0x37 // Character string values textWithoutLanguageValueTag tag = 0x41 nameWithoutLanguageValueTag tag = 0x42 keyWordValueTag tag = 0x44 uriValueTag tag = 0x45 uriSchemeValueTag tag = 0x46 charsetValueTag tag = 0x47 naturalLanguageValueTag tag = 0x48 mimeMediaTypeValueTag tag = 0x49 memberAttrNameValueTag tag = 0x4a ) // Operation-id, defined in rfc8011 type OperationId uint16 const ( PrintJob OperationId = 0x0002 PrintURI OperationId = 0x0003 ValidateJob OperationId = 0x0004 CreateJob OperationId = 0x0005 SendDocument OperationId = 0x0006 SendURI OperationId = 0x0007 CancelJob OperationId = 0x0008 GetJobAttributes OperationId = 0x0009 GetJobs OperationId = 0x000a GetPrinterAttributes OperationId = 0x000b HoldJob OperationId = 0x000c ReleaseJob OperationId = 0x000d RestartJob OperationId = 0x000e PausePrinter OperationId = 0x0010 ResumePrinter OperationId = 0x0011 PurgeJobs OperationId = 0x0012 ) type printerState int32 const ( Idle printerState = 3 Processing printerState = 4 Stopped printerState = 5 ) type statusCode uint16 const ( SuccessfulOk statusCode = 0x0000 ClientErrorBadRequest statusCode = 0x0400 ) type versionNumber uint16 func (v versionNumber) String() string { vn := uint16(v) return fmt.Sprintf("%x.%x", vn&0xff00>>8, vn&0x00ff) } func unmarshalSingleValue(byteStream io.Reader) (string, string) { 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), string(attributeValue) } func marshalNameValue(name, value string, b []byte) { p := 0 binary.BigEndian.PutUint16(b[p:p+2], uint16(len(name))) p += 2 copy(b[p:], []byte(name)) p += len(name) binary.BigEndian.PutUint16(b[p:p+2], uint16(len(value))) p += 2 copy(b[p:], []byte(value)) }