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
36{
37public:
39 static constexpr uint8_t PREAMBLE[4] = { 0xFF, 0xE4, 0x5C, 0x39 };
40
42 static constexpr size_t npos = static_cast<size_t>( -1 );
43
45 static constexpr int MAX_NESTING = 64;
46
49 {
50 public:
51 NEST_GUARD( ORCAD_STREAM& aStream, const wxString& aWhat );
53
54 NEST_GUARD( const NEST_GUARD& ) = delete;
55 NEST_GUARD& operator=( const NEST_GUARD& ) = delete;
56
57 private:
59 };
60
63 {
64 public:
65 LIMIT_GUARD( ORCAD_STREAM& aStream, size_t aEnd );
67
68 LIMIT_GUARD( const LIMIT_GUARD& ) = delete;
69 LIMIT_GUARD& operator=( const LIMIT_GUARD& ) = delete;
70
71 private:
74 };
75
76 ORCAD_STREAM( const void* aData, size_t aLength );
77 explicit ORCAD_STREAM( const std::vector<char>& aData );
78
80
81 uint8_t ReadU8();
82 int8_t ReadI8();
83 uint16_t ReadU16();
84 int16_t ReadI16();
85 uint32_t ReadU32();
86 int32_t ReadI32();
87
89
91 std::string ReadLzt();
92
94 std::string ReadZt();
95
97
99 std::vector<uint8_t> ReadBytes( size_t aCount );
100
102 void Skip( size_t aCount );
103
105 void Seek( size_t aOffset );
106
107 size_t GetOffset() const { return m_offset; }
108 size_t Size() const { return m_size; }
109
111 size_t Remaining() const { return m_offset >= m_size ? 0 : m_size - m_offset; }
112
113 bool AtEnd() const { return m_offset >= m_size; }
114
116 const uint8_t* Data() const { return m_data; }
117
119
121 int PeekU8( size_t aAhead = 0 ) const;
122
124 bool PeekMatches( const uint8_t* aBytes, size_t aCount, size_t aAhead = 0 ) const;
125
127 bool AtPreamble( size_t aAhead = 0 ) const;
128
130
132 void Expect( const uint8_t* aBytes, size_t aCount, const wxString& aWhat );
133
135 void ExpectByte( uint8_t aValue, const wxString& aWhat );
136
138 void ExpectPreamble( const wxString& aWhat );
139
142
143private:
145 void requireBytes( size_t aCount ) const;
146
147 const uint8_t* m_data;
148 size_t m_size;
149 size_t m_offset;
151};
152
153
155wxString FromOrcadString( const std::string& aText );
156
157#endif // ORCAD_STREAM_H_
LIMIT_GUARD & operator=(const LIMIT_GUARD &)=delete
LIMIT_GUARD(const LIMIT_GUARD &)=delete
LIMIT_GUARD(ORCAD_STREAM &aStream, size_t aEnd)
NEST_GUARD & operator=(const NEST_GUARD &)=delete
NEST_GUARD(const NEST_GUARD &)=delete
NEST_GUARD(ORCAD_STREAM &aStream, const wxString &aWhat)
ORCAD_STREAM & m_stream
static constexpr int MAX_NESTING
Nesting limit of the recursive readers; real files stay far below it.
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
– non-throwing lookahead ---------------------------------------------------—
void SkipOptionalPreambleBlock()
Legacy primitives have no trailing preamble.
bool AtPreamble(size_t aAhead=0) const
True when the 4 preamble bytes FF E4 5C 39 sit at cursor + aAhead.
uint8_t ReadU8()
– scalars (little-endian, bounds-checked, throw IO_ERROR on overrun) ----—
static constexpr size_t npos
Generic invalid offset sentinel.
size_t GetOffset() const
uint16_t ReadU16()
std::vector< uint8_t > ReadBytes(size_t aCount)
– buffers / cursor ---------------------------------------------------------—
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()
– strings ----------------------------------------------------------------—
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 bounded lexical lookahead and payload extraction.
std::string ReadZt()
Consumes the NUL; throws IO_ERROR if no terminator remains.
bool PeekMatches(const uint8_t *aBytes, size_t aCount, size_t aAhead=0) const
Returns false if fewer than aCount bytes remain; does not advance the cursor.
void Seek(size_t aOffset)
Set the absolute cursor position; throws IO_ERROR when aOffset exceeds Size().
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)
– validated reads ------------------------------------------------------------—
int16_t ReadI16()
wxString FromOrcadString(const std::string &aText)
Use an 8-bit fallback if Windows-1252 decoding fails.