Exemplo n.º 1
0
 def write_files(self, f: BinaryIO) -> None:
     """Writes file data to f.
     
     Args:
         f (BinaryIO): file-like output stream
     """
     # TODO: name 	bstring 	Full path and name of the file. Only present if Bit 9 of archiveFlags is set.
     self.i = 0
     total = self.files_count
     for folder in self.sorted_folders:
         for file in folder.sorted_files:
             p = f"{file.folder.name}\\{file.name}"
             # logging.info(f"Writing {p:100s}[{(i * 100) / total:2.2f}%]")
             data_start = f.tell()
             with open(os.path.join(self.data_path, folder.name, file.name), "rb") as o:
                 if not self.compress:
                     f.write(o.read())
                 else:
                     uncompressed_data = o.read()
                     compressed_data = lz4.frame.compress(uncompressed_data, compression_level=self.compression_level)
                     f.write(struct.pack("<L", len(uncompressed_data)))
                     f.write(compressed_data)
             size = f.tell() - data_start
             f.seek(file.record_offset + 8)
             f.write(struct.pack("<LL", size + (4 if self.compress else 0), data_start))
             f.seek(0, os.SEEK_END)
             self.i += 1
Exemplo n.º 2
0
 def write_file_records(self, f: BinaryIO) -> None:
     """Writes the file records block to f
     
     Args:
         f (BinaryIO): file-like output stream
     """
     logging.debug("Writing file records")
     for folder in self.sorted_folders:
         logging.debug(f"Processing file records for folder {folder.name}")
         offset = f.tell()
         f.seek(folder.record_offset + 8 + 4 + 4)
         f.write(struct.pack("<Q", offset + self.total_file_name_length))
         f.seek(0, os.SEEK_END)
         if (self.flags & Flags.INCLUDE_DIRECTORY_NAMES) > 0:
             f.write(pack_str(folder.name))
         logging.debug(f"Sorted files in {folder.name}: {[x.tes_hash for x in folder.sorted_files]}")
         for file in folder.sorted_files:
             file.record_offset = f.tell()
             f.write(
                 struct.pack(
                     "<QLL",
                     file.tes_hash,
                     0,
                     0
                 )
             )
Exemplo n.º 3
0
    def read(self, file_input: BinaryIO, file_size: int) -> Flags:
        """populate header data"""

        first_dg = (file_input.tell() == 0)
        chunk = file_input.read(16)
        hdr_data = struct.unpack("<IBBHII", chunk)

        self.length = hdr_data[0]
        self.stx = hdr_data[1]
        self.id = hdr_data[2]
        self.model = hdr_data[3]
        self.date = hdr_data[4]
        self.time = hdr_data[5]

        if first_dg and self.stx != 2:
            if self.verbose:
                logger.warning("invalid Kongberg file > STX: %s" % self.stx)
            return self.Flags.MISSING_FIRST_STX

        if (self.stx != 2) or (self.id == 0):
            if self.verbose:
                logger.warning("corrupted datagram")
            return self.Flags.CORRUPTED_START_DATAGRAM

        # try to read ETX

        # Make sure we don't try to read beyond the EOF (-13 since 16 for header and 3 for ender)
        if (file_input.tell() + (self.length - 13)) >= file_size:
            if self.verbose:
                logger.warning("unexpected EOF > current pos: %s, datagram length: %s, file size: %s"
                               % (file_input.tell(), self.length, file_size))
            return self.Flags.UNEXPECTED_EOF

        # move file cursor to the end of the datagram
        file_input.seek(self.length - 15, 1)

        chunk = file_input.read(3)
        footer_data = struct.unpack("<BH", chunk)
        self.etx = footer_data[0]
        self.checksum = footer_data[1]

        if self.etx != 3:
            # print 'ETX not found, trying next datagram at position',file.tell()-(length+3)

            return self.Flags.CORRUPTED_END_DATAGRAM

        return self.Flags.VALID
Exemplo n.º 4
0
    def read(self, file_input: BinaryIO, file_size: int) -> Flags:
        """populate header data"""

        chunk = file_input.read(20)
        hdr_data = struct.unpack("<I4cBBHII", chunk)

        self.length = hdr_data[0]
        # logger.debug('length: %s' % self.length)
        self.id = b''.join(hdr_data[1:5])
        # logger.debug('type: %s -> %s' % (self.type, self.kmall_datagrams[self.type]))
        self.version = hdr_data[5]
        # logger.debug('version: %s' % self.version)
        self.system_id = hdr_data[6]
        # logger.debug('system id: %s' % self.system_id)
        self.sounder_id = hdr_data[7]
        # logger.debug('sounder id: %s' % self.sounder_id)
        self.time_sec = hdr_data[8]
        # logger.debug('time sec: %s' % self.time_sec)
        self.time_nanosec = hdr_data[9]
        # logger.debug('time nanosec: %s' % self.time_nanosec)
        self.dg_time = self.kmall_datetime(self.time_sec, self.time_nanosec)
        # logger.debug('datetime: %s' % self.dg_time.strftime('%Y-%m-%d %H:%M:%S.%f'))

        # try to read ETX

        # Make sure we don't try to read beyond the EOF (-13 since 16 for header and 3 for ender)
        if (file_input.tell() + (self.length - 20)) >= file_size:
            if self.verbose:
                logger.warning("unexpected EOF > current pos: %s, datagram length: %s, file size: %s"
                               % (file_input.tell(), self.length, file_size))
            return self.Flags.UNEXPECTED_EOF

        # move file cursor to the end of the datagram
        file_input.seek(self.length - 24, 1)

        chunk = file_input.read(4)
        footer_length = struct.unpack("<I", chunk)[0]

        if footer_length != self.length:
            logger.info("datagram length mismatch: %s vs. %s" % (self.length, footer_length))

            return self.Flags.CORRUPTED_END_DATAGRAM

        return self.Flags.VALID
Exemplo n.º 5
0
    def read(self, file_input: BinaryIO, file_size: int) -> Flags:
        """populate header data"""

        chunk = file_input.read(20)
        hdr_data = struct.unpack("<I4cBBHII", chunk)

        self.length = hdr_data[0]
        # logger.debug('length: %s' % self.length)
        self.type = b''.join(hdr_data[1:5])
        # logger.debug('type: %s -> %s' % (self.type, self.kmall_datagrams[self.type]))
        self.version = hdr_data[5]
        # logger.debug('version: %s' % self.version)
        self.system_id = hdr_data[6]
        # logger.debug('system id: %s' % self.system_id)
        self.sounder_id = hdr_data[7]
        # logger.debug('sounder id: %s' % self.sounder_id)
        self.time_sec = hdr_data[8]
        # logger.debug('time sec: %s' % self.time_sec)
        self.time_microsec = hdr_data[9]
        # logger.debug('time microsec: %s' % self.time_microsec)
        self.datetime = datetime.utcfromtimestamp(self.time_sec) + timedelta(
            microseconds=(self.time_microsec * 10e-3))
        # logger.debug('datetime: %s' % self.datetime.strftime('%Y-%m-%d %H:%M:%S.%f'))

        # Make sure we don't try to read beyond the EOF (-13 since 16 for header and 3 for ender)
        if (file_input.tell() + (self.length - 20)) > file_size:
            if self.verbose:
                logging.warning(
                    "unexpected EOF > current pos: %s, datagram length: %s, file size: %s"
                    % (file_input.tell(), self.length, file_size))
            return self.Flags.UNEXPECTED_EOF

        # move file cursor to almost the end of the datagram (just minus the length field)
        file_input.seek(self.length - 24, 1)  # 1 -> current file position

        chunk = file_input.read(4)
        footer_length = struct.unpack("<I", chunk)[0]
        if self.length != footer_length:
            logging.warning(
                "mismatch between initial and end datagram length: %s != %s" %
                (self.length, footer_length))
            return self.Flags.CORRUPTED_END_DATAGRAM

        return self.Flags.VALID
Exemplo n.º 6
0
    def __send_file(self, file: BinaryIO, filename: str):
        """
        Sends a file in the socket.
        :param file: file to be sent
        """
        self.__send_string(filename)

        # get file size
        file.seek(0, io.SEEK_END)
        file_len = file.tell()
        file.seek(0)

        self.__send_int(file_len)
        self.socket.sendfile(file)
Exemplo n.º 7
0
 def write_folder_records(self, f: BinaryIO) -> None:
     """Writes the folder records block to f
     
     Args:
         f (BinaryIO): file-like output stream
     """
     # And write their info
     logging.debug("Writing folder records")
     logging.debug(f"Sorted folder hashes: {[x.tes_hash for x in self.sorted_folders]}")
     for folder in self.sorted_folders:
         folder.record_offset = f.tell()
         f.write(
             struct.pack(
                 "<QLLQ",
                 folder.tes_hash,
                 len(folder.files),
                 0,
                 0
             )
         )