34int32_t i32At(
const std::vector<uint8_t>& aBytes,
size_t aOffset )
36 return static_cast<int32_t
>(
static_cast<uint32_t
>( aBytes[aOffset] )
37 |
static_cast<uint32_t
>( aBytes[aOffset + 1] ) << 8
38 |
static_cast<uint32_t
>( aBytes[aOffset + 2] ) << 16
39 |
static_cast<uint32_t
>( aBytes[aOffset + 3] ) << 24 );
66 for( uint32_t&
flag : flags )
90 int fontCount = stream.
ReadU16();
92 for(
int i = 0; i < fontCount - 1; i++ )
95 std::vector<uint8_t> rec = stream.
ReadBytes( 60 );
98 font.
height = i32At( rec, 0 );
99 font.
italic = rec[20] != 0;
100 font.
bold = i32At( rec, 16 ) >= 600;
104 while( faceLen < 32 && rec[28 + faceLen] != 0 )
107 font.
face.assign(
reinterpret_cast<const char*
>( rec.data() + 28 ), faceLen );
109 lib.
fonts.push_back( std::move( font ) );
115 uint16_t someLen = stream.
ReadU16();
116 stream.
Skip( 2 *
static_cast<size_t>( someLen ) );
126 for(
int i = 0; i < 8; i++ )
136 auto readStringTable = [&](
bool aU16Count ) ->
bool
138 stream.
Seek( tablePos );
144 ||
static_cast<uint64_t
>( count ) * 3
145 >
static_cast<uint64_t
>( stream.
Remaining() ) + 16 )
150 for( uint32_t i = 0; i < count; i++ )
161 if( !readStringTable( u16First ) && !readStringTable( !u16First ) )
163 stream.
Seek( tablePos );
171 if( !readStringTable( !u16First ) )
173 stream.
Seek( tablePos );
179 stream.
Seek( tablePos );
188 uint16_t aliasCount = stream.
ReadU16();
190 if(
static_cast<uint64_t
>( aliasCount ) * 2 <= stream.
Remaining() + 4 )
192 for( uint16_t i = 0; i < aliasCount; i++ )
194 std::string alias = stream.
ReadLzt();
195 std::string part = stream.
ReadLzt();
197 lib.
partAliases.emplace_back( std::move( alias ), std::move( part ) );
202 if( lib.
introduction.rfind(
"OrCAD Windows Design", 0 ) == 0 )
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Little-endian byte cursor over one OrCAD Capture DSN stream.
size_t Remaining() const
Bytes left; 0 when the cursor is at or past the end.
std::vector< uint8_t > ReadBytes(size_t aCount)
Read exactly aCount bytes; throws IO_ERROR on overrun.
void Skip(size_t aCount)
Advance the cursor; throws IO_ERROR when aCount exceeds the remaining bytes.
std::string ReadLzt()
Read a length-prefixed zero-terminated string: u16 length, length content bytes, then a mandatory 0x0...
std::string ReadZt()
Read a bare zero-terminated string (no length prefix); consumes the NUL.
void Seek(size_t aOffset)
Set the absolute cursor position.
ORCAD_PAGE_SETTINGS OrcadParsePageSettings(ORCAD_STREAM &aStream)
Read one 156-byte PageSettings block at the current cursor (embedded both in the Library stream and i...
ORCAD_LIBRARY_INFO OrcadParseLibrary(const std::vector< char > &aData)
Parse the whole 'Library' stream.
Parser for the DSN root 'Library' stream: format version, fonts, page settings and the global string ...
One text font from the Library stream (a Win32 LOGFONTA record, 60 bytes: lfHeight i32 at +0,...
int height
raw lfHeight (typically negative)
Decoded Library stream: format version, fonts, and the string table that all property name/value indi...
std::string introduction
fixed 32-byte NUL-terminated buffer
std::vector< std::string > strings
global string table
std::vector< ORCAD_FONT > fonts
std::vector< std::pair< std::string, std::string > > partAliases
std::string schematicName
root schematic folder name
std::vector< std::string > partFields
the 8 named part fields
The 156-byte PageSettings block embedded in the Library stream and in every Page stream: 8 bytes crea...