KiCad PCB EDA Suite
Loading...
Searching...
No Matches
orcad_stream.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * Based on the dsn2kicad reference implementation and on OrCAD file format
7 * documentation from the OpenOrCadParser project (MIT licensed).
8 *
9 * This program is free software: you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifndef ORCAD_STREAM_H_
24#define ORCAD_STREAM_H_
25
26#include <cstddef>
27#include <cstdint>
28#include <string>
29#include <vector>
30
31#include <wx/string.h>
32
58{
59public:
61 static constexpr uint8_t PREAMBLE[4] = { 0xFF, 0xE4, 0x5C, 0x39 };
62
64 static constexpr size_t npos = static_cast<size_t>( -1 );
65
66 ORCAD_STREAM( const void* aData, size_t aLength );
67 explicit ORCAD_STREAM( const std::vector<char>& aData );
68
69 // -- scalars (little-endian, bounds-checked, throw IO_ERROR on overrun) -------
70
71 uint8_t ReadU8();
72 int8_t ReadI8();
73 uint16_t ReadU16();
74 int16_t ReadI16();
75 uint32_t ReadU32();
76 int32_t ReadI32();
77
78 // -- strings -------------------------------------------------------------------
79
85 std::string ReadLzt();
86
91 std::string ReadZt();
92
93 // -- buffers / cursor ------------------------------------------------------------
94
96 std::vector<uint8_t> ReadBytes( size_t aCount );
97
99 void Skip( size_t aCount );
100
106 void Seek( size_t aOffset ) { m_offset = aOffset; }
107
108 size_t GetOffset() const { return m_offset; }
109 size_t Size() const { return m_size; }
110
112 size_t Remaining() const { return m_offset >= m_size ? 0 : m_size - m_offset; }
113
114 bool AtEnd() const { return m_offset >= m_size; }
115
117 const uint8_t* Data() const { return m_data; }
118
119 // -- non-throwing lookahead ------------------------------------------------------
120
125 int PeekU8( size_t aAhead = 0 ) const;
126
131 bool PeekMatches( const uint8_t* aBytes, size_t aCount, size_t aAhead = 0 ) const;
132
134 bool AtPreamble( size_t aAhead = 0 ) const;
135
137 bool HasPreambleAt( size_t aAbsoluteOffset ) const;
138
143 size_t FindPreamble( size_t aFrom ) const;
144
145 // -- validated reads ---------------------------------------------------------------
146
152 void Expect( const uint8_t* aBytes, size_t aCount, const wxString& aWhat );
153
155 void ExpectByte( uint8_t aValue, const wxString& aWhat );
156
158 void ExpectPreamble( const wxString& aWhat );
159
166
167private:
169 void requireBytes( size_t aCount ) const;
170
171 const uint8_t* m_data;
172 size_t m_size;
173 size_t m_offset;
174};
175
176
181wxString FromOrcadString( const std::string& aText );
182
183#endif // ORCAD_STREAM_H_
void ExpectPreamble(const wxString &aWhat)
Consume the 4 preamble bytes; throws IO_ERROR naming aWhat when absent.
size_t Remaining() const
Bytes left; 0 when the cursor is at or past the end.
const uint8_t * m_data
int PeekU8(size_t aAhead=0) const
Peek one byte at cursor + aAhead without advancing.
size_t FindPreamble(size_t aFrom) const
Find the next preamble at or after the given absolute offset.
void SkipOptionalPreambleBlock()
If the preamble sits at the cursor, consume it plus its u32 trailLen and the trailLen trailing bytes;...
bool AtPreamble(size_t aAhead=0) const
True when the 4 preamble bytes FF E4 5C 39 sit at cursor + aAhead.
uint8_t ReadU8()
static constexpr size_t npos
Returned by FindPreamble() when no further preamble exists.
size_t GetOffset() const
int8_t ReadI8()
bool HasPreambleAt(size_t aAbsoluteOffset) const
True when the preamble sits at the given absolute offset (false if out of range).
uint16_t ReadU16()
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.
static constexpr uint8_t PREAMBLE[4]
Magic preceding every framed structure body: FF E4 5C 39.
bool AtEnd() const
std::string ReadLzt()
Read a length-prefixed zero-terminated string: u16 length, length content bytes, then a mandatory 0x0...
ORCAD_STREAM(const void *aData, size_t aLength)
void requireBytes(size_t aCount) const
Throw IO_ERROR unless aCount bytes remain at the cursor.
size_t Size() const
const uint8_t * Data() const
Raw buffer access for scan-and-backtrack parsers (cache/hierarchy walkers).
std::string ReadZt()
Read a bare zero-terminated string (no length prefix); consumes the NUL.
bool PeekMatches(const uint8_t *aBytes, size_t aCount, size_t aAhead=0) const
Compare aCount bytes at cursor + aAhead against aBytes without advancing.
void Seek(size_t aOffset)
Set the absolute cursor position.
int32_t ReadI32()
void ExpectByte(uint8_t aValue, const wxString &aWhat)
Consume one byte and require the given value.
uint32_t ReadU32()
void Expect(const uint8_t *aBytes, size_t aCount, const wxString &aWhat)
Consume aCount bytes and require them to equal aBytes; throws IO_ERROR naming aWhat and showing expec...
int16_t ReadI16()
wxString FromOrcadString(const std::string &aText)
Decode raw stream bytes (Windows-1252) into a wxString for UI/UX use.