def read_trace(n, l, f=5): ret = [] if PRINT == True: for i in range(n): buf = FH.read(l) # IBM floats - 4 byte - Must be big endian if f == 1: ret.append( construct.BFloat32("x").parse(ibmfloat.ibm2ieee32(buf))) # INT - 4 byte or 2 byte elif f == 2: if ENDIAN == 'little': # Swap 4 byte b = construct.SLInt32("x").parse(buf) else: b = construct.SBInt32("x").parse(buf) ret.append(b) elif f == 3: if ENDIAN == 'little': # Swap 2 byte b = construct.SLInt16("x").parse(buf) else: b = construct.SBInt16("x").parse(buf) ret.append(b) # IEEE floats - 4 byte elif f == 5: if ENDIAN == 'little': # Swap 4 byte b = construct.LFloat32("x").parse(buf) else: b = construct.BFloat32("x").parse(buf) ret.append(b) # INT - 1 byte elif f == 8: ret.append(construct.SBInt8("x").parse(buf)) else: FH.read(n * l) return ret
class TestRegValue(interface.WinRegValue): """Implementation of the Registry value interface for testing.""" _INT32_BIG_ENDIAN = construct.SBInt32('value') _INT32_LITTLE_ENDIAN = construct.SLInt32('value') _INT64_LITTLE_ENDIAN = construct.SLInt64('value') def __init__(self, name, data, data_type, offset=0): """Set up the test reg value object.""" super(TestRegValue, self).__init__() self._name = name self._data = data self._data_type = data_type self._offset = offset self._type_str = '' @property def name(self): """The name of the value.""" return self._name @property def offset(self): """The offset of the value within the Windows Registry file.""" return self._offset @property def data_type(self): """Numeric value that contains the data type.""" return self._data_type @property def raw_data(self): """The value data as a byte string.""" return self._data @property def data(self): """The value data as a native Python object.""" if not self._data: return None if self._data_type in [self.REG_SZ, self.REG_EXPAND_SZ, self.REG_LINK]: try: return unicode(self._data.decode('utf-16-le')) except UnicodeError: pass elif self._data_type == self.REG_DWORD and len(self._data) == 4: return self._INT32_LITTLE_ENDIAN.parse(self._data) elif self._data_type == self.REG_DWORD_BIG_ENDIAN and len( self._data) == 4: return self._INT32_BIG_ENDIAN.parse(self._data) elif self._data_type == self.REG_QWORD and len(self._data) == 8: return self._INT64_LITTLE_ENDIAN.parse(self._data) elif self._data_type == self.REG_MULTI_SZ: try: utf16_string = unicode(self._data.decode('utf-16-le')) return filter(None, utf16_string.split('\x00')) except UnicodeError: pass return self._data
class FakeWinRegistryValue(interface.WinRegistryValue): """Fake implementation of a Windows Registry value.""" _INT32_BIG_ENDIAN = construct.SBInt32(u'value') _INT32_LITTLE_ENDIAN = construct.SLInt32(u'value') _INT64_LITTLE_ENDIAN = construct.SLInt64(u'value') def __init__(self, name, data=b'', data_type=0, offset=0): """Initializes a Windows Registry value object. Args: name: the name of the Windows Registry value. data: optional binary string containing the value data. data_type: optional integer containing the value data type. offset: optional offset of the value within the Windows Registry file. """ super(FakeWinRegistryValue, self).__init__() self._data = data self._data_type = data_type self._data_size = len(data) self._name = name self._offset = offset @property def data(self): """The value data as a native Python object. Raises: WinRegistryValueError: if the value data cannot be read. """ if not self._data: return None if self._data_type in self._STRING_VALUE_TYPES: try: return self._data.decode(u'utf-16-le') except UnicodeError as exception: raise errors.WinRegistryValueError( u'Unable to read data from value: {0:s} with error: {1:s}'. format(self._name, exception)) elif (self._data_type == definitions.REG_DWORD and self._data_size == 4): return self._INT32_LITTLE_ENDIAN.parse(self._data) elif (self._data_type == definitions.REG_DWORD_BIG_ENDIAN and self._data_size == 4): return self._INT32_BIG_ENDIAN.parse(self._data) elif (self._data_type == definitions.REG_QWORD and self._data_size == 8): return self._INT64_LITTLE_ENDIAN.parse(self._data) elif self._data_type == definitions.REG_MULTI_SZ: try: utf16_string = self._data.decode(u'utf-16-le') return filter(None, utf16_string.split(u'\x00')) except UnicodeError as exception: raise errors.WinRegistryValueError( u'Unable to read data from value: {0:s} with error: {1:s}'. format(self._name, exception)) return self._data @property def data_type(self): """Numeric value that contains the data type.""" return self._data_type @property def name(self): """The name of the value.""" return self._name @property def offset(self): """The offset of the value within the Windows Registry file.""" return self._pyregf_value.offset @property def raw_data(self): """The value data as a byte string.""" return self._data
import construct as cons class FrameAdapter(cons.Adapter): def _decode(self, obj, context): return Frame(context['_']['slp_file'], obj) FRAME = cons.Struct( 'frames', cons.ULInt32('cmd_table_offset'), cons.ULInt32('outline_table_offset'), cons.ULInt32('palette_offset'), cons.ULInt32('properties'), cons.SLInt32('width'), cons.SLInt32('height'), cons.SLInt32('hotspot_x'), cons.SLInt32('hotspot_y'), ) HEADER = cons.Struct( 'header', cons.String('version', 4), cons.ULInt32('num_frames'), cons.String('comment', 24), cons.Array(lambda ctx: ctx['num_frames'], FrameAdapter(FRAME)), ) class ImageAdapter(object):
class FakeWinRegistryValue(interface.WinRegistryValue): """Fake implementation of a Windows Registry value.""" _INT32_BIG_ENDIAN = construct.SBInt32(u'value') _INT32_LITTLE_ENDIAN = construct.SLInt32(u'value') _INT64_LITTLE_ENDIAN = construct.SLInt64(u'value') def __init__(self, name, data=b'', data_type=definitions.REG_NONE, offset=0): """Initializes a Windows Registry value. Args: name (str): name of the Windows Registry value. data (Optional[bytes]): value data. data_type (Optional[int]): value data type. offset (Optional[int]): offset of the value within the Windows Registry file. """ super(FakeWinRegistryValue, self).__init__() self._data = data self._data_type = data_type self._data_size = len(data) self._name = name self._offset = offset @property def data(self): """bytes: value data as a byte string.""" return self._data @property def data_type(self): """int: data type.""" return self._data_type @property def name(self): """str: name of the value.""" return self._name @property def offset(self): """int: offset of the value within the Windows Registry file.""" return self._offset def GetDataAsObject(self): """Retrieves the data as an object. Returns: object: data as a Python type. Raises: WinRegistryValueError: if the value data cannot be read. """ if not self._data: return if self._data_type in self._STRING_VALUE_TYPES: try: return self._data.decode(u'utf-16-le') # AttributeError is raised when self._data has no decode method. except AttributeError as exception: raise errors.WinRegistryValueError(( u'Unsupported data type: {0!s} of value: {1!s} with error: ' u'{2!s}').format(type(self._data), self._name, exception)) except UnicodeError as exception: raise errors.WinRegistryValueError( u'Unable to decode data of value: {0!s} with error: {1!s}'.format( self._name, exception)) elif (self._data_type == definitions.REG_DWORD and self._data_size == 4): return self._INT32_LITTLE_ENDIAN.parse(self._data) elif (self._data_type == definitions.REG_DWORD_BIG_ENDIAN and self._data_size == 4): return self._INT32_BIG_ENDIAN.parse(self._data) elif (self._data_type == definitions.REG_QWORD and self._data_size == 8): return self._INT64_LITTLE_ENDIAN.parse(self._data) elif self._data_type == definitions.REG_MULTI_SZ: try: utf16_string = self._data.decode(u'utf-16-le') # TODO: evaluate the use of filter here is appropriate behavior. return list(filter(None, utf16_string.split(u'\x00'))) # AttributeError is raised when self._data has no decode method. except AttributeError as exception: raise errors.WinRegistryValueError(( u'Unsupported data type: {0!s} of value: {1!s} with error: ' u'{2!s}').format(type(self._data), self._name, exception)) except UnicodeError as exception: raise errors.WinRegistryValueError( u'Unable to read data from value: {0!s} with error: {1!s}'.format( self._name, exception)) return self._data
class _GzipMember(object): """Gzip member. Gzip files have no index of members, so each member must be read sequentially before metadata and random seeks are possible. This class provides caching of gzip member data during the initial read of each member. Attributes: comment (str): comment stored in the member. member_end_offset (int): offset to the end of the member in the parent file object. member_start_offset (int): offset to the start of the member in the parent file object. operating_system (int): type of file system on which the compression took place. original_filename (str): original filename of the uncompressed file. uncompressed_data_offset (int): offset of the start of the uncompressed data in this member relative to the whole gzip file's uncompressed data. uncompressed_data_size (int): total size of the data in this gzip member after decompression. """ _MEMBER_HEADER_STRUCT = construct.Struct( 'file_header', construct.ULInt16('signature'), construct.UBInt8('compression_method'), construct.UBInt8('flags'), construct.SLInt32('modification_time'), construct.UBInt8('extra_flags'), construct.UBInt8('operating_system')) _MEMBER_FOOTER_STRUCT = construct.Struct( 'file_footer', construct.ULInt32('checksum'), construct.ULInt32('uncompressed_data_size')) _GZIP_SIGNATURE = 0x8b1f _COMPRESSION_METHOD_DEFLATE = 8 _FLAG_FTEXT = 0x01 _FLAG_FHCRC = 0x02 _FLAG_FEXTRA = 0x04 _FLAG_FNAME = 0x08 _FLAG_FCOMMENT = 0x10 # The maximum size of the uncompressed data cache. _UNCOMPRESSED_DATA_CACHE_SIZE = 2 * 1024 * 1024 def __init__(self, file_object, member_start_offset, uncompressed_data_offset): """Initializes a gzip member. Args: file_object (FileIO): file-like object, containing the gzip member. member_start_offset (int): offset to the beginning of the gzip member in the containing file. uncompressed_data_offset (int): current offset into the uncompressed data in the containing file. """ self.comment = None self.modification_time = None self.operating_system = None self.original_filename = None # Offset into this member's uncompressed data of the first item in # the cache. self._cache_start_offset = None # Offset into this member's uncompressed data of the last item in # the cache. self._cache_end_offset = None self._cache = b'' # Total size of the data in this gzip member after decompression. self.uncompressed_data_size = None # Offset of the start of the uncompressed data in this member relative to # the whole gzip file's uncompressed data. self.uncompressed_data_offset = uncompressed_data_offset # Offset to the start of the member in the parent file object. self.member_start_offset = member_start_offset # Initialize the member with data. self._file_object = file_object self._file_object.seek(self.member_start_offset, os.SEEK_SET) self._ReadAndParseHeader(file_object) # Offset to the beginning of the compressed data in the file object. self._compressed_data_start = file_object.get_offset() self._decompressor_state = _GzipDecompressorState( self._compressed_data_start) self._LoadDataIntoCache(file_object, 0, read_all_data=True) self._ReadAndParseFooter(file_object) # Offset to the end of the member in the parent file object. self.member_end_offset = file_object.get_offset() def GetCacheSize(self): """Determines the size of the uncompressed cached data. Returns: int: number of cached bytes. """ if not self._cache_start_offset or not self._cache_end_offset: return 0 return self._cache_end_offset - self._cache_start_offset def IsCacheFull(self): """Checks whether the uncompressed data cache is full. Returns: bool: True if the cache is full. """ return self.GetCacheSize() >= self._UNCOMPRESSED_DATA_CACHE_SIZE def FlushCache(self): """Empties the cache that holds cached decompressed data.""" self._cache = b'' self._cache_start_offset = None self._cache_end_offset = None self._ResetDecompressorState() def _ResetDecompressorState(self): """Resets the state of the internal decompression object.""" self._decompressor_state = _GzipDecompressorState( self._compressed_data_start) def ReadAtOffset(self, offset, size=None): """Reads a byte string from the gzip member at the specified offset. The function will read a byte string of the specified size or all of the remaining data if no size was specified. Args: offset (int): offset within the uncompressed data in this member to read from. size (Optional[int]): maximum number of bytes to read, where None represents all remaining data, to a maximum of the uncompressed cache size. Returns: bytes: data read. Raises: IOError: if the read failed. ValueError: if a negative read size or offset is specified. """ if size is not None and size < 0: raise ValueError('Invalid size value {0!d}'.format(size)) if offset < 0: raise ValueError('Invalid offset value {0!d}'.format(offset)) if size == 0 or offset >= self.uncompressed_data_size: return b'' if self._cache_start_offset is None: self._LoadDataIntoCache(self._file_object, offset) if offset > self._cache_end_offset or offset < self._cache_start_offset: self.FlushCache() self._LoadDataIntoCache(self._file_object, offset) cache_offset = offset - self._cache_start_offset if not size: return self._cache[cache_offset:] data_end_offset = cache_offset + size if data_end_offset > self._cache_end_offset: return self._cache[cache_offset:] return self._cache[cache_offset:data_end_offset] def _LoadDataIntoCache(self, file_object, minimum_offset, read_all_data=False): """Reads and decompresses the data in the member. This function already loads as much data as possible in the cache, up to UNCOMPRESSED_DATA_CACHE_SIZE bytes. Args: file_object (FileIO): file-like object. minimum_offset (int): offset into this member's uncompressed data at which the cache should start. read_all_data (bool): True if all the compressed data should be read from the member. """ # Decompression can only be performed from beginning to end of the stream. # So, if data before the current position of the decompressor in the stream # is required, it's necessary to throw away the current decompression # state and start again. if minimum_offset < self._decompressor_state.uncompressed_offset: self._ResetDecompressorState() while not self.IsCacheFull() or read_all_data: decompressed_data = self._decompressor_state.Read(file_object) decompressed_data_length = len(decompressed_data) decompressed_end_offset = self._decompressor_state.uncompressed_offset decompressed_start_offset = (decompressed_end_offset - decompressed_data_length) data_to_add = decompressed_data added_data_start_offset = decompressed_start_offset if decompressed_start_offset < minimum_offset: data_to_add = None if decompressed_start_offset < minimum_offset < decompressed_end_offset: data_add_offset = decompressed_end_offset - minimum_offset data_to_add = decompressed_data[-data_add_offset] added_data_start_offset = decompressed_end_offset - data_add_offset if not self.IsCacheFull() and data_to_add: self._cache = b''.join([self._cache, data_to_add]) if self._cache_start_offset is None: self._cache_start_offset = added_data_start_offset if self._cache_end_offset is None: self._cache_end_offset = self._cache_start_offset + len( data_to_add) else: self._cache_end_offset += len(data_to_add) # If there's no more data in the member, the unused_data value is # populated in the decompressor. When this situation arises, we rewind # to the end of the compressed_data section. unused_data = self._decompressor_state.GetUnusedData() if unused_data: seek_offset = -len(unused_data) file_object.seek(seek_offset, os.SEEK_CUR) self._ResetDecompressorState() break def _ReadAndParseHeader(self, file_object): """Reads the member header and sets relevant member values. Args: file_object (FileIO): file-like object to read from. Raises: FileFormatError: if file format related errors are detected. """ member_header = self._MEMBER_HEADER_STRUCT.parse_stream(file_object) if member_header.signature != self._GZIP_SIGNATURE: raise errors.FileFormatError( 'Unsupported file signature: 0x{0:04x}.'.format( member_header.signature)) if member_header.compression_method != self._COMPRESSION_METHOD_DEFLATE: raise errors.FileFormatError( 'Unsupported compression method: {0:d}.'.format( member_header.compression_method)) self.modification_time = member_header.modification_time self.operating_system = member_header.operating_system if member_header.flags & self._FLAG_FEXTRA: extra_field_data_size = construct.ULInt16( 'extra_field_data_size').parse_stream(file_object) file_object.seek(extra_field_data_size, os.SEEK_CUR) if member_header.flags & self._FLAG_FNAME: # Since encoding is set construct will convert the C string to Unicode. # Note that construct 2 does not support the encoding to be a Unicode # string. self.original_filename = construct.CString( 'original_filename', encoding=b'iso-8859-1').parse_stream(file_object) if member_header.flags & self._FLAG_FCOMMENT: # Since encoding is set construct will convert the C string to Unicode. # Note that construct 2 does not support the encoding to be a Unicode # string. self.comment = construct.CString( 'comment', encoding=b'iso-8859-1').parse_stream(file_object) if member_header.flags & self._FLAG_FHCRC: file_object.read(2) def _ReadAndParseFooter(self, file_object): """Reads the member footer and sets relevant member values. Args: file_object (FileIO): file-like object to read from. Raises: FileFormatError: if file format related errors are detected. """ file_footer = self._MEMBER_FOOTER_STRUCT.parse_stream(file_object) self.uncompressed_data_size = file_footer.uncompressed_data_size
class GzipFile(file_object_io.FileObjectIO): """Class that implements a file-like object of a gzip file. The gzip file is a zlib compressed data stream with additional metadata. """ _FILE_HEADER_STRUCT = construct.Struct( u'file_header', construct.ULInt16(u'signature'), construct.UBInt8(u'compression_method'), construct.UBInt8(u'flags'), construct.SLInt32(u'modification_time'), construct.UBInt8(u'extra_flags'), construct.UBInt8(u'operating_system')) _FILE_FOOTER_STRUCT = construct.Struct( u'file_footer', construct.ULInt32(u'checksum'), construct.ULInt32(u'uncompressed_data_size')) _FILE_SIGNATURE = 0x8b1f _COMPRESSION_METHOD_DEFLATE = 8 _FLAG_FTEXT = 0x01 _FLAG_FHCRC = 0x02 _FLAG_FEXTRA = 0x04 _FLAG_FNAME = 0x08 _FLAG_FCOMMENT = 0x10 def __init__(self, resolver_context, file_object=None): """Initializes the file-like object. Args: resolver_context: the resolver context (instance of resolver.Context). file_object: optional file-like object. The default is None. Raises: ValueError: when file_object is set. """ if file_object: raise ValueError(u'File object value set.') super(GzipFile, self).__init__(resolver_context) self._compressed_data_offset = -1 self._compressed_data_size = -1 self.comment = None self.modification_time = None self.operating_system = None self.original_filename = None self.uncompressed_data_size = 0 def _ReadFileHeader(self, file_object): """Reads the file header. Args: file_object: the file-like object to read from. Raises: FileFormatError: if file format related errors are detected. """ file_object.seek(0, os.SEEK_SET) file_header = self._FILE_HEADER_STRUCT.parse_stream(file_object) self._compressed_data_offset = file_object.get_offset() if file_header.signature != self._FILE_SIGNATURE: raise errors.FileFormatError( u'Unsuppored file signature: 0x{0:04x}.'.format( file_header.signature)) if file_header.compression_method != self._COMPRESSION_METHOD_DEFLATE: raise errors.FileFormatError( u'Unsuppored compression method: {0:d}.'.format( file_header.compression_method)) self.modification_time = file_header.modification_time self.operating_system = file_header.operating_system if file_header.flags & self._FLAG_FEXTRA: extra_field_data_size = construct.ULInt16( u'extra_field_data_size').parse_stream(file_object) file_object.seek(extra_field_data_size, os.SEEK_CUR) self._compressed_data_offset += 2 + extra_field_data_size if file_header.flags & self._FLAG_FNAME: # Since encoding is set construct will convert the C string to Unicode. # Note that construct 2 does not support the encoding to be a Unicode # string. self.original_filename = construct.CString( u'original_filename', encoding='iso-8859-1').parse_stream( file_object) self._compressed_data_offset = file_object.get_offset() if file_header.flags & self._FLAG_FCOMMENT: # Since encoding is set construct will convert the C string to Unicode. # Note that construct 2 does not support the encoding to be a Unicode # string. self.comment = construct.CString( u'comment', encoding='iso-8859-1').parse_stream(file_object) self._compressed_data_offset = file_object.get_offset() if file_header.flags & self._FLAG_FHCRC: self._compressed_data_offset += 2 self._compressed_data_size = ( file_object.get_size() - (self._compressed_data_offset + 8)) def _ReadFileFooter(self, file_object): """Reads the file footer. Args: file_object: the file-like object to read from. Raises: FileFormatError: if file format related errors are detected. """ file_object.seek(-8, os.SEEK_END) file_footer = self._FILE_FOOTER_STRUCT.parse_stream(file_object) self.uncompressed_data_size = file_footer.uncompressed_data_size def _OpenFileObject(self, path_spec): """Opens the file-like object defined by path specification. Args: path_spec: optional the path specification (instance of path.PathSpec). The default is None. Returns: A file-like object. """ gzip_file_object = resolver.Resolver.OpenFileObject( path_spec.parent, resolver_context=self._resolver_context) try: self._ReadFileHeader(gzip_file_object) self._ReadFileFooter(gzip_file_object) finally: gzip_file_object.close() path_spec_data_range = data_range_path_spec.DataRangePathSpec( range_offset=self._compressed_data_offset, range_size=self._compressed_data_size, parent=path_spec.parent) path_spec_compressed_stream = ( compressed_stream_path_spec.CompressedStreamPathSpec( compression_method=definitions.COMPRESSION_METHOD_DEFLATE, parent=path_spec_data_range)) return resolver.Resolver.OpenFileObject( path_spec_compressed_stream, resolver_context=self._resolver_context)
def bin_header_le_int(): BIN = construct.Struct( "BIN", # GMT year corresponding to reference (zero) time in # file. construct.SLInt32("nzyear"), construct.SLInt32("nzjday"), # GMT julian day. construct.SLInt32("nzhour"), # GMT hour. construct.SLInt32("nzmin"), # GMT minute. construct.SLInt32("nzsec"), # GMT second. construct.SLInt32("nzmsec"), # GMT millisecond. # Header version number. Current value is the # integer 6. construct.SLInt32("nvhdr"), # Older version data (NVHDR < 6) are automatically # updated construct.SLInt32("norid"), # Origin ID (CSS 3.0) construct.SLInt32("nevid"), # Event ID (CSS 3.0) # Number of points per data component. [required] construct.SLInt32("npts"), construct.SLInt32("nsnpts"), # construct.SLInt32("nwfid"), # Waveform ID (CSS 3.0) construct.SLInt32("nxsize"), # construct.SLInt32("nysize"), # construct.SLInt32("unused15"), # # Type of file [required]: construct.SLInt32("iftype"), # * ITIME {Time series file} # * IRLIM {Spectral file---real and imaginary} # * IAMPH {Spectral file---amplitude and phase} # * IXY {General x versus y data} # * IXYZ {General XYZ (3-D) file} # Type of dependent variable: construct.SLInt32("idep"), # * IUNKN (Unknown) # * IDISP (Displacement in nm) # * IVEL (Velocity in nm/sec) # * IVOLTS (Velocity in volts) # * IACC (Acceleration in nm/sec/sec) # Reference time equivalence: construct.SLInt32("iztype"), # * IUNKN (5): Unknown # * IB (9): Begin time # * IDAY (10): Midnight of refernece GMT day # * IO (11): Event origin time # * IA (12): First arrival time # * ITn (13-22): User defined time pick n,n=0,9 construct.SLInt32("unused16"), # # Type of recording instrument. [currently not used] construct.SLInt32("iinst"), # Station geographic region. [not currently used] construct.SLInt32("istreg"), # Event geographic region. [not currently used] construct.SLInt32("ievreg"), construct.SLInt32("ievtyp"), # Type of event: # * IUNKN (Unknown) # * INUCL (Nuclear event) # * IPREN (Nuclear pre-shot event) # * IPOSTN (Nuclear post-shot event) # * IQUAKE (Earthquake) # * IPREQ (Foreshock) # * IPOSTQ (Aftershock) # * ICHEM (Chemical explosion) # * IQB (Quarry or mine blast confirmed by quarry) # * IQB1 (Quarry/mine blast with designed shot # info-ripple fired) # * IQB2 (Quarry/mine blast with observed shot # info-ripple fired) # * IQMT (Quarry/mining-induced events: # tremors and rockbursts) # * IEQ (Earthquake) # * IEQ1 (Earthquakes in a swarm or aftershock # sequence) # * IEQ2 (Felt earthquake) # * IME (Marine explosion) # * IEX (Other explosion) # * INU (Nuclear explosion) # * INC (Nuclear cavity collapse) # * IO\_ (Other source of known origin) # * IR (Regional event of unknown origin) # * IT (Teleseismic event of unknown origin) # * IU (Undetermined or conflicting information) # Quality of data [not currently used]: construct.SLInt32("iqual"), # * IGOOD (Good data) # * IGLCH (Glitches) # * IDROP (Dropouts) # * ILOWSN (Low signal to noise ratio) # * IOTHER (Other) # Synthetic data flag [not currently used]: construct.SLInt32("isynth"), # * IRLDTA (Real data) # * ????? # (Flags for various synthetic seismogram # codes) construct.SLInt32("imagtyp"), # construct.SLInt32("imagsrc"), # construct.SLInt32("unused19"), # construct.SLInt32("unused20"), # construct.SLInt32("unused21"), # construct.SLInt32("unused22"), # construct.SLInt32("unused23"), # construct.SLInt32("unused24"), # construct.SLInt32("unused25"), # construct.SLInt32("unused26"), # # TRUE if data is evenly spaced. [required] construct.SLInt32("leven"), # TRUE if station components have a positive # polarity construct.SLInt32("lpspol"), # (left-hand rule). # TRUE if it is okay to overwrite this file on disk. construct.SLInt32("lovrok"), # TRUE if DIST AZ BAZ and GCARC are to be calculated # from construct.SLInt32("lcalda"), # st event coordinates. construct.SLInt32("unused27")) return BIN