def pack_ibm_floats(values): """Pack floats into binary-encoded big-endian single-precision IBM floats. Args: values: An iterable series of numeric values. Returns: A sequence of bytes. """ return EMPTY_BYTE_STRING.join(bytes(IBMFloat.from_real(value)) for value in values)
def write_extended_textual_headers(fh, pages, encoding): """Write extended textual headers. Args: fh: A file-like object open in binary mode for writing. pages: An iterables series of sequences of Unicode strings, where the outer iterable represents 3200 byte pages, each comprised of a sequence of exactly 40 strings of nominally 80 characters each. Although Unicode strings are accepted, and when encoded they should result in exact 80 bytes sequences. To produce a valid data structure for pages, consider using format_extended_textual_header() encoding: Either 'cp037' for EBCDIC or 'ascii' for ASCII. Post-condition: The file pointer in fh will be position at the first byte after the extended textual headers, which is also the first byte of the first trace-header. Raises: ValueError: If the provided header data has the wrong shape. UnicodeError: If the textual data could not be encoded into the specified encoding. """ if not is_supported_encoding(encoding): raise UnsupportedEncodingError("Writing extended textual header", encoding) fh.seek(REEL_HEADER_NUM_BYTES) encoded_pages = [] for page_index, page in enumerate(pages): encoded_page = [] # TODO: Share some of this code with writing the textual reel header. for line_index, line in enumerate(page): encoded_line = line.encode(encoding) num_encoded_bytes = len(encoded_line) if num_encoded_bytes != CARD_LENGTH: raise ValueError( "Extended textual header line {} of page {} at {} bytes is not " "{} bytes".format(line_index, page_index, num_encoded_bytes, CARD_LENGTH)) encoded_page.append(encoded_line) num_encoded_lines = len(encoded_page) if num_encoded_lines != CARDS_PER_HEADER: raise ValueError("Extended textual header page {} number of " "lines {} is not {}".format( page_index, num_encoded_lines, CARDS_PER_HEADER)) encoded_pages.append(encoded_page), for encoded_page in encoded_pages: concatenated_page = EMPTY_BYTE_STRING.join(encoded_page) assert (len(concatenated_page) == TEXTUAL_HEADER_NUM_BYTES) fh.write(concatenated_page)
def write_extended_textual_headers(fh, pages, encoding): """Write extended textual headers. Args: fh: A file-like object open in binary mode for writing. pages: An iterables series of sequences of Unicode strings, where the outer iterable represents 3200 byte pages, each comprised of a sequence of exactly 40 strings of nominally 80 characters each. Although Unicode strings are accepted, and when encoded they should result in exact 80 bytes sequences. To produce a valid data structure for pages, consider using format_extended_textual_header() encoding: Either 'cp037' for EBCDIC or 'ascii' for ASCII. Post-condition: The file pointer in fh will be position at the first byte after the extended textual headers, which is also the first byte of the first trace-header. Raises: ValueError: If the provided header data has the wrong shape. UnicodeError: If the textual data could not be encoded into the specified encoding. """ if not is_supported_encoding(encoding): raise UnsupportedEncodingError("Writing extended textual header", encoding) fh.seek(REEL_HEADER_NUM_BYTES) encoded_pages = [] for page_index, page in enumerate(pages): encoded_page = [] # TODO: Share some of this code with writing the textual reel header. for line_index, line in enumerate(page): encoded_line = line.encode(encoding) num_encoded_bytes = len(encoded_line) if num_encoded_bytes != CARD_LENGTH: raise ValueError("Extended textual header line {} of page {} at {} bytes is not " "{} bytes".format(line_index, page_index, num_encoded_bytes, CARD_LENGTH)) encoded_page.append(encoded_line) num_encoded_lines = len(encoded_page) if num_encoded_lines != CARDS_PER_HEADER: raise ValueError("Extended textual header page {} number of " "lines {} is not {}".format(num_encoded_lines, CARDS_PER_HEADER)) encoded_pages.append(encoded_page) for encoded_page in encoded_pages: concatenated_page = EMPTY_BYTE_STRING.join(encoded_page) assert(len(concatenated_page) == TEXTUAL_HEADER_NUM_BYTES) fh.write(concatenated_page)
def write_textual_reel_header(fh, lines, encoding): """Write the SEG Y card image header, also known as the textual header Args: fh: A file-like object open in binary mode positioned such that the beginning of the textual header will be the next byte to read. lines: An iterable series of forty lines, each of which must be a Unicode string of CARD_LENGTH characters. The first three characters of each line are often "C 1" to "C40" (as required by the SEG Y standard) although this is not enforced by this function, since many widespread SEG Y readers and writers do not adhere to this constraint. To produce a SEG Y compliant series of header lines consider using the format_standard_textual_header() function. Any lines longer than CARD_LENGTH characters will be truncated without warning. Any excess lines over CARDS_PER_HEADER will be discarded. Short or omitted lines will be padded with spaces. encoding: Typically 'cp037' for EBCDIC or 'ascii' for ASCII. Post-condition: The file pointer in fh will be positioned at the first byte following the textual header. Raises: UnsupportedEncodingError: If encoding is neither EBCDIC nor ASCII. UnicodeError: If the data provided in lines cannot be encoded with the encoding. """ if not is_supported_encoding(encoding): raise UnsupportedEncodingError("Writing textual reel header", encoding) fh.seek(0) padded_lines = [line.encode(encoding).ljust(CARD_LENGTH, ' '.encode(encoding))[:CARD_LENGTH] for line in pad(lines, padding='', size=CARDS_PER_HEADER)] joined_header = EMPTY_BYTE_STRING.join(padded_lines) assert len(joined_header) == 3200 fh.write(joined_header) fh.seek(TEXTUAL_HEADER_NUM_BYTES)
def pack(self, values): return EMPTY_BYTE_STRING.join( bytes(IBMFloat.from_real(value)) for value in values)
def pack_ibm_floats_py(values): return EMPTY_BYTE_STRING.join( bytes(IBMFloat.from_real(value)) for value in values)
def pack(self, values): return EMPTY_BYTE_STRING.join(bytes(IBMFloat.from_real(value)) for value in values)