コード例 #1
0
ファイル: decoder.py プロジェクト: weggiswa/pybufrkit
    def process(self,
                s,
                file_path='<string>',
                start_signature=MESSAGE_START_SIGNATURE,
                info_only=False,
                ignore_value_expectation=False,
                wire_template_data=True):
        """
        Decoding the given message string.

        :param s: Message string that contains the BUFR Message
        :param file_path: The file where this string is read from.
        :param start_signature: Locate the starting position of the message
            string with the given signature.
        :param info_only: Only show information up to template data (exclusive)
        :param ignore_value_expectation: Do not validate the expected value
        :param wire_template_data: Whether to wire the template data to construct
            a fully hierarchical structure from the flat lists. Only takes effect
            when it is NOT info_only.

        :return: A BufrMessage object that contains the decoded information.
        """
        idx = s.find(start_signature) if start_signature is not None else 0
        if idx == -1:
            raise PyBufrKitError(
                'Cannot find start signature: {}'.format(start_signature))
        s = s[idx:]

        bit_reader = get_bit_reader(s)
        bufr_message = BufrMessage(file_path)

        configuration_transformers = (
            self.section_configurer.info_configuration, ) if info_only else ()
        if ignore_value_expectation:
            configuration_transformers += (
                self.section_configurer.ignore_value_expectation, )

        nbits_decoded = 0
        section_index = 0  # Always start decoding from section 0
        while True:
            section = self.section_configurer.configure_section(
                bufr_message, section_index, configuration_transformers)
            section_index += 1
            if section is None:  # when optional section is not present
                continue
            nbits_decoded += self.process_section(bufr_message, bit_reader,
                                                  section)
            if section.end_of_message:
                break

        # The exact bytes that have been decoded
        bufr_message.serialized_bytes = s[:nbits_decoded // NBITS_PER_BYTE]

        if not info_only and wire_template_data:
            bufr_message.wire()

        return bufr_message
コード例 #2
0
ファイル: encoder.py プロジェクト: sreeds82/pybufrkit
    def process(self, s, file_path='<string>', wire_template_data=True):
        """
        Entry point for the encoding process. The process encodes a JSON format
        message to BUFR message.

        :param s: A JSON or its string serialized form
        :param file_path: The file path to the JSON file.
        :param wire_template_data: Whether to wire the template data to construct
            a fully hierarchical structure from the flat lists.

        :return: A bitstring object of the encoded message.
        """

        if isinstance(s, (six.binary_type, six.text_type)):
            # TODO: ensure all strings are loaded as plain ascii instead of unicode from JSON
            json_data = json.loads(s) if six.PY3 else json.loads(s, encoding='latin-1')
        else:
            json_data = s

        bit_writer = get_bit_writer()
        bufr_message = BufrMessage(filename=file_path)

        nbits_encoded = 0
        section_index = 0
        # When a section is not present in the json data. The index must not be
        # increase for the section.
        index_offset = 0
        while True:
            section = self.section_configurer.configure_section_with_values(
                bufr_message, section_index, json_data[section_index - index_offset],
                self.overrides)
            section_index += 1
            if section is None:  # optional section is not present
                index_offset += 1  # This section should not be counted
                continue
            nbits_encoded += self.process_section(bufr_message, bit_writer, section)
            if section.end_of_message:
                break

        # A zero length means the actual length must be calculated
        # Fix is needed for both the message object and the serialized bits
        nbytes_write = bit_writer.get_pos() // NBITS_PER_BYTE
        if bufr_message.length.value == 0 or self.ignore_declared_length:
            bufr_message.length.value = nbytes_write
            section = bufr_message.length.parent
            bit_writer.set_uint(
                bufr_message.length.value,
                bufr_message.length.nbits,
                section.get_metadata(BITPOS_START) + section.get_parameter_offset('length')
            )
        elif bufr_message.length.value != nbytes_write:
            raise PyBufrKitError('Write exceeds declared total length {} by {} bytes'.format(
                bufr_message.length.value, nbytes_write - bufr_message.length.value
            ))

        bufr_message.serialized_bytes = bit_writer.to_bytes()

        if wire_template_data:
            bufr_message.wire()

        return bufr_message