def __init__(self, array=None, copy=True): if array == None: self._array = None elif isinstance(array, Blob): # Use the existing _array. Don't need to check for copy. self._array = array._array else: array = Common.stringToUtf8Array(array) if copy: # We are copying, so just make another bytearray. # We always use a memoryview so that slicing is efficient. if type(array) is _memoryviewWrapper: # Use the underlying memoryview directly. (When we only # support Python 3.3 or later, this check is not necessary.) self._array = memoryview(bytearray(array._view)) else: self._array = memoryview(bytearray(array)) else: if type(array) is bytearray: # We always use a memoryview so that slicing is efficient. self._array = memoryview(array) else: # Can't take a memoryview, so use as-is. self._array = array if not _memoryviewUsesInt and type(self._array) is memoryview: # memoryview elements are not int (Python versions before 3.3) # so we need a wrapper which will return int elements. self._array = _memoryviewWrapper(self._array)
def __init__(self, array = None, copy = True): self._hash = None if array == None: self._array = None elif isinstance(array, Blob): # Use the existing _array. Don't need to check for copy. self._array = array._array else: array = Common.stringToUtf8Array(array) if copy: # We are copying, so just make another bytearray. # We always use a memoryview so that slicing is efficient. if type(array) is _memoryviewWrapper: # Use the underlying memoryview directly. (When we only # support Python 3.3 or later, this check is not necessary.) self._array = memoryview(bytearray(array._view)) else: self._array = memoryview(bytearray(array)) else: if type(array) is bytearray: # We always use a memoryview so that slicing is efficient. self._array = memoryview(array) else: # Can't take a memoryview, so use as-is. self._array = array if not _memoryviewUsesInt and type(self._array) is memoryview: # memoryview elements are not int (Python versions before 3.3) # so we need a wrapper which will return int elements. self._array = _memoryviewWrapper(self._array)
def _encodeMessageValue(message, encoder): # Note: We can't use ListFields because it sorts by field number. descriptor = message.DESCRIPTOR # Reverse so that we encode backwards. for field in reversed(descriptor.fields): tlvType = field.number if field.label == field.LABEL_REPEATED: # Reverse so that we encode backwards. values = reversed(getattr(message, field.name)) else: if message.HasField(field.name): # Make a singleton list. values = [getattr(message, field.name)] else: continue for value in values: if field.type == field.TYPE_MESSAGE: saveLength = len(encoder) # Encode backwards. ProtobufTlv._encodeMessageValue(value, encoder) encoder.writeTypeAndLength(tlvType, len(encoder) - saveLength) elif (field.type == field.TYPE_UINT32 or field.type == field.TYPE_UINT64): encoder.writeNonNegativeIntegerTlv(tlvType, value) elif (field.type == field.TYPE_ENUM): if value < 0: raise RuntimeError( "ProtobufTlv.encode: ENUM value may not be negative" ) encoder.writeNonNegativeIntegerTlv(tlvType, value) elif (field.type == field.TYPE_BYTES or field.type == field.TYPE_STRING): encoder.writeBlobTlv(tlvType, Common.stringToUtf8Array(value)) elif field.type == field.TYPE_BOOL: if value: encoder.writeTypeAndLength(tlvType, 0) else: raise RuntimeError( "ProtobufTlv.encode: Unknown field type")
def _encodeMessageValue(message, encoder): # Note: We can't use ListFields because it sorts by field number. descriptor = message.DESCRIPTOR # Reverse so that we encode backwards. for field in reversed(descriptor.fields): tlvType = field.number if field.label == field.LABEL_REPEATED: # Reverse so that we encode backwards. values = reversed(getattr(message, field.name)) else: if message.HasField(field.name): # Make a singleton list. values = [getattr(message, field.name)] else: continue for value in values: if field.type == field.TYPE_MESSAGE: saveLength = len(encoder) # Encode backwards. ProtobufTlv._encodeMessageValue(value, encoder) encoder.writeTypeAndLength( tlvType, len(encoder) - saveLength) elif (field.type == field.TYPE_UINT32 or field.type == field.TYPE_UINT64): encoder.writeNonNegativeIntegerTlv(tlvType, value) elif (field.type == field.TYPE_ENUM): if value < 0: raise RuntimeError( "ProtobufTlv::encode: ENUM value may not be negative") encoder.writeNonNegativeIntegerTlv(tlvType, value) elif (field.type == field.TYPE_BYTES or field.type == field.TYPE_STRING): encoder.writeBlobTlv(tlvType, Common.stringToUtf8Array(value)) elif field.type == field.TYPE_BOOL: if value: encoder.writeTypeAndLength(tlvType, 0) else: raise RuntimeError("ProtobufTlv::encode: Unknown field type")