Commit cf33053b authored by Javier Quinteros's avatar Javier Quinteros
Browse files

Support for Big and Little Endian.

parent f44d4d58
......@@ -54,19 +54,24 @@ def main():
with open(args.filename, 'rb') as fi:
leadin = fi.read(HEADERLEN)
(tag, ToCmask, version, segmentOffset, dataOffset) = struct.unpack('<4siiQQ', leadin)
(tag, ToCmask) = struct.unpack('<4si', leadin[:8])
# All input from now on will be formatted by this
endian = '>' if ToCmask & kTocBigEndian else '<'
(version, segmentOffset, dataOffset) = struct.unpack('%ciQQ' % endian, leadin[8:])
if tag.decode() != 'TDSm':
raise Exception('Tag is not TDSm!')
if version != 4713:
logs.warning('Version number is not 4713!')
logs.debug('Metadata: ' + ('yes' if ToCmask & kTocMetaData else 'no'))
logs.debug('Object list: ' + ('yes' if ToCmask & kTocNewObjList else 'no'))
logs.debug('Raw data: ' + ('yes' if ToCmask & kTocRawData else 'no'))
logs.debug('Interleaved data: ' + ('yes' if ToCmask & kTocInterleavedData else 'no'))
logs.debug('BigEndian: ' + ('yes' if ToCmask & kTocBigEndian else 'no'))
logs.debug('DAQmx raw data: ' + ('yes' if ToCmask & kTocDAQmxRawData else 'no'))
logs.info('Metadata: ' + ('yes' if ToCmask & kTocMetaData else 'no'))
logs.info('Object list: ' + ('yes' if ToCmask & kTocNewObjList else 'no'))
logs.info('Raw data: ' + ('yes' if ToCmask & kTocRawData else 'no'))
logs.info('Interleaved data: ' + ('yes' if ToCmask & kTocInterleavedData else 'no'))
logs.info('BigEndian: ' + ('yes' if ToCmask & kTocBigEndian else 'no'))
logs.info('DAQmx raw data: ' + ('yes' if ToCmask & kTocDAQmxRawData else 'no'))
if segmentOffset == FF64b:
logs.error('Severe problem while writing data (crash, power outage)')
......@@ -78,18 +83,18 @@ def main():
# Metadata
# Number of objects (unsigned int - 32b)
numObjects = struct.unpack('<I', fi.read(4))[0]
numObjects = struct.unpack('%cI' % endian, fi.read(4))[0]
logs.info('Number of objects in metadata: %s' % numObjects)
for obj in range(numObjects):
objPath = readstring(fi)
objPath = readstring(fi, endian)
logs.info('Object %s: %s' % (obj, objPath))
rawDataIdx = struct.unpack('<I', fi.read(4))[0]
rawDataIdx = struct.unpack('%cI' % endian, fi.read(4))[0]
if rawDataIdx == FF32b:
logs.warning('No raw data assigned to this segment')
readproperties(fi)
logs.info('No raw data assigned to this segment')
readproperties(fi, endian)
elif not rawDataIdx:
logs.info('Raw data index in this segment matches the index the same object had in the previous segment')
......@@ -97,98 +102,71 @@ def main():
else:
# There is raw data!
sizeBytes = None
datatype = readdatatype(fi)
arraylen = struct.unpack('<I', fi.read(4))[0]
numValues = struct.unpack('<Q', fi.read(8))[0]
datatype, arraylen, numValues = struct.unpack('%cIIQ' % endian, fi.read(16))
if datatype == 0x20:
sizeBytes = struct.unpack('<Q', fi.read(8))[0]
sizeBytes = struct.unpack('%cQ' % endian, fi.read(8))[0]
logs.debug('rawDataIdx %s' % rawDataIdx)
logs.debug(datatype)
logs.debug(arraylen)
logs.debug(numValues)
logs.debug(sizeBytes)
if arraylen != 1:
logs.error('Array length MUST be 1! Actual value: %s' % arraylen)
readproperties(fi)
logs.debug('rawDataIdx %s; datatype: %s; numValues: %s' % (rawDataIdx, datatype, numValues))
# logs.debug('rawDataIdx: %s %x %o' % (rawDataIdx, rawDataIdx, rawDataIdx))
# raise Exception()
readproperties(fi, endian)
print(fi.tell())
def readproperties(fi):
def readproperties(fi, endian='<'):
logs = logging.getLogger('readproperties')
numProps = struct.unpack('<I', fi.read(4))[0]
numProps = struct.unpack('%cI' % endian, fi.read(4))[0]
logs.debug('%s properties' % numProps)
for prop in range(numProps):
propStr = readstring(fi)
propStr = readstring(fi, endian)
logs.debug('Prop: %s' % propStr)
value = readvalue(fi)
value = readvalue(fi, endian)
logs.debug(value)
# enum
# {
# tdsTypeVoid,
# tdsTypeI8,
# tdsTypeI16,
# tdsTypeI32,
# tdsTypeI64,
# tdsTypeU8,
# tdsTypeU16,
# tdsTypeU32,
# tdsTypeU64,
# tdsTypeSingleFloat,
# tdsTypeDoubleFloat,
# tdsTypeExtendedFloat,
# tdsTypeSingleFloatWithUnit = 0x19,
# tdsTypeDoubleFloatWithUnit,
# tdsTypeExtendedFloatWithUnit,
# tdsTypeString = 0x20,
# tdsTypeBoolean = 0x21,
# tdsTypeTimeStamp = 0x44,
data2mask = {
0: ('c', 1), # tdsTypeVoid
1: ('b', 1), # tdsTypeI8
2: ('h', 2), # tdsTypeI16
3: ('i', 4), # tdsTypeI32
4: ('q', 8), # tdsTypeI64
5: ('b', 1), # tdsTypeU8
6: ('h', 2), # tdsTypeU16
7: ('i', 4), # tdsTypeU32
8: ('q', 8), # tdsTypeU64
9: ('f', 4), # tdsTypeSingleFloat
10: ('d', 8), # tdsTypeDoubleFloat
0x20: ('I', 4), # tdsTypeString
0x21: ('?', 1), # tdsTypeBoolean
0x44: ('Qq', 16) # tdsTypeTimeStamp
}
# tdsTypeFixedPoint = 0x4F,
# tdsTypeComplexSingleFloat = 0x08000c,
# tdsTypeComplexDoubleFloat = 0x10000d,
# tdsTypeDAQmxRawData = 0xFFFFFFFF
# } tdsDataType;
data2mask = {
0: ('c', 1),
1: ('b', 1),
2: ('h', 2),
3: ('i', 4),
4: ('q', 8),
5: ('b', 1),
6: ('h', 2),
7: ('i', 4),
8: ('q', 8),
9: ('f', 4),
10: ('d', 8),
0x20: ('I', 4),
0x21: ('?', 1),
0x44: ('Qq', 16)
}
def readdatatype(fi):
return struct.unpack('<I', fi.read(4))[0]
def readdatatype(fi, endian='<'):
return struct.unpack('%cI' % endian, fi.read(4))[0]
def readvalue(fi):
def readvalue(fi, endian='<'):
logs = logging.getLogger('readvalue')
datatype = readdatatype(fi)
datatype = readdatatype(fi, endian)
logs.debug('datatype: 0x%x' % datatype)
# Consider cases which need another read
# 0x20 is a string. Read again!
if datatype == 0x20:
return readstring(fi)
return readstring(fi, endian)
(mask, numBytes) = data2mask[datatype]
logs.debug('Mask: %s; Bytes: %s' % (mask, numBytes))
# This instruction returns a tuple. Needed for timestamps
result = struct.unpack('<%s' % mask, fi.read(numBytes))
result = struct.unpack('%c%s' % (endian, mask), fi.read(numBytes))
# 0x44 is a timestamp. Read again!
if datatype == 0x44:
......@@ -213,10 +191,10 @@ def tup2time(fraction, seconds):
return result
def readstring(fi):
logs = logging.getLogger('readstring')
strlen = struct.unpack('<I', fi.read(4))
logs.debug('String of length %s' % strlen)
def readstring(fi, endian='<'):
# logs = logging.getLogger('readstring')
strlen = struct.unpack('%cI' % endian, fi.read(4))
# logs.debug('String of length %s' % strlen)
return fi.read(strlen[0]).decode()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment