Files
stepanalyser/.venv/lib/python3.12/site-packages/ezdxf/addons/dwg/classes_section.py
Christian Anetzberger a197de9456 initial
2026-01-22 20:23:51 +01:00

83 lines
3.0 KiB
Python

# Copyright (c) 2020-2021, Manfred Moitzi
# License: MIT License
from typing import Iterable, Tuple
import struct
from ezdxf.tools.binarydata import BitStream
from ezdxf.entities import DXFClass
from .const import *
from .crc import crc8
from .fileheader import FileHeader
from .header_section import DwgSectionLoader
def load_classes_section(specs: FileHeader, data: Bytes, crc_check=False):
if specs.version <= ACAD_2000:
return DwgClassesSectionR2000(specs, data, crc_check)
else:
return DwgClassesSectionR2004(specs, data, crc_check)
class DwgClassesSectionR2000(DwgSectionLoader):
def load_data_section(self, data: Bytes) -> Bytes:
if self.specs.version > ACAD_2000:
raise DwgVersionError(self.specs.version)
seeker, section_size = self.specs.sections[CLASSES_ID]
return data[seeker : seeker + section_size]
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."
)
class DwgClassesSectionR2004(DwgClassesSectionR2000):
def load_data(self, data: Bytes) -> Bytes:
raise NotImplementedError()