#! /usr/bin/env python

import string
import struct
import sys


class FileExtract:
    '''Decode binary data from a file'''

    def __init__(self, f, b='='):
        '''Initialize with an open binary file and optional byte order'''

        self.file = f
        self.byte_order = b
        self.offsets = list()

    def set_byte_order(self, b):
        '''Set the byte order, valid values are "big", "little", "swap", "native", "<", ">", "@", "="'''
        if b == 'big':
            self.byte_order = '>'
        elif b == 'little':
            self.byte_order = '<'
        elif b == 'swap':
            # swap what ever the current byte order is
            self.byte_order = swap_unpack_char()
        elif b == 'native':
            self.byte_order = '='
        elif b == '<' or b == '>' or b == '@' or b == '=':
            self.byte_order = b
        else:
            print("error: invalid byte order specified: '%s'" % b)

    def is_in_memory(self):
        return False

    def seek(self, offset, whence=0):
        if self.file:
            return self.file.seek(offset, whence)
        raise ValueError

    def tell(self):
        if self.file:
            return self.file.tell()
        raise ValueError

    def read_size(self, byte_size):
        s = self.file.read(byte_size)
        if len(s) != byte_size:
            return None
        return s

    def push_offset_and_seek(self, offset):
        '''Push the current file offset and seek to "offset"'''
        self.offsets.append(self.file.tell())
        self.file.seek(offset, 0)

    def pop_offset_and_seek(self):
        '''Pop a previously pushed file offset, or do nothing if there were no previously pushed offsets'''
        if len(self.offsets) > 0:
            self.file.seek(self.offsets.pop())

    def get_sint8(self, fail_value=0):
        '''Extract a single int8_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(1)
        if s:
            v, = struct.unpack(self.byte_order + 'b', s)
            return v
        else:
            return fail_value

    def get_uint8(self, fail_value=0):
        '''Extract a single uint8_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(1)
        if s:
            v, = struct.unpack(self.byte_order + 'B', s)
            return v
        else:
            return fail_value

    def get_sint16(self, fail_value=0):
        '''Extract a single int16_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(2)
        if s:
            v, = struct.unpack(self.byte_order + 'h', s)
            return v
        else:
            return fail_value

    def get_uint16(self, fail_value=0):
        '''Extract a single uint16_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(2)
        if s:
            v, = struct.unpack(self.byte_order + 'H', s)
            return v
        else:
            return fail_value

    def get_sint32(self, fail_value=0):
        '''Extract a single int32_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(4)
        if s:
            v, = struct.unpack(self.byte_order + 'i', s)
            return v
        else:
            return fail_value

    def get_uint32(self, fail_value=0):
        '''Extract a single uint32_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(4)
        if s:
            v, = struct.unpack(self.byte_order + 'I', s)
            return v
        else:
            return fail_value

    def get_sint64(self, fail_value=0):
        '''Extract a single int64_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(8)
        if s:
            v, = struct.unpack(self.byte_order + 'q', s)
            return v
        else:
            return fail_value

    def get_uint64(self, fail_value=0):
        '''Extract a single uint64_t from the binary file at the current file position, returns a single integer'''
        s = self.read_size(8)
        if s:
            v, = struct.unpack(self.byte_order + 'Q', s)
            return v
        else:
            return fail_value

    def get_fixed_length_c_string(
            self,
            n,
            fail_value='',
            isprint_only_with_space_padding=False):
        '''Extract a single fixed length C string from the binary file at the current file position, returns a single C string'''
        s = self.read_size(n)
        if s:
            cstr, = struct.unpack(self.byte_order + ("%i" % n) + 's', s)
            # Strip trialing NULLs
            cstr = string.strip(cstr, "\0")
            if isprint_only_with_space_padding:
                for c in cstr:
                    if c in string.printable or ord(c) == 0:
                        continue
                    return fail_value
            return cstr
        else:
            return fail_value

    def get_c_string(self):
        '''Extract a single NULL terminated C string from the binary file at the current file position, returns a single C string'''
        cstr = ''
        byte = self.get_uint8()
        while byte != 0:
            cstr += "%c" % byte
            byte = self.get_uint8()
        return cstr

    def get_n_sint8(self, n, fail_value=0):
        '''Extract "n" int8_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'b', s)
        else:
            return (fail_value,) * n

    def get_n_uint8(self, n, fail_value=0):
        '''Extract "n" uint8_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'B', s)
        else:
            return (fail_value,) * n

    def get_n_sint16(self, n, fail_value=0):
        '''Extract "n" int16_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(2 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'h', s)
        else:
            return (fail_value,) * n

    def get_n_uint16(self, n, fail_value=0):
        '''Extract "n" uint16_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(2 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'H', s)
        else:
            return (fail_value,) * n

    def get_n_sint32(self, n, fail_value=0):
        '''Extract "n" int32_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(4 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'i', s)
        else:
            return (fail_value,) * n

    def get_n_uint32(self, n, fail_value=0):
        '''Extract "n" uint32_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(4 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'I', s)
        else:
            return (fail_value,) * n

    def get_n_sint64(self, n, fail_value=0):
        '''Extract "n" int64_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(8 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'q', s)
        else:
            return (fail_value,) * n

    def get_n_uint64(self, n, fail_value=0):
        '''Extract "n" uint64_t integers from the binary file at the current file position, returns a list of integers'''
        s = self.read_size(8 * n)
        if s:
            return struct.unpack(self.byte_order + ("%u" % n) + 'Q', s)
        else:
            return (fail_value,) * n
