Exemple #1
0
def test_read_unsigned_long():
    # little endian!
    data = b"\x00\x0e\xfc\xda\xb0"
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_unsigned_long() == 0xABCDEF00
    assert bs.read_bits(4) == 0
Exemple #2
0
def test_read_unsigned_long():
    # little endian!
    data = b'\x00\x0e\xfc\xda\xb0'
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_unsigned_long() == 0xabcdef00
    assert bs.read_bits(4) == 0
Exemple #3
0
def parse_bitstream(bs: BitStream,
                    commands: List[Tuple[str, Any]]) -> Dict[str, Any]:
    version = bs.dxfversion
    min_ver = ACAD_13
    max_ver = ACAD_LATEST
    hdr_vars: Dict[str, Any] = dict()
    skip_next_cmd = False
    for cmd, params in commands:
        if skip_next_cmd:
            skip_next_cmd = False
            continue

        if cmd == CMD_SET_VERSION:
            min_ver, max_ver = params
        elif cmd == CMD_SKIP_BITS:
            bs.skip(int(params))
        elif cmd == CMD_SKIP_NEXT_IF:
            skip_next_cmd = eval(params, None, {"header": hdr_vars})
        elif cmd == CMD_SET_VAR:
            if min_ver <= version <= max_ver:
                name, code = params
                hdr_vars[name] = bs.read_code(code)
        else:
            raise ValueError(f"Unknown command: {cmd}")
    return hdr_vars
Exemple #4
0
def test_read_unsigned_short():
    # little endian!
    data = b"\x0c\xda\xb0"
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_unsigned_short() == 0xABCD
    assert bs.read_bits(4) == 0
Exemple #5
0
def test_read_bits():
    data = b"\x0f\x0f"
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_bits(2) == 3
    assert bs.read_bits(3) == 6
    assert bs.read_bits(4) == 1
    assert bs.read_bits(3) == 7
Exemple #6
0
def test_read_bitshort():
    bs = BitStream(b"\xe0")
    assert bs.read_bit_short() == 256  # 11
    assert bs.read_bit_short() == 0  # 10
    bs = BitStream(b"\x00\xff\xff")
    bs.read_bits(6)
    assert bs.read_bit_short() == -1
    assert BitStream(b"\x7f\x00").read_bit_short() == 252
Exemple #7
0
def test_read_signed_modular_chars():
    bs = BitStream(bytes([
        0b11101001, 0b10010111, 0b11100110, 0b00110101,
        0b10000010, 0b00100100,
        0b10000101, 0b01001011,
    ]))
    mc = bs.read_signed_modular_chars()
    assert mc == 112823273
    mc = bs.read_signed_modular_chars()
    assert mc == 4610
    mc = bs.read_signed_modular_chars()
    assert mc == -1413
Exemple #8
0
def test_read_modular_shorts():
    bs = BitStream(
        bytes(
            [
                0b00110001,
                0b11110100,
                0b10001101,
                0b00000000,
            ]
        )
    )
    ms = bs.read_modular_shorts()
    assert ms == 4650033
    def load_classes(self) -> Iterable[Tuple[int, DXFClass]]:
        sentinel = self.data[:SENTINEL_SIZE]
        if (
            sentinel
            != b"\x8D\xA1\xC4\xB8\xC4\xA9\xF8\xC5\xC0\xDC\xF4\x5F\xE7\xCF\xB6\x8A"
        ):
            raise DwgCorruptedClassesSection(
                "Sentinel for start of CLASSES section not found."
            )
        start_index = SENTINEL_SIZE
        bs = BitStream(
            self.data[start_index:],
            dxfversion=self.specs.version,
            encoding=self.specs.encoding,
        )
        class_data_size = bs.read_unsigned_long()  # data size in bytes
        end_sentinel_index = SENTINEL_SIZE + 6 + class_data_size
        end_index = end_sentinel_index - 2
        end_bit_index = (3 + class_data_size) << 3

        while bs.bit_index < end_bit_index:
            class_num = bs.read_bit_short()
            dxfattribs = {
                "flags": bs.read_bit_short(),  # version?
                "app_name": bs.read_text(),
                "cpp_class_name": bs.read_text(),
                "name": bs.read_text(),
                "was_a_proxy": bs.read_bit(),
                "is_an_entity": int(bs.read_bit_short() == 0x1F2),
            }
            yield class_num, DXFClass.new(dxfattribs=dxfattribs)

        if self.crc_check and False:
            check = struct.unpack_from("<H", self.data, end_index)[0]
            # TODO: classes crc check
            # Which data should be checked? This is not correct:
            crc = crc8(self.data[start_index:end_index])
            if check != crc:
                raise CRCError("CRC error in classes section.")
        sentinel = self.data[
            end_sentinel_index : end_sentinel_index + SENTINEL_SIZE
        ]
        if (
            sentinel
            != b"\x72\x5E\x3B\x47\x3B\x56\x07\x3A\x3F\x23\x0B\xA0\x18\x30\x49\x75"
        ):
            raise DwgCorruptedClassesSection(
                "Sentinel for end of CLASSES section not found."
            )
Exemple #10
0
 def load_header_vars(self) -> Dict:
     data = self.data
     sentinel = data[:16]
     if (sentinel !=
             b"\xCF\x7B\x1F\x23\xFD\xDE\x38\xA9\x5F\x7C\x68\xB8\x4E\x6D\x33\x5F"
         ):
         raise DwgCorruptedHeaderSection(
             "Sentinel for start of HEADER section not found.")
     index = 16
     size = struct.unpack_from("<L", data, index)[0]
     index += 4
     bs = BitStream(
         data[index:index + size],
         dxfversion=self.specs.version,
         encoding=self.specs.encoding,
     )
     hdr_vars = parse_header(bs)
     index += size
     if self.crc_check:
         check = struct.unpack_from("<H", data, index)[0]
         # CRC of data from end of sentinel until start of crc value
         crc = crc8(data[16:-18], seed=0xC0C1)
         if check != crc:
             raise CRCError("CRC error in header section.")
     sentinel = data[-16:]
     if (sentinel !=
             b"\x30\x84\xE0\xDC\x02\x21\xC7\x56\xA0\x83\x97\x47\xB1\x92\xCC\xA0"
         ):
         raise DwgCorruptedHeaderSection(
             "Sentinel for end of HEADER section not found.")
     return hdr_vars
Exemple #11
0
def test_read_object_type():
    assert BitStream(bytes([0b00000000, 0b01000000])).read_object_type() == 1
    assert (
        BitStream(bytes([0b01000000, 0b01000000])).read_object_type()
        == 1 + 0x1F0
    )
    assert (
        BitStream(
            bytes([0b10000000, 0b01000000, 0b01000000])
        ).read_object_type()
        == 257
    )
    assert (
        BitStream(
            bytes([0b11000000, 0b01000000, 0b01000000])
        ).read_object_type()
        == 257
    )
Exemple #12
0
    def classes_R2000(self) -> None:
        seeker, section_size = self.specs.sections[CLASSES_ID]
        sentinel = self.data[seeker:seeker + SENTINEL_SIZE]
        if sentinel != b'\x8D\xA1\xC4\xB8\xC4\xA9\xF8\xC5\xC0\xDC\xF4\x5F\xE7\xCF\xB6\x8A':
            raise DwgCorruptedClassesSection(
                'Sentinel for start of section not found.')

        cls_tag = DXFTag(0, 'CLASS')
        classes = self.sections['CLASSES']
        bs = BitStream(
            self.data[seeker + SENTINEL_SIZE:seeker + section_size],
            dxfversion=self.specs.version,
            encoding=self.specs.encoding,
        )
        class_data_size = bs.read_unsigned_long()  # data size in bytes
        end_index = (3 + class_data_size) << 3

        while bs.bit_index < end_index:
            class_num = bs.read_bit_short()
            flags = bs.read_bit_short()  # version?
            app_name = bs.read_text()
            cpp_class_name = bs.read_text()
            class_dxf_name = bs.read_text()
            was_a_zombie = bs.read_bit()
            item_class_id = bs.read_bit_short()
            # print((class_num, flags, app_name, class_dxf_name, cpp_class_name, was_a_zombie, item_class_id))
            classes.append(
                Tags([
                    cls_tag,
                    DXFTag(1, class_dxf_name),
                    DXFTag(2, cpp_class_name),
                    DXFTag(3, app_name),
                    DXFTag(90, flags),
                    DXFTag(280, was_a_zombie),
                    DXFTag(281, 1 if item_class_id == 0x1f2 else 0)
                ]))
            self.dxf_object_types[class_num] = class_dxf_name

        # Ignore crc for the sake of speed.
        # _index = index + (20 + class_data_size)
        # crc = struct.unpack_from('<h', self.data, index)
        _index = seeker + (SENTINEL_SIZE + 6 + class_data_size)
        sentinel = self.data[_index:_index + SENTINEL_SIZE]
        if sentinel != b'\x72\x5E\x3B\x47\x3B\x56\x07\x3A\x3F\x23\x0B\xA0\x18\x30\x49\x75':
            raise DwgCorruptedClassesSection(
                'Sentinel for end of section not found.')
Exemple #13
0
def test_read_bit():
    data = b"\xaa"
    bs = BitStream(data)
    assert bs.read_bit() == 1
    assert bs.read_bit() == 0
    assert bs.read_bit() == 1
    assert bs.read_bit() == 0
    assert bs.read_bit() == 1
    assert bs.read_bit() == 0
    assert bs.read_bit() == 1
    assert bs.read_bit() == 0
    with pytest.raises(EndOfBufferError):
        _ = bs.read_bit()
Exemple #14
0
    def lwpolyline(self, data: bytes):
        # OpenDesign Specs LWPLINE: 20.4.85 Page 211
        logger.warning(
            'Untested proxy graphic entity: LWPOLYLINE - Need examples!')
        bs = BitStream(data)
        flag = bs.read_bit_short()
        attribs = self._build_dxf_attribs()
        if flag & 4:
            attribs['const_width'] = bs.read_bit_double()
        if flag & 8:
            attribs['elevation'] = bs.read_bit_double()
        if flag & 2:
            attribs['thickness'] = bs.read_bit_double()
        if flag & 1:
            attribs['extrusion'] = Vec3(bs.read_bit_double(3))

        num_points = bs.read_bit_long()
        if flag & 16:
            num_bulges = bs.read_bit_long()
        else:
            num_bulges = 0

        if self.dxfversion >= 'AC1024':  # R2010+
            vertex_id_count = bs.read_bit_long()
        else:
            vertex_id_count = 0

        if flag & 32:
            num_width = bs.read_bit_long()
        else:
            num_width = 0
        # ignore DXF R13/14 special vertex order

        vertices = [bs.read_raw_double(2)]
        prev_point = vertices[-1]
        for _ in range(num_points - 1):
            x = bs.read_bit_double_default(default=prev_point[0])
            y = bs.read_bit_double_default(default=prev_point[1])
            prev_point = (x, y)
            vertices.append(prev_point)
        bulges = [bs.read_bit_double() for _ in range(num_bulges)]
        vertex_ids = [bs.read_bit_long() for _ in range(vertex_id_count)]
        widths = [(bs.read_bit_double(), bs.read_bit_double())
                  for _ in range(num_width)]
        if len(bulges) == 0:
            bulges = list(repeat(0, num_points))
        if len(widths) == 0:
            widths = list(repeat((0, 0), num_points))
        points = []
        for v, w, b in zip(vertices, widths, bulges):
            points.append((v[0], v[1], w[0], w[1], b))
        lwpolyline = cast('LWPolyline',
                          self._factory('LWPOLYLINE', dxfattribs=attribs))
        lwpolyline.set_points(points)
        return lwpolyline
Exemple #15
0
def test_read_unsigned_byte():
    data = b'\x0f\x0f'
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_unsigned_byte() == 0xf0
Exemple #16
0
def test_read_aligned_unsigned_long():
    # little endian!
    data = b'\x00\xef\xcd\xab'
    bs = BitStream(data)
    assert bs.read_unsigned_long() == 0xabcdef00
Exemple #17
0
def test_read_aligned_unsigned_long():
    # little endian!
    data = b"\x00\xef\xcd\xab"
    bs = BitStream(data)
    assert bs.read_unsigned_long() == 0xABCDEF00
Exemple #18
0
def test_read_aligned_unsigned_short():
    # little endian!
    data = b"\x00\xcd\xab"
    bs = BitStream(data)
    assert bs.read_unsigned_byte() == 0
    assert bs.read_unsigned_short() == 0xABCD
Exemple #19
0
def test_read_signed_byte():
    data = b"\x0f\xf0"
    bs = BitStream(data)
    assert bs.read_bits(4) == 0
    assert bs.read_signed_byte() == -1