From defcb49ac82aa2e3abdb3c322acd5e4128c55f20 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Sun, 4 Feb 2024 20:14:19 +0300 Subject: [PATCH] Support Altium Schematic ASCII import --- common/CMakeLists.txt | 4 +- common/io/altium/altium_ascii_parser.cpp | 134 ++++ common/io/altium/altium_ascii_parser.h | 54 ++ ...um_parser.cpp => altium_binary_parser.cpp} | 134 +--- ...altium_parser.h => altium_binary_parser.h} | 38 +- common/io/altium/altium_props_utils.cpp | 153 +++++ common/io/altium/altium_props_utils.h | 58 ++ eeschema/sch_io/altium/altium_parser_sch.cpp | 286 ++++---- eeschema/sch_io/altium/altium_parser_sch.h | 7 +- eeschema/sch_io/altium/sch_io_altium.cpp | 623 +++++++++++------- eeschema/sch_io/altium/sch_io_altium.h | 7 + pcbnew/pcb_io/altium/altium_parser_pcb.cpp | 293 ++++---- pcbnew/pcb_io/altium/altium_parser_pcb.h | 36 +- pcbnew/pcb_io/altium/altium_pcb.cpp | 57 +- .../altium/pcb_io_altium_circuit_maker.cpp | 2 +- .../altium/pcb_io_altium_circuit_studio.cpp | 2 +- .../pcb_io/altium/pcb_io_altium_designer.cpp | 4 +- pcbnew/pcb_io/altium/pcb_io_solidworks.cpp | 2 +- .../common/io/altium/test_altium_parser.cpp | 16 +- 19 files changed, 1178 insertions(+), 732 deletions(-) create mode 100644 common/io/altium/altium_ascii_parser.cpp create mode 100644 common/io/altium/altium_ascii_parser.h rename common/io/altium/{altium_parser.cpp => altium_binary_parser.cpp} (80%) rename common/io/altium/{altium_parser.h => altium_binary_parser.h} (89%) create mode 100644 common/io/altium/altium_props_utils.cpp create mode 100644 common/io/altium/altium_props_utils.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d1d885957b..89743e57e5 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -388,8 +388,10 @@ set( COMMON_IO_SRCS io/io_utils.cpp # Altium - io/altium/altium_parser.cpp + io/altium/altium_binary_parser.cpp + io/altium/altium_ascii_parser.cpp io/altium/altium_parser_utils.cpp + io/altium/altium_props_utils.cpp # Cadstar io/cadstar/cadstar_archive_parser.cpp diff --git a/common/io/altium/altium_ascii_parser.cpp b/common/io/altium/altium_ascii_parser.cpp new file mode 100644 index 0000000000..8cba09a053 --- /dev/null +++ b/common/io/altium/altium_ascii_parser.cpp @@ -0,0 +1,134 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Thomas Pointhuber + * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "altium_ascii_parser.h" +#include "altium_parser_utils.h" + + +ALTIUM_ASCII_PARSER::ALTIUM_ASCII_PARSER( const wxString& aInputFile ) : + m_fileInput( aInputFile.fn_str() ) +{ +} + + +std::map ALTIUM_ASCII_PARSER::ReadProperties() +{ + std::map kv; + std::string str; + std::string line; + + // Lines ending with |> continue on the next line + do + { + if( !std::getline( m_fileInput, line ) ) + { + m_error = true; + return kv; + } + + if( ( line.size() > 2 && line[line.size() - 2] == '|' && line[line.size() - 1] == '>' ) ) + { + str.append( line, 0, line.size() - 2 ); + } + else + { + str.append( line ); + break; + } + } while( true ); + + std::size_t token_end = 0; + + while( token_end < str.size() && token_end != std::string::npos ) + { + std::size_t token_start = str.find( '|', token_end ); + std::size_t token_equal = str.find( '=', token_end ); + std::size_t key_start; + + if( token_start <= token_equal ) + { + key_start = token_start + 1; + } + else + { + // Leading "|" before "RECORD=28" may be missing in older schematic versions. + key_start = token_end; + } + + token_end = str.find( '|', key_start ); + + if( token_equal >= token_end ) + { + continue; // this looks like an error: skip the entry. Also matches on std::string::npos + } + + if( token_end == std::string::npos ) + { + token_end = str.size() + 1; // this is the correct offset + } + + std::string keyS = str.substr( key_start, token_equal - key_start ); + std::string valueS = str.substr( token_equal + 1, token_end - token_equal - 1 ); + + // convert the strings to wxStrings, since we use them everywhere + // value can have non-ASCII characters, so we convert them from LATIN1/ISO8859-1 + wxString key( keyS.c_str(), wxConvISO8859_1 ); + // Altium stores keys either in Upper, or in CamelCase. Lets unify it. + wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper(); + // If the key starts with '%UTF8%' we have to parse the value using UTF8 + wxString value; + + if( canonicalKey.StartsWith( "%UTF8%" ) ) + value = wxString( valueS.c_str(), wxConvUTF8 ); + else + value = wxString( valueS.c_str(), wxConvISO8859_1 ); + + if( canonicalKey != wxS( "PATTERN" ) && canonicalKey != wxS( "SOURCEFOOTPRINTLIBRARY" ) ) + { + // Breathless hack because I haven't a clue what the story is here (but this character + // appears in a lot of radial dimensions and is rendered by Altium as a space). + value.Replace( wxT( "ÿ" ), wxT( " " ) ); + } + + // Storage binary data do not need conversion. + if( str.rfind( "|BINARY", 0 ) != 0 ) + { + if( canonicalKey == wxT( "DESIGNATOR" ) || canonicalKey == wxT( "NAME" ) + || canonicalKey == wxT( "TEXT" ) ) + { + value = AltiumPropertyToKiCadString( value ); + } + } + + kv.insert( { canonicalKey, value.Trim() } ); + } + + return kv; +} + + +bool ALTIUM_ASCII_PARSER::CanRead() +{ + return m_fileInput && m_fileInput.peek() != std::ifstream::traits_type::eof(); +} diff --git a/common/io/altium/altium_ascii_parser.h b/common/io/altium/altium_ascii_parser.h new file mode 100644 index 0000000000..0657912d84 --- /dev/null +++ b/common/io/altium/altium_ascii_parser.h @@ -0,0 +1,54 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Thomas Pointhuber + * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _ALTIUM_PARSER_H +#define _ALTIUM_PARSER_H + +#include +#include +#include + +#include + + +class ALTIUM_ASCII_PARSER +{ +public: + ALTIUM_ASCII_PARSER( const wxString& aInputFile ); + + std::map ReadProperties(); + + bool CanRead(); + + bool HasParsingError() + { + return m_error; + } + +private: + std::ifstream m_fileInput; + bool m_error = false; +}; + +#endif //_ALTIUM_PARSER_H diff --git a/common/io/altium/altium_parser.cpp b/common/io/altium/altium_binary_parser.cpp similarity index 80% rename from common/io/altium/altium_parser.cpp rename to common/io/altium/altium_binary_parser.cpp index a83062c25e..d36a82ca39 100644 --- a/common/io/altium/altium_parser.cpp +++ b/common/io/altium/altium_binary_parser.cpp @@ -22,7 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "altium_parser.h" +#include "altium_binary_parser.h" #include "altium_parser_utils.h" #include @@ -350,13 +350,13 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames() if( m_reader->IsStream( entry ) && fileName == L"Parameters" ) { - ALTIUM_PARSER parametersReader( *this, entry ); + ALTIUM_BINARY_PARSER parametersReader( *this, entry ); std::map parameterProperties = parametersReader.ReadProperties(); - wxString key = ALTIUM_PARSER::ReadString( + wxString key = ALTIUM_PROPS_UTILS::ReadString( parameterProperties, wxT( "PATTERN" ), wxT( "" ) ); - wxString fpName = ALTIUM_PARSER::ReadUnicodeString( + wxString fpName = ALTIUM_PROPS_UTILS::ReadUnicodeString( parameterProperties, wxT( "PATTERN" ), wxT( "" ) ); m_libFootprintDirNameCache[key] = fpName; @@ -370,7 +370,7 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames() } -ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile, +ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { m_subrecord_end = nullptr; @@ -384,7 +384,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile, } -ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr& aContent, size_t aSize ) +ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( std::unique_ptr& aContent, size_t aSize ) { m_subrecord_end = nullptr; m_size = aSize; @@ -394,7 +394,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr& aContent, size_t aSize ) } -std::map ALTIUM_PARSER::ReadProperties( +std::map ALTIUM_BINARY_PARSER::ReadProperties( std::function( const std::string& )> handleBinaryData ) { @@ -502,123 +502,3 @@ std::map ALTIUM_PARSER::ReadProperties( return kv; } - -int32_t ALTIUM_PARSER::ConvertToKicadUnit( const double aValue ) -{ - constexpr double int_limit = ( std::numeric_limits::max() - 10 ) / 2.54; - - int32_t iu = KiROUND( Clamp( -int_limit, aValue, int_limit ) * 2.54 ); - - // Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean - // up most rounding errors. This allows lossless conversion of increments of 0.05mils and - // 0.01um. - return KiROUND( (double) iu / 10.0 ) * 10; -} - - -int ALTIUM_PARSER::ReadInt( const std::map& aProps, const wxString& aKey, - int aDefault ) -{ - const std::map::const_iterator& value = aProps.find( aKey ); - return value == aProps.end() ? aDefault : wxAtoi( value->second ); -} - - -double ALTIUM_PARSER::ReadDouble( const std::map& aProps, const wxString& aKey, - double aDefault ) -{ - const std::map::const_iterator& value = aProps.find( aKey ); - - if( value == aProps.end() ) - return aDefault; - - // Locale independent str -> double conversation - std::istringstream istr( (const char*) value->second.mb_str() ); - istr.imbue( std::locale::classic() ); - - double doubleValue; - istr >> doubleValue; - return doubleValue; -} - - -bool ALTIUM_PARSER::ReadBool( const std::map& aProps, const wxString& aKey, - bool aDefault ) -{ - const std::map::const_iterator& value = aProps.find( aKey ); - - if( value == aProps.end() ) - return aDefault; - else - return value->second == "T" || value->second == "TRUE"; -} - - -int32_t ALTIUM_PARSER::ReadKicadUnit( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ) -{ - const wxString& value = ReadString( aProps, aKey, aDefault ); - - wxString prefix; - - if( !value.EndsWith( "mil", &prefix ) ) - { - wxLogError( _( "Unit '%s' does not end with 'mil'." ), value ); - return 0; - } - - prefix.StartsWith( "+", &prefix ); - - double mils; - - if( !prefix.ToCDouble( &mils ) ) - { - wxLogError( _( "Cannot convert '%s' to double." ), prefix ); - return 0; - } - - return ConvertToKicadUnit( mils * 10000 ); -} - - -wxString ALTIUM_PARSER::ReadString( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ) -{ - const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey ); - - if( utf8Value != aProps.end() ) - return utf8Value->second; - - const auto& value = aProps.find( aKey ); - - if( value != aProps.end() ) - return value->second; - - return aDefault; -} - - -wxString ALTIUM_PARSER::ReadUnicodeString( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ) -{ - const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) ); - - if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) ) - { - const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey ); - - if( unicodeValue != aProps.end() ) - { - wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' ); - wxString out; - - for( wxString part : arr ) - out += wxString( wchar_t( wxAtoi( part ) ) ); - - return out; - } - } - - return ReadString( aProps, aKey, aDefault ); -} - diff --git a/common/io/altium/altium_parser.h b/common/io/altium/altium_binary_parser.h similarity index 89% rename from common/io/altium/altium_parser.h rename to common/io/altium/altium_binary_parser.h index 1d2ab599e9..7719814416 100644 --- a/common/io/altium/altium_parser.h +++ b/common/io/altium/altium_binary_parser.h @@ -22,8 +22,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef ALTIUM_PARSER_H -#define ALTIUM_PARSER_H +#ifndef _ALTIUM_BINARY_PARSER_H +#define _ALTIUM_BINARY_PARSER_H + +#include "altium_props_utils.h" #include #include @@ -106,12 +108,12 @@ private: }; -class ALTIUM_PARSER +class ALTIUM_BINARY_PARSER { public: - ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ); - ALTIUM_PARSER( std::unique_ptr& aContent, size_t aSize ); - ~ALTIUM_PARSER() = default; + ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ); + ALTIUM_BINARY_PARSER( std::unique_ptr& aContent, size_t aSize ); + ~ALTIUM_BINARY_PARSER() = default; template Type Read() @@ -229,7 +231,7 @@ public: int32_t ReadKicadUnit() { - return ConvertToKicadUnit( Read() ); + return ALTIUM_PROPS_UTILS::ConvertToKicadUnit( Read() ); } int32_t ReadKicadUnitX() @@ -270,26 +272,6 @@ public: return std::map(); } ); - static int32_t ConvertToKicadUnit( const double aValue ); - - static int ReadInt( const std::map& aProps, - const wxString& aKey, int aDefault ); - - static double ReadDouble( const std::map& aProps, - const wxString& aKey, double aDefault ); - - static bool ReadBool( const std::map& aProps, - const wxString& aKey, bool aDefault ); - - static int32_t ReadKicadUnit( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ); - - static wxString ReadString( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ); - - static wxString ReadUnicodeString( const std::map& aProps, - const wxString& aKey, const wxString& aDefault ); - void Skip( size_t aLength ) { if( GetRemainingBytes() >= aLength ) @@ -447,4 +429,4 @@ private: } }; -#endif //ALTIUM_PARSER_H +#endif //_ALTIUM_BINARY_PARSER_H diff --git a/common/io/altium/altium_props_utils.cpp b/common/io/altium/altium_props_utils.cpp new file mode 100644 index 0000000000..7c6d6ed8a6 --- /dev/null +++ b/common/io/altium/altium_props_utils.cpp @@ -0,0 +1,153 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Thomas Pointhuber + * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "altium_props_utils.h" + +#include +#include +#include + +#include +#include +#include + + +int32_t ALTIUM_PROPS_UTILS::ConvertToKicadUnit( const double aValue ) +{ + constexpr double int_limit = ( std::numeric_limits::max() - 10 ) / 2.54; + + int32_t iu = KiROUND( Clamp( -int_limit, aValue, int_limit ) * 2.54 ); + + // Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean + // up most rounding errors. This allows lossless conversion of increments of 0.05mils and + // 0.01um. + return KiROUND( (double) iu / 10.0 ) * 10; +} + + +int ALTIUM_PROPS_UTILS::ReadInt( const std::map& aProps, const wxString& aKey, + int aDefault ) +{ + const std::map::const_iterator& value = aProps.find( aKey ); + return value == aProps.end() ? aDefault : wxAtoi( value->second ); +} + + +double ALTIUM_PROPS_UTILS::ReadDouble( const std::map& aProps, const wxString& aKey, + double aDefault ) +{ + const std::map::const_iterator& value = aProps.find( aKey ); + + if( value == aProps.end() ) + return aDefault; + + // Locale independent str -> double conversation + std::istringstream istr( (const char*) value->second.mb_str() ); + istr.imbue( std::locale::classic() ); + + double doubleValue; + istr >> doubleValue; + return doubleValue; +} + + +bool ALTIUM_PROPS_UTILS::ReadBool( const std::map& aProps, const wxString& aKey, + bool aDefault ) +{ + const std::map::const_iterator& value = aProps.find( aKey ); + + if( value == aProps.end() ) + return aDefault; + else + return value->second == "T" || value->second == "TRUE"; +} + + +int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map& aProps, + const wxString& aKey, const wxString& aDefault ) +{ + const wxString& value = ReadString( aProps, aKey, aDefault ); + + wxString prefix; + + if( !value.EndsWith( "mil", &prefix ) ) + { + wxLogError( _( "Unit '%s' does not end with 'mil'." ), value ); + return 0; + } + + prefix.StartsWith( "+", &prefix ); + + double mils; + + if( !prefix.ToCDouble( &mils ) ) + { + wxLogError( _( "Cannot convert '%s' to double." ), prefix ); + return 0; + } + + return ConvertToKicadUnit( mils * 10000 ); +} + + +wxString ALTIUM_PROPS_UTILS::ReadString( const std::map& aProps, + const wxString& aKey, const wxString& aDefault ) +{ + const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey ); + + if( utf8Value != aProps.end() ) + return utf8Value->second; + + const auto& value = aProps.find( aKey ); + + if( value != aProps.end() ) + return value->second; + + return aDefault; +} + + +wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map& aProps, + const wxString& aKey, const wxString& aDefault ) +{ + const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) ); + + if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) ) + { + const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey ); + + if( unicodeValue != aProps.end() ) + { + wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' ); + wxString out; + + for( wxString part : arr ) + out += wxString( wchar_t( wxAtoi( part ) ) ); + + return out; + } + } + + return ReadString( aProps, aKey, aDefault ); +} \ No newline at end of file diff --git a/common/io/altium/altium_props_utils.h b/common/io/altium/altium_props_utils.h new file mode 100644 index 0000000000..f302c5ec68 --- /dev/null +++ b/common/io/altium/altium_props_utils.h @@ -0,0 +1,58 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Thomas Pointhuber + * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _ALTIUM_PROPS_UTILS_H +#define _ALTIUM_PROPS_UTILS_H + +#include +#include + +#include + + +class ALTIUM_PROPS_UTILS +{ +public: + static int32_t ConvertToKicadUnit( const double aValue ); + + static int ReadInt( const std::map& aProps, const wxString& aKey, + int aDefault ); + + static double ReadDouble( const std::map& aProps, const wxString& aKey, + double aDefault ); + + static bool ReadBool( const std::map& aProps, const wxString& aKey, + bool aDefault ); + + static int32_t ReadKicadUnit( const std::map& aProps, const wxString& aKey, + const wxString& aDefault ); + + static wxString ReadString( const std::map& aProps, const wxString& aKey, + const wxString& aDefault ); + + static wxString ReadUnicodeString( const std::map& aProps, + const wxString& aKey, const wxString& aDefault ); +}; + +#endif //_ALTIUM_PROPS_UTILS_H diff --git a/eeschema/sch_io/altium/altium_parser_sch.cpp b/eeschema/sch_io/altium/altium_parser_sch.cpp index a7c207d4a3..ba38b49c2b 100644 --- a/eeschema/sch_io/altium/altium_parser_sch.cpp +++ b/eeschema/sch_io/altium/altium_parser_sch.cpp @@ -24,19 +24,21 @@ #include #include +#include #include #include #include -#include "io/altium/altium_parser.h" #include "sch_io/altium/altium_parser_sch.h" +#include "io/altium/altium_binary_parser.h" +#include "io/altium/altium_props_utils.h" ALTIUM_SCH_RECORD ReadRecord( const std::map& aProps ) { - int recordId = ALTIUM_PARSER::ReadInt( aProps, "RECORD", -1 ); + int recordId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "RECORD", -1 ); return static_cast( recordId ); } @@ -55,8 +57,8 @@ constexpr int Altium2KiCadUnit( const int val, const int frac ) int ReadKiCadUnitFrac( const std::map& aProps, const wxString& aKey ) { // a unit is stored using two fields, denoting the size in mils and a fraction size - int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 ); - int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + "_FRAC", 0 ); + int key = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, 0 ); + int keyFrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey + "_FRAC", 0 ); return Altium2KiCadUnit( key, keyFrac ); } @@ -65,21 +67,21 @@ int ReadKiCadUnitFrac1( const std::map& aProps, const wxStri { // a unit is stored using two fields, denoting the size in mils and a fraction size // Dunno why Altium invents different units for the same purpose - int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 ); - int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + "_FRAC1", 0 ); + int key = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, 0 ); + int keyFrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey + "_FRAC1", 0 ); return Altium2KiCadUnit( key * 10, keyFrac ); } int ReadOwnerIndex( const std::map& aProperties ) { - return ALTIUM_PARSER::ReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); + return ALTIUM_PROPS_UTILS::ReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); } int ReadOwnerPartId( const std::map& aProperties ) { - return ALTIUM_PARSER::ReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); + return ALTIUM_PROPS_UTILS::ReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE ); } @@ -87,7 +89,7 @@ template T ReadEnum( const std::map& aProps, const wxString& aKey, int aLower, int aUpper, T aDefault ) { - int value = ALTIUM_PARSER::ReadInt( aProps, aKey, static_cast( aDefault ) ); + int value = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, static_cast( aDefault ) ); if( value < aLower || value > aUpper ) return aDefault; @@ -96,7 +98,41 @@ T ReadEnum( const std::map& aProps, const wxString& aKey, in } -ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader ) +ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( const std::map& aProps ) +{ + filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); + size_t dataSize = ALTIUM_PROPS_UTILS::ReadInt( aProps, "DATA_LEN", 0 ); + + wxString hexData = ALTIUM_PROPS_UTILS::ReadString( aProps, "DATA", "" ); + const size_t charCount = hexData.size(); + + if( charCount != dataSize * 2 ) + { + THROW_IO_ERROR( wxString::Format( "Invalid binary file hex data size. Chars expected: %d, " + "hex string length: %d", + int( dataSize * 2 ), int( hexData.size() ) ) ); + } + + data.resize( dataSize ); + + char str[3] = { 0 }; + uint8_t b = 0; + size_t outputId = 0; + + for( size_t inputId = 1; inputId < charCount; inputId += 2 ) + { + str[0] = (char) hexData[inputId - 1]; + str[1] = (char) hexData[inputId]; + + std::from_chars( str, str + 2, b, 16 ); + data[outputId] = b; + + outputId++; + } +} + + +ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_BINARY_PARSER& aReader ) { aReader.Skip( 5 ); filename = aReader.ReadWxString(); @@ -108,7 +144,7 @@ ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader ) } -ASCH_ADDITIONAL_FILE::ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader ) +ASCH_ADDITIONAL_FILE::ASCH_ADDITIONAL_FILE( ALTIUM_BINARY_PARSER& aReader ) { aReader.Skip( 5 ); FileName = aReader.ReadWxString(); @@ -124,23 +160,23 @@ ASCH_SYMBOL::ASCH_SYMBOL( const std::map& aProps ) { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT ); - currentpartid = ALTIUM_PARSER::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE ); - libreference = ALTIUM_PARSER::ReadString( aProps, "LIBREFERENCE", "" ); - sourcelibraryname = ALTIUM_PARSER::ReadString( aProps, "SOURCELIBRARYNAME", "" ); - componentdescription = ALTIUM_PARSER::ReadString( aProps, "COMPONENTDESCRIPTION", "" ); + currentpartid = ALTIUM_PROPS_UTILS::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE ); + libreference = ALTIUM_PROPS_UTILS::ReadString( aProps, "LIBREFERENCE", "" ); + sourcelibraryname = ALTIUM_PROPS_UTILS::ReadString( aProps, "SOURCELIBRARYNAME", "" ); + componentdescription = ALTIUM_PROPS_UTILS::ReadString( aProps, "COMPONENTDESCRIPTION", "" ); - orientation = ALTIUM_PARSER::ReadInt( aProps, "ORIENTATION", 0 ); - isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false ); + orientation = ALTIUM_PROPS_UTILS::ReadInt( aProps, "ORIENTATION", 0 ); + isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false ); location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - partcount = ALTIUM_PARSER::ReadInt( aProps, "PARTCOUNT", 0 ); - displaymodecount = ALTIUM_PARSER::ReadInt( aProps, "DISPLAYMODECOUNT", 0 ); - m_indexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", -1 ); + partcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PARTCOUNT", 0 ); + displaymodecount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "DISPLAYMODECOUNT", 0 ); + m_indexInSheet = ALTIUM_PROPS_UTILS::ReadInt( aProps, "INDEXINSHEET", -1 ); // DISPLAYMODE may be a string. Leave displaymode at 0 in this case. displaymode = 0; - wxString displayModeStr = ALTIUM_PARSER::ReadString( aProps, "DISPLAYMODE", "" ); + wxString displayModeStr = ALTIUM_PROPS_UTILS::ReadString( aProps, "DISPLAYMODE", "" ); long v = 0; @@ -154,7 +190,7 @@ ASCH_TEMPLATE::ASCH_TEMPLATE( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::TEMPLATE ); - filename = ALTIUM_PARSER::ReadString( aProps, "FILENAME", "" ); + filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "FILENAME", "" ); } @@ -163,29 +199,29 @@ ASCH_PIN::ASCH_PIN( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PIN ); - isKiCadLibPin = ALTIUM_PARSER::ReadBool( aProps, "ISKICADLIBPIN", false ); - ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); + isKiCadLibPin = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISKICADLIBPIN", false ); + ownerpartdisplaymode = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); - name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); - designator = ALTIUM_PARSER::ReadString( aProps, "DESIGNATOR", "" ); + name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); + designator = ALTIUM_PROPS_UTILS::ReadString( aProps, "DESIGNATOR", "" ); - int symbolOuterInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_OUTER", 0 ); + int symbolOuterInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_OUTER", 0 ); symbolOuter = ASCH_PIN_SYMBOL::FromInt( symbolOuterInt ); - int symbolInnerInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_INNER", 0 ); + int symbolInnerInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_INNER", 0 ); symbolInner = ASCH_PIN_SYMBOL::FromInt( symbolInnerInt ); - int symbolOuterEdgeInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_OUTEREDGE", 0 ); + int symbolOuterEdgeInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_OUTEREDGE", 0 ); symbolOuterEdge = ASCH_PIN_SYMBOL::FromInt( symbolOuterEdgeInt ); - int symbolInnerEdgeInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_INNEREDGE", 0 ); + int symbolInnerEdgeInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_INNEREDGE", 0 ); symbolInnerEdge = ASCH_PIN_SYMBOL::FromInt( symbolInnerEdgeInt ); electrical = ReadEnum( aProps, "ELECTRICAL", 0, 7, ASCH_PIN_ELECTRICAL::INPUT ); - int pinconglomerate = ALTIUM_PARSER::ReadInt( aProps, "PINCONGLOMERATE", 0 ); + int pinconglomerate = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINCONGLOMERATE", 0 ); orientation = static_cast( pinconglomerate & 0x03 ); hidden = ( pinconglomerate & 0x04 ) != 0; @@ -195,14 +231,14 @@ ASCH_PIN::ASCH_PIN( const std::map& aProps ) : locked = ( pinconglomerate & 0x40 ) != 0; - int x = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X", 0 ); - int xfrac = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X_FRAC", 0 ); - int y = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.Y", 0 ); - int yfrac = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.Y_FRAC", 0 ); + int x = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.X", 0 ); + int xfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.X_FRAC", 0 ); + int y = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.Y", 0 ); + int yfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.Y_FRAC", 0 ); location = VECTOR2I( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) ); - int p = ALTIUM_PARSER::ReadInt( aProps, "PINLENGTH", 0 ); - int pfrac = ALTIUM_PARSER::ReadInt( aProps, "PINLENGTH_FRAC", 0 ); + int p = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINLENGTH", 0 ); + int pfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINLENGTH_FRAC", 0 ); pinlength = Altium2KiCadUnit( p, pfrac ); // this code calculates the location as required by KiCad without rounding error attached @@ -256,17 +292,17 @@ ASCH_OWNER_INTERFACE::ASCH_OWNER_INTERFACE( const std::map& { ownerindex = ReadOwnerIndex( aProps ); ownerpartid = ReadOwnerPartId( aProps ); - ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); - indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 ); - IsNotAccesible = ALTIUM_PARSER::ReadBool( aProps, "ISNOTACCESIBLE", false ); + ownerpartdisplaymode = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 ); + indexinsheet = ALTIUM_PROPS_UTILS::ReadInt( aProps, "INDEXINSHEET", 0 ); + IsNotAccesible = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISNOTACCESIBLE", false ); } ASCH_FILL_INTERFACE::ASCH_FILL_INTERFACE( const std::map& aProps ) { - AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); - IsSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false ); - IsTransparent = ALTIUM_PARSER::ReadBool( aProps, "TRANSPARENT", false ); + AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 ); + IsSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false ); + IsTransparent = ALTIUM_PROPS_UTILS::ReadBool( aProps, "TRANSPARENT", false ); } @@ -279,7 +315,7 @@ ASCH_BORDER_INTERFACE::ASCH_BORDER_INTERFACE( const std::map if( LineWidth == 0 ) LineWidth = schIUScale.MilsToIU( 1 ); - Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); + Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); } @@ -291,11 +327,11 @@ ASCH_LABEL::ASCH_LABEL( const std::map& aProps ) : location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); textColor = 0; - fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 ); - isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false ); + fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 ); + isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false ); justification = ReadEnum( aProps, "JUSTIFICATION", 0, 8, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT ); @@ -321,20 +357,20 @@ ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map& aProps ) : Size = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ) - Location.x, -ReadKiCadUnitFrac( aProps, "CORNER.Y" ) - Location.y ); - Text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + Text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); Text.Replace( "~1", "\n", true ); - FontID = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 ); - IsWordWrapped = ALTIUM_PARSER::ReadBool( aProps, "WORDWRAP", false ); - ShowBorder = ALTIUM_PARSER::ReadBool( aProps, "SHOWBORDER", false ); + FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 ); + IsWordWrapped = ALTIUM_PROPS_UTILS::ReadBool( aProps, "WORDWRAP", false ); + ShowBorder = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWBORDER", false ); TextMargin = ReadKiCadUnitFrac( aProps, "TEXTMARGIN" ); - AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); - BorderColor = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); - TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 ); + AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 ); + BorderColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); + TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 ); BorderWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" ); - isSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false ); + isSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false ); Alignment = ReadEnum( aProps, "ALIGNMENT", 1, 3, ASCH_TEXT_FRAME_ALIGNMENT::LEFT ); @@ -346,7 +382,7 @@ ASCH_NOTE::ASCH_NOTE( const std::map& aProperties ) : { wxASSERT( ReadRecord( aProperties ) == ALTIUM_SCH_RECORD::NOTE ); - author = ALTIUM_PARSER::ReadString( aProperties, "AUTHOR", "" ); + author = ALTIUM_PROPS_UTILS::ReadString( aProperties, "AUTHOR", "" ); } @@ -356,7 +392,7 @@ ASCH_BEZIER::ASCH_BEZIER( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BEZIER ); - int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationCount; i++ ) { @@ -373,7 +409,7 @@ ASCH_POLYLINE::ASCH_POLYLINE( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYLINE ); - int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationCount; i++ ) { @@ -394,7 +430,7 @@ ASCH_POLYGON::ASCH_POLYGON( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYGON ); - int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationCount; i++ ) { @@ -437,8 +473,8 @@ ASCH_ARC::ASCH_ARC( const std::map& aProps ) : if( m_IsElliptical ) m_SecondaryRadius = ReadKiCadUnitFrac( aProps, "SECONDARYRADIUS" ); - m_StartAngle = ALTIUM_PARSER::ReadDouble( aProps, "STARTANGLE", 0 ); - m_EndAngle = ALTIUM_PARSER::ReadDouble( aProps, "ENDANGLE", 0 ); + m_StartAngle = ALTIUM_PROPS_UTILS::ReadDouble( aProps, "STARTANGLE", 0 ); + m_EndAngle = ALTIUM_PROPS_UTILS::ReadDouble( aProps, "ENDANGLE", 0 ); } @@ -479,7 +515,7 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map& aP wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SIGNAL_HARNESS ); - int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationCount; i++ ) { @@ -488,7 +524,7 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map& aP -ReadKiCadUnitFrac( aProps, "Y" + si ) ); } - Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); + Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" ); } @@ -503,8 +539,8 @@ ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map& aPro Side = ReadEnum( aProps, "SIDE", 0, 3, ASCH_SHEET_ENTRY_SIDE::LEFT ); - Name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); + Name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); - OwnerIndexAdditionalList = ALTIUM_PARSER::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true ); + OwnerIndexAdditionalList = ALTIUM_PROPS_UTILS::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true ); - Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); - AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); - TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 ); - TextFontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 ); + Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); + AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 ); + TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 ); + TextFontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 ); TextStyle = 0; } @@ -545,16 +581,16 @@ ASCH_HARNESS_TYPE::ASCH_HARNESS_TYPE( const std::map& aProps //ownerindex = ReadOwnerIndex( aProps ); // use SCH_IO_ALTIUM::m_harnessEntryParent instead! - Text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + Text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - IsHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false ); - OwnerIndexAdditionalList = ALTIUM_PARSER::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true ); + IsHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false ); + OwnerIndexAdditionalList = ALTIUM_PROPS_UTILS::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true ); - Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); - FontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 ); + Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); + FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 ); } @@ -583,10 +619,10 @@ ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map& aProps size = VECTOR2I( ReadKiCadUnitFrac( aProps, "XSIZE" ), ReadKiCadUnitFrac( aProps, "YSIZE" ) ); - isSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false ); + isSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false ); - color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); - areacolor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); + color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); + areacolor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 ); } @@ -600,7 +636,7 @@ ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map& aProps ) side = ReadEnum( aProps, "SIDE", 0, 3, ASCH_SHEET_ENTRY_SIDE::LEFT ); - name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); + name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); iotype = ReadEnum( aProps, "IOTYPE", 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED ); style = ReadEnum( aProps, "STYLE", 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL ); @@ -619,8 +655,8 @@ ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map& aProps ) : orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); - showNetName = ALTIUM_PARSER::ReadBool( aProps, "SHOWNETNAME", true ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); + showNetName = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWNETNAME", true ); style = ReadEnum( aProps, "STYLE", 0, 10, ASCH_POWER_PORT_STYLE::CIRCLE ); @@ -636,8 +672,8 @@ ASCH_PORT::ASCH_PORT( const std::map& aProps ) : Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - Name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); - HarnessType = ALTIUM_PARSER::ReadString( aProps, "HARNESSTYPE", "" ); + Name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); + HarnessType = ALTIUM_PROPS_UTILS::ReadString( aProps, "HARNESSTYPE", "" ); Width = ReadKiCadUnitFrac( aProps, "WIDTH" ); Height = ReadKiCadUnitFrac( aProps, "HEIGHT" ); @@ -645,10 +681,10 @@ ASCH_PORT::ASCH_PORT( const std::map& aProps ) : IOtype = ReadEnum( aProps, "IOTYPE", 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED ); Style = ReadEnum( aProps, "STYLE", 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL ); - AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 ); - Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 ); - FontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 ); - TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 ); + AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 ); + Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 ); + FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 ); + TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 ); Alignment = ReadEnum( aProps, "ALIGNMENT", 1, 3, ASCH_TEXT_FRAME_ALIGNMENT::LEFT ); @@ -662,8 +698,8 @@ ASCH_NO_ERC::ASCH_NO_ERC( const std::map& aProps ) location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - isActive = ALTIUM_PARSER::ReadBool( aProps, "ISACTIVE", true ); - suppressAll = ALTIUM_PARSER::ReadInt( aProps, "SUPPRESSALL", true ); + isActive = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISACTIVE", true ); + suppressAll = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SUPPRESSALL", true ); } @@ -672,7 +708,7 @@ ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NET_LABEL ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); @@ -690,7 +726,7 @@ ASCH_BUS::ASCH_BUS( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS ); - int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationcount; i++ ) { @@ -708,7 +744,7 @@ ASCH_WIRE::ASCH_WIRE( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE ); - int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 ); + int locationcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 ); for( int i = 1; i <= locationcount; i++ ) { @@ -738,15 +774,15 @@ ASCH_IMAGE::ASCH_IMAGE( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMAGE ); - filename = ALTIUM_PARSER::ReadString( aProps, "FILENAME", "" ); + filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "FILENAME", "" ); location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); corner = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ), -ReadKiCadUnitFrac( aProps, "CORNER.Y" ) ); - embedimage = ALTIUM_PARSER::ReadBool( aProps, "EMBEDIMAGE", false ); - keepaspect = ALTIUM_PARSER::ReadBool( aProps, "KEEPASPECT", false ); + embedimage = ALTIUM_PROPS_UTILS::ReadBool( aProps, "EMBEDIMAGE", false ); + keepaspect = ALTIUM_PROPS_UTILS::ReadBool( aProps, "KEEPASPECT", false ); } @@ -757,16 +793,16 @@ ASCH_SHEET_FONT::ASCH_SHEET_FONT( const std::map& aProps, in const wxString sid = std::to_string( aId ); - FontName = ALTIUM_PARSER::ReadString( aProps, "FONTNAME" + sid, "" ); + FontName = ALTIUM_PROPS_UTILS::ReadString( aProps, "FONTNAME" + sid, "" ); Size = ReadKiCadUnitFrac( aProps, "SIZE" + sid ); - Rotation = ALTIUM_PARSER::ReadInt( aProps, "ROTATION" + sid, 0 ); + Rotation = ALTIUM_PROPS_UTILS::ReadInt( aProps, "ROTATION" + sid, 0 ); - Italic = ALTIUM_PARSER::ReadBool( aProps, "ITALIC" + sid, false ); - Bold = ALTIUM_PARSER::ReadBool( aProps, "BOLD" + sid, false ); - Underline = ALTIUM_PARSER::ReadBool( aProps, "UNDERLINE" + sid, false ); + Italic = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ITALIC" + sid, false ); + Bold = ALTIUM_PROPS_UTILS::ReadBool( aProps, "BOLD" + sid, false ); + Underline = ALTIUM_PROPS_UTILS::ReadBool( aProps, "UNDERLINE" + sid, false ); - AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR" + sid, 0 ); + AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR" + sid, 0 ); } @@ -803,12 +839,12 @@ ASCH_SHEET::ASCH_SHEET( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET ); - int fontidcount = ALTIUM_PARSER::ReadInt( aProps, "FONTIDCOUNT", 0 ); + int fontidcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTIDCOUNT", 0 ); for( int i = 1; i <= fontidcount; i++ ) fonts.emplace_back( aProps, i ); - useCustomSheet = ALTIUM_PARSER::ReadBool( aProps, "USECUSTOMSHEET", false ); + useCustomSheet = ALTIUM_PROPS_UTILS::ReadBool( aProps, "USECUSTOMSHEET", false ); customSize = VECTOR2I( ReadKiCadUnitFrac( aProps, "CUSTOMX" ), ReadKiCadUnitFrac( aProps, "CUSTOMY" ) ); @@ -824,7 +860,7 @@ ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_NAME ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); @@ -832,7 +868,7 @@ ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map& aProps ) : location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false ); + isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false ); } @@ -841,7 +877,7 @@ ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::FILE_NAME ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); @@ -849,7 +885,7 @@ ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map& aProps ) : location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ), -ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) ); - isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false ); + isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false ); } @@ -858,9 +894,9 @@ ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::DESIGNATOR ); - name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); - fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 ); + name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); + fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 ); justification = ReadEnum( aProps, "JUSTIFICATION", 0, 8, ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT ); @@ -878,12 +914,12 @@ ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map& aP { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION ); - ownerindex = ALTIUM_PARSER::ReadInt( aProps, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); - name = ALTIUM_PARSER::ReadString( aProps, "MODELNAME", "" ); - type = ALTIUM_PARSER::ReadString( aProps, "MODELTYPE", "" ); - libname = ALTIUM_PARSER::ReadString( aProps, "MODELDATAFILE0", "" ); - description = ALTIUM_PARSER::ReadString( aProps, "DESCRIPTION", "" ); - isCurrent = ALTIUM_PARSER::ReadBool( aProps, "ISCURRENT", false ); + ownerindex = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERINDEX", ALTIUM_COMPONENT_NONE ); + name = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELNAME", "" ); + type = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELTYPE", "" ); + libname = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELDATAFILE0", "" ); + description = ALTIUM_PROPS_UTILS::ReadString( aProps, "DESCRIPTION", "" ); + isCurrent = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISCURRENT", false ); } @@ -920,14 +956,14 @@ ASCH_PARAMETER::ASCH_PARAMETER( const std::map& aProps ) : orientation = ReadEnum( aProps, "ORIENTATION", 0, 3, ASCH_RECORD_ORIENTATION::RIGHTWARDS ); - name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" ); - text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" ); + name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" ); + text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" ); - isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false ); - isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false ); - isShowName = ALTIUM_PARSER::ReadBool( aProps, "SHOWNAME", false ); + isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false ); + isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false ); + isShowName = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWNAME", false ); - fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 ); + fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 ); } @@ -936,5 +972,5 @@ ASCH_HYPERLINK::ASCH_HYPERLINK( const std::map& aProps ) : { wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HYPERLINK ); - url = ALTIUM_PARSER::ReadString( aProps, "URL", "" ); + url = ALTIUM_PROPS_UTILS::ReadString( aProps, "URL", "" ); } \ No newline at end of file diff --git a/eeschema/sch_io/altium/altium_parser_sch.h b/eeschema/sch_io/altium/altium_parser_sch.h index 81bdf3ee25..813a95dc9b 100644 --- a/eeschema/sch_io/altium/altium_parser_sch.h +++ b/eeschema/sch_io/altium/altium_parser_sch.h @@ -36,14 +36,15 @@ // this constant specifies a item which is not inside an component const int ALTIUM_COMPONENT_NONE = -1; -class ALTIUM_PARSER; +class ALTIUM_BINARY_PARSER; struct ASCH_STORAGE_FILE { wxString filename; std::vector data; - explicit ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader ); + explicit ASCH_STORAGE_FILE( const std::map& aProps ); + explicit ASCH_STORAGE_FILE( ALTIUM_BINARY_PARSER& aReader ); }; struct ASCH_ADDITIONAL_FILE @@ -51,7 +52,7 @@ struct ASCH_ADDITIONAL_FILE wxString FileName; std::vector Data; - explicit ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader ); + explicit ASCH_ADDITIONAL_FILE( ALTIUM_BINARY_PARSER& aReader ); }; enum class ALTIUM_SCH_RECORD diff --git a/eeschema/sch_io/altium/sch_io_altium.cpp b/eeschema/sch_io/altium/sch_io_altium.cpp index f73d200c78..97f7d8c6d5 100644 --- a/eeschema/sch_io/altium/sch_io_altium.cpp +++ b/eeschema/sch_io/altium/sch_io_altium.cpp @@ -27,7 +27,8 @@ #include "altium_parser_sch.h" #include "sch_shape.h" #include -#include +#include +#include #include #include @@ -65,6 +66,7 @@ #include #include #include +#include "sch_io_altium.h" // Harness port object itself does not contain color information about itself // It seems altium is drawing harness ports using these colors @@ -242,13 +244,26 @@ int SCH_IO_ALTIUM::GetModifyHash() const } -bool SCH_IO_ALTIUM::checkFileHeader( const wxString& aFileName ) +bool SCH_IO_ALTIUM::isBinaryFile( const wxString& aFileName ) { // Compound File Binary Format header return IO_UTILS::fileStartsWithBinaryHeader( aFileName, IO_UTILS::COMPOUND_FILE_HEADER ); } +bool SCH_IO_ALTIUM::isASCIIFile( const wxString& aFileName ) +{ + // ASCII file format + return IO_UTILS::fileStartsWithPrefix( aFileName, wxS( "|HEADER=" ), false ); +} + + +bool SCH_IO_ALTIUM::checkFileHeader( const wxString& aFileName ) +{ + return isBinaryFile( aFileName ) || isASCIIFile( aFileName ); +} + + bool SCH_IO_ALTIUM::CanReadSchematicFile( const wxString& aFileName ) const { if( !SCH_IO::CanReadSchematicFile( aFileName ) ) @@ -441,27 +456,34 @@ SCH_SHEET* SCH_IO_ALTIUM::getCurrentSheet() void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName ) { - ALTIUM_COMPOUND_FILE altiumSchFile( aFileName ); - // Load path may be different from the project path. wxFileName parentFileName = aFileName; - try + if( isBinaryFile( aFileName ) ) { - ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader - ParseFileHeader( altiumSchFile ); + ALTIUM_COMPOUND_FILE altiumSchFile( aFileName ); - // Parse "Additional" because sheet is set up during "FileHeader" parsing. - ParseAdditional( altiumSchFile ); + try + { + ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader + ParseFileHeader( altiumSchFile ); + + // Parse "Additional" because sheet is set up during "FileHeader" parsing. + ParseAdditional( altiumSchFile ); + } + catch( const CFB::CFBException& exception ) + { + THROW_IO_ERROR( exception.what() ); + } + catch( const std::exception& exc ) + { + wxLogDebug( wxT( "Unhandled exception in Altium schematic parsers: %s." ), exc.what() ); + throw; + } } - catch( const CFB::CFBException& exception ) + else // ASCII { - THROW_IO_ERROR( exception.what() ); - } - catch( const std::exception& exc ) - { - wxLogDebug( wxT( "Unhandled exception in Altium schematic parsers: %s." ), exc.what() ); - throw; + ParseASCIISchematic( aFileName ); } SCH_SCREEN* currentScreen = getCurrentScreen(); @@ -550,11 +572,11 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) if( file == nullptr ) return; - ALTIUM_PARSER reader( aAltiumSchFile, file ); + ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file ); std::map properties = reader.ReadProperties(); - wxString header = ALTIUM_PARSER::ReadString( properties, "HEADER", "" ); - int weight = ALTIUM_PARSER::ReadInt( properties, "WEIGHT", 0 ); + wxString header = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" ); + int weight = ALTIUM_PROPS_UTILS::ReadInt( properties, "WEIGHT", 0 ); if( weight < 0 ) THROW_IO_ERROR( "Storage weight is negative!" ); @@ -579,13 +601,15 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) { - const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Additional" } ); + wxString streamName = wxS( "Additional" ); + + const CFB::COMPOUND_FILE_ENTRY* file = + aAltiumSchFile.FindStream( { streamName.ToStdString() } ); if( file == nullptr ) return; - ALTIUM_PARSER reader( aAltiumSchFile, file ); - + ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file ); if( reader.GetRemainingBytes() <= 0 ) { @@ -595,7 +619,7 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile { std::map properties = reader.ReadProperties(); - int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 ); + int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 ); ALTIUM_SCH_RECORD record = static_cast( recordId ); if( record != ALTIUM_SCH_RECORD::HEADER ) @@ -606,39 +630,7 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile { std::map properties = reader.ReadProperties(); - int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 ); - ALTIUM_SCH_RECORD record = static_cast( recordId ); - - // see: https://github.com/vadmium/python-altium/blob/master/format.md - switch( record ) - { - case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR: - ParseHarnessConnector( index, properties ); - break; - - case ALTIUM_SCH_RECORD::HARNESS_ENTRY: - ParseHarnessEntry( properties ); - break; - - case ALTIUM_SCH_RECORD::HARNESS_TYPE: - ParseHarnessType( properties ); - break; - - case ALTIUM_SCH_RECORD::SIGNAL_HARNESS: - ParseSignalHarness( properties ); - break; - - case ALTIUM_SCH_RECORD::BLANKET: - m_reporter->Report( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR ); - break; - - default: - m_reporter->Report( wxString::Format( _( "Unknown or unexpected record ID %d found " - "inside \"Additional\" section." ), - recordId ), - RPT_SEVERITY_ERROR ); - break; - } + ParseRecord( index, properties, streamName ); } // Handle harness Ports @@ -657,12 +649,15 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) { - const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } ); + wxString streamName = wxS( "FileHeader" ); + + const CFB::COMPOUND_FILE_ENTRY* file = + aAltiumSchFile.FindStream( { streamName.ToStdString() } ); if( file == nullptr ) THROW_IO_ERROR( "FileHeader not found" ); - ALTIUM_PARSER reader( aAltiumSchFile, file ); + ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file ); if( reader.GetRemainingBytes() <= 0 ) { @@ -672,7 +667,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile { std::map properties = reader.ReadProperties(); - wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" ); + wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" ); if( libtype.CmpNoCase( "Protel for Windows - Schematic Capture Binary File Version 5.0" ) ) THROW_IO_ERROR( _( "Expected Altium Schematic file version 5.0" ) ); @@ -689,183 +684,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile { std::map properties = reader.ReadProperties(); - int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", -1 ); - ALTIUM_SCH_RECORD record = static_cast( recordId ); - - // see: https://github.com/vadmium/python-altium/blob/master/format.md - switch( record ) - { - case ALTIUM_SCH_RECORD::HEADER: - THROW_IO_ERROR( "Header already parsed" ); - - case ALTIUM_SCH_RECORD::COMPONENT: - ParseComponent( index, properties ); - break; - - case ALTIUM_SCH_RECORD::PIN: - ParsePin( properties ); - break; - - case ALTIUM_SCH_RECORD::IEEE_SYMBOL: - m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO ); - break; - - case ALTIUM_SCH_RECORD::LABEL: - ParseLabel( properties ); - break; - - case ALTIUM_SCH_RECORD::BEZIER: - ParseBezier( properties ); - break; - - case ALTIUM_SCH_RECORD::POLYLINE: - ParsePolyline( properties ); - break; - - case ALTIUM_SCH_RECORD::POLYGON: - ParsePolygon( properties ); - break; - - case ALTIUM_SCH_RECORD::ELLIPSE: - ParseEllipse( properties ); - break; - - case ALTIUM_SCH_RECORD::PIECHART: - m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO ); - break; - - case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: - ParseRoundRectangle( properties ); - break; - - case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: - case ALTIUM_SCH_RECORD::ARC: - ParseArc( properties ); - break; - - case ALTIUM_SCH_RECORD::LINE: - ParseLine( properties ); - break; - - case ALTIUM_SCH_RECORD::RECTANGLE: - ParseRectangle( properties ); - break; - - case ALTIUM_SCH_RECORD::SHEET_SYMBOL: - ParseSheetSymbol( index, properties ); - break; - - case ALTIUM_SCH_RECORD::SHEET_ENTRY: - ParseSheetEntry( properties ); - break; - - case ALTIUM_SCH_RECORD::POWER_PORT: - ParsePowerPort( properties ); - break; - - case ALTIUM_SCH_RECORD::PORT: - // Ports are parsed after the sheet was parsed - // This is required because we need all electrical connection points before placing. - m_altiumPortsCurrentSheet.emplace_back( properties ); - break; - - case ALTIUM_SCH_RECORD::NO_ERC: - ParseNoERC( properties ); - break; - - case ALTIUM_SCH_RECORD::NET_LABEL: - ParseNetLabel( properties ); - break; - - case ALTIUM_SCH_RECORD::BUS: - ParseBus( properties ); - break; - - case ALTIUM_SCH_RECORD::WIRE: - ParseWire( properties ); - break; - - case ALTIUM_SCH_RECORD::TEXT_FRAME: - ParseTextFrame( properties ); - break; - - case ALTIUM_SCH_RECORD::JUNCTION: - ParseJunction( properties ); - break; - - case ALTIUM_SCH_RECORD::IMAGE: - ParseImage( properties ); - break; - - case ALTIUM_SCH_RECORD::SHEET: - ParseSheet( properties ); - break; - - case ALTIUM_SCH_RECORD::SHEET_NAME: - ParseSheetName( properties ); - break; - - case ALTIUM_SCH_RECORD::FILE_NAME: - ParseFileName( properties ); - break; - - case ALTIUM_SCH_RECORD::DESIGNATOR: - ParseDesignator( properties ); - break; - - case ALTIUM_SCH_RECORD::BUS_ENTRY: - ParseBusEntry( properties ); - break; - - case ALTIUM_SCH_RECORD::TEMPLATE: - ParseTemplate( index, properties ); - break; - - case ALTIUM_SCH_RECORD::PARAMETER: - ParseParameter( properties ); - break; - - case ALTIUM_SCH_RECORD::PARAMETER_SET: - m_reporter->Report( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR ); - break; - - case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST: - ParseImplementationList( index, properties ); - break; - - case ALTIUM_SCH_RECORD::IMPLEMENTATION: - ParseImplementation( properties ); - break; - - case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST: - break; - - case ALTIUM_SCH_RECORD::MAP_DEFINER: - break; - - case ALTIUM_SCH_RECORD::IMPL_PARAMS: - break; - - case ALTIUM_SCH_RECORD::NOTE: - ParseNote( properties ); - break; - - case ALTIUM_SCH_RECORD::COMPILE_MASK: - m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR ); - break; - - case ALTIUM_SCH_RECORD::HYPERLINK: - break; - - default: - m_reporter->Report( wxString::Format( _( "Unknown or unexpected record id %d found " - "inside \"FileHeader\" section." ), - recordId ), - RPT_SEVERITY_ERROR ); - break; - } - - SCH_IO_ALTIUM::m_harnessOwnerIndexOffset = index; + ParseRecord( index, properties, streamName ); } if( reader.HasParsingError() ) @@ -902,6 +721,8 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile m_altiumPortsCurrentSheet.clear(); m_altiumComponents.clear(); m_altiumTemplates.clear(); + m_altiumImplementationList.clear(); + m_symbols.clear(); m_libSymbols.clear(); @@ -914,6 +735,324 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile } +void SCH_IO_ALTIUM::ParseASCIISchematic( const wxString& aFileName ) +{ + // Read storage content first + { + ALTIUM_ASCII_PARSER storageReader( aFileName ); + + while( storageReader.CanRead() ) + { + std::map properties = storageReader.ReadProperties(); + + // Binary data + if( properties.find( wxS( "BINARY" ) ) != properties.end() ) + m_altiumStorage.emplace_back( properties ); + } + } + + // Read other data + ALTIUM_ASCII_PARSER reader( aFileName ); + + if( !reader.CanRead() ) + { + THROW_IO_ERROR( "FileHeader does not contain any data" ); + } + else + { + std::map properties = reader.ReadProperties(); + + wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" ); + + if( libtype.CmpNoCase( "Protel for Windows - Schematic Capture Ascii File Version 5.0" ) ) + THROW_IO_ERROR( _( "Expected Altium Schematic file version 5.0" ) ); + } + + // Prepare some local variables + wxCHECK( m_altiumPortsCurrentSheet.empty(), /* void */ ); + wxCHECK( !m_currentTitleBlock, /* void */ ); + + m_currentTitleBlock = std::make_unique(); + + // index is required to resolve OWNERINDEX + int index = 0; + + while( reader.CanRead() ) + { + std::map properties = reader.ReadProperties(); + + // Reset index at headers + if( properties.find( wxS( "HEADER" ) ) != properties.end() ) + { + index = 0; + continue; + } + + if( properties.find( wxS( "RECORD" ) ) != properties.end() ) + ParseRecord( index, properties, aFileName ); + + index++; + } + + if( reader.HasParsingError() ) + THROW_IO_ERROR( "stream was not parsed correctly!" ); + + if( reader.CanRead() ) + THROW_IO_ERROR( "stream is not fully parsed" ); + + // assign LIB_SYMBOL -> COMPONENT + for( std::pair& symbol : m_symbols ) + { + auto libSymbolIt = m_libSymbols.find( symbol.first ); + + if( libSymbolIt == m_libSymbols.end() ) + THROW_IO_ERROR( "every symbol should have a symbol attached" ); + + m_pi->SaveSymbol( getLibFileName().GetFullPath(), + new LIB_SYMBOL( *( libSymbolIt->second ) ), m_properties.get() ); + + symbol.second->SetLibSymbol( libSymbolIt->second ); + } + + SCH_SCREEN* screen = getCurrentScreen(); + wxCHECK( screen, /* void */ ); + + // Handle title blocks + screen->SetTitleBlock( *m_currentTitleBlock ); + m_currentTitleBlock.reset(); + + // Handle harness Ports + for( const ASCH_PORT& port : m_altiumHarnessPortsCurrentSheet ) + ParseHarnessPort( port ); + + // Handle Ports + for( const ASCH_PORT& port : m_altiumPortsCurrentSheet ) + ParsePort( port ); + + m_altiumPortsCurrentSheet.clear(); + m_altiumComponents.clear(); + m_altiumTemplates.clear(); + m_altiumImplementationList.clear(); + + m_symbols.clear(); + m_libSymbols.clear(); + + // Otherwise we cannot save the imported sheet? + SCH_SHEET* sheet = getCurrentSheet(); + + wxCHECK( sheet, /* void */ ); + + sheet->SetModified(); +} + + +void SCH_IO_ALTIUM::ParseRecord( int index, std::map& properties, + const wxString& aSectionName ) +{ + int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", -1 ); + ALTIUM_SCH_RECORD record = static_cast( recordId ); + + // see: https://github.com/vadmium/python-altium/blob/master/format.md + switch( record ) + { + // FileHeader section + + case ALTIUM_SCH_RECORD::HEADER: + THROW_IO_ERROR( "Header already parsed" ); + + case ALTIUM_SCH_RECORD::COMPONENT: + ParseComponent( index, properties ); + break; + + case ALTIUM_SCH_RECORD::PIN: + ParsePin( properties ); + break; + + case ALTIUM_SCH_RECORD::IEEE_SYMBOL: + m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO ); + break; + + case ALTIUM_SCH_RECORD::LABEL: + ParseLabel( properties ); + break; + + case ALTIUM_SCH_RECORD::BEZIER: + ParseBezier( properties ); + break; + + case ALTIUM_SCH_RECORD::POLYLINE: + ParsePolyline( properties ); + break; + + case ALTIUM_SCH_RECORD::POLYGON: + ParsePolygon( properties ); + break; + + case ALTIUM_SCH_RECORD::ELLIPSE: + ParseEllipse( properties ); + break; + + case ALTIUM_SCH_RECORD::PIECHART: + m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO ); + break; + + case ALTIUM_SCH_RECORD::ROUND_RECTANGLE: + ParseRoundRectangle( properties ); + break; + + case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC: + case ALTIUM_SCH_RECORD::ARC: + ParseArc( properties ); + break; + + case ALTIUM_SCH_RECORD::LINE: + ParseLine( properties ); + break; + + case ALTIUM_SCH_RECORD::RECTANGLE: + ParseRectangle( properties ); + break; + + case ALTIUM_SCH_RECORD::SHEET_SYMBOL: + ParseSheetSymbol( index, properties ); + break; + + case ALTIUM_SCH_RECORD::SHEET_ENTRY: + ParseSheetEntry( properties ); + break; + + case ALTIUM_SCH_RECORD::POWER_PORT: + ParsePowerPort( properties ); + break; + + case ALTIUM_SCH_RECORD::PORT: + // Ports are parsed after the sheet was parsed + // This is required because we need all electrical connection points before placing. + m_altiumPortsCurrentSheet.emplace_back( properties ); + break; + + case ALTIUM_SCH_RECORD::NO_ERC: + ParseNoERC( properties ); + break; + + case ALTIUM_SCH_RECORD::NET_LABEL: + ParseNetLabel( properties ); + break; + + case ALTIUM_SCH_RECORD::BUS: + ParseBus( properties ); + break; + + case ALTIUM_SCH_RECORD::WIRE: + ParseWire( properties ); + break; + + case ALTIUM_SCH_RECORD::TEXT_FRAME: + ParseTextFrame( properties ); + break; + + case ALTIUM_SCH_RECORD::JUNCTION: + ParseJunction( properties ); + break; + + case ALTIUM_SCH_RECORD::IMAGE: + ParseImage( properties ); + break; + + case ALTIUM_SCH_RECORD::SHEET: + ParseSheet( properties ); + break; + + case ALTIUM_SCH_RECORD::SHEET_NAME: + ParseSheetName( properties ); + break; + + case ALTIUM_SCH_RECORD::FILE_NAME: + ParseFileName( properties ); + break; + + case ALTIUM_SCH_RECORD::DESIGNATOR: + ParseDesignator( properties ); + break; + + case ALTIUM_SCH_RECORD::BUS_ENTRY: + ParseBusEntry( properties ); + break; + + case ALTIUM_SCH_RECORD::TEMPLATE: + ParseTemplate( index, properties ); + break; + + case ALTIUM_SCH_RECORD::PARAMETER: + ParseParameter( properties ); + break; + + case ALTIUM_SCH_RECORD::PARAMETER_SET: + m_reporter->Report( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR ); + break; + + case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST: + ParseImplementationList( index, properties ); + break; + + case ALTIUM_SCH_RECORD::IMPLEMENTATION: + ParseImplementation( properties ); + break; + + case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST: + break; + + case ALTIUM_SCH_RECORD::MAP_DEFINER: + break; + + case ALTIUM_SCH_RECORD::IMPL_PARAMS: + break; + + case ALTIUM_SCH_RECORD::NOTE: + ParseNote( properties ); + break; + + case ALTIUM_SCH_RECORD::COMPILE_MASK: + m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR ); + break; + + case ALTIUM_SCH_RECORD::HYPERLINK: + break; + + // Additional section + + case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR: + ParseHarnessConnector( index, properties ); + break; + + case ALTIUM_SCH_RECORD::HARNESS_ENTRY: + ParseHarnessEntry( properties ); + break; + + case ALTIUM_SCH_RECORD::HARNESS_TYPE: + ParseHarnessType( properties ); + break; + + case ALTIUM_SCH_RECORD::SIGNAL_HARNESS: + ParseSignalHarness( properties ); + break; + + case ALTIUM_SCH_RECORD::BLANKET: + m_reporter->Report( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR ); + break; + + default: + m_reporter->Report( + wxString::Format( _( "Unknown or unexpected record id %d found in %s." ), recordId, + aSectionName ), + RPT_SEVERITY_ERROR ); + break; + } + + SCH_IO_ALTIUM::m_harnessOwnerIndexOffset = index; +} + + bool SCH_IO_ALTIUM::IsComponentPartVisible( const ASCH_OWNER_INTERFACE& aElem ) const { const auto& component = m_altiumComponents.find( aElem.ownerindex ); @@ -3411,7 +3550,7 @@ void SCH_IO_ALTIUM::ParseWire( const std::map& aProperties ) SCH_LINE* wire = new SCH_LINE( elem.points.at( i ) + m_sheetOffset, SCH_LAYER_ID::LAYER_WIRE ); wire->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset ); - wire->SetLineWidth( elem.lineWidth ); + // wire->SetLineWidth( elem.lineWidth ); wire->SetFlags( IS_NEW ); screen->Append( wire ); @@ -3985,7 +4124,7 @@ std::map SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN for( auto& [name, entry] : syms ) { - ALTIUM_PARSER reader( aAltiumLibFile, entry ); + ALTIUM_BINARY_PARSER reader( aAltiumLibFile, entry ); std::vector symbols; if( reader.GetRemainingBytes() <= 0 ) @@ -3995,7 +4134,7 @@ std::map SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN { std::map properties = reader.ReadProperties(); - int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 ); + int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 ); ALTIUM_SCH_RECORD record = static_cast( recordId ); if( record != ALTIUM_SCH_RECORD::COMPONENT ) @@ -4060,7 +4199,7 @@ std::map SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN if( properties.empty() ) continue; - int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 ); + int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 ); ALTIUM_SCH_RECORD record = static_cast( recordId ); switch( record ) @@ -4225,7 +4364,7 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, if( file == nullptr ) THROW_IO_ERROR( "FileHeader not found" ); - ALTIUM_PARSER reader( aAltiumSchFile, file ); + ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file ); if( reader.GetRemainingBytes() <= 0 ) { @@ -4234,7 +4373,7 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, std::map properties = reader.ReadProperties(); - wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" ); + wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" ); if( libtype.CmpNoCase( "Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) ) THROW_IO_ERROR( _( "Expected Altium Schematic Library file version 5.0" ) ); diff --git a/eeschema/sch_io/altium/sch_io_altium.h b/eeschema/sch_io/altium/sch_io_altium.h index ebf0224959..956c3daec5 100644 --- a/eeschema/sch_io/altium/sch_io_altium.h +++ b/eeschema/sch_io/altium/sch_io_altium.h @@ -116,6 +116,11 @@ public: void ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); void ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); + void ParseASCIISchematic( const wxString& aFileName ); + + void ParseRecord( int index, std::map& properties, + const wxString& aSectionName ); + private: SCH_SCREEN* getCurrentScreen(); SCH_SHEET* getCurrentSheet(); @@ -212,6 +217,8 @@ private: void ensureLoadedLibrary( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties ); long long getLibraryTimestamp( const wxString& aLibraryPath ) const; + static bool isBinaryFile( const wxString& aFileName ); + static bool isASCIIFile( const wxString& aFileName ); static bool checkFileHeader( const wxString& aFileName ); std::map m_timestamps; diff --git a/pcbnew/pcb_io/altium/altium_parser_pcb.cpp b/pcbnew/pcb_io/altium/altium_parser_pcb.cpp index 1a3761dce5..9567b3256f 100644 --- a/pcbnew/pcb_io/altium/altium_parser_pcb.cpp +++ b/pcbnew/pcb_io/altium/altium_parser_pcb.cpp @@ -31,7 +31,8 @@ #include #include "altium_parser_pcb.h" -#include "io/altium/altium_parser.h" +#include "io/altium/altium_binary_parser.h" +#include "io/altium/altium_props_utils.h" ALTIUM_LAYER altium_layer_from_name( const wxString& aName ) @@ -154,14 +155,14 @@ void altium_parse_polygons( std::map& aProps, if( aProps.find( vxi ) == aProps.end() || aProps.find( vyi ) == aProps.end() ) break; // it doesn't seem like we know beforehand how many vertices are inside a polygon - const bool isRound = ALTIUM_PARSER::ReadInt( aProps, wxT( "KIND" ) + si, 0 ) != 0; - const int32_t radius = ALTIUM_PARSER::ReadKicadUnit( aProps, wxT( "R" ) + si, wxT( "0mil" ) ); - const double sa = ALTIUM_PARSER::ReadDouble( aProps, wxT( "SA" ) + si, 0. ); - const double ea = ALTIUM_PARSER::ReadDouble( aProps, wxT( "EA" ) + si, 0. ); - const VECTOR2I vp = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( aProps, vxi, wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( aProps, vyi, wxT( "0mil" ) ) ); - const VECTOR2I cp = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( aProps, wxT( "CX" ) + si, wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( aProps, wxT( "CY" ) + si, wxT( "0mil" ) ) ); + const bool isRound = ALTIUM_PROPS_UTILS::ReadInt( aProps, wxT( "KIND" ) + si, 0 ) != 0; + const int32_t radius = ALTIUM_PROPS_UTILS::ReadKicadUnit( aProps, wxT( "R" ) + si, wxT( "0mil" ) ); + const double sa = ALTIUM_PROPS_UTILS::ReadDouble( aProps, wxT( "SA" ) + si, 0. ); + const double ea = ALTIUM_PROPS_UTILS::ReadDouble( aProps, wxT( "EA" ) + si, 0. ); + const VECTOR2I vp = VECTOR2I( ALTIUM_PROPS_UTILS::ReadKicadUnit( aProps, vxi, wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( aProps, vyi, wxT( "0mil" ) ) ); + const VECTOR2I cp = VECTOR2I( ALTIUM_PROPS_UTILS::ReadKicadUnit( aProps, wxT( "CX" ) + si, wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( aProps, wxT( "CY" ) + si, wxT( "0mil" ) ) ); aVertices.emplace_back( isRound, radius, sa, ea, vp, cp ); } @@ -171,7 +172,7 @@ void altium_parse_polygons( std::map& aProps, static ALTIUM_MODE ReadAltiumModeFromProperties( const std::map& aProps, wxString aKey ) { - wxString mode = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) ); + wxString mode = ALTIUM_PROPS_UTILS::ReadString( aProps, aKey, wxT( "" ) ); if( mode == wxT( "None" ) ) return ALTIUM_MODE::NONE; @@ -188,7 +189,7 @@ static ALTIUM_MODE ReadAltiumModeFromProperties( const std::map& aProps, wxString aKey ) { - wxString record = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) ); + wxString record = ALTIUM_PROPS_UTILS::ReadString( aProps, aKey, wxT( "" ) ); if( record == wxT( "Arc" ) ) return ALTIUM_RECORD::ARC; @@ -216,7 +217,7 @@ static AEXTENDED_PRIMITIVE_INFORMATION_TYPE ReadAltiumExtendedPrimitiveInformationTypeFromProperties( const std::map& aProps, wxString aKey ) { - wxString parsedType = ALTIUM_PARSER::ReadString( aProps, aKey, wxT( "" ) ); + wxString parsedType = ALTIUM_PROPS_UTILS::ReadString( aProps, aKey, wxT( "" ) ); if( parsedType == wxT( "Mask" ) ) return AEXTENDED_PRIMITIVE_INFORMATION_TYPE::MASK; @@ -248,40 +249,40 @@ static void ExpectSubrecordLengthAtLeast( const std::string& aStreamType, } -AEXTENDED_PRIMITIVE_INFORMATION::AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_PARSER& aReader ) +AEXTENDED_PRIMITIVE_INFORMATION::AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_BINARY_PARSER& aReader ) { const std::map props = aReader.ReadProperties(); if( props.empty() ) THROW_IO_ERROR( wxT( "ExtendedPrimitiveInformation stream has no properties!" ) ); - primitiveIndex = ALTIUM_PARSER::ReadInt( props, wxT( "PRIMITIVEINDEX" ), -1 ); + primitiveIndex = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "PRIMITIVEINDEX" ), -1 ); primitiveObjectId = ReadAltiumRecordFromProperties( props, wxT( "PRIMITIVEOBJECTID" ) ); type = ReadAltiumExtendedPrimitiveInformationTypeFromProperties( props, wxT( "TYPE" ) ); pastemaskexpansionmode = ReadAltiumModeFromProperties( props, wxT( "PASTEMASKEXPANSIONMODE" ) ); - pastemaskexpansionmanual = ALTIUM_PARSER::ReadKicadUnit( + pastemaskexpansionmanual = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "PASTEMASKEXPANSION_MANUAL" ), wxT( "0mil" ) ); soldermaskexpansionmode = ReadAltiumModeFromProperties( props, wxT( "SOLDERMASKEXPANSIONMODE" ) ); - soldermaskexpansionmanual = ALTIUM_PARSER::ReadKicadUnit( + soldermaskexpansionmanual = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "SOLDERMASKEXPANSION_MANUAL" ), wxT( "0mil" ) ); } -ABOARD6::ABOARD6( ALTIUM_PARSER& aReader ) +ABOARD6::ABOARD6( ALTIUM_BINARY_PARSER& aReader ) { std::map props = aReader.ReadProperties(); if( props.empty() ) THROW_IO_ERROR( wxT( "Board6 stream has no properties!" ) ); - sheetpos = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETX" ), wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETY" ), wxT( "0mil" ) ) ); - sheetsize = wxSize( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETWIDTH" ), wxT( "0mil" ) ), - ALTIUM_PARSER::ReadKicadUnit( props, wxT( "SHEETHEIGHT" ), wxT( "0mil" ) ) ); + sheetpos = VECTOR2I( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "SHEETX" ), wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "SHEETY" ), wxT( "0mil" ) ) ); + sheetsize = wxSize( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "SHEETWIDTH" ), wxT( "0mil" ) ), + ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "SHEETHEIGHT" ), wxT( "0mil" ) ) ); - layercount = ALTIUM_PARSER::ReadInt( props, wxT( "LAYERSETSCOUNT" ), 1 ) + 1; + layercount = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "LAYERSETSCOUNT" ), 1 ) + 1; for( size_t i = 1; i < std::numeric_limits::max(); i++ ) { @@ -295,7 +296,7 @@ ABOARD6::ABOARD6( ALTIUM_PARSER& aReader ) ABOARD6_LAYER_STACKUP l; - l.name = ALTIUM_PARSER::ReadString( props, layername, wxT( "" ) ); + l.name = ALTIUM_PROPS_UTILS::ReadString( props, layername, wxT( "" ) ); wxString originalName = l.name; int ii = 2; @@ -303,13 +304,13 @@ ABOARD6::ABOARD6( ALTIUM_PARSER& aReader ) while( !layerNames.insert( l.name ).second ) l.name = wxString::Format( wxT( "%s %d" ), originalName, ii++ ); - l.nextId = ALTIUM_PARSER::ReadInt( props, layeri + wxT( "NEXT" ), 0 ); - l.prevId = ALTIUM_PARSER::ReadInt( props, layeri + wxT( "PREV" ), 0 ); - l.copperthick = ALTIUM_PARSER::ReadKicadUnit( props, layeri + wxT( "COPTHICK" ), wxT( "1.4mil" ) ); + l.nextId = ALTIUM_PROPS_UTILS::ReadInt( props, layeri + wxT( "NEXT" ), 0 ); + l.prevId = ALTIUM_PROPS_UTILS::ReadInt( props, layeri + wxT( "PREV" ), 0 ); + l.copperthick = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, layeri + wxT( "COPTHICK" ), wxT( "1.4mil" ) ); - l.dielectricconst = ALTIUM_PARSER::ReadDouble( props, layeri + wxT( "DIELCONST" ), 0. ); - l.dielectricthick = ALTIUM_PARSER::ReadKicadUnit( props, layeri + wxT( "DIELHEIGHT" ), wxT( "60mil" ) ); - l.dielectricmaterial = ALTIUM_PARSER::ReadString( props, layeri + wxT( "DIELMATERIAL" ), wxT( "FR-4" ) ); + l.dielectricconst = ALTIUM_PROPS_UTILS::ReadDouble( props, layeri + wxT( "DIELCONST" ), 0. ); + l.dielectricthick = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, layeri + wxT( "DIELHEIGHT" ), wxT( "60mil" ) ); + l.dielectricmaterial = ALTIUM_PROPS_UTILS::ReadString( props, layeri + wxT( "DIELMATERIAL" ), wxT( "FR-4" ) ); stackup.push_back( l ); } @@ -320,16 +321,16 @@ ABOARD6::ABOARD6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Board6 stream was not parsed correctly!" ) ); } -ACLASS6::ACLASS6( ALTIUM_PARSER& aReader ) +ACLASS6::ACLASS6( ALTIUM_BINARY_PARSER& aReader ) { std::map properties = aReader.ReadProperties(); if( properties.empty() ) THROW_IO_ERROR( wxT( "Classes6 stream has no properties!" ) ); - name = ALTIUM_PARSER::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); - uniqueid = ALTIUM_PARSER::ReadString( properties, wxT( "UNIQUEID" ), wxT( "" ) ); - kind = static_cast( ALTIUM_PARSER::ReadInt( properties, wxT( "KIND" ), -1 ) ); + name = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); + uniqueid = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "UNIQUEID" ), wxT( "" ) ); + kind = static_cast( ALTIUM_PROPS_UTILS::ReadInt( properties, wxT( "KIND" ), -1 ) ); for( size_t i = 0; i < std::numeric_limits::max(); i++ ) { @@ -345,39 +346,39 @@ ACLASS6::ACLASS6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Classes6 stream was not parsed correctly" ) ); } -ACOMPONENT6::ACOMPONENT6( ALTIUM_PARSER& aReader ) +ACOMPONENT6::ACOMPONENT6( ALTIUM_BINARY_PARSER& aReader ) { std::map props = aReader.ReadProperties(); if( props.empty() ) THROW_IO_ERROR( wxT( "Components6 stream has no props" ) ); - layer = altium_layer_from_name( ALTIUM_PARSER::ReadString( props, wxT( "LAYER" ), wxT( "" ) ) ); - position = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "X" ), wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( props, wxT( "Y" ), wxT( "0mil" ) ) ); - rotation = ALTIUM_PARSER::ReadDouble( props, wxT( "ROTATION" ), 0. ); - locked = ALTIUM_PARSER::ReadBool( props, wxT( "LOCKED" ), false ); - nameon = ALTIUM_PARSER::ReadBool( props, wxT( "NAMEON" ), true ); - commenton = ALTIUM_PARSER::ReadBool( props, wxT( "COMMENTON" ), false ); - sourcedesignator = ALTIUM_PARSER::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) ); + layer = altium_layer_from_name( ALTIUM_PROPS_UTILS::ReadString( props, wxT( "LAYER" ), wxT( "" ) ) ); + position = VECTOR2I( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "X" ), wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "Y" ), wxT( "0mil" ) ) ); + rotation = ALTIUM_PROPS_UTILS::ReadDouble( props, wxT( "ROTATION" ), 0. ); + locked = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "LOCKED" ), false ); + nameon = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "NAMEON" ), true ); + commenton = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "COMMENTON" ), false ); + sourcedesignator = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCEDESIGNATOR" ), wxT( "" ) ); sourcefootprintlibrary = - ALTIUM_PARSER::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) ); - pattern = ALTIUM_PARSER::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) ); + ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "SOURCEFOOTPRINTLIBRARY" ), wxT( "" ) ); + pattern = ALTIUM_PROPS_UTILS::ReadUnicodeString( props, wxT( "PATTERN" ), wxT( "" ) ); - sourcecomponentlibrary = ALTIUM_PARSER::ReadString( props, wxT( "SOURCECOMPONENTLIBRARY" ), wxT( "" ) ); - sourcelibreference = ALTIUM_PARSER::ReadString( props, wxT( "SOURCELIBREFERENCE" ), wxT( "" ) ); + sourcecomponentlibrary = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCECOMPONENTLIBRARY" ), wxT( "" ) ); + sourcelibreference = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SOURCELIBREFERENCE" ), wxT( "" ) ); nameautoposition = static_cast( - ALTIUM_PARSER::ReadInt( props, wxT( "NAMEAUTOPOSITION" ), 0 ) ); + ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "NAMEAUTOPOSITION" ), 0 ) ); commentautoposition = static_cast( - ALTIUM_PARSER::ReadInt( props, wxT( "COMMENTAUTOPOSITION" ), 0 ) ); + ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "COMMENTAUTOPOSITION" ), 0 ) ); if( aReader.HasParsingError() ) THROW_IO_ERROR( wxT( "Components6 stream was not parsed correctly" ) ); } -ADIMENSION6::ADIMENSION6( ALTIUM_PARSER& aReader ) +ADIMENSION6::ADIMENSION6( ALTIUM_BINARY_PARSER& aReader ) { aReader.Skip( 2 ); @@ -386,38 +387,38 @@ ADIMENSION6::ADIMENSION6( ALTIUM_PARSER& aReader ) if( props.empty() ) THROW_IO_ERROR( wxT( "Dimensions6 stream has no props" ) ); - layer = altium_layer_from_name( ALTIUM_PARSER::ReadString( props, wxT( "LAYER" ), wxT( "" ) ) ); - kind = static_cast( ALTIUM_PARSER::ReadInt( props, wxT( "DIMENSIONKIND" ), 0 ) ); + layer = altium_layer_from_name( ALTIUM_PROPS_UTILS::ReadString( props, wxT( "LAYER" ), wxT( "" ) ) ); + kind = static_cast( ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "DIMENSIONKIND" ), 0 ) ); - textformat = ALTIUM_PARSER::ReadString( props, wxT( "TEXTFORMAT" ), wxT( "" ) ); - textprefix = ALTIUM_PARSER::ReadString( props, wxT( "TEXTPREFIX" ), wxT( "" ) ); - textsuffix = ALTIUM_PARSER::ReadString( props, wxT( "TEXTSUFFIX" ), wxT( "" ) ); + textformat = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "TEXTFORMAT" ), wxT( "" ) ); + textprefix = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "TEXTPREFIX" ), wxT( "" ) ); + textsuffix = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "TEXTSUFFIX" ), wxT( "" ) ); - height = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "HEIGHT" ), wxT( "0mil" ) ); - angle = ALTIUM_PARSER::ReadDouble( props, wxT( "ANGLE" ), 0. ); + height = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "HEIGHT" ), wxT( "0mil" ) ); + angle = ALTIUM_PROPS_UTILS::ReadDouble( props, wxT( "ANGLE" ), 0. ); - linewidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "LINEWIDTH" ), wxT( "10mil" ) ); - textheight = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "TEXTHEIGHT" ), wxT( "10mil" ) ); - textlinewidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "TEXTLINEWIDTH" ), wxT( "6mil" ) ); - textprecision = ALTIUM_PARSER::ReadInt( props, wxT( "TEXTPRECISION" ), 2 ); - textbold = ALTIUM_PARSER::ReadBool( props, wxT( "TEXTLINEWIDTH" ), false ); - textitalic = ALTIUM_PARSER::ReadBool( props, wxT( "ITALIC" ), false ); - textgap = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "TEXTGAP" ), wxT( "10mil" ) ); + linewidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "LINEWIDTH" ), wxT( "10mil" ) ); + textheight = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "TEXTHEIGHT" ), wxT( "10mil" ) ); + textlinewidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "TEXTLINEWIDTH" ), wxT( "6mil" ) ); + textprecision = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "TEXTPRECISION" ), 2 ); + textbold = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "TEXTLINEWIDTH" ), false ); + textitalic = ALTIUM_PROPS_UTILS::ReadBool( props, wxT( "ITALIC" ), false ); + textgap = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "TEXTGAP" ), wxT( "10mil" ) ); - arrowsize = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "ARROWSIZE" ), wxT( "60mil" ) ); + arrowsize = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "ARROWSIZE" ), wxT( "60mil" ) ); - wxString text_position_raw = ALTIUM_PARSER::ReadString( props, wxT( "TEXTPOSITION" ), wxT( "" ) ); + wxString text_position_raw = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "TEXTPOSITION" ), wxT( "" ) ); - xy1 = VECTOR2I( ALTIUM_PARSER::ReadKicadUnit( props, wxT( "X1" ), wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( props, wxT( "Y1" ), wxT( "0mil" ) ) ); + xy1 = VECTOR2I( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "X1" ), wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "Y1" ), wxT( "0mil" ) ) ); - int refcount = ALTIUM_PARSER::ReadInt( props, wxT( "REFERENCES_COUNT" ), 0 ); + int refcount = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "REFERENCES_COUNT" ), 0 ); for( int i = 0; i < refcount; i++ ) { const std::string refi = "REFERENCE" + std::to_string( i ) + "POINT"; - referencePoint.emplace_back( ALTIUM_PARSER::ReadKicadUnit( props, refi + wxT( "X" ), wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( props, refi + wxT( "Y" ), wxT( "0mil" ) ) ); + referencePoint.emplace_back( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, refi + wxT( "X" ), wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( props, refi + wxT( "Y" ), wxT( "0mil" ) ) ); } for( size_t i = 1; i < std::numeric_limits::max(); i++ ) @@ -429,11 +430,11 @@ ADIMENSION6::ADIMENSION6( ALTIUM_PARSER& aReader ) if( props.find( textix ) == props.end() || props.find( textiy ) == props.end() ) break; // it doesn't seem like we know beforehand how many vertices are inside a polygon - textPoint.emplace_back( ALTIUM_PARSER::ReadKicadUnit( props, textix, wxT( "0mil" ) ), - -ALTIUM_PARSER::ReadKicadUnit( props, textiy, wxT( "0mil" ) ) ); + textPoint.emplace_back( ALTIUM_PROPS_UTILS::ReadKicadUnit( props, textix, wxT( "0mil" ) ), + -ALTIUM_PROPS_UTILS::ReadKicadUnit( props, textiy, wxT( "0mil" ) ) ); } - wxString dimensionunit = ALTIUM_PARSER::ReadString( props, wxT( "TEXTDIMENSIONUNIT" ), wxT( "Millimeters" ) ); + wxString dimensionunit = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "TEXTDIMENSIONUNIT" ), wxT( "Millimeters" ) ); if( dimensionunit == wxT( "Inches" ) ) textunit = ALTIUM_UNIT::INCHES; else if( dimensionunit == wxT( "Mils" ) ) textunit = ALTIUM_UNIT::MILS; @@ -445,59 +446,59 @@ ADIMENSION6::ADIMENSION6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Dimensions6 stream was not parsed correctly" ) ); } -AMODEL::AMODEL( ALTIUM_PARSER& aReader ) +AMODEL::AMODEL( ALTIUM_BINARY_PARSER& aReader ) { std::map properties = aReader.ReadProperties(); if( properties.empty() ) THROW_IO_ERROR( wxT( "Model stream has no properties!" ) ); - name = ALTIUM_PARSER::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); - id = ALTIUM_PARSER::ReadString( properties, wxT( "ID" ), wxT( "" ) ); - isEmbedded = ALTIUM_PARSER::ReadBool( properties, wxT( "EMBED" ), false ); + name = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); + id = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "ID" ), wxT( "" ) ); + isEmbedded = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "EMBED" ), false ); - rotation.x = ALTIUM_PARSER::ReadDouble( properties, wxT( "ROTX" ), 0. ); - rotation.y = ALTIUM_PARSER::ReadDouble( properties, wxT( "ROTY" ), 0. ); - rotation.z = ALTIUM_PARSER::ReadDouble( properties, wxT( "ROTZ" ), 0. ); + rotation.x = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "ROTX" ), 0. ); + rotation.y = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "ROTY" ), 0. ); + rotation.z = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "ROTZ" ), 0. ); if( aReader.HasParsingError() ) THROW_IO_ERROR( wxT( "Model stream was not parsed correctly" ) ); } -ANET6::ANET6( ALTIUM_PARSER& aReader ) +ANET6::ANET6( ALTIUM_BINARY_PARSER& aReader ) { std::map properties = aReader.ReadProperties(); if( properties.empty() ) THROW_IO_ERROR( wxT( "Nets6 stream has no properties" ) ); - name = ALTIUM_PARSER::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); + name = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "NAME" ), wxT( "" ) ); if( aReader.HasParsingError() ) THROW_IO_ERROR( wxT( "Nets6 stream was not parsed correctly" ) ); } -APOLYGON6::APOLYGON6( ALTIUM_PARSER& aReader ) +APOLYGON6::APOLYGON6( ALTIUM_BINARY_PARSER& aReader ) { std::map properties = aReader.ReadProperties(); if( properties.empty() ) THROW_IO_ERROR( wxT( "Polygons6 stream has no properties" ) ); - layer = altium_layer_from_name( ALTIUM_PARSER::ReadString( properties, wxT( "LAYER" ), wxT( "" ) ) ); - net = ALTIUM_PARSER::ReadInt( properties, wxT( "NET" ), ALTIUM_NET_UNCONNECTED ); - locked = ALTIUM_PARSER::ReadBool( properties, wxT( "LOCKED" ), false ); + layer = altium_layer_from_name( ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "LAYER" ), wxT( "" ) ) ); + net = ALTIUM_PROPS_UTILS::ReadInt( properties, wxT( "NET" ), ALTIUM_NET_UNCONNECTED ); + locked = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "LOCKED" ), false ); // TODO: kind - gridsize = ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "GRIDSIZE" ), wxT( "0mil" ) ); - trackwidth = ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "TRACKWIDTH" ), wxT( "0mil" ) ); - minprimlength = ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "MINPRIMLENGTH" ), wxT( "0mil" ) ); - useoctagons = ALTIUM_PARSER::ReadBool( properties, wxT( "USEOCTAGONS" ), false ); + gridsize = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "GRIDSIZE" ), wxT( "0mil" ) ); + trackwidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "TRACKWIDTH" ), wxT( "0mil" ) ); + minprimlength = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "MINPRIMLENGTH" ), wxT( "0mil" ) ); + useoctagons = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "USEOCTAGONS" ), false ); - pourindex = ALTIUM_PARSER::ReadInt( properties, wxT( "POURINDEX" ), 0 ); + pourindex = ALTIUM_PROPS_UTILS::ReadInt( properties, wxT( "POURINDEX" ), 0 ); - wxString hatchstyleraw = ALTIUM_PARSER::ReadString( properties, wxT( "HATCHSTYLE" ), wxT( "" ) ); + wxString hatchstyleraw = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "HATCHSTYLE" ), wxT( "" ) ); if( hatchstyleraw == wxT( "Solid" ) ) hatchstyle = ALTIUM_POLYGON_HATCHSTYLE::SOLID; else if( hatchstyleraw == wxT( "45Degree" ) ) hatchstyle = ALTIUM_POLYGON_HATCHSTYLE::DEGREE_45; @@ -513,7 +514,7 @@ APOLYGON6::APOLYGON6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Polygons6 stream was not parsed correctly" ) ); } -ARULE6::ARULE6( ALTIUM_PARSER& aReader ) +ARULE6::ARULE6( ALTIUM_BINARY_PARSER& aReader ) { // Initialize all variables and make Coverity happy minLimit = 0; @@ -535,17 +536,17 @@ ARULE6::ARULE6( ALTIUM_PARSER& aReader ) if( props.empty() ) THROW_IO_ERROR( wxT( "Rules6 stream has no props" ) ); - name = ALTIUM_PARSER::ReadString( props, wxT( "NAME" ), wxT( "" ) ); - priority = ALTIUM_PARSER::ReadInt( props, wxT( "PRIORITY" ), 1 ); + name = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "NAME" ), wxT( "" ) ); + priority = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "PRIORITY" ), 1 ); - scope1expr = ALTIUM_PARSER::ReadString( props, wxT( "SCOPE1EXPRESSION" ), wxT( "" ) ); - scope2expr = ALTIUM_PARSER::ReadString( props, wxT( "SCOPE2EXPRESSION" ), wxT( "" ) ); + scope1expr = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SCOPE1EXPRESSION" ), wxT( "" ) ); + scope2expr = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "SCOPE2EXPRESSION" ), wxT( "" ) ); - wxString rulekind = ALTIUM_PARSER::ReadString( props, wxT( "RULEKIND" ), wxT( "" ) ); + wxString rulekind = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "RULEKIND" ), wxT( "" ) ); if( rulekind == wxT( "Clearance" ) ) { kind = ALTIUM_RULE_KIND::CLEARANCE; - clearanceGap = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "GAP" ), wxT( "10mil" ) ); + clearanceGap = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "GAP" ), wxT( "10mil" ) ); } else if( rulekind == wxT( "DiffPairsRouting" ) ) { @@ -558,54 +559,54 @@ ARULE6::ARULE6( ALTIUM_PARSER& aReader ) else if( rulekind == wxT( "HoleSize" ) ) { kind = ALTIUM_RULE_KIND::HOLE_SIZE; - minLimit = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MINLIMIT" ), wxT( "1mil" ) ); - maxLimit = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MAXLIMIT" ), wxT( "150mil" ) ); + minLimit = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MINLIMIT" ), wxT( "1mil" ) ); + maxLimit = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MAXLIMIT" ), wxT( "150mil" ) ); } else if( rulekind == wxT( "HoleToHoleClearance" ) ) { kind = ALTIUM_RULE_KIND::HOLE_TO_HOLE_CLEARANCE; - clearanceGap = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "GAP" ), wxT( "10mil" ) ); + clearanceGap = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "GAP" ), wxT( "10mil" ) ); } else if( rulekind == wxT( "RoutingVias" ) ) { kind = ALTIUM_RULE_KIND::ROUTING_VIAS; - width = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "WIDTH" ), wxT( "20mil" ) ); - minWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MINWIDTH" ), wxT( "20mil" ) ); - maxWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MAXWIDTH" ), wxT( "50mil" ) ); - holeWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "HOLEWIDTH" ), wxT( "10mil" ) ); - minHoleWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MINHOLEWIDTH" ), wxT( "10mil" ) ); - maxHoleWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MAXHOLEWIDTH" ), wxT( "28mil" ) ); + width = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "WIDTH" ), wxT( "20mil" ) ); + minWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MINWIDTH" ), wxT( "20mil" ) ); + maxWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MAXWIDTH" ), wxT( "50mil" ) ); + holeWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "HOLEWIDTH" ), wxT( "10mil" ) ); + minHoleWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MINHOLEWIDTH" ), wxT( "10mil" ) ); + maxHoleWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MAXHOLEWIDTH" ), wxT( "28mil" ) ); } else if( rulekind == wxT( "Width" ) ) { kind = ALTIUM_RULE_KIND::WIDTH; - minLimit = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MINLIMIT" ), wxT( "6mil" ) ); - maxLimit = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "MAXLIMIT" ), wxT( "40mil" ) ); - preferredWidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "PREFERREDWIDTH" ), wxT( "6mil" ) ); + minLimit = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MINLIMIT" ), wxT( "6mil" ) ); + maxLimit = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "MAXLIMIT" ), wxT( "40mil" ) ); + preferredWidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "PREFERREDWIDTH" ), wxT( "6mil" ) ); } else if( rulekind == wxT( "PasteMaskExpansion" ) ) { kind = ALTIUM_RULE_KIND::PASTE_MASK_EXPANSION; - pastemaskExpansion = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "EXPANSION" ), wxT( "0" ) ); + pastemaskExpansion = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "EXPANSION" ), wxT( "0" ) ); } else if( rulekind == wxT( "SolderMaskExpansion" ) ) { kind = ALTIUM_RULE_KIND::SOLDER_MASK_EXPANSION; - soldermaskExpansion = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "EXPANSION" ), wxT( "4mil" ) ); + soldermaskExpansion = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "EXPANSION" ), wxT( "4mil" ) ); } else if( rulekind == wxT( "PlaneClearance" ) ) { kind = ALTIUM_RULE_KIND::PLANE_CLEARANCE; - planeclearanceClearance = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "CLEARANCE" ), wxT( "10mil" ) ); + planeclearanceClearance = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "CLEARANCE" ), wxT( "10mil" ) ); } else if( rulekind == wxT( "PolygonConnect" ) ) { kind = ALTIUM_RULE_KIND::POLYGON_CONNECT; - polygonconnectAirgapwidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "AIRGAPWIDTH" ), wxT( "10mil" ) ); - polygonconnectReliefconductorwidth = ALTIUM_PARSER::ReadKicadUnit( props, wxT( "RELIEFCONDUCTORWIDTH" ), wxT( "10mil" ) ); - polygonconnectReliefentries = ALTIUM_PARSER::ReadInt( props, wxT( "RELIEFENTRIES" ), 4 ); + polygonconnectAirgapwidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "AIRGAPWIDTH" ), wxT( "10mil" ) ); + polygonconnectReliefconductorwidth = ALTIUM_PROPS_UTILS::ReadKicadUnit( props, wxT( "RELIEFCONDUCTORWIDTH" ), wxT( "10mil" ) ); + polygonconnectReliefentries = ALTIUM_PROPS_UTILS::ReadInt( props, wxT( "RELIEFENTRIES" ), 4 ); - wxString style = ALTIUM_PARSER::ReadString( props, wxT( "CONNECTSTYLE" ), wxT( "" ) ); + wxString style = ALTIUM_PROPS_UTILS::ReadString( props, wxT( "CONNECTSTYLE" ), wxT( "" ) ); if( style == wxT( "Direct" ) ) polygonconnectStyle = ALTIUM_CONNECT_STYLE::DIRECT; else if( style == wxT( "Relief" ) ) polygonconnectStyle = ALTIUM_CONNECT_STYLE::RELIEF; @@ -621,7 +622,7 @@ ARULE6::ARULE6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Rules6 stream was not parsed correctly" ) ); } -AARC6::AARC6( ALTIUM_PARSER& aReader ) +AARC6::AARC6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); if( recordtype != ALTIUM_RECORD::ARC ) @@ -670,7 +671,7 @@ AARC6::AARC6( ALTIUM_PARSER& aReader ) } } -ACOMPONENTBODY6::ACOMPONENTBODY6( ALTIUM_PARSER& aReader ) +ACOMPONENTBODY6::ACOMPONENTBODY6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -688,21 +689,21 @@ ACOMPONENTBODY6::ACOMPONENTBODY6( ALTIUM_PARSER& aReader ) if( properties.empty() ) THROW_IO_ERROR( wxT( "ComponentsBodies6 stream has no properties" ) ); - modelName = ALTIUM_PARSER::ReadString( properties, wxT( "MODEL.NAME" ), wxT( "" ) ); - modelId = ALTIUM_PARSER::ReadString( properties, wxT( "MODELID" ), wxT( "" ) ); - modelIsEmbedded = ALTIUM_PARSER::ReadBool( properties, wxT( "MODEL.EMBED" ), false ); + modelName = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "MODEL.NAME" ), wxT( "" ) ); + modelId = ALTIUM_PROPS_UTILS::ReadString( properties, wxT( "MODELID" ), wxT( "" ) ); + modelIsEmbedded = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "MODEL.EMBED" ), false ); - modelPosition.x = ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "MODEL.2D.X" ), wxT( "0mil" ) ); - modelPosition.y = -ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "MODEL.2D.Y" ), wxT( "0mil" ) ); - modelPosition.z = ALTIUM_PARSER::ReadKicadUnit( properties, wxT( "MODEL.3D.DZ" ), wxT( "0mil" ) ); + modelPosition.x = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "MODEL.2D.X" ), wxT( "0mil" ) ); + modelPosition.y = -ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "MODEL.2D.Y" ), wxT( "0mil" ) ); + modelPosition.z = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, wxT( "MODEL.3D.DZ" ), wxT( "0mil" ) ); - modelRotation.x = ALTIUM_PARSER::ReadDouble( properties, wxT( "MODEL.3D.ROTX" ), 0. ); - modelRotation.y = ALTIUM_PARSER::ReadDouble( properties, wxT( "MODEL.3D.ROTY" ), 0. ); - modelRotation.z = ALTIUM_PARSER::ReadDouble( properties, wxT( "MODEL.3D.ROTZ" ), 0. ); + modelRotation.x = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "MODEL.3D.ROTX" ), 0. ); + modelRotation.y = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "MODEL.3D.ROTY" ), 0. ); + modelRotation.z = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "MODEL.3D.ROTZ" ), 0. ); - rotation = ALTIUM_PARSER::ReadDouble( properties, wxT( "MODEL.2D.ROTATION" ), 0. ); + rotation = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "MODEL.2D.ROTATION" ), 0. ); - bodyOpacity = ALTIUM_PARSER::ReadDouble( properties, wxT( "BODYOPACITY3D" ), 1. ); + bodyOpacity = ALTIUM_PROPS_UTILS::ReadDouble( properties, wxT( "BODYOPACITY3D" ), 1. ); aReader.SkipSubrecord(); @@ -710,7 +711,7 @@ ACOMPONENTBODY6::ACOMPONENTBODY6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Components6 stream was not parsed correctly" ) ); } -APAD6::APAD6( ALTIUM_PARSER& aReader ) +APAD6::APAD6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -870,7 +871,7 @@ APAD6::APAD6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Pads6 stream was not parsed correctly" ) ); } -AVIA6::AVIA6( ALTIUM_PARSER& aReader ) +AVIA6::AVIA6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -916,7 +917,7 @@ AVIA6::AVIA6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Vias6 stream was not parsed correctly" ) ); } -ATRACK6::ATRACK6( ALTIUM_PARSER& aReader ) +ATRACK6::ATRACK6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -960,7 +961,7 @@ ATRACK6::ATRACK6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Tracks6 stream was not parsed correctly" ) ); } -ATEXT6::ATEXT6( ALTIUM_PARSER& aReader, std::map& aStringTable ) +ATEXT6::ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map& aStringTable ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -1026,7 +1027,7 @@ ATEXT6::ATEXT6( ALTIUM_PARSER& aReader, std::map& aStringTab THROW_IO_ERROR( wxT( "Texts6 stream was not parsed correctly" ) ); } -AFILL6::AFILL6( ALTIUM_PARSER& aReader ) +AFILL6::AFILL6( ALTIUM_BINARY_PARSER& aReader ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -1068,7 +1069,7 @@ AFILL6::AFILL6( ALTIUM_PARSER& aReader ) THROW_IO_ERROR( wxT( "Fills6 stream was not parsed correctly" ) ); } -AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ) +AREGION6::AREGION6( ALTIUM_BINARY_PARSER& aReader, bool aExtendedVertices ) { ALTIUM_RECORD recordtype = static_cast( aReader.Read() ); @@ -1098,17 +1099,17 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ) if( properties.empty() ) THROW_IO_ERROR( wxT( "Regions6 stream has empty properties" ) ); - int pkind = ALTIUM_PARSER::ReadInt( properties, wxT( "KIND" ), 0 ); - bool is_cutout = ALTIUM_PARSER::ReadBool( properties, wxT( "ISBOARDCUTOUT" ), false ); + int pkind = ALTIUM_PROPS_UTILS::ReadInt( properties, wxT( "KIND" ), 0 ); + bool is_cutout = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "ISBOARDCUTOUT" ), false ); - is_shapebased = ALTIUM_PARSER::ReadBool( properties, wxT( "ISSHAPEBASED" ), false ); + is_shapebased = ALTIUM_PROPS_UTILS::ReadBool( properties, wxT( "ISSHAPEBASED" ), false ); keepoutrestrictions = static_cast( - ALTIUM_PARSER::ReadInt( properties, wxT( "KEEPOUTRESTRIC" ), 0x1F ) ); + ALTIUM_PROPS_UTILS::ReadInt( properties, wxT( "KEEPOUTRESTRIC" ), 0x1F ) ); // TODO: this can differ from the other subpolyindex?! // Note: "the other subpolyindex" is "polygon" subpolyindex = static_cast( - ALTIUM_PARSER::ReadInt( properties, "SUBPOLYINDEX", ALTIUM_POLYGON_NONE ) ); + ALTIUM_PROPS_UTILS::ReadInt( properties, "SUBPOLYINDEX", ALTIUM_POLYGON_NONE ) ); switch( pkind ) { @@ -1159,8 +1160,8 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ) else { // For some regions the coordinates are stored as double and not as int32_t - int32_t x = ALTIUM_PARSER::ConvertToKicadUnit( aReader.Read() ); - int32_t y = ALTIUM_PARSER::ConvertToKicadUnit( -aReader.Read() ); + int32_t x = ALTIUM_PROPS_UTILS::ConvertToKicadUnit( aReader.Read() ); + int32_t y = ALTIUM_PROPS_UTILS::ConvertToKicadUnit( -aReader.Read() ); outline.emplace_back( VECTOR2I( x, y ) ); } } @@ -1173,8 +1174,8 @@ AREGION6::AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ) for( uint32_t i = 0; i < num_hole_vertices; i++ ) { - int32_t x = ALTIUM_PARSER::ConvertToKicadUnit( aReader.Read() ); - int32_t y = ALTIUM_PARSER::ConvertToKicadUnit( -aReader.Read() ); + int32_t x = ALTIUM_PROPS_UTILS::ConvertToKicadUnit( aReader.Read() ); + int32_t y = ALTIUM_PROPS_UTILS::ConvertToKicadUnit( -aReader.Read() ); holes.at( k ).emplace_back( VECTOR2I( x, y ) ); } } diff --git a/pcbnew/pcb_io/altium/altium_parser_pcb.h b/pcbnew/pcb_io/altium/altium_parser_pcb.h index 2e60368226..dbc30fdd20 100644 --- a/pcbnew/pcb_io/altium/altium_parser_pcb.h +++ b/pcbnew/pcb_io/altium/altium_parser_pcb.h @@ -335,7 +335,7 @@ enum class ALTIUM_LAYER VIA_HOLES = 82, }; -class ALTIUM_PARSER; +class ALTIUM_BINARY_PARSER; enum class AEXTENDED_PRIMITIVE_INFORMATION_TYPE { @@ -357,7 +357,7 @@ struct AEXTENDED_PRIMITIVE_INFORMATION ALTIUM_MODE soldermaskexpansionmode; int32_t soldermaskexpansionmanual; - explicit AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_PARSER& aReader ); + explicit AEXTENDED_PRIMITIVE_INFORMATION( ALTIUM_BINARY_PARSER& aReader ); }; struct ABOARD6_LAYER_STACKUP @@ -385,7 +385,7 @@ struct ABOARD6 std::vector board_vertices; - explicit ABOARD6( ALTIUM_PARSER& aReader ); + explicit ABOARD6( ALTIUM_BINARY_PARSER& aReader ); }; struct ACLASS6 @@ -397,7 +397,7 @@ struct ACLASS6 std::vector names; - explicit ACLASS6( ALTIUM_PARSER& aReader ); + explicit ACLASS6( ALTIUM_BINARY_PARSER& aReader ); }; struct ACOMPONENT6 @@ -417,7 +417,7 @@ struct ACOMPONENT6 ALTIUM_TEXT_POSITION nameautoposition; ALTIUM_TEXT_POSITION commentautoposition; - explicit ACOMPONENT6( ALTIUM_PARSER& aReader ); + explicit ACOMPONENT6( ALTIUM_BINARY_PARSER& aReader ); }; struct ADIMENSION6 @@ -449,7 +449,7 @@ struct ADIMENSION6 std::vector referencePoint; std::vector textPoint; - explicit ADIMENSION6( ALTIUM_PARSER& aReader ); + explicit ADIMENSION6( ALTIUM_BINARY_PARSER& aReader ); }; struct AMODEL @@ -460,14 +460,14 @@ struct AMODEL VECTOR3D rotation; - explicit AMODEL( ALTIUM_PARSER& aReader ); + explicit AMODEL( ALTIUM_BINARY_PARSER& aReader ); }; struct ANET6 { wxString name; - explicit ANET6( ALTIUM_PARSER& aReader ); + explicit ANET6( ALTIUM_BINARY_PARSER& aReader ); }; struct APOLYGON6 @@ -488,7 +488,7 @@ struct APOLYGON6 std::vector vertices; - explicit APOLYGON6( ALTIUM_PARSER& aReader ); + explicit APOLYGON6( ALTIUM_BINARY_PARSER& aReader ); }; @@ -539,7 +539,7 @@ struct ARULE6 // TODO: implement different types of rules we need to parse - explicit ARULE6( ALTIUM_PARSER& aReader ); + explicit ARULE6( ALTIUM_BINARY_PARSER& aReader ); }; struct AREGION6 @@ -562,7 +562,7 @@ struct AREGION6 std::vector outline; std::vector> holes; - explicit AREGION6( ALTIUM_PARSER& aReader, bool aExtendedVertices ); + explicit AREGION6( ALTIUM_BINARY_PARSER& aReader, bool aExtendedVertices ); }; struct AARC6 @@ -584,7 +584,7 @@ struct AARC6 double endangle; uint32_t width; - explicit AARC6( ALTIUM_PARSER& aReader ); + explicit AARC6( ALTIUM_BINARY_PARSER& aReader ); }; struct ACOMPONENTBODY6 @@ -600,7 +600,7 @@ struct ACOMPONENTBODY6 double rotation; double bodyOpacity; - explicit ACOMPONENTBODY6( ALTIUM_PARSER& aReader ); + explicit ACOMPONENTBODY6( ALTIUM_BINARY_PARSER& aReader ); }; struct APAD6_SIZE_AND_SHAPE @@ -655,7 +655,7 @@ struct APAD6 std::unique_ptr sizeAndShape; - explicit APAD6( ALTIUM_PARSER& aReader ); + explicit APAD6( ALTIUM_BINARY_PARSER& aReader ); }; struct AVIA6 @@ -676,7 +676,7 @@ struct AVIA6 ALTIUM_LAYER layer_end; ALTIUM_PAD_MODE viamode; - explicit AVIA6( ALTIUM_PARSER& aReader ); + explicit AVIA6( ALTIUM_BINARY_PARSER& aReader ); }; struct ATRACK6 @@ -696,7 +696,7 @@ struct ATRACK6 VECTOR2I end; uint32_t width; - explicit ATRACK6( ALTIUM_PARSER& aReader ); + explicit ATRACK6( ALTIUM_BINARY_PARSER& aReader ); }; struct ATEXT6 @@ -723,7 +723,7 @@ struct ATEXT6 wxString text; - explicit ATEXT6( ALTIUM_PARSER& aReader, std::map& aStringTable ); + explicit ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map& aStringTable ); }; struct AFILL6 @@ -740,7 +740,7 @@ struct AFILL6 VECTOR2I pos2; double rotation; - explicit AFILL6( ALTIUM_PARSER& aReader ); + explicit AFILL6( ALTIUM_BINARY_PARSER& aReader ); }; diff --git a/pcbnew/pcb_io/altium/altium_pcb.cpp b/pcbnew/pcb_io/altium/altium_pcb.cpp index 3df7658e86..0441f5d9b2 100644 --- a/pcbnew/pcb_io/altium/altium_pcb.cpp +++ b/pcbnew/pcb_io/altium/altium_pcb.cpp @@ -24,7 +24,7 @@ #include "altium_pcb.h" #include "altium_parser_pcb.h" -#include "io/altium/altium_parser.h" +#include #include #include @@ -435,8 +435,8 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi if( file == nullptr ) continue; - ALTIUM_PARSER reader( altiumPcbFile, file ); - uint32_t numOfRecords = reader.Read(); + ALTIUM_BINARY_PARSER reader( altiumPcbFile, file ); + uint32_t numOfRecords = reader.Read(); if( reader.HasParsingError() ) { @@ -663,7 +663,7 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( ALTIUM_COMPOUND_FILE& altiumLibFile, FormatPath( streamName ) ) ); } - ALTIUM_PARSER parser( altiumLibFile, footprintData ); + ALTIUM_BINARY_PARSER parser( altiumLibFile, footprintData ); parser.ReadAndSetSubrecordLength(); //wxString footprintName = parser.ReadWxString(); // Not used (single-byte char set) @@ -679,11 +679,10 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( ALTIUM_COMPOUND_FILE& altiumLibFile, if( parametersData != nullptr ) { - ALTIUM_PARSER parametersReader( altiumLibFile, parametersData ); + ALTIUM_BINARY_PARSER parametersReader( altiumLibFile, parametersData ); std::map parameterProperties = parametersReader.ReadProperties(); - wxString description = ALTIUM_PARSER::ReadString( parameterProperties, - wxT( "DESCRIPTION" ), - wxT( "" ) ); + wxString description = ALTIUM_PROPS_UTILS::ReadString( parameterProperties, + wxT( "DESCRIPTION" ), wxT( "" ) ); footprint->SetLibDescription( description ); } else @@ -845,7 +844,7 @@ const ARULE6* ALTIUM_PCB::GetRuleDefault( ALTIUM_RULE_KIND aKind ) const void ALTIUM_PCB::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, const CFB::COMPOUND_FILE_ENTRY* aEntry ) { - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); reader.ReadAndSetSubrecordLength(); wxString header = reader.ReadWxString(); @@ -865,7 +864,7 @@ void ALTIUM_PCB::ParseExtendedPrimitiveInformationData( const ALTIUM_COMPOUND_FI if( m_progressReporter ) m_progressReporter->Report( _( "Loading extended primitive information data..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -886,7 +885,7 @@ void ALTIUM_PCB::ParseBoard6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile if( m_progressReporter ) m_progressReporter->Report( _( "Loading board data..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); checkpoint(); ABOARD6 elem( reader ); @@ -1066,7 +1065,7 @@ void ALTIUM_PCB::ParseClasses6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFi if( m_progressReporter ) m_progressReporter->Report( _( "Loading netclasses..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1112,7 +1111,7 @@ void ALTIUM_PCB::ParseComponents6Data( const ALTIUM_COMPOUND_FILE& aAltiumPc if( m_progressReporter ) m_progressReporter->Report( _( "Loading components..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); uint16_t componentId = 0; @@ -1173,7 +1172,7 @@ void ALTIUM_PCB::ParseComponentsBodies6Data( const ALTIUM_COMPOUND_FILE& aAl if( m_progressReporter ) m_progressReporter->Report( _( "Loading component 3D models..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1554,7 +1553,7 @@ void ALTIUM_PCB::ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPc if( m_progressReporter ) m_progressReporter->Report( _( "Loading dimension drawings..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1597,7 +1596,7 @@ void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile if( m_progressReporter ) m_progressReporter->Report( _( "Loading 3D models..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); if( reader.GetRemainingBytes() == 0 ) return; @@ -1690,7 +1689,7 @@ void ALTIUM_PCB::ParseNets6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, if( m_progressReporter ) m_progressReporter->Report( _( "Loading nets..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); wxASSERT( m_altiumToKicadNetcodes.empty() ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) @@ -1714,7 +1713,7 @@ void ALTIUM_PCB::ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbF if( m_progressReporter ) m_progressReporter->Report( _( "Loading polygons..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1860,7 +1859,7 @@ void ALTIUM_PCB::ParseRules6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile if( m_progressReporter ) m_progressReporter->Report( _( "Loading rules..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1928,7 +1927,7 @@ void ALTIUM_PCB::ParseBoardRegionsData( const ALTIUM_COMPOUND_FILE& aAltiumP if( m_progressReporter ) m_progressReporter->Report( _( "Loading board regions..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -1948,7 +1947,7 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data( const ALTIUM_COMPOUND_FILE& aA if( m_progressReporter ) m_progressReporter->Report( _( "Loading polygons..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); /* TODO: use Header section of file */ for( int primitiveIndex = 0; reader.GetRemainingBytes() >= 4; primitiveIndex++ ) @@ -2351,7 +2350,7 @@ void ALTIUM_PCB::ParseRegions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFi if( m_progressReporter ) m_progressReporter->Report( _( "Loading zone fills..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -2426,7 +2425,7 @@ void ALTIUM_PCB::ParseArcs6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, if( m_progressReporter ) m_progressReporter->Report( _( "Loading arcs..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); for( int primitiveIndex = 0; reader.GetRemainingBytes() >= 4; primitiveIndex++ ) { @@ -2669,7 +2668,7 @@ void ALTIUM_PCB::ParsePads6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, if( m_progressReporter ) m_progressReporter->Report( _( "Loading pads..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -3213,7 +3212,7 @@ void ALTIUM_PCB::ParseVias6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, if( m_progressReporter ) m_progressReporter->Report( _( "Loading vias..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -3273,7 +3272,7 @@ void ALTIUM_PCB::ParseTracks6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFil if( m_progressReporter ) m_progressReporter->Report( _( "Loading tracks..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); for( int primitiveIndex = 0; reader.GetRemainingBytes() >= 4; primitiveIndex++ ) { @@ -3481,7 +3480,7 @@ void ALTIUM_PCB::ParseWideStrings6Data( const ALTIUM_COMPOUND_FILE& aAltiumP if( m_progressReporter ) m_progressReporter->Report( _( "Loading unicode strings..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); m_unicodeStrings = reader.ReadWideStringTable(); @@ -3495,7 +3494,7 @@ void ALTIUM_PCB::ParseTexts6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile if( m_progressReporter ) m_progressReporter->Report( _( "Loading text..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { @@ -3657,7 +3656,7 @@ void ALTIUM_PCB::ParseFills6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile if( m_progressReporter ) m_progressReporter->Report( _( "Loading rectangles..." ) ); - ALTIUM_PARSER reader( aAltiumPcbFile, aEntry ); + ALTIUM_BINARY_PARSER reader( aAltiumPcbFile, aEntry ); while( reader.GetRemainingBytes() >= 4 /* TODO: use Header section of file */ ) { diff --git a/pcbnew/pcb_io/altium/pcb_io_altium_circuit_maker.cpp b/pcbnew/pcb_io/altium/pcb_io_altium_circuit_maker.cpp index eb339bcaa7..00df3a641f 100644 --- a/pcbnew/pcb_io/altium/pcb_io_altium_circuit_maker.cpp +++ b/pcbnew/pcb_io/altium/pcb_io_altium_circuit_maker.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/pcbnew/pcb_io/altium/pcb_io_altium_circuit_studio.cpp b/pcbnew/pcb_io/altium/pcb_io_altium_circuit_studio.cpp index fff15cdcea..3685e9897f 100644 --- a/pcbnew/pcb_io/altium/pcb_io_altium_circuit_studio.cpp +++ b/pcbnew/pcb_io/altium/pcb_io_altium_circuit_studio.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp b/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp index a74a25b7bc..42992b72e8 100644 --- a/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp +++ b/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include @@ -209,7 +209,7 @@ void PCB_IO_ALTIUM_DESIGNER::FootprintEnumerate( wxArrayString& aFootprintNames FormatPath( streamName ) ) ); } - ALTIUM_PARSER parser( *altiumLibFile, libraryData ); + ALTIUM_BINARY_PARSER parser( *altiumLibFile, libraryData ); std::map properties = parser.ReadProperties(); diff --git a/pcbnew/pcb_io/altium/pcb_io_solidworks.cpp b/pcbnew/pcb_io/altium/pcb_io_solidworks.cpp index b4906b7274..44c42413c0 100644 --- a/pcbnew/pcb_io/altium/pcb_io_solidworks.cpp +++ b/pcbnew/pcb_io/altium/pcb_io_solidworks.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/qa/tests/common/io/altium/test_altium_parser.cpp b/qa/tests/common/io/altium/test_altium_parser.cpp index fb98a9dfb4..a9b333350e 100644 --- a/qa/tests/common/io/altium/test_altium_parser.cpp +++ b/qa/tests/common/io/altium/test_altium_parser.cpp @@ -23,23 +23,23 @@ /** * @file test_altium_parser.cpp - * Test suite for #ALTIUM_PARSER + * Test suite for #ALTIUM_BINARY_PARSER */ #include -#include +#include -struct ALTIUM_PARSER_FIXTURE +struct ALTIUM_BINARY_PARSER_FIXTURE { - ALTIUM_PARSER_FIXTURE() {} + ALTIUM_BINARY_PARSER_FIXTURE() {} }; /** * Declares the struct as the Boost test fixture. */ -BOOST_FIXTURE_TEST_SUITE( AltiumParser, ALTIUM_PARSER_FIXTURE ) +BOOST_FIXTURE_TEST_SUITE( AltiumParser, ALTIUM_BINARY_PARSER_FIXTURE ) struct ALTIUM_TO_KICAD_UNIT_CASE { @@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE( ConvertToKicadUnit ) { BOOST_TEST_CONTEXT( wxString::Format( wxT( "%i -> %i" ), c.input, c.exp_result ) ) { - int result = ALTIUM_PARSER::ConvertToKicadUnit( c.input ); + int result = ALTIUM_PROPS_UTILS::ConvertToKicadUnit( c.input ); // These are all valid BOOST_CHECK_EQUAL( result, c.exp_result ); @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE( PropertiesReadKicadUnit ) { std::map properties = { { "TEST", c.input } }; - int result = ALTIUM_PARSER::ReadKicadUnit( properties, "TEST", "0mil" ); + int result = ALTIUM_PROPS_UTILS::ReadKicadUnit( properties, "TEST", "0mil" ); // These are all valid BOOST_CHECK_EQUAL( result, c.exp_result ); @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE( ReadProperties ) *content.get() = c.input.size(); std::memcpy( content.get() + 4, c.input.c_str(), c.input.size() ); - ALTIUM_PARSER parser( content, size ); + ALTIUM_BINARY_PARSER parser( content, size ); std::map result = parser.ReadProperties();