26#include <unordered_map> 
   40    static const std::unordered_map<std::string, ALTIUM_LAYER> hash_map = {
 
  132    auto it = hash_map.find( std::string( aName.c_str() ) );
 
  134    if( it == hash_map.end() )
 
  136        wxLogError( 
_( 
"Unknown mapping of the Altium layer '%s'." ), aName );
 
 
  146                            std::vector<ALTIUM_VERTICE>& aVertices )
 
  148    for( 
size_t i = 0; i < std::numeric_limits<size_t>::max(); i++ )
 
  150        const wxString si = std::to_string( i );
 
  152        const wxString vxi = wxT( 
"VX" ) + si;
 
  153        const wxString vyi = wxT( 
"VY" ) + si;
 
  155        if( aProps.find( vxi ) == aProps.end() || aProps.find( vyi ) == aProps.end() )
 
  167        aVertices.emplace_back( isRound, 
radius, sa, ea, vp, cp );
 
 
  177    if( mode == wxT( 
"None" ) )
 
  179    else if( mode == wxT( 
"Rule" ) )
 
  181    else if( mode == wxT( 
"Manual" ) )
 
  184    wxLogError( 
_( 
"Unknown Mode string: '%s'." ), mode );
 
 
  194    if( record == wxT( 
"Arc" ) )
 
  196    else if( record == wxT( 
"Pad" ) )
 
  198    else if( record == wxT( 
"Via" ) )
 
  200    else if( record == wxT( 
"Track" ) )
 
  202    else if( record == wxT( 
"Text" ) )
 
  204    else if( record == wxT( 
"Fill" ) )
 
  206    else if( record == wxT( 
"Region" ) ) 
 
  208    else if( record == wxT( 
"Model" ) )
 
  211    wxLogError( 
_( 
"Unknown Record name string: '%s'." ), record );
 
 
  218        const std::map<wxString, wxString>& aProps, wxString aKey )
 
  222    if( parsedType == wxT( 
"Mask" ) )
 
  225    wxLogError( 
_( 
"Unknown Extended Primitive Information type: '%s'." ), parsedType );
 
 
  239                                          const std::string& aSubrecordName, 
size_t aExpectedLength,
 
  240                                          size_t aActualLength )
 
  242    if( aActualLength < aExpectedLength )
 
  245                                          "which is unexpected (expected at least %d)",
 
  246                                          aStreamType, aSubrecordName, aActualLength,
 
 
  254    const std::map<wxString, wxString> props = aReader.
ReadProperties();
 
  257        THROW_IO_ERROR( wxT( 
"ExtendedPrimitiveInformation stream has no properties!" ) );
 
  265            props, wxT( 
"PASTEMASKEXPANSION_MANUAL" ), wxT( 
"0mil" ) );
 
  269            props, wxT( 
"SOLDERMASKEXPANSION_MANUAL" ), wxT( 
"0mil" ) );
 
 
  287    for( 
size_t i = 1; i < std::numeric_limits<size_t>::max(); i++ )
 
  289        const wxString layeri    = wxT( 
"LAYER" ) + wxString( std::to_string( i ) );
 
  290        const wxString layername = layeri + wxT( 
"NAME" );
 
  292        auto layernameit = props.find( layername );
 
  294        if( layernameit == props.end() )
 
  300        wxString originalName = l.
name;
 
  305            l.
name = wxString::Format( wxT( 
"%s %d" ), originalName, ii++ );
 
  321        THROW_IO_ERROR( wxT( 
"Board6 stream was not parsed correctly!" ) );
 
 
  326    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
  328    if( properties.empty() )
 
  335    for( 
size_t i = 0; i < std::numeric_limits<size_t>::max(); i++ )
 
  337        auto mit = properties.find( wxT( 
"M" ) + wxString( std::to_string( i ) ) );
 
  339        if( mit == properties.end() )
 
  342        names.push_back( mit->second );
 
  346        THROW_IO_ERROR( wxT( 
"Classes6 stream was not parsed correctly" ) );
 
 
  385        THROW_IO_ERROR( wxT( 
"Components6 stream was not parsed correctly" ) );
 
 
  424    for( 
int i = 0; i < refcount; i++ )
 
  426        const std::string refi = 
"REFERENCE" + std::to_string( i ) + 
"POINT";
 
  427        const wxString ref( refi );
 
  432    for( 
size_t i = 1; i < std::numeric_limits<size_t>::max(); i++ )
 
  434        const std::string texti  = 
"TEXT" + std::to_string( i );
 
  435        const std::string textix = texti + 
"X";
 
  436        const std::string textiy = texti + 
"Y";
 
  438        if( props.find( textix ) == props.end() || props.find( textiy ) == props.end() )
 
  454        THROW_IO_ERROR( wxT( 
"Dimensions6 stream was not parsed correctly" ) );
 
 
  459    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
  461    if( properties.empty() )
 
 
  481    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
  483    if( properties.empty() )
 
 
  494    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
  496    if( properties.empty() )
 
  525        THROW_IO_ERROR( wxT( 
"Polygons6 stream was not parsed correctly" ) );
 
 
  544    if( rulekind == wxT( 
"Clearance" ) )
 
  549    else if( rulekind == wxT( 
"DiffPairsRouting" ) )
 
  553    else if( rulekind == wxT( 
"Height" ) )
 
  557    else if( rulekind == wxT( 
"HoleSize" ) )
 
  563    else if( rulekind == wxT( 
"HoleToHoleClearance" ) )
 
  568    else if( rulekind == wxT( 
"RoutingVias" ) )
 
  578    else if( rulekind == wxT( 
"Width" ) )
 
  585    else if( rulekind == wxT( 
"PasteMaskExpansion" ) )
 
  590    else if( rulekind == wxT( 
"SolderMaskExpansion" ) )
 
  595    else if( rulekind == wxT( 
"PlaneClearance" ) )
 
  600    else if( rulekind == wxT( 
"PolygonConnect" ) )
 
  620        THROW_IO_ERROR( wxT( 
"Rules6 stream was not parsed correctly" ) );
 
 
  636    uint8_t flags1    = aReader.
Read<uint8_t>();
 
  640    uint8_t flags2 = aReader.
Read<uint8_t>();
 
  643    net          = aReader.
Read<uint16_t>();
 
 
  677        THROW_IO_ERROR( wxT( 
"ComponentsBodies6 stream has invalid recordtype" ) );
 
  685    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
  687    if( properties.empty() )
 
  688        THROW_IO_ERROR( wxT( 
"ComponentsBodies6 stream has no properties" ) );
 
  710        THROW_IO_ERROR( wxT( 
"Components6 stream was not parsed correctly" ) );
 
 
  723    if( subrecord1 == 0 )
 
  729        THROW_IO_ERROR( wxT( 
"Pads6 stream has invalid subrecord1 length" ) );
 
  754    uint8_t flags1  = aReader.
Read<uint8_t>();
 
  760    uint8_t flags2     = aReader.
Read<uint8_t>();
 
  763    net = aReader.
Read<uint16_t>();
 
  793    if( subrecord5 == 110 )
 
  802            THROW_IO_ERROR( wxString::Format( 
"Pads6 stream subrecord5 + 106 has value %d, " 
  803                                              "which is unexpected",
 
  815    if( subrecord5 >= 120 )
 
  822    else if( subrecord5 == 171 )
 
  826    if( subrecord5 >= 202 )
 
  840    if( subrecord6 >= 596 )
 
  842        sizeAndShape = std::make_unique<APAD6_SIZE_AND_SHAPE>();
 
  873    else if( subrecord6 != 0 )
 
  875        wxLogError( 
_( 
"Pads6 stream has unexpected length for subrecord 6: %d." ), subrecord6 );
 
 
  895    uint8_t flags1  = aReader.
Read<uint8_t>();
 
  901    uint8_t flags2     = aReader.
Read<uint8_t>();
 
  904    net = aReader.
Read<uint16_t>();
 
  913    if( subrecord1 <= 74 )
 
  919        uint8_t temp_byte = aReader.
Read<uint8_t>(); 
 
  934        temp_byte = aReader.
Read<uint8_t>();
 
  941        for( 
int ii = 0; ii < 32; ++ii )
 
  947    if( subrecord1 >= 246 )
 
  954    if( subrecord1 >= 307 )
 
 
  980    uint8_t flags1    = aReader.
Read<uint8_t>();
 
  984    uint8_t flags2 = aReader.
Read<uint8_t>();
 
  987    net          = aReader.
Read<uint16_t>();
 
 1009        THROW_IO_ERROR( wxT( 
"Tracks6 stream was not parsed correctly" ) );
 
 
 1035    if( subrecord1 < 123 )
 
 1049    char fontData[64] = { 0 };
 
 1050    aReader.
ReadBytes( fontData, 
sizeof( fontData ) );
 
 1051    fontname = wxString( fontData, wxMBConvUTF16LE(), 
sizeof( fontData ) ).BeforeFirst( 
'\0' );
 
 1053    char tmpbyte = aReader.
Read<uint8_t>();
 
 1069    if( remaining >= 103 )
 
 1072        printf(
" Unk vec: %d, %d\n", unk_vec.
x, unk_vec.
y);
 
 1077        printf(
" Unk32: %d\n", unk32);
 
 1080        uint8_t unk8 = aReader.
Read<uint8_t>();
 
 1081        printf(
" Unk8: %u\n", unk8);
 
 1086        aReader.
ReadBytes( fontData, 
sizeof( fontData ) );
 
 1087        barcode_fontname = wxString( fontData, wxMBConvUTF16LE(), 
sizeof( fontData ) ).BeforeFirst( 
'\0' );
 
 1089        for( 
size_t ii = 0; ii < 5; ++ii )
 
 1091            uint8_t temp = aReader.
Peek<uint8_t>();
 
 1093            printf( 
"2ATEXT6 %zu:\t Byte:%u, Kicad:%u\n", ii, temp, temp32 );
 
 1103        for( 
size_t ii = 0; ii < 8; ++ii )
 
 1105            uint8_t temp = aReader.
Peek<uint8_t>();
 
 1107            printf( 
"3ATEXT6 %zu:\t Byte:%u, Kicad:%u\n", ii, temp, temp32 );
 
 1117    if( remaining >= 115 )
 
 1135    if( entry != aStringTable.end() )
 
 1136        text = entry->second;
 
 1141    text.Replace( wxT( 
"\r\n" ), wxT( 
"\n" ) );
 
 1153        THROW_IO_ERROR( wxT( 
"Texts6 stream was not parsed correctly" ) );
 
 
 1168    uint8_t flags1 = aReader.
Read<uint8_t>();
 
 1171    uint8_t flags2 = aReader.
Read<uint8_t>();
 
 1174    net = aReader.
Read<uint16_t>();
 
 1195        THROW_IO_ERROR( wxT( 
"Fills6 stream was not parsed correctly" ) );
 
 
 1203        THROW_IO_ERROR( wxT( 
"Regions6 stream has invalid recordtype" ) );
 
 1210    uint8_t flags1 = aReader.
Read<uint8_t>();
 
 1213    uint8_t flags2 = aReader.
Read<uint8_t>();
 
 1216    net = aReader.
Read<uint16_t>();
 
 1223    std::map<wxString, wxString> properties = aReader.
ReadProperties();
 
 1225    if( properties.empty() )
 
 1269    uint32_t num_outline_vertices = aReader.
Read<uint32_t>();
 
 1271    if( aExtendedVertices )
 
 1272        num_outline_vertices++; 
 
 1274    for( uint32_t i = 0; i < num_outline_vertices; i++ )
 
 1276        if( aExtendedVertices )
 
 1278            bool     isRound  = aReader.
Read<uint8_t>() != 0;
 
 1282            double   angle1   = aReader.
Read<
double>();
 
 1283            double   angle2   = aReader.
Read<
double>();
 
 1296    for( uint16_t k = 0; k < 
holecount; k++ )
 
 1298        uint32_t num_hole_vertices = aReader.
Read<uint32_t>();
 
 1299        holes.at( k ).reserve( num_hole_vertices );
 
 1301        for( uint32_t i = 0; i < num_hole_vertices; i++ )
 
 1312        THROW_IO_ERROR( wxT( 
"Regions6 stream was not parsed correctly" ) );
 
 
void altium_parse_polygons(std::map< wxString, wxString > &aProps, std::vector< ALTIUM_VERTICE > &aVertices)
 
static void ExpectSubrecordLengthAtLeast(const std::string &aStreamType, const std::string &aSubrecordName, size_t aExpectedLength, size_t aActualLength)
Throw an IO_ERROR if the actual length is less than the expected length.
 
ALTIUM_LAYER altium_layer_from_name(const wxString &aName)
 
static AEXTENDED_PRIMITIVE_INFORMATION_TYPE ReadAltiumExtendedPrimitiveInformationTypeFromProperties(const std::map< wxString, wxString > &aProps, wxString aKey)
 
static ALTIUM_MODE ReadAltiumModeFromProperties(const std::map< wxString, wxString > &aProps, wxString aKey)
 
static ALTIUM_RECORD ReadAltiumRecordFromProperties(const std::map< wxString, wxString > &aProps, wxString aKey)
 
const uint16_t ALTIUM_NET_UNCONNECTED
 
const uint16_t ALTIUM_POLYGON_NONE
 
AEXTENDED_PRIMITIVE_INFORMATION_TYPE
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
void Skip(size_t aLength)
 
size_t ReadAndSetSubrecordLength()
 
VECTOR2I ReadVector2ISize()
 
VECTOR2I ReadVector2IPos()
 
size_t GetRemainingSubrecordBytes() const
 
std::map< wxString, wxString > ReadProperties(std::function< std::map< wxString, wxString >(const std::string &)> handleBinaryData=[](const std::string &) { return std::map< wxString, wxString >();})
 
int ReadBytes(char *aOut, size_t aSize)
 
static int ReadInt(const std::map< wxString, wxString > &aProps, const wxString &aKey, int aDefault)
 
static int32_t ReadKicadUnit(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
 
static bool ReadBool(const std::map< wxString, wxString > &aProps, const wxString &aKey, bool aDefault)
 
static wxString ReadUnicodeString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
 
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
 
static double ReadDouble(const std::map< wxString, wxString > &aProps, const wxString &aKey, double aDefault)
 
static int32_t ConvertToKicadUnit(const double aValue)
 
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
 
AARC6(ALTIUM_BINARY_PARSER &aReader)
 
uint8_t keepoutrestrictions
 
wxString dielectricmaterial
 
std::set< wxString > layerNames
 
ABOARD6(ALTIUM_BINARY_PARSER &aReader)
 
std::vector< ABOARD6_LAYER_STACKUP > stackup
 
std::vector< ALTIUM_VERTICE > board_vertices
 
std::vector< wxString > names
 
ACLASS6(ALTIUM_BINARY_PARSER &aReader)
 
wxString sourceHierachicalPath
 
ALTIUM_TEXT_POSITION commentautoposition
 
ALTIUM_TEXT_POSITION nameautoposition
 
ACOMPONENT6(ALTIUM_BINARY_PARSER &aReader)
 
wxString sourcefootprintlibrary
 
wxString sourcelibreference
 
wxString sourcedesignator
 
wxString sourcecomponentlibrary
 
ACOMPONENTBODY6(ALTIUM_BINARY_PARSER &aReader)
 
std::vector< VECTOR2I > textPoint
 
ALTIUM_DIMENSION_KIND kind
 
ADIMENSION6(ALTIUM_BINARY_PARSER &aReader)
 
std::vector< VECTOR2I > referencePoint
 
uint8_t keepoutrestrictions
 
AFILL6(ALTIUM_BINARY_PARSER &aReader)
 
AMODEL(ALTIUM_BINARY_PARSER &aReader)
 
ANET6(ALTIUM_BINARY_PARSER &aReader)
 
int32_t soldermaskexpansionmanual
 
APAD6(ALTIUM_BINARY_PARSER &aReader)
 
std::unique_ptr< APAD6_SIZE_AND_SHAPE > sizeAndShape
 
ALTIUM_PAD_SHAPE topshape
 
ALTIUM_MODE pastemaskexpansionmode
 
ALTIUM_MODE soldermaskexpansionmode
 
ALTIUM_PAD_SHAPE botshape
 
ALTIUM_PAD_SHAPE midshape
 
int32_t pastemaskexpansionmanual
 
int32_t pad_to_die_length
 
std::vector< ALTIUM_VERTICE > vertices
 
APOLYGON6(ALTIUM_BINARY_PARSER &aReader)
 
ALTIUM_POLYGON_HATCHSTYLE hatchstyle
 
uint8_t keepoutrestrictions
 
AREGION6(ALTIUM_BINARY_PARSER &aReader, bool aExtendedVertices)
 
std::vector< ALTIUM_VERTICE > outline
 
std::vector< std::vector< ALTIUM_VERTICE > > holes
 
ALTIUM_CONNECT_STYLE polygonconnectStyle
 
int planeclearanceClearance
 
int32_t polygonconnectReliefconductorwidth
 
ARULE6(ALTIUM_BINARY_PARSER &aReader)
 
int32_t polygonconnectAirgapwidth
 
int polygonconnectReliefentries
 
uint32_t text_offset_width
 
uint32_t textbox_rect_height
 
ALTIUM_TEXT_POSITION textbox_rect_justification
 
uint32_t widestring_index
 
uint32_t textbox_rect_width
 
uint32_t margin_border_width
 
bool isJustificationValid
 
ALTIUM_BARCODE_TYPE barcode_type
 
ALTIUM_TEXT_TYPE fonttype
 
STROKE_FONT_TYPE strokefonttype
 
wxString barcode_fontname
 
ATEXT6(ALTIUM_BINARY_PARSER &aReader, std::map< uint32_t, wxString > &aStringTable)
 
ATRACK6(ALTIUM_BINARY_PARSER &aReader)
 
uint8_t keepoutrestrictions
 
bool soldermask_expansion_linked
 
uint32_t thermal_relief_conductorcount
 
int32_t thermal_relief_airgap
 
int32_t soldermask_expansion_front
 
bool soldermask_expansion_manual
 
AVIA6(ALTIUM_BINARY_PARSER &aReader)
 
uint32_t thermal_relief_conductorwidth
 
int32_t soldermask_expansion_back
 
uint32_t diameter_by_layer[32]
 
VECTOR2< int32_t > VECTOR2I