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