+def encode_element_id(element_id):
+ """
+
+ Encodes an element ID.
+
+ :arg element_id: an element ID
+ :type element_id: int
+ :returns: the encoded representation bytes
+ :rtype: bytearray
+
+ """
+
+ length = MAXIMUM_ELEMENT_ID_LENGTH
+ while length and not (element_id & (vint_mask_for_length(length) << ((length - 1) * 8))):
+ length -= 1
+ if not length:
+ raise ValueError('Cannot encode invalid element ID %s.' % hex(element_id))
+
+ data = bytearray(length)
+ for index in reversed(xrange(length)):
+ data[index] = octet(element_id)
+ element_id >>= 8
+
+ return data
+
+
+def encode_element_size(element_size, length=None):
+ """
+
+ Encodes an element size. If element_size is None, the size will be encoded as unknown. If length is not None, the size will be encoded in that many bytes; otherwise, the size will be encoded in the minimum number of bytes required, or in 8 bytes if the size is unknown (element_size is None).
+
+ :arg element_size: the element size, or None if unknown
+ :type element_size: int or None
+ :arg length: the length of the encoded representation, or None for the minimum length required (defaults to None)
+ :type length: int or None
+ :returns: the encoded representation bytes
+ :rtype: bytearray
+
+ """
+
+ if length is not None and (length < 1 or length > MAXIMUM_ELEMENT_SIZE_LENGTH):
+ raise ValueError('Cannot encode element sizes into representations shorter than one byte long or longer than %i bytes long.' % MAXIMUM_ELEMENT_SIZE_LENGTH)
+ if element_size is not None:
+ if element_size > maximum_element_size_for_length(MAXIMUM_ELEMENT_SIZE_LENGTH if length is None else length):
+ raise ValueError('Cannot encode element size %i as it would have an encoded representation longer than %i bytes.' % (element_size, (MAXIMUM_ELEMENT_SIZE_LENGTH if length is None else length)))
+ req_length = 1
+ while (element_size >> ((req_length - 1) * 8)) >= (vint_mask_for_length(req_length) - 1) and req_length < MAXIMUM_ELEMENT_SIZE_LENGTH:
+ req_length += 1
+ if length is None:
+ length = req_length
+ else:
+ if length is None:
+ length = 8 # other libraries do this, so unless another length is specified for the unknown size descriptor, do as they do to avoid compatibility issues.
+ element_size = maximum_element_size_for_length(length) + 1
+
+ data = bytearray(length)
+ for index in reversed(xrange(length)):
+ data[index] = octet(element_size)
+ element_size >>= 8
+ if not index:
+ data[index] = data[index] | vint_mask_for_length(length)
+
+ return data
+
+
+def encode_unsigned_integer(uint, length=None):
+ """
+
+ Encodes an unsigned integer value. If length is not None, uint will be encoded in that many bytes; otherwise, uint will be encoded in the minimum number of bytes required. If uint is None or 0, the minimum number of bytes required is 0.
+
+ :arg uint: the unsigned integer value
+ :type uint: int
+ :arg length: the length of the encoded representation, or None for the minimum length required (defaults to None)
+ :type length: int or None
+ :returns: the encoded representation bytes
+ :rtype: bytearray
+
+ """
+
+ if uint is None:
+ uint = 0
+ if uint > ((2**((MAXIMUM_UNSIGNED_INTEGER_LENGTH if length is None else length) * 8)) - 1):
+ raise ValueError('Cannot encode unsigned integer value %i as it would have an encoded representation longer than %i bytes.' % (uint, (MAXIMUM_UNSIGNED_INTEGER_LENGTH if length is None else length)))
+ elif uint == 0:
+ req_length = 0
+ else:
+ req_length = 1
+ while uint >= (1 << (req_length * 8)) and req_length < MAXIMUM_UNSIGNED_INTEGER_LENGTH:
+ req_length += 1
+ if length is None:
+ length = req_length
+
+ data = bytearray(length)
+ for index in reversed(xrange(length)):
+ data[index] = octet(uint)
+ uint >>= 8
+
+ return data
+
+
+def encode_signed_integer(sint, length=None):
+ """
+
+ Encodes a signed integer value. If length is not None, sint will be encoded in that many bytes; otherwise, sint will be encoded in the minimum number of bytes required. If sint is None or 0, the minimum number of bytes required is 0.
+
+ :arg sint: the signed integer value
+ :type sint: int
+ :arg length: the length of the encoded representation, or None for the minimum length required (defaults to None)
+ :type length: int or None
+ :returns: the encoded representation bytes
+ :rtype: bytearray
+
+ """
+
+ if sint is None:
+ sint = 0
+ if not (-(2**(7+(8*((MAXIMUM_SIGNED_INTEGER_LENGTH if length is None else length)-1)))) <= sint <= (2**(7+(8*((MAXIMUM_SIGNED_INTEGER_LENGTH if length is None else length)-1))))-1):
+ raise ValueError('Cannot encode signed integer value %i as it would have an encoded representation longer than %i bytes.' % (sint, (MAXIMUM_SIGNED_INTEGER_LENGTH if length is None else length)))
+ elif sint == 0:
+ req_length = 0
+ uint = 0
+ if length is None:
+ length = req_length
+ else:
+ uint = ((-sint - 1) << 1) if sint < 0 else (sint << 1)
+ req_length = 1
+ while uint >= (1 << (req_length * 8)) and req_length < MAXIMUM_UNSIGNED_INTEGER_LENGTH:
+ req_length += 1
+ if length is None:
+ length = req_length
+ if sint >= 0:
+ uint = sint
+ else:
+ uint = 2**(length*8) - abs(sint)
+
+ data = bytearray(length)
+ for index in reversed(xrange(length)):
+ data[index] = octet(uint)
+ uint >>= 8
+
+ return data