Changeset fa0d0ef for server/lib/ippvalue.py
- Timestamp:
- Mar 7, 2011, 9:03:02 PM (14 years ago)
- Branches:
- no-cups
- Children:
- fc427ef
- Parents:
- c269bc7
- git-author:
- Jessica B. Hamrick <jhamrick@…> (03/07/11 21:03:02)
- git-committer:
- Jessica B. Hamrick <jhamrick@…> (03/07/11 21:03:02)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
server/lib/ippvalue.py
rc269bc7 rfa0d0ef 7 7 logger = logging.getLogger("ippLogger") 8 8 9 class Value( ):9 class Value(object): 10 10 """ 11 11 An IPP value consists of a tag and a value. … … 23 23 """ 24 24 25 def __init__(self, value_tag=None, value=None , unpack=True):25 def __init__(self, value_tag=None, value=None): 26 26 """ 27 27 Initialize a Value. There are three different ways you can … … 31 31 32 32 Value(value_tag, value) -- creates a Value instance from 33 binary values 34 35 Value(value_tag, value, unpack=False) -- creates a Value 36 instance from non-binary values 33 a non-binary value 37 34 38 35 If you create an empty Value instance, once you have set 39 value_tag and value, you should call pack(), or if you set40 value_tag and binary_value, call unpack().36 value_tag and value, you can retrieve the packed value from 37 the packed_value property. 41 38 42 39 Arguments: … … 44 41 value_tag -- one byte, identifying the type of value 45 42 46 value -- variable size, containing the actual value. If 47 unpack is True, then this should be a binary value, 48 otherwise it should be a string or number. 49 50 unpack -- boolean which indicates whether the value passed 51 in is binary (i.e., should be unpacked) or not (i.e., does 52 not need to be unpacked) 43 value -- variable size, containing the actual value. 44 It should be a string or number. 53 45 """ 54 46 55 47 # make sure the arguments are valid 56 if value_tag is not None: 57 assert value is not None, \ 58 "value must not be null because " + \ 59 "value_tag is not null!" 60 elif value_tag is None: 61 assert value is None, \ 62 "value must be null because value_tag is null!" 48 if value is not None: 49 assert value_tag is not None, \ 50 "value_tag must not be null because " + \ 51 "value is not null!" 63 52 64 53 # initialize member variables 65 self.value_tag = None # one byte, the type of value 66 self.value = None # non-binary value of self.value 67 self.tag_size = 1 # length of the tag in bytes 68 self.value_size = None # size of self.value in bytes 69 self.binary_value = None # binary value of self.value 70 71 if value_tag is not None and value is not None: 72 if unpack: 73 self.value_tag = value_tag 74 self.binary_value = value 75 self.value_size, self.value = self.unpack() 76 else: 77 self.value_tag = value_tag 78 self.value = value 79 self.value_size, self.binary_value = self.pack() 80 81 self.verify() 82 83 def unpack(self): 84 """ 85 Given self.value_tag and self.binary_value, unpack the binary 54 self.value_tag = value_tag # one byte, the type of value 55 self.value = value # non-binary value of self.value 56 57 @classmethod 58 def unpack(cls, value_tag, packed_value): 59 """Unpack a binary IPP value 60 61 Unpacks a binary string into a Value object. 62 63 """ 64 return cls(value_tag, cls._unpack(value_tag, packed_value)) 65 66 @staticmethod 67 def _unpack(value_tag, packed_value): 68 """ 69 Given self.value_tag and self.packed_value, unpack the binary 86 70 value into either a string or number. These values MUST NOT 87 be null. Furthermore, if self.value and self.value_size are 88 set, this method will check to make sure that unpacking 89 self.binary_value matches up. 90 91 Returns: tuple of (value_size, value) 92 """ 93 94 assert self.value_tag is not None, \ 71 be null. 72 73 Returns: unpacked value 74 75 """ 76 77 assert value_tag is not None, \ 95 78 "Cannot unpack values with unspecified value tag!" 96 assert self.binary_value is not None, \79 assert packed_value is not None, \ 97 80 "Cannot unpack null values!" 98 81 99 value_size = None100 82 value = None 101 83 102 84 # out-of-band value tags 103 if self.value_tag == OutOfBandTags.UNSUPPORTED or \104 self.value_tag == OutOfBandTags.DEFAULT or \105 self.value_tag == OutOfBandTags.UNKNOWN or \106 self.value_tag == OutOfBandTags.NO_VALUE:85 if value_tag == OutOfBandTags.UNSUPPORTED or \ 86 value_tag == OutOfBandTags.DEFAULT or \ 87 value_tag == OutOfBandTags.UNKNOWN or \ 88 value_tag == OutOfBandTags.NO_VALUE: 107 89 value_size = 0 108 90 value = '' 109 91 110 92 # integer value tags 111 elif self.value_tag == IntegerTags.INTEGER: 112 value_size = 4 113 value = struct.unpack('>i', self.binary_value)[0] 114 elif self.value_tag == IntegerTags.BOOLEAN: 115 value_size = 1 116 value = struct.unpack('>?', self.binary_value)[0] 117 elif self.value_tag == IntegerTags.ENUM: 118 value_size = 4 119 value = struct.unpack('>i', self.binary_value)[0] 93 elif value_tag == IntegerTags.INTEGER: 94 value = struct.unpack('>i', packed_value)[0] 95 elif value_tag == IntegerTags.BOOLEAN: 96 value = struct.unpack('>?', packed_value)[0] 97 elif value_tag == IntegerTags.ENUM: 98 value = struct.unpack('>i', packed_value)[0] 120 99 121 100 122 elif self.value_tag == OctetStringTags.DATETIME:101 elif value_tag == OctetStringTags.DATETIME: 123 102 # field octets contents range 124 103 # ----- ------ -------- ----- … … 135 114 # 10 11 minutes from UTC 0..59 136 115 137 value_size = 11 138 value = struct.unpack('>hbbbbbbcbb', self.binary_value)[0] 139 140 elif self.value_tag == OctetStringTags.RESOLUTION: 116 value = struct.unpack('>hbbbbbbcbb', packed_value) 117 118 elif value_tag == OctetStringTags.RESOLUTION: 141 119 # OCTET-STRING consisting of nine octets of 2 142 120 # SIGNED-INTEGERs followed by a SIGNED-BYTE. The first … … 146 124 # contains the units 147 125 148 value_size = 9 149 value = struct.unpack('>iib', self.binary_value) 150 151 elif self.value_tag == OctetStringTags.RANGE_OF_INTEGER: 126 value = struct.unpack('>iib', packed_value) 127 128 elif value_tag == OctetStringTags.RANGE_OF_INTEGER: 152 129 # Eight octets consisting of 2 SIGNED-INTEGERs. The first 153 130 # SIGNED-INTEGER contains the lower bound and the second 154 131 # SIGNED-INTEGER contains the upper bound. 155 132 156 value_size = 8 157 value = struct.unpack('>ii', self.binary_value) 158 159 elif self.value_tag == OctetStringTags.TEXT_WITH_LANGUAGE or \ 160 self.value_tag == OctetStringTags.NAME_WITH_LANGUAGE: 161 a = struct.unpack('>h', self.binary_value[:2])[0] 162 b = struct.unpack('>%ss' % a, self.binary_value[2:a+2])[0] 163 c = struct.unpack('>h', self.binary_value[a+2:a+4])[0] 164 d = struct.unpack('>%ss' % c, self.binary_value[a+4:][0]) 165 value_size = 4 + a + c 133 value = struct.unpack('>ii', packed_value) 134 135 elif value_tag == OctetStringTags.TEXT_WITH_LANGUAGE or \ 136 value_tag == OctetStringTags.NAME_WITH_LANGUAGE: 137 a = struct.unpack('>h', packed_value[:2])[0] 138 b = struct.unpack('>%ss' % a, packed_value[2:a+2])[0] 139 c = struct.unpack('>h', packed_value[a+2:a+4])[0] 140 d = struct.unpack('>%ss' % c, packed_value[a+4:][0]) 166 141 value = (a, b, c, d) 167 142 168 143 # character string value tags 169 elif self.value_tag == \144 elif value_tag == \ 170 145 CharacterStringTags.TEXT_WITHOUT_LANGUAGE or \ 171 self.value_tag == \146 value_tag == \ 172 147 CharacterStringTags.NAME_WITHOUT_LANGUAGE: 173 value_size = len(str(self.binary_value)) 174 value = str(self.binary_value) 175 elif self.value_tag == CharacterStringTags.GENERIC or \ 176 self.value_tag == CharacterStringTags.KEYWORD or \ 177 self.value_tag == CharacterStringTags.URI or \ 178 self.value_tag == CharacterStringTags.URI_SCHEME or \ 179 self.value_tag == CharacterStringTags.CHARSET or \ 180 self.value_tag == CharacterStringTags.NATURAL_LANGUAGE or \ 181 self.value_tag == CharacterStringTags.MIME_MEDIA_TYPE: 182 value_size = len(str(self.binary_value)) 183 value = str(self.binary_value) 148 value = str(packed_value) 149 elif value_tag == CharacterStringTags.GENERIC or \ 150 value_tag == CharacterStringTags.KEYWORD or \ 151 value_tag == CharacterStringTags.URI or \ 152 value_tag == CharacterStringTags.URI_SCHEME or \ 153 value_tag == CharacterStringTags.CHARSET or \ 154 value_tag == CharacterStringTags.NATURAL_LANGUAGE or \ 155 value_tag == CharacterStringTags.MIME_MEDIA_TYPE: 156 value = str(packed_value) 184 157 185 158 # anything else that we didn't handle 186 159 else: 187 if value_size is None and value is None: 188 value_size = len(self.binary_value) 189 value = self.binary_value 190 191 if self.value_size is not None: 192 assert value_size == self.value_size, \ 193 "unpacked value_size is not the same " + \ 194 "as self.value_size!" 195 if self.value is not None: 196 assert value == self.value, \ 197 "unpacked value is not the same as self.value!" 198 199 return value_size, value 200 201 def pack(self): 160 if value is None: 161 value = packed_value 162 163 return value 164 165 @property 166 def packed_value(self): 202 167 """ 203 168 Given self.value_tag and self.value, pack the value into 204 binary formo. These values MUST NOT be null. Furthermore, if 205 self.binary_value and self.value_size are set, this method 206 will check to make sure that packing self.value matches up. 207 208 Returns: tuple of (value_size, binary_value) 169 binary form. These values MUST NOT be null. 170 171 Returns: packed_value 172 209 173 """ 210 174 … … 214 178 "cannot pack null value!" 215 179 216 value_size = None 217 binary_value = None 180 packed_value = None 218 181 219 182 # out-of-band value tags … … 222 185 self.value_tag == OutOfBandTags.UNKNOWN or \ 223 186 self.value_tag == OutOfBandTags.NO_VALUE: 224 value_size = 0 225 binary_value = '' 187 packed_value = '' 226 188 227 189 # integer value tags 228 190 elif self.value_tag == IntegerTags.INTEGER: 229 value_size = 4 230 binary_value = struct.pack('>i', self.value) 191 packed_value = struct.pack('>i', self.value) 231 192 elif self.value_tag == IntegerTags.BOOLEAN: 232 value_size = 1 233 binary_value = struct.pack('>?', self.value) 193 packed_value = struct.pack('>?', self.value) 234 194 elif self.value_tag == IntegerTags.ENUM: 235 value_size = 4 236 binary_value = struct.pack('>i', self.value) 195 packed_value = struct.pack('>i', self.value) 237 196 238 197 # octet string value tags … … 252 211 # 10 11 minutes from UTC 0..59 253 212 254 value_size = 11 255 binary_value = struct.pack('>hbbbbbbcbb', self.value) 213 packed_value = struct.pack('>hbbbbbbcbb', *self.value) 256 214 257 215 elif self.value_tag == OctetStringTags.RESOLUTION: … … 263 221 # contains the units 264 222 265 value_size = 9 266 binary_value = truct.pack('>iib', self.value) 223 packed_value = truct.pack('>iib', self.value) 267 224 268 225 elif self.value_tag == OctetStringTags.RANGE_OF_INTEGER: … … 271 228 # SIGNED-INTEGER contains the upper bound. 272 229 273 value_size = 8 274 binary_value = struct.pack('>ii', self.value) 230 packed_value = struct.pack('>ii', self.value) 275 231 276 232 elif self.value_tag == OctetStringTags.TEXT_WITH_LANGUAGE or \ … … 282 238 d_bin = struct.pack('>%ss' % self.value[2], self.value[3]) 283 239 284 value_size = 4 + self.value[0] + self.value[2] 285 binary_value = a_bin + b_bin + c_bin + d_bin 240 packed_value = a_bin + b_bin + c_bin + d_bin 286 241 287 242 # character string value tags … … 291 246 CharacterStringTags.NAME_WITHOUT_LANGUAGE: 292 247 293 value_size = len(self.value) 294 binary_value = struct.pack('>%ss' % len(self.value), 248 packed_value = struct.pack('>%ss' % len(self.value), 295 249 self.value) 296 250 … … 303 257 self.value_tag == CharacterStringTags.MIME_MEDIA_TYPE: 304 258 305 value_size = len(self.value) 306 binary_value = struct.pack('>%ss' % len(self.value), 259 packed_value = struct.pack('>%ss' % len(self.value), 307 260 self.value) 308 261 309 262 else: 310 value_size = len(self.value) 311 binary_value = self.value 312 313 return value_size, binary_value 314 315 def verify(self): 316 """ 317 Verifies that the binary and non-binary values for this Value 318 instance line up. All of self.value, self.binary_value, 319 self.value_size, and self.value_tag must be defined. 320 321 This function will throw an assertion error if the Value 322 instance is not valid. 323 """ 324 325 assert self.value is not None, \ 326 "value is null!" 327 assert self.binary_value is not None, \ 328 "binary value is null!" 329 assert self.value_size is not None, \ 330 "value size is unknown!" 331 assert self.value_tag is not None, \ 332 "value type is unknown!" 333 334 value_size1, binary_value = self.pack() 335 value_size2, value = self.unpack() 336 337 assert value_size1 == value_size2, \ 338 "packed value size is not the same as " + \ 339 "unpacked value size!" 340 assert value_size == self.value_size, \ 341 "packed value size is not the same as " + \ 342 "self.value_size!" 343 assert binary_value == self.binary_value, \ 344 "packed binary value is not the same as " + \ 345 "self.binary_value!" 346 347 def getValue(self): 348 """ 349 Get the non-binary value. 350 """ 351 352 return self.value 353 354 def getBinaryValue(self): 355 """ 356 Get the binary value. 263 packed_value = self.value 264 265 return packed_value 266 267 @packed_value.setter 268 def set_packed_value(self, packed_value): 269 """Replace a value using a new packed value 270 271 Unpacks a new packed_value (of the same value_tag). 272 273 """ 274 self.value = self._unpack(self.value_tag, packed_value) 275 276 @property 277 def packed_value_size(self): 278 """ 279 Get the size of the value in bytes. 357 280 """ 358 281 359 return self.binary_value 360 361 def getValueTag(self): 362 """ 363 Get the value tag (type of value). This is an integer 364 corresponding to a value in ippconstants. 365 """ 366 367 return self.value_tag 368 369 def getValueSize(self): 370 """ 371 Get the size of the value in bytes. 372 """ 373 374 return self.value_size 375 376 def getTagSize(self): 377 """ 378 Get the size of the value tag in bytes. 379 """ 380 381 return self.tag_size 382 383 def setValue(self, value): 384 """ 385 Set the non-binary value. 386 """ 387 388 self.value = value 389 390 def setBinaryValue(self, binary_value): 391 """ 392 Set the binary value. 393 """ 394 395 self.binary_value = binary_value 396 397 def setValueTag(self, value_tag): 398 """ 399 Set the type (tag) of the value. This should correspond to an 400 integer defined in ippconstants. 401 """ 402 403 self.value_tag = value_tag 404 405 def setValueSize(self, size): 406 """ 407 Set the size of the value in bytes. 408 """ 409 410 self.value_size = size 411 412 def getTotalSize(self): 282 return len(self.packed_value) 283 284 @property 285 def total_size(self): 413 286 """ 414 287 Get the total size of the IPP value. 415 288 """ 416 289 417 return self.value_size + self.tag_size 290 # 1 byte for the tag 291 return self.packed_value_size + 1 418 292 419 293 def __str__(self): 420 return self.value 294 return str(self.value) 295 296 def __repr__(self): 297 return '<IPPValue (%r, %r)>' % (self.value_tag, self.value)
Note: See TracChangeset
for help on using the changeset viewer.