KiCad PCB EDA Suite
altium_parser.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 (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #ifndef ALTIUM_PARSER_H
26 #define ALTIUM_PARSER_H
27 
28 #include <map>
29 #include <memory>
30 
31 #include <math/util.h>
32 #include <wx/gdicmn.h>
33 
34 
35 namespace CFB
36 {
37 class CompoundFileReader;
38 struct COMPOUND_FILE_ENTRY;
39 } // namespace CFB
40 
41 // Helper method to find file inside compound file
42 const CFB::COMPOUND_FILE_ENTRY* FindStream(
43  const CFB::CompoundFileReader& aReader, const char* aStreamName );
44 
45 
47 {
48 public:
49  ALTIUM_PARSER( const CFB::CompoundFileReader& aReader, const CFB::COMPOUND_FILE_ENTRY* aEntry );
50  ~ALTIUM_PARSER() = default;
51 
52  template <typename Type>
53  Type Read()
54  {
55  if( GetRemainingBytes() >= sizeof( Type ) )
56  {
57  Type val = *(Type*) ( m_pos );
58  m_pos += sizeof( Type );
59  return val;
60  }
61  else
62  {
63  m_error = true;
64  return 0;
65  }
66  }
67 
68  wxString ReadWxString()
69  {
70  uint8_t len = Read<uint8_t>();
71  if( GetRemainingBytes() >= len )
72  {
73 
74  //altium uses LATIN1/ISO 8859-1, convert it
75  wxString val = wxString( m_pos, wxConvISO8859_1, len );
76  m_pos += len;
77  return val;
78  }
79  else
80  {
81  m_error = true;
82  return wxString( "" );
83  }
84  }
85 
86  int32_t ReadKicadUnit()
87  {
88  return ConvertToKicadUnit( Read<int32_t>() );
89  }
90 
91  int32_t ReadKicadUnitX()
92  {
93  return ReadKicadUnit();
94  }
95 
96  int32_t ReadKicadUnitY()
97  {
98  return -ReadKicadUnit();
99  }
100 
102  {
103  int32_t x = ReadKicadUnitX();
104  int32_t y = ReadKicadUnitY();
105  return { x, y };
106  }
107 
108  wxSize ReadWxSize()
109  {
110  int32_t x = ReadKicadUnit();
111  int32_t y = ReadKicadUnit();
112  return { x, y };
113  }
114 
116  {
117  uint32_t length = Read<uint32_t>();
118  m_subrecord_end = m_pos + length;
119  return length;
120  }
121 
122  std::map<wxString, wxString> ReadProperties();
123 
124  static int32_t ConvertToKicadUnit( const double aValue )
125  {
126  double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
127 
128  return KiROUND( Clamp<double>( -int_limit, aValue * 2.54, int_limit ) );
129  }
130 
131  static int PropertiesReadInt(
132  const std::map<wxString, wxString>& aProperties, const wxString& aKey, int aDefault );
133 
134  static double PropertiesReadDouble( const std::map<wxString, wxString>& aProperties,
135  const wxString& aKey, double aDefault );
136 
137  static bool PropertiesReadBool(
138  const std::map<wxString, wxString>& aProperties, const wxString& aKey, bool aDefault );
139 
140  static int32_t PropertiesReadKicadUnit( const std::map<wxString, wxString>& aProperties,
141  const wxString& aKey, const wxString& aDefault );
142 
143  static wxString PropertiesReadString( const std::map<wxString, wxString>& aProperties,
144  const wxString& aKey, const wxString& aDefault );
145 
146  void Skip( size_t aLength )
147  {
148  if( GetRemainingBytes() >= aLength )
149  {
150  m_pos += aLength;
151  }
152  else
153  {
154  m_error = true;
155  }
156  }
157 
159  {
160  if( m_subrecord_end == nullptr || m_subrecord_end < m_pos )
161  {
162  m_error = true;
163  }
164  else
165  {
167  }
168  };
169 
170  size_t GetRemainingBytes() const
171  {
172  return m_pos == nullptr ? 0 : m_size - ( m_pos - m_content.get() );
173  }
174 
176  {
177  return m_pos == nullptr || m_subrecord_end == nullptr || m_subrecord_end <= m_pos ?
178  0 :
180  };
181 
183  {
184  return m_error;
185  }
186 
187 private:
188  std::unique_ptr<char[]> m_content;
189  size_t m_size;
190 
191  char* m_pos; // current read pointer
192  char* m_subrecord_end; // pointer which points to next subrecord start
193  bool m_error;
194 };
195 
196 
197 #endif //ALTIUM_PARSER_H
static int PropertiesReadInt(const std::map< wxString, wxString > &aProperties, const wxString &aKey, int aDefault)
~ALTIUM_PARSER()=default
char * m_subrecord_end
size_t GetRemainingBytes() const
static bool PropertiesReadBool(const std::map< wxString, wxString > &aProperties, const wxString &aKey, bool aDefault)
static int32_t PropertiesReadKicadUnit(const std::map< wxString, wxString > &aProperties, const wxString &aKey, const wxString &aDefault)
static int32_t ConvertToKicadUnit(const double aValue)
void Skip(size_t aLength)
size_t GetRemainingSubrecordBytes() const
wxSize ReadWxSize()
size_t ReadAndSetSubrecordLength()
std::map< wxString, wxString > ReadProperties()
wxPoint ReadWxPoint()
static double PropertiesReadDouble(const std::map< wxString, wxString > &aProperties, const wxString &aKey, double aDefault)
int32_t ReadKicadUnit()
Definition: altium_parser.h:86
ALTIUM_PARSER(const CFB::CompoundFileReader &aReader, const CFB::COMPOUND_FILE_ENTRY *aEntry)
wxString ReadWxString()
Definition: altium_parser.h:68
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
int32_t ReadKicadUnitX()
Definition: altium_parser.h:91
void SkipSubrecord()
const CFB::COMPOUND_FILE_ENTRY * FindStream(const CFB::CompoundFileReader &aReader, const char *aStreamName)
int32_t ReadKicadUnitY()
Definition: altium_parser.h:96
static wxString PropertiesReadString(const std::map< wxString, wxString > &aProperties, const wxString &aKey, const wxString &aDefault)
std::unique_ptr< char[]> m_content
bool HasParsingError()