/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Roberto Fernandez Bautista * Copyright (C) 2020 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 3 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, see . */ /** * @file cadstar_pcb_archive_parser.cpp * @brief Parses a CADSTAR PCB Archive file */ #include #include // pow() void CADSTAR_PCB_ARCHIVE_PARSER::Parse() { XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ) ); XNODE* cNode = fileRootNode->GetChildren(); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARPCB" ) ); for( ; cNode; cNode = cNode->GetNext() ) { if( cNode->GetName() == wxT( "HEADER" ) ) { Header.Parse( cNode ); switch( Header.Resolution ) { case RESOLUTION::HUNDREDTH_MICRON: KiCadUnitMultiplier = 10; break; default: wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) ); break; } } else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) ) Assignments.Parse( cNode ); else if( cNode->GetName() == wxT( "LIBRARY" ) ) Library.Parse( cNode ); else if( cNode->GetName() == wxT( "DEFAULTS" ) ) { // No design information here (no need to parse) // Only contains CADSTAR configuration data such as default shapes, text and units // In future some of this could be converted to KiCad but limited value } else if( cNode->GetName() == wxT( "PARTS" ) ) Parts.Parse( cNode ); else if( cNode->GetName() == wxT( "LAYOUT" ) ) Layout.Parse( cNode ); else if( cNode->GetName() == wxT( "DISPLAY" ) ) { // No design information here (no need to parse) // Contains CADSTAR Display settings such as layer/element colours and visibility. // In the future these settings could be converted to KiCad } else { THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) ); } } delete fileRootNode; } CADSTAR_PCB_ARCHIVE_PARSER::ALIGNMENT CADSTAR_PCB_ARCHIVE_PARSER::ParseAlignment( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ALIGN" ) ); wxString alignmentStr = GetXmlAttributeIDString( aNode, 0 ); if( alignmentStr == wxT( "BOTTOMCENTER" ) ) return ALIGNMENT::BOTTOMCENTER; else if( alignmentStr == wxT( "BOTTOMLEFT" ) ) return ALIGNMENT::BOTTOMLEFT; else if( alignmentStr == wxT( "BOTTOMRIGHT" ) ) return ALIGNMENT::BOTTOMRIGHT; else if( alignmentStr == wxT( "CENTERCENTER" ) ) return ALIGNMENT::CENTERCENTER; else if( alignmentStr == wxT( "CENTERLEFT" ) ) return ALIGNMENT::CENTERLEFT; else if( alignmentStr == wxT( "CENTERRIGHT" ) ) return ALIGNMENT::CENTERRIGHT; else if( alignmentStr == wxT( "TOPCENTER" ) ) return ALIGNMENT::TOPCENTER; else if( alignmentStr == wxT( "TOPLEFT" ) ) return ALIGNMENT::TOPLEFT; else if( alignmentStr == wxT( "TOPRIGHT" ) ) return ALIGNMENT::TOPRIGHT; else THROW_UNKNOWN_PARAMETER_IO_ERROR( alignmentStr, wxT( "ALIGN" ) ); //shouldn't be here but avoids compiler warning return ALIGNMENT::NO_ALIGNMENT; } CADSTAR_PCB_ARCHIVE_PARSER::JUSTIFICATION CADSTAR_PCB_ARCHIVE_PARSER::ParseJustification( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "JUSTIFICATION" ) ); wxString justificationStr = GetXmlAttributeIDString( aNode, 0 ); if( justificationStr == wxT( "LEFT" ) ) return JUSTIFICATION::LEFT; else if( justificationStr == wxT( "RIGHT" ) ) return JUSTIFICATION::RIGHT; else if( justificationStr == wxT( "CENTER" ) ) return JUSTIFICATION::CENTER; else THROW_UNKNOWN_PARAMETER_IO_ERROR( justificationStr, wxT( "JUSTIFICATION" ) ); return JUSTIFICATION::LEFT; } CADSTAR_PCB_ARCHIVE_PARSER::READABILITY CADSTAR_PCB_ARCHIVE_PARSER::ParseReadability( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "READABILITY" ) ); wxString readabilityStr = GetXmlAttributeIDString( aNode, 0 ); if( readabilityStr == wxT( "BOTTOM_TO_TOP" ) ) return READABILITY::BOTTOM_TO_TOP; else if( readabilityStr == wxT( "TOP_TO_BOTTOM" ) ) return READABILITY::TOP_TO_BOTTOM; else THROW_UNKNOWN_PARAMETER_IO_ERROR( readabilityStr, wxT( "READABILITY" ) ); return READABILITY::BOTTOM_TO_TOP; } CADSTAR_PCB_ARCHIVE_PARSER::ANGUNITS CADSTAR_PCB_ARCHIVE_PARSER::ParseAngunits( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ANGUNITS" ) ); wxString angUnitStr = GetXmlAttributeIDString( aNode, 0 ); if( angUnitStr == wxT( "DEGREES" ) ) return ANGUNITS::DEGREES; else if( angUnitStr == wxT( "RADIANS" ) ) return ANGUNITS::RADIANS; else THROW_UNKNOWN_PARAMETER_IO_ERROR( angUnitStr, aNode->GetName() ); return ANGUNITS(); } void CADSTAR_PCB_ARCHIVE_PARSER::ASSIGNMENTS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ASSIGNMENTS" ) ); XNODE* cNode = aNode->GetChildren(); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "TECHNOLOGY" ), wxT( "ASSIGNMENTS" ) ); for( ; cNode; cNode = cNode->GetNext() ) { if( cNode->GetName() == wxT( "LAYERDEFS" ) ) Layerdefs.Parse( cNode ); else if( cNode->GetName() == wxT( "CODEDEFS" ) ) Codedefs.Parse( cNode ); else if( cNode->GetName() == wxT( "TECHNOLOGY" ) ) Technology.Parse( cNode ); else if( cNode->GetName() == wxT( "GRIDS" ) ) Grids.Parse( cNode ); else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) ) NetclassEditAttributeSettings = true; else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) ) SpacingclassEditAttributeSettings = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::LAYERDEFS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LAYERDEFS" ) ); wxXmlAttribute* xmlAttribute = NULL; XNODE* cNode = aNode->GetChildren(); if( !cNode ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "LAYERSTACK" ), wxT( "LAYERDEFS" ) ); for( ; cNode; cNode = cNode->GetNext() ) { wxString nodeName = cNode->GetName(); if( nodeName == wxT( "LAYERSTACK" ) ) { xmlAttribute = cNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; else LayerStack.push_back( (LAYER_ID) xmlAttribute->GetValue() ); } CheckNoChildNodes( cNode ); } else if( nodeName == wxT( "MATERIAL" ) ) { MATERIAL material; material.Parse( cNode ); Materials.insert( std::make_pair( material.ID, material ) ); } else if( nodeName == wxT( "LAYER" ) ) { LAYER layer; layer.Parse( cNode ); Layers.insert( std::make_pair( layer.ID, layer ) ); } else if( nodeName == wxT( "SWAPPAIR" ) ) { LAYER_ID layerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 0 ); LAYER_ID swapLayerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 1 ); Layers[layerId].SwapLayerID = swapLayerId; } else { THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::RULESET::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "RULESET" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString nodeName = cNode->GetName(); if( nodeName == wxT( "ROUCODEREF" ) ) AreaRouteCodeID = GetXmlAttributeIDString( cNode, 0 ); else if( nodeName == wxT( "VIACODEREF" ) ) AreaViaCodeID = GetXmlAttributeIDString( cNode, 0 ); else if( nodeName == wxT( "SPACINGCODE" ) ) { SPACINGCODE spacingcode; spacingcode.Parse( cNode ); SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::CODEDEFS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "CODEDEFS" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString nodeName = cNode->GetName(); if( nodeName == wxT( "LINECODE" ) ) { LINECODE linecode; linecode.Parse( cNode ); LineCodes.insert( std::make_pair( linecode.ID, linecode ) ); } else if( nodeName == wxT( "HATCHCODE" ) ) { HATCHCODE hatchcode; hatchcode.Parse( cNode ); HatchCodes.insert( std::make_pair( hatchcode.ID, hatchcode ) ); } else if( nodeName == wxT( "TEXTCODE" ) ) { TEXTCODE textcode; textcode.Parse( cNode ); TextCodes.insert( std::make_pair( textcode.ID, textcode ) ); } else if( nodeName == wxT( "ROUTECODE" ) ) { ROUTECODE routecode; routecode.Parse( cNode ); RouteCodes.insert( std::make_pair( routecode.ID, routecode ) ); } else if( nodeName == wxT( "COPPERCODE" ) ) { COPPERCODE coppercode; coppercode.Parse( cNode ); CopperCodes.insert( std::make_pair( coppercode.ID, coppercode ) ); } else if( nodeName == wxT( "SPACINGCODE" ) ) { SPACINGCODE spacingcode; spacingcode.Parse( cNode ); SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) ); } else if( nodeName == wxT( "RULESET" ) ) { RULESET ruleset; ruleset.Parse( cNode ); Rulesets.insert( std::make_pair( ruleset.ID, ruleset ) ); } else if( nodeName == wxT( "PADCODE" ) ) { PADCODE padcode; padcode.Parse( cNode ); PadCodes.insert( std::make_pair( padcode.ID, padcode ) ); } else if( nodeName == wxT( "VIACODE" ) ) { VIACODE viacode; viacode.Parse( cNode ); ViaCodes.insert( std::make_pair( viacode.ID, viacode ) ); } else if( nodeName == wxT( "LAYERPAIR" ) ) { LAYERPAIR layerpair; layerpair.Parse( cNode ); LayerPairs.insert( std::make_pair( layerpair.ID, layerpair ) ); } else if( nodeName == wxT( "ATTRNAME" ) ) { ATTRNAME attrname; attrname.Parse( cNode ); AttributeNames.insert( std::make_pair( attrname.ID, attrname ) ); } else if( nodeName == wxT( "NETCLASS" ) ) { NETCLASS netclass; netclass.Parse( cNode ); NetClasses.insert( std::make_pair( netclass.ID, netclass ) ); } else if( nodeName == wxT( "SPCCLASSNAME" ) ) { SPCCLASSNAME spcclassname; spcclassname.Parse( cNode ); SpacingClassNames.insert( std::make_pair( spcclassname.ID, spcclassname ) ); } else if( nodeName == wxT( "SPCCLASSSPACE" ) ) { SPCCLASSSPACE spcclassspace; spcclassspace.Parse( cNode ); SpacingClasses.push_back( spcclassspace ); } else { THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::MATERIAL::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "MATERIAL" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); wxString sType = GetXmlAttributeIDString( aNode, 2 ); if( sType == wxT( "CONSTRUCTION" ) ) { Type = MATERIAL_LAYER_TYPE::CONSTRUCTION; } else if( sType == wxT( "ELECTRICAL" ) ) { Type = MATERIAL_LAYER_TYPE::ELECTRICAL; } else if( sType == wxT( "NONELEC" ) ) { Type = MATERIAL_LAYER_TYPE::NON_ELECTRICAL; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( sType, wxString::Format( "MATERIAL %s", Name ) ); } XNODE* iNode = aNode->GetChildren(); if( !iNode ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "RESISTIVITY" ), wxString::Format( "MATERIAL %s", Name ) ); for( ; iNode; iNode = iNode->GetNext() ) { wxString nodeName = iNode->GetName(); if( nodeName == wxT( "RELPERMIT" ) ) { ParseChildEValue( iNode, Permittivity ); } else if( nodeName == wxT( "LOSSTANGENT" ) ) { ParseChildEValue( iNode, LossTangent ); } else if( nodeName == wxT( "RESISTIVITY" ) ) { ParseChildEValue( iNode, Resistivity ); } else { THROW_UNKNOWN_NODE_IO_ERROR( nodeName, wxString::Format( "MATERIAL %s", Name ) ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::LAYER::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LAYER" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); auto processLayerMaterialDetails = [&]() { XNODE* tempNode = cNode->GetChildren(); for( ; tempNode; tempNode = tempNode->GetNext() ) { wxString tempNodeName = tempNode->GetName(); if( tempNodeName == wxT( "MAKE" ) ) { MaterialId = GetXmlAttributeIDString( tempNode, 0 ); Thickness = GetXmlAttributeIDLong( tempNode, 1 ); XNODE* childOfTempNode = tempNode->GetChildren(); if( childOfTempNode ) { if( childOfTempNode->GetName() == wxT( "EMBEDS" ) ) { wxString embedsValue = GetXmlAttributeIDString( childOfTempNode, 0 ); if( embedsValue == wxT( "UPWARDS" ) ) { Embedding = EMBEDDING::ABOVE; } else if( embedsValue == wxT( "DOWNWARDS" ) ) { Embedding = EMBEDDING::BELOW; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( embedsValue, wxString::Format( "LAYER %s -> EMBEDS", Name ) ); } } else { THROW_UNKNOWN_NODE_IO_ERROR( childOfTempNode->GetName(), wxString::Format( "LAYER %s->MAKE", Name ) ); } } } else if( tempNodeName == wxT( "BIAS" ) ) { wxString bias = GetXmlAttributeIDString( tempNode, 0 ); if( bias == wxT( "X_BIASED" ) ) { RoutingBias = ROUTING_BIAS::X; } else if( bias == wxT( "Y_BIASED" ) ) { RoutingBias = ROUTING_BIAS::Y; } else if( bias == wxT( "ANTITRACK" ) ) { RoutingBias = ROUTING_BIAS::ANTI_ROUTE; } else if( bias == wxT( "OBSTACLE" ) ) { RoutingBias = ROUTING_BIAS::OBSTACLE; } else if( bias == wxT( "UNBIASED" ) ) { RoutingBias = ROUTING_BIAS::UNBIASED; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( bias, wxString::Format( "LAYER %s -> BIAS", Name ) ); } } else { THROW_UNKNOWN_NODE_IO_ERROR( tempNodeName, wxString::Format( "LAYER %s", Name ) ); } } }; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ALLDOC" ) ) { Type = LAYER_TYPE::ALLDOC; } else if( cNodeName == wxT( "ALLELEC" ) ) { Type = LAYER_TYPE::ALLELEC; } else if( cNodeName == wxT( "ALLLAYER" ) ) { Type = LAYER_TYPE::ALLLAYER; } else if( cNodeName == wxT( "ASSCOMPCOPP" ) ) { Type = LAYER_TYPE::ASSCOMPCOPP; } else if( cNodeName == wxT( "JUMPERLAYER" ) ) { Type = LAYER_TYPE::JUMPERLAYER; } else if( cNodeName == wxT( "NOLAYER" ) ) { Type = LAYER_TYPE::NOLAYER; } else if( cNodeName == wxT( "POWER" ) ) { Type = LAYER_TYPE::POWER; PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 ); processLayerMaterialDetails(); } else if( cNodeName == wxT( "DOC" ) ) { Type = LAYER_TYPE::DOC; } else if( cNodeName == wxT( "CONSTRUCTION" ) ) { Type = LAYER_TYPE::CONSTRUCTION; processLayerMaterialDetails(); } else if( cNodeName == wxT( "ELEC" ) ) { Type = LAYER_TYPE::ELEC; PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 ); processLayerMaterialDetails(); } else if( cNodeName == wxT( "NONELEC" ) ) { Type = LAYER_TYPE::NONELEC; PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 ); processLayerMaterialDetails(); } else if( cNodeName == wxT( "DESCRIPTION" ) ) { Description = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "LASUBTYP" ) ) { //Process subtype wxString sSubType = GetXmlAttributeIDString( cNode, 0 ); if( sSubType == wxT( "LAYERSUBTYPE_ASSEMBLY" ) ) { this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY; } else if( sSubType == wxT( "LAYERSUBTYPE_PASTE" ) ) { this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_PASTE; } else if( sSubType == wxT( "LAYERSUBTYPE_PLACEMENT" ) ) { this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_PLACEMENT; } else if( sSubType == wxT( "LAYERSUBTYPE_SILKSCREEN" ) ) { this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_SILKSCREEN; } else if( sSubType == wxT( "LAYERSUBTYPE_SOLDERRESIST" ) ) { this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_SOLDERRESIST; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( sSubType, wxString::Format( "LAYER %s %s", Name, cNodeName ) ); } } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxString::Format( "LAYER %s", Name ) ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::FORMAT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "FORMAT" ) ); Type = GetXmlAttributeIDString( aNode, 0 ); SomeInt = GetXmlAttributeIDLong( aNode, 1 ); Version = GetXmlAttributeIDLong( aNode, 2 ); } void CADSTAR_PCB_ARCHIVE_PARSER::TIMESTAMP::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TIMESTAMP" ) ); if( !GetXmlAttributeIDString( aNode, 0 ).ToLong( &Year ) || !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Month ) || !GetXmlAttributeIDString( aNode, 2 ).ToLong( &Day ) || !GetXmlAttributeIDString( aNode, 3 ).ToLong( &Hour ) || !GetXmlAttributeIDString( aNode, 4 ).ToLong( &Minute ) || !GetXmlAttributeIDString( aNode, 5 ).ToLong( &Second ) ) THROW_PARSING_IO_ERROR( wxT( "TIMESTAMP" ), wxString::Format( "HEADER" ) ); } void CADSTAR_PCB_ARCHIVE_PARSER::HEADER::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "HEADER" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString nodeName = cNode->GetName(); if( nodeName == wxT( "FORMAT" ) ) { Format.Parse( cNode ); if( Format.Type != wxT( "LAYOUT" ) ) THROW_IO_ERROR( "Not a CADSTAR PCB Layout file!" ); } else if( nodeName == wxT( "JOBFILE" ) ) JobFile = GetXmlAttributeIDString( cNode, 0 ); else if( nodeName == wxT( "JOBTITLE" ) ) JobTitle = GetXmlAttributeIDString( cNode, 0 ); else if( nodeName == wxT( "GENERATOR" ) ) Generator = GetXmlAttributeIDString( cNode, 0 ); else if( nodeName == wxT( "RESOLUTION" ) ) { XNODE* subNode = cNode->GetChildren(); if( ( subNode->GetName() == wxT( "METRIC" ) ) && ( GetXmlAttributeIDString( subNode, 0 ) == wxT( "HUNDREDTH" ) ) && ( GetXmlAttributeIDString( subNode, 1 ) == wxT( "MICRON" ) ) ) { Resolution = RESOLUTION::HUNDREDTH_MICRON; } else // TODO Need to find out if there are other possible resolutions. Logically // there must be other base units that could be used, such as "IMPERIAL INCH" // or "METRIC MM" but so far none of settings in CADSTAR generated a different // output resolution to "HUNDREDTH MICRON" THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), wxT( "HEADER->RESOLUTION" ) ); } else if( nodeName == wxT( "TIMESTAMP" ) ) Timestamp.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "HEADER" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::LINECODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LINECODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); if( !GetXmlAttributeIDString( aNode, 2 ).ToLong( &Width ) ) THROW_PARSING_IO_ERROR( wxT( "Line Width" ), wxString::Format( "LINECODE -> %s", Name ) ); XNODE* cNode = aNode->GetChildren(); if( cNode->GetName() != wxT( "STYLE" ) ) THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxString::Format( "LINECODE -> %s", Name ) ); wxString styleStr = GetXmlAttributeIDString( cNode, 0 ); if( styleStr == wxT( "SOLID" ) ) Style = LINESTYLE::SOLID; else if( styleStr == wxT( "DASH" ) ) Style = LINESTYLE::DASH; else if( styleStr == wxT( "DASHDOT" ) ) Style = LINESTYLE::DASHDOT; else if( styleStr == wxT( "DASHDOTDOT" ) ) Style = LINESTYLE::DASHDOTDOT; else if( styleStr == wxT( "DOT" ) ) Style = LINESTYLE::DOT; else THROW_UNKNOWN_PARAMETER_IO_ERROR( wxString::Format( "STYLE %s", styleStr ), wxString::Format( "LINECODE -> %s", Name ) ); } void CADSTAR_PCB_ARCHIVE_PARSER::HATCH::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "HATCH" ) ); Step = GetXmlAttributeIDLong( aNode, 0 ); LineWidth = GetXmlAttributeIDLong( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); if( !cNode || cNode->GetName() != wxT( "ORIENT" ) ) THROW_MISSING_NODE_IO_ERROR( wxT( "ORIENT" ), wxT( "HATCH" ) ); OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); } void CADSTAR_PCB_ARCHIVE_PARSER::HATCHCODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "HATCHCODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "HATCHCODE -> %s", Name ); for( ; cNode; cNode = cNode->GetNext() ) { if( cNode->GetName() != wxT( "HATCH" ) ) THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), location ); HATCH hatch; hatch.Parse( cNode ); Hatches.push_back( hatch ); } } void CADSTAR_PCB_ARCHIVE_PARSER::FONT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "FONT" ) ); Name = GetXmlAttributeIDString( aNode, 0 ); Modifier1 = GetXmlAttributeIDLong( aNode, 1 ); Modifier2 = GetXmlAttributeIDLong( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ITALIC" ) ) Italic = true; else if( cNodeName == wxT( "KERNING" ) ) KerningPairs = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::TEXTCODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TEXTCODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); LineWidth = GetXmlAttributeIDLong( aNode, 2 ); Height = GetXmlAttributeIDLong( aNode, 3 ); Width = GetXmlAttributeIDLong( aNode, 4 ); XNODE* cNode = aNode->GetChildren(); if( cNode ) { if( cNode->GetName() == wxT( "FONT" ) ) Font.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::ROUTECODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ROUTECODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); OptimalWidth = GetXmlAttributeIDLong( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "NECKWIDTH" ) ) NeckedWidth = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MINWIDTH" ) ) MinWidth = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MAXWIDTH" ) ) MaxWidth = GetXmlAttributeIDLong( cNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::COPREASSIGN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COPREASSIGN" ) ); LayerID = GetXmlAttributeIDString( aNode, 0 ); CopperWidth = GetXmlAttributeIDLong( aNode, 1 ); } void CADSTAR_PCB_ARCHIVE_PARSER::COPPERCODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COPPERCODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); CopperWidth = GetXmlAttributeIDLong( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { if( cNode->GetName() == wxT( "COPREASSIGN" ) ) { CADSTAR_PCB_ARCHIVE_PARSER::COPREASSIGN reassign; reassign.Parse( cNode ); Reassigns.push_back( reassign ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::SPACINGCODE::REASSIGN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SPACEREASSIGN" ) ); LayerID = GetXmlAttributeIDString( aNode, 0 ); Spacing = GetXmlAttributeIDLong( aNode, 1 ); CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::SPACINGCODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SPACINGCODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Spacing = GetXmlAttributeIDLong( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "SPACEREASSIGN" ) ) { REASSIGN reassign; reassign.Parse( cNode ); Reassigns.push_back( reassign ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } bool CADSTAR_PCB_ARCHIVE_PARSER::PAD_SHAPE::IsPadShape( XNODE* aNode ) { wxString aNodeName = aNode->GetName(); if( aNodeName == wxT( "ANNULUS" ) || aNodeName == wxT( "BULLET" ) || aNodeName == wxT( "ROUND" ) || aNodeName == wxT( "DIAMOND" ) || aNodeName == wxT( "FINGER" ) || aNodeName == wxT( "OCTAGON" ) || aNodeName == wxT( "RECTANGLE" ) || aNodeName == wxT( "ROUNDED" ) || aNodeName == wxT( "SQUARE" ) ) return true; else return false; } void CADSTAR_PCB_ARCHIVE_PARSER::PAD_SHAPE::Parse( XNODE* aNode ) { wxASSERT( IsPadShape( aNode ) ); wxString aNodeName = aNode->GetName(); if( aNodeName == wxT( "ANNULUS" ) ) ShapeType = PAD_SHAPE_TYPE::ANNULUS; else if( aNodeName == wxT( "BULLET" ) ) ShapeType = PAD_SHAPE_TYPE::BULLET; else if( aNodeName == wxT( "ROUND" ) ) ShapeType = PAD_SHAPE_TYPE::CIRCLE; else if( aNodeName == wxT( "DIAMOND" ) ) ShapeType = PAD_SHAPE_TYPE::DIAMOND; else if( aNodeName == wxT( "FINGER" ) ) ShapeType = PAD_SHAPE_TYPE::FINGER; else if( aNodeName == wxT( "OCTAGON" ) ) ShapeType = PAD_SHAPE_TYPE::OCTAGON; else if( aNodeName == wxT( "RECTANGLE" ) ) ShapeType = PAD_SHAPE_TYPE::RECTANGLE; else if( aNodeName == wxT( "ROUNDED" ) ) ShapeType = PAD_SHAPE_TYPE::ROUNDED_RECT; else if( aNodeName == wxT( "SQUARE" ) ) ShapeType = PAD_SHAPE_TYPE::SQUARE; else wxASSERT( true ); switch( ShapeType ) { case PAD_SHAPE_TYPE::ANNULUS: Size = GetXmlAttributeIDLong( aNode, 0 ); InternalFeature = GetXmlAttributeIDLong( aNode, 1 ); break; case PAD_SHAPE_TYPE::ROUNDED_RECT: InternalFeature = GetXmlAttributeIDLong( aNode, 3 ); //Fall through case PAD_SHAPE_TYPE::BULLET: case PAD_SHAPE_TYPE::FINGER: case PAD_SHAPE_TYPE::RECTANGLE: RightLength = GetXmlAttributeIDLong( aNode, 2 ); LeftLength = GetXmlAttributeIDLong( aNode, 1 ); //Fall through case PAD_SHAPE_TYPE::SQUARE: if( aNode->GetChildren() ) { if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) ) { OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 ); } else THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() ); CheckNoNextNodes( aNode->GetChildren() ); } //Fall through case PAD_SHAPE_TYPE::CIRCLE: Size = GetXmlAttributeIDLong( aNode, 0 ); break; } } void CADSTAR_PCB_ARCHIVE_PARSER::PADREASSIGN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PADREASSIGN" ) ); LayerID = GetXmlAttributeIDString( aNode, 0 ); if( PAD_SHAPE::IsPadShape( aNode->GetChildren() ) ) Shape.Parse( aNode->GetChildren() ); else THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() ); CheckNoNextNodes( aNode->GetChildren() ); } void CADSTAR_PCB_ARCHIVE_PARSER::PADCODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PADCODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "PADCODE -> %s", Name ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( PAD_SHAPE::IsPadShape( cNode ) ) Shape.Parse( cNode ); else if( cNodeName == wxT( "CLEARANCE" ) ) ReliefClearance = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "RELIEFWIDTH" ) ) ReliefWidth = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DRILL" ) ) { DrillDiameter = GetXmlAttributeIDLong( cNode, 0 ); XNODE* subNode = cNode->GetChildren(); for( ; subNode; subNode = subNode->GetNext() ) { wxString subNodeName = subNode->GetName(); if( subNodeName == wxT( "NONPLATED" ) ) Plated = false; else if( subNodeName == wxT( "OVERSIZE" ) ) DrillOversize = GetXmlAttributeIDLong( subNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location ); } } else if( cNodeName == wxT( "DRILLLENGTH" ) ) SlotLength = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DRILLORIENTATION" ) ) SlotOrientation = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DRILLXOFFSET" ) ) DrillXoffset = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DRILLYOFFSET" ) ) DrillYoffset = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "PADREASSIGN" ) ) { PADREASSIGN reassign; reassign.Parse( cNode ); Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::VIAREASSIGN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "VIAREASSIGN" ) ); LayerID = GetXmlAttributeIDString( aNode, 0 ); if( PAD_SHAPE::IsPadShape( aNode->GetChildren() ) ) Shape.Parse( aNode->GetChildren() ); else THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() ); CheckNoNextNodes( aNode->GetChildren() ); } void CADSTAR_PCB_ARCHIVE_PARSER::VIACODE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "VIACODE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "VIACODE -> %s", Name ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( PAD_SHAPE::IsPadShape( cNode ) ) Shape.Parse( cNode ); else if( cNodeName == wxT( "CLEARANCE" ) ) ReliefClearance = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "RELIEFWIDTH" ) ) ReliefWidth = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DRILL" ) ) { DrillDiameter = GetXmlAttributeIDLong( cNode, 0 ); XNODE* subNode = cNode->GetChildren(); for( ; subNode; subNode = subNode->GetNext() ) { wxString subNodeName = subNode->GetName(); if( subNodeName == wxT( "OVERSIZE" ) ) DrillOversize = GetXmlAttributeIDLong( subNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location ); } } else if( cNodeName == wxT( "VIAREASSIGN" ) ) { VIAREASSIGN reassign; reassign.Parse( cNode ); Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::LAYERPAIR::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LAYERPAIR" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); PhysicalLayerStart = GetXmlAttributeIDLong( aNode, 2 ); PhysicalLayerEnd = GetXmlAttributeIDLong( aNode, 3 ); wxString location = wxString::Format( "LAYERPAIR -> %s", Name ); if( aNode->GetChildren() ) { if( aNode->GetChildren()->GetName() == wxT( "VIACODEREF" ) ) { ViacodeID = GetXmlAttributeIDString( aNode->GetChildren(), 0 ); } else THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), location ); CheckNoNextNodes( aNode->GetChildren() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::ATTRNAME::COLUMNORDER::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COLUMNORDER" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); Order = GetXmlAttributeIDLong( aNode, 1 ); CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::ATTRNAME::COLUMNWIDTH::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COLUMNWIDTH" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); Width = GetXmlAttributeIDLong( aNode, 1 ); CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::ATTRNAME::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ATTRNAME" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "ATTRNAME -> %s", Name ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ATTROWNER" ) ) { wxString attOwnerVal = GetXmlAttributeIDString( cNode, 0 ); if( attOwnerVal == wxT( "ALL_ITEMS" ) ) AttributeOwner = ATTROWNER::ALL_ITEMS; else if( attOwnerVal == wxT( "AREA" ) ) AttributeOwner = ATTROWNER::AREA; else if( attOwnerVal == wxT( "BOARD" ) ) AttributeOwner = ATTROWNER::BOARD; else if( attOwnerVal == wxT( "COMPONENT" ) ) AttributeOwner = ATTROWNER::COMPONENT; else if( attOwnerVal == wxT( "CONNECTION" ) ) AttributeOwner = ATTROWNER::CONNECTION; else if( attOwnerVal == wxT( "COPPER" ) ) AttributeOwner = ATTROWNER::COPPER; else if( attOwnerVal == wxT( "DOCSYMBOL" ) ) AttributeOwner = ATTROWNER::DOCSYMBOL; else if( attOwnerVal == wxT( "FIGURE" ) ) AttributeOwner = ATTROWNER::FIGURE; else if( attOwnerVal == wxT( "NET" ) ) AttributeOwner = ATTROWNER::NET; else if( attOwnerVal == wxT( "NETCLASS" ) ) AttributeOwner = ATTROWNER::NETCLASS; else if( attOwnerVal == wxT( "PART" ) ) AttributeOwner = ATTROWNER::PART; else if( attOwnerVal == wxT( "PART_DEFINITION" ) ) AttributeOwner = ATTROWNER::PART_DEFINITION; else if( attOwnerVal == wxT( "PIN" ) ) AttributeOwner = ATTROWNER::PIN; else if( attOwnerVal == wxT( "SYMDEF" ) ) AttributeOwner = ATTROWNER::SYMDEF; else if( attOwnerVal == wxT( "TEMPLATE" ) ) AttributeOwner = ATTROWNER::TEMPLATE; else if( attOwnerVal == wxT( "TESTPOINT" ) ) AttributeOwner = ATTROWNER::TESTPOINT; else THROW_UNKNOWN_PARAMETER_IO_ERROR( attOwnerVal, location ); } else if( cNodeName == wxT( "ATTRUSAGE" ) ) { wxString attUsageVal = GetXmlAttributeIDString( cNode, 0 ); if( attUsageVal == wxT( "BOTH" ) ) AttributeUsage = ATTRUSAGE::BOTH; else if( attUsageVal == wxT( "COMPONENT" ) ) AttributeUsage = ATTRUSAGE::COMPONENT; else if( attUsageVal == wxT( "PART_DEFINITION" ) ) AttributeUsage = ATTRUSAGE::PART_DEFINITION; else if( attUsageVal == wxT( "PART_LIBRARY" ) ) AttributeUsage = ATTRUSAGE::PART_LIBRARY; else if( attUsageVal == wxT( "SYMBOL" ) ) AttributeUsage = ATTRUSAGE::SYMBOL; else THROW_UNKNOWN_PARAMETER_IO_ERROR( attUsageVal, location ); } else if( cNodeName == wxT( "NOTRANSFER" ) ) NoTransfer = true; else if( cNodeName == wxT( "COLUMNORDER" ) ) { COLUMNORDER cOrder; cOrder.Parse( cNode ); ColumnOrders.push_back( cOrder ); } else if( cNodeName == wxT( "COLUMNWIDTH" ) ) { COLUMNWIDTH cWidth; cWidth.Parse( cNode ); ColumnWidths.push_back( cWidth ); } else if( cNodeName == wxT( "COLUMNINVISIBLE" ) ) ColumnInvisible = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::ATTRIBUTE_VALUE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ATTR" ) ); AttributeID = GetXmlAttributeIDString( aNode, 0 ); Value = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { if( cNode->GetName() == wxT( "READONLY" ) ) ReadOnly = true; else if( cNode->GetName() == wxT( "ATTRLOC" ) ) { AttributeLocation.Parse( cNode ); HasLocation = true; } else THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "ATTR" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::NETCLASS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "NETCLASS" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "NETCLASS -> %s", Name ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attribute_val; attribute_val.Parse( cNode ); Attributes.push_back( attribute_val ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::SPCCLASSNAME::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SPCCLASSNAME" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); } void CADSTAR_PCB_ARCHIVE_PARSER::SPCCLASSSPACE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SPCCLASSSPACE" ) ); SpacingClassID1 = GetXmlAttributeIDString( aNode, 0 ); SpacingClassID2 = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 2 ); Spacing = GetXmlAttributeIDLong( aNode, 3 ); } CADSTAR_PCB_ARCHIVE_PARSER::UNITS CADSTAR_PCB_ARCHIVE_PARSER::ParseUnits( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "UNITS" ) ); wxString unit = GetXmlAttributeIDString( aNode, 0 ); if( unit == wxT( "CENTIMETER" ) ) return UNITS::CENTIMETER; else if( unit == wxT( "INCH" ) ) return UNITS::INCH; else if( unit == wxT( "METER" ) ) return UNITS::METER; else if( unit == wxT( "MICROMETRE" ) ) return UNITS::MICROMETRE; else if( unit == wxT( "MM" ) ) return UNITS::MM; else if( unit == wxT( "THOU" ) ) return UNITS::THOU; else THROW_UNKNOWN_PARAMETER_IO_ERROR( unit, wxT( "UNITS" ) ); return UNITS(); } void CADSTAR_PCB_ARCHIVE_PARSER::TECHNOLOGY_SECTION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TECHNOLOGY" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "UNITS" ) ) Units = ParseUnits( cNode ); else if( cNodeName == wxT( "UNITSPRECISION" ) ) UnitDisplPrecision = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "INTERLINEGAP" ) ) InterlineGap = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "BARLINEGAP" ) ) BarlineGap = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "ALLOWBARTEXT" ) ) AllowBarredText = true; else if( cNodeName == wxT( "ANGULARPRECISION" ) ) AngularPrecision = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MINROUTEWIDTH" ) ) MinRouteWidth = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MINNECKED" ) ) MinNeckedLength = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MINUNNECKED" ) ) MinUnneckedLength = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MINMITER" ) ) MinMitre = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MAXMITER" ) ) MaxMitre = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MAXPHYSLAYER" ) ) MaxPhysicalLayer = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "TRACKGRID" ) ) TrackGrid = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "VIAGRID" ) ) ViaGrid = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "DESIGNORIGIN" ) ) { DesignOrigin.Parse( cNode->GetChildren() ); } else if( cNodeName == wxT( "DESIGNAREA" ) ) { std::vector pts = ParseAllChildPoints( cNode, true, 2 ); DesignArea = std::make_pair( pts[0], pts[1] ); } else if( cNodeName == wxT( "DESIGNREF" ) ) { DesignOrigin.Parse( cNode->GetChildren() ); } else if( cNodeName == wxT( "DESIGNLIMIT" ) ) { DesignLimit.Parse( cNode->GetChildren() ); } else if( cNodeName == wxT( "BACKOFFJCTS" ) ) BackOffJunctions = true; else if( cNodeName == wxT( "BCKOFFWIDCHANGE" ) ) BackOffWidthChange = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TECHNOLOGY" ) ); } } bool CADSTAR_PCB_ARCHIVE_PARSER::GRID::IsGrid( XNODE* aNode ) { wxString aNodeName = aNode->GetName(); if( aNodeName == wxT( "FRACTIONALGRID" ) || aNodeName == wxT( "STEPGRID" ) ) return true; else return false; } void CADSTAR_PCB_ARCHIVE_PARSER::GRID::Parse( XNODE* aNode ) { wxASSERT( IsGrid( aNode ) ); wxString aNodeName = aNode->GetName(); if( aNodeName == wxT( "FRACTIONALGRID" ) ) Type = GRID_TYPE::FRACTIONALGRID; else if( aNodeName == wxT( "STEPGRID" ) ) Type = GRID_TYPE::STEPGRID; else wxASSERT_MSG( true, wxT( "Unknown Grid Type" ) ); Name = GetXmlAttributeIDString( aNode, 0 ); Param1 = GetXmlAttributeIDLong( aNode, 1 ); Param2 = GetXmlAttributeIDLong( aNode, 2 ); } void CADSTAR_PCB_ARCHIVE_PARSER::GRIDS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "GRIDS" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "WORKINGGRID" ) ) { XNODE* workingGridNode = cNode->GetChildren(); if( !GRID::IsGrid( workingGridNode ) ) THROW_UNKNOWN_NODE_IO_ERROR( workingGridNode->GetName(), wxT( "GRIDS -> WORKINGGRID" ) ); else WorkingGrid.Parse( workingGridNode ); } else if( cNodeName == wxT( "SCREENGRID" ) ) { XNODE* screenGridNode = cNode->GetChildren(); if( !GRID::IsGrid( screenGridNode ) ) THROW_UNKNOWN_NODE_IO_ERROR( screenGridNode->GetName(), wxT( "GRIDS -> SCREENGRID" ) ); else ScreenGrid.Parse( screenGridNode ); } else if( GRID::IsGrid( cNode ) ) { GRID userGrid; userGrid.Parse( cNode ); UserGrids.push_back( userGrid ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::FIGURE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "FIGURE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LineCodeID = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); bool shapeIsInitialised = false; // Stop more than one Shape Object wxString location = wxString::Format( "Figure %s", ID ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeIsInitialised && Shape.IsShape( cNode ) ) { Shape.Parse( cNode ); shapeIsInitialised = true; } else if( cNodeName == wxT( "SWAPRULE" ) ) { SwapRule = ParseSwapRule( cNode ); } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } CADSTAR_PCB_ARCHIVE_PARSER::SWAP_RULE CADSTAR_PCB_ARCHIVE_PARSER::ParseSwapRule( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SWAPRULE" ) ); SWAP_RULE retval; wxString swapRuleStr = GetXmlAttributeIDString( aNode, 0 ); if( swapRuleStr == wxT( "NO_SWAP" ) ) retval = SWAP_RULE::NO_SWAP; else if( swapRuleStr == wxT( "USE_SWAP_LAYER" ) ) retval = SWAP_RULE::USE_SWAP_LAYER; else THROW_UNKNOWN_PARAMETER_IO_ERROR( swapRuleStr, wxT( "SWAPRULE" ) ); return retval; } void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT_COPPER::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COMPCOPPER" ) ); CopperCodeID = GetXmlAttributeIDString( aNode, 0 ); LayerID = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); bool shapeIsInitialised = false; // Stop more than one Shape Object wxString location = wxT( "COMPCOPPER" ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeIsInitialised && Shape.IsShape( cNode ) ) { Shape.Parse( cNode ); shapeIsInitialised = true; } else if( cNodeName == wxT( "SWAPRULE" ) ) { SwapRule = ParseSwapRule( cNode ); } else if( cNodeName == wxT( "ASSOCPIN" ) ) { wxXmlAttribute* xmlAttribute = cNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; long padId; if( !xmlAttribute->GetValue().ToLong( &padId ) ) THROW_PARSING_IO_ERROR( wxT( "ASSOCPIN" ), location ); AssociatedPadIDs.push_back( (PAD_ID) padId ); } CheckNoChildNodes( cNode ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT_AREA::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COMPAREA" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LineCodeID = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 3 ); XNODE* cNode = aNode->GetChildren(); bool shapeIsInitialised = false; // Stop more than one Shape Object wxString location = wxString::Format( "COMPAREA %s", ID ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeIsInitialised && SHAPE::IsShape( cNode ) ) { Shape.Parse( cNode ); shapeIsInitialised = true; } else if( cNodeName == wxT( "SWAPRULE" ) ) { SwapRule = ParseSwapRule( cNode ); } else if( cNodeName == wxT( "USAGE" ) ) { wxXmlAttribute* xmlAttribute = cNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) ) NoTracks = true; else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) ) NoVias = true; else THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location ); } CheckNoChildNodes( cNode ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PAD_EXITS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "EXITS" ) ); wxXmlAttribute* xmlAttribute = aNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; if( xmlAttribute->GetValue() == wxT( "FREE" ) ) FreeAngle = true; else if( xmlAttribute->GetValue() == wxT( "N" ) ) North = true; else if( xmlAttribute->GetValue() == wxT( "S" ) ) South = true; else if( xmlAttribute->GetValue() == wxT( "E" ) ) East = true; else if( xmlAttribute->GetValue() == wxT( "W" ) ) West = true; else if( xmlAttribute->GetValue() == wxT( "NE" ) ) NorthEast = true; else if( xmlAttribute->GetValue() == wxT( "NW" ) ) NorthWest = true; else if( xmlAttribute->GetValue() == wxT( "SE" ) ) SouthEast = true; else if( xmlAttribute->GetValue() == wxT( "SW" ) ) SouthWest = true; else THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), wxT( "EXITS" ) ); } CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::PAD::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PAD" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); PadCodeID = GetXmlAttributeIDString( aNode, 2 ); wxString padSideStr = GetXmlAttributeIDString( aNode, 3 ); if( padSideStr == wxT( "THRU" ) ) Side = PAD_SIDE::THROUGH_HOLE; else if( padSideStr == wxT( "BOTTOM" ) ) Side = PAD_SIDE::MAXIMUM; else if( padSideStr == wxT( "TOP" ) ) Side = PAD_SIDE::MINIMUM; XNODE* cNode = aNode->GetChildren(); wxString location = wxString::Format( "PAD %d", ID ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "FIRSTPAD" ) ) FirstPad = true; else if( cNodeName == wxT( "EXITS" ) ) Exits.Parse( cNode ); else if( cNodeName == wxT( "PADIDENTIFIER" ) ) Identifier = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "PCBONLYPAD" ) ) PCBonlyPad = true; else if( cNodeName == wxT( "PT" ) ) Position.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::TEXT_LOCATION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TEXTLOC" ) ); wxString attributeStr = GetXmlAttributeIDString( aNode, 0 ); bool attributeIDisSet = false; if( attributeStr == wxT( "PART_NAME" ) ) { AttributeID = PART_NAME_ATTRID; attributeIDisSet = true; } else if( attributeStr == wxT( "COMP_NAME" ) ) { AttributeID = COMPONENT_NAME_ATTRID; attributeIDisSet = true; } else if( attributeStr == wxT( "COMP_NAME2" ) ) { AttributeID = COMPONENT_NAME_2_ATTRID; attributeIDisSet = true; } else if( attributeStr == wxT( "ATTRREF" ) ) { //We will initialise when we parse all child nodes attributeIDisSet = false; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( attributeStr, wxT( "TEXTLOC" ) ); } TextCodeID = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 2 ); //Parse child nodes XNODE* cNode = aNode->GetChildren(); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "TEXTLOC" ) ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PT" ) ) Position.Parse( cNode ); else if( !attributeIDisSet && cNodeName == wxT( "ATTRREF" ) ) { AttributeID = GetXmlAttributeIDString( cNode, 0 ); attributeIDisSet = true; } else if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "ALIGN" ) ) Alignment = ParseAlignment( cNode ); else if( cNodeName == wxT( "JUSTIFICATION" ) ) Justification = ParseJustification( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEXTLOC" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::TEXT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TEXT" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); //TODO: Need to lex/parse "Text" to identify design fields (e.g "<@DESIGN_TITLE@>") and // hyperlinks (e.g. "<@HYPERLINK\"[link]\"[link text]@>") Text = GetXmlAttributeIDString( aNode, 1 ); TextCodeID = GetXmlAttributeIDString( aNode, 2 ); LayerID = GetXmlAttributeIDString( aNode, 3 ); XNODE* cNode = aNode->GetChildren(); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "TEXT" ) ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PT" ) ) Position.Parse( cNode ); else if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "SWAPRULE" ) ) SwapRule = ParseSwapRule( cNode ); else if( cNodeName == wxT( "ALIGN" ) ) Alignment = ParseAlignment( cNode ); else if( cNodeName == wxT( "JUSTIFICATION" ) ) Justification = ParseJustification( cNode ); else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEXT" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::ARROW::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "DIMARROW" ) ); bool arrowStyleInitialised = false; bool upperAngleInitialised = false; bool lowerAngleInitialised = false; ArrowLength = GetXmlAttributeIDLong( aNode, 3 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ARROWSTYLE" ) ) { wxString arrowStyleStr = GetXmlAttributeIDString( cNode, 0 ); arrowStyleInitialised = true; if( arrowStyleStr == wxT( "DIMENSION_ARROWOPEN" ) ) ArrowStyle = STYLE::OPEN; else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSED" ) ) ArrowStyle = STYLE::CLOSED; else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLEAR" ) ) ArrowStyle = STYLE::CLEAR; else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSEDFILLED" ) ) ArrowStyle = STYLE::CLOSED_FILLED; else THROW_UNKNOWN_PARAMETER_IO_ERROR( arrowStyleStr, cNodeName ); } else if( cNodeName == wxT( "ARROWANGLEA" ) ) { UpperAngle = GetXmlAttributeIDLong( cNode, 0 ); upperAngleInitialised = true; } else if( cNodeName == wxT( "ARROWANGLEB" ) ) { UpperAngle = GetXmlAttributeIDLong( cNode, 0 ); lowerAngleInitialised = true; } else { THROW_UNKNOWN_PARAMETER_IO_ERROR( cNodeName, wxT( "DIMARROW" ) ); } } if( !arrowStyleInitialised ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWSTYLE" ), wxT( "DIMARROW" ) ); if( !upperAngleInitialised ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEA" ), wxT( "DIMARROW" ) ); if( !lowerAngleInitialised ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEB" ), wxT( "DIMARROW" ) ); } void CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::TEXTFORMAT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "DIMTEXT" ) ); TextGap = GetXmlAttributeIDLong( aNode, 1 ); TextOffset = GetXmlAttributeIDLong( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); if( cNode->GetName() != wxT( "TXTSTYLE" ) ) THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "DIMTEXT" ) ); wxString styleStr = GetXmlAttributeIDString( cNode, 0 ); if( styleStr == wxT( "DIMENSION_INTERNAL" ) ) Style = STYLE::INSIDE; else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) ) Style = STYLE::OUTSIDE; else THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, wxT( "TXTSTYLE" ) ); CheckNoNextNodes( cNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::EXTENSION_LINE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "EXTLINE" ) ); LineCodeID = GetXmlAttributeIDString( aNode, 0 ); Overshoot = GetXmlAttributeIDLong( aNode, 3 ); Offset = GetXmlAttributeIDLong( aNode, 4 ); XNODE* cNode = aNode->GetChildren(); int noOfPoints = 0; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( noOfPoints < 2 && cNodeName == wxT( "PT" ) ) { ++noOfPoints; if( noOfPoints == 1 ) Start.Parse( cNode ); else End.Parse( cNode ); } else if( cNodeName == wxT( "SUPPRESSFIRST" ) ) SuppressFirst = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "EXTLINE" ) ); } if( noOfPoints != 2 ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), wxT( "EXTLINE" ) ); } bool CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::LINE::IsLine( XNODE* aNode ) { if( aNode->GetName() == wxT( "LEADERLINE" ) || aNode->GetName() == wxT( "LINEARLINE" ) || aNode->GetName() == wxT( "ANGULARLINE" ) ) return true; else return false; } void CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::LINE::Parse( XNODE* aNode ) { wxASSERT( IsLine( aNode ) ); if( aNode->GetName() == wxT( "LINEARLINE" ) ) Type = TYPE::LINEARLINE; else if( aNode->GetName() == wxT( "LEADERLINE" ) ) Type = TYPE::LEADERLINE; else if( aNode->GetName() == wxT( "ANGULARLINE" ) ) Type = TYPE::ANGULARLINE; else wxASSERT_MSG( true, "Not a valid type. What happened to the node Name?" ); LineCodeID = GetXmlAttributeIDString( aNode, 0 ); if( Type == TYPE::LEADERLINE ) { LeaderLineLength = GetXmlAttributeIDLong( aNode, 5 ); LeaderLineExtensionLength = GetXmlAttributeIDLong( aNode, 6 ); } XNODE* cNode = aNode->GetChildren(); int noOfPoints = 0; int requiredNoOfPoints = 2; if( Type == TYPE::ANGULARLINE ) requiredNoOfPoints = 3; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "DIMLINETYPE" ) ) { wxString styleStr = GetXmlAttributeIDString( cNode, 0 ); if( styleStr == wxT( "DIMENSION_INTERNAL" ) ) Style = STYLE::INTERNAL; else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) ) Style = STYLE::EXTERNAL; else THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, cNodeName ); } else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT( "PT" ) ) { ++noOfPoints; if( noOfPoints == 1 ) Start.Parse( cNode ); else if( noOfPoints == 2 ) End.Parse( cNode ); else Centre.Parse( cNode ); } else if( Type == TYPE::LEADERLINE && cNodeName == wxT( "LEADERANG" ) ) { LeaderAngle = GetXmlAttributeIDLong( cNode, 0 ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } if( noOfPoints != requiredNoOfPoints ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() ); } bool CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::IsDimension( XNODE* aNode ) { if( aNode->GetName() == wxT( "LINEARDIM" ) || aNode->GetName() == wxT( "LEADERDIM" ) || aNode->GetName() == wxT( "ANGLEDIM" ) ) return true; else return false; } void CADSTAR_PCB_ARCHIVE_PARSER::DIMENSION::Parse( XNODE* aNode ) { wxASSERT( IsDimension( aNode ) ); std::map typeMap = { { wxT( "LINEARDIM" ), TYPE::LINEARDIM }, { wxT( "LEADERDIM" ), TYPE::LEADERDIM }, { wxT( "ANGLEDIM" ), TYPE::ANGLEDIM } }; //make sure aNode is valid TYPE wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(), "Not a valid type. What happened to the node Name?" ); Type = typeMap[aNode->GetName()]; LayerID = GetXmlAttributeIDString( aNode, 1 ); wxString subTypeStr = GetXmlAttributeIDString( aNode, 2 ); std::map subTypeMap = { { wxT( "DIMENSION_ORTHOGONAL" ), SUBTYPE::ORTHOGONAL }, { wxT( "DIMENSION_DIRECT" ), SUBTYPE::DIRECT }, { wxT( "DIMENSION_ANGLED" ), SUBTYPE::ANGLED }, { wxT( "DIMENSION_DIAMETER" ), SUBTYPE::DIAMETER }, { wxT( "DIMENSION_RADIUS" ), SUBTYPE::RADIUS }, { wxT( "DIMENSION_ANGULAR" ), SUBTYPE::ANGULAR } }; if( subTypeMap.find( subTypeStr ) == subTypeMap.end() ) THROW_UNKNOWN_PARAMETER_IO_ERROR( subTypeStr, aNode->GetName() ); Subtype = subTypeMap[subTypeStr]; Precision = GetXmlAttributeIDLong( aNode, 3 ); XNODE* cNode = aNode->GetChildren(); bool idParsed = false; bool unitsParsed = false; //UNITS or ANGUNITS bool arrowParsed = false; bool textFormatParsed = false; bool extLineParsed = false; bool lineParsed = false; bool textParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !idParsed && cNodeName == wxT( "DIMREF" ) ) { ID = GetXmlAttributeIDString( cNode, 0 ); idParsed = true; } else if( !unitsParsed && cNodeName == wxT( "UNITS" ) ) { LinearUnits = ParseUnits( cNode ); unitsParsed = true; } else if( !unitsParsed && cNodeName == wxT( "ANGUNITS" ) ) { AngularUnits = ParseAngunits( cNode ); unitsParsed = true; } else if( !arrowParsed && cNodeName == wxT( "DIMARROW" ) ) { Arrow.Parse( cNode ); arrowParsed = true; } else if( !textFormatParsed && cNodeName == wxT( "DIMTEXT" ) ) { TextParams.Parse( cNode ); textFormatParsed = true; } else if( !extLineParsed && cNodeName == wxT( "EXTLINE" ) ) { ExtensionLineParams.Parse( cNode ); extLineParsed = true; } else if( !lineParsed && LINE::IsLine( cNode ) ) { Line.Parse( cNode ); lineParsed = true; } else if( !textParsed && cNodeName == wxT( "TEXT" ) ) { Text.Parse( cNode ); textParsed = true; } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::SYMDEF::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SYMDEF" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); ReferenceName = GetXmlAttributeIDString( aNode, 1 ); wxString rest; if( ReferenceName.StartsWith( wxT( "JUMPERNF" ), &rest ) ) Type = SYMDEF_TYPE::JUMPER; else if( ReferenceName.StartsWith( wxT( "STARPOINTNF" ), &rest ) ) Type = SYMDEF_TYPE::STARPOINT; else if( ReferenceName == wxT( "TESTPOINT" ) ) Type = SYMDEF_TYPE::TESTPOINT; else Type = SYMDEF_TYPE::COMPONENT; Alternate = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); bool originParsed = false; bool symHeightParsed = false; bool vesionParsed = false; bool dimensionsParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !originParsed && cNodeName == wxT( "PT" ) ) { Origin.Parse( cNode ); originParsed = true; } else if( cNodeName == wxT( "STUB" ) ) { Stub = true; } else if( !symHeightParsed && cNodeName == wxT( "SYMHEIGHT" ) ) { SymHeight = GetXmlAttributeIDLong( cNode, 0 ); symHeightParsed = true; } else if( !vesionParsed && cNodeName == wxT( "VERSION" ) ) { Version = GetXmlAttributeIDLong( cNode, 0 ); vesionParsed = true; } else if( cNodeName == wxT( "FIGURE" ) ) { FIGURE figure; figure.Parse( cNode ); Figures.insert( std::make_pair( figure.ID, figure ) ); } else if( cNodeName == wxT( "COMPCOPPER" ) ) { COMPONENT_COPPER compcopper; compcopper.Parse( cNode ); ComponentCoppers.push_back( compcopper ); } else if( cNodeName == wxT( "COMPAREA" ) ) { COMPONENT_AREA area; area.Parse( cNode ); ComponentAreas.insert( std::make_pair( area.ID, area ) ); } else if( cNodeName == wxT( "TEXT" ) ) { TEXT txt; txt.Parse( cNode ); Texts.insert( std::make_pair( txt.ID, txt ) ); } else if( cNodeName == wxT( "PAD" ) ) { PAD pad; pad.Parse( cNode ); Pads.insert( std::make_pair( pad.ID, pad ) ); } else if( cNodeName == wxT( "TEXTLOC" ) ) { TEXT_LOCATION textloc; textloc.Parse( cNode ); TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attrVal; attrVal.Parse( cNode ); AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) ); } else if( !dimensionsParsed && cNodeName == wxT( "DIMENSIONS" ) ) { XNODE* dimensionNode = cNode->GetChildren(); for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() ) { if( DIMENSION::IsDimension( dimensionNode ) ) { DIMENSION dim; dim.Parse( dimensionNode ); Dimensions.insert( std::make_pair( dim.ID, dim ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName ); } dimensionsParsed = true; } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } if( !originParsed ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() ); } void CADSTAR_PCB_ARCHIVE_PARSER::LIBRARY::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LIBRARY" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "SYMDEF" ) ) { SYMDEF symdef; symdef.Parse( cNode ); ComponentDefinitions.insert( std::make_pair( symdef.ID, symdef ) ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::GATE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "GATEDEFINITION" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); Alternate = GetXmlAttributeIDString( aNode, 2 ); PinCount = GetXmlAttributeIDLong( aNode, 3 ); CheckNoChildNodes( aNode ); } CADSTAR_PCB_ARCHIVE_PARSER::PART::PIN_TYPE CADSTAR_PCB_ARCHIVE_PARSER::PART::GetPinType( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PINTYPE" ) ); wxString pinTypeStr = GetXmlAttributeIDString( aNode, 0 ); std::map pinTypeMap = { { wxT( "INPUT" ), PIN_TYPE::INPUT }, { wxT( "OUTPUT_OR" ), PIN_TYPE::OUTPUT_OR }, { wxT( "OUTPUT_NOT_OR" ), PIN_TYPE::OUTPUT_NOT_OR }, { wxT( "OUTPUT_NOT_NORM_OR" ), PIN_TYPE::OUTPUT_NOT_NORM_OR }, { wxT( "POWER" ), PIN_TYPE::POWER }, { wxT( "GROUND" ), PIN_TYPE::GROUND }, { wxT( "TRISTATE_BIDIR" ), PIN_TYPE::TRISTATE_BIDIR }, { wxT( "TRISTATE_INPUT" ), PIN_TYPE::TRISTATE_INPUT }, { wxT( "TRISTATE_DRIVER" ), PIN_TYPE::TRISTATE_DRIVER } }; if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() ) THROW_UNKNOWN_PARAMETER_IO_ERROR( pinTypeStr, aNode->GetName() ); return pinTypeMap[pinTypeStr]; } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::PIN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PARTDEFINITIONPIN" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PINNAME" ) ) Name = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "PINLABEL" ) ) Label = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "PINSIGNAL" ) ) Signal = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "PINTERM" ) ) { TerminalGate = GetXmlAttributeIDString( cNode, 0 ); TerminalPin = GetXmlAttributeIDLong( cNode, 1 ); } else if( cNodeName == wxT( "PINTYPE" ) ) Type = GetPinType( cNode ); else if( cNodeName == wxT( "PINLOAD" ) ) Load = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "PINPOSITION" ) ) Position = (POSITION) GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "PINIDENTIFIER" ) ) Identifier = GetXmlAttributeIDString( cNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PART::PART_PIN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PARTPIN" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PINNAME" ) ) Name = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "PINTYPE" ) ) Type = GetPinType( cNode ); else if( cNodeName == wxT( "PINIDENTIFIER" ) ) Identifier = GetXmlAttributeIDString( cNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::PIN_EQUIVALENCE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PINEQUIVALENCE" ) ); wxXmlAttribute* xmlAttribute = aNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; long pinId; if( !xmlAttribute->GetValue().ToLong( &pinId ) ) THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), aNode->GetName() ); PinIDs.push_back( (PART_DEFINITION_PIN_ID) pinId ); } CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::SWAP_GATE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SWAPGATE" ) ); wxXmlAttribute* xmlAttribute = aNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; long pinId; if( !xmlAttribute->GetValue().ToLong( &pinId ) ) THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), aNode->GetName() ); PinIDs.push_back( (PART_DEFINITION_PIN_ID) pinId ); } CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::SWAP_GROUP::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "SWAPGROUP" ) ); GateName = GetXmlAttributeIDString( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "EXTERNAL" ) ) External = true; else if( cNodeName == wxT( "SWAPGATE" ) ) { SWAP_GATE swapGate; swapGate.Parse( cNode ); SwapGates.push_back( swapGate ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PART::DEFINITION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PARTDEFINITION" ) ); Name = GetXmlAttributeIDString( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "HIDEPINNAMES" ) ) HidePinNames = true; else if( cNodeName == wxT( "MAXPIN" ) ) MaxPinCount = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "GATEDEFINITION" ) ) { GATE gate; gate.Parse( cNode ); GateSymbols.insert( std::make_pair( gate.ID, gate ) ); } else if( cNodeName == wxT( "PARTDEFINITIONPIN" ) ) { PIN pin; pin.Parse( cNode ); Pins.insert( std::make_pair( pin.ID, pin ) ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else if( cNodeName == wxT( "PINEQUIVALENCE" ) ) { PIN_EQUIVALENCE pinEq; pinEq.Parse( cNode ); PinEquivalences.push_back( pinEq ); } else if( cNodeName == wxT( "SWAPGROUP" ) ) { SWAP_GROUP swapGroup; swapGroup.Parse( cNode ); SwapGroups.push_back( swapGroup ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PART::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PART" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "VERSION" ) ) Version = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "PARTDEFINITION" ) ) { Definition.Parse( cNode ); } else if( cNodeName == wxT( "PARTPIN" ) ) { PART_PIN pin; pin.Parse( cNode ); PartPins.insert( std::make_pair( pin.ID, pin ) ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PARTS::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PARTS" ) ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PART" ) ) { PART part; part.Parse( cNode ); PartDefinitions.insert( std::make_pair( part.ID, part ) ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::BOARD::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "BOARD" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LineCodeID = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); bool shapeIsInitialised = false; // Stop more than one Shape Object wxString location = wxString::Format( "BOARD %s", ID ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeIsInitialised && SHAPE::IsShape( cNode ) ) { Shape.Parse( cNode ); shapeIsInitialised = true; } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::AREA::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "AREA" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LineCodeID = GetXmlAttributeIDString( aNode, 1 ); Name = GetXmlAttributeIDString( aNode, 2 ); LayerID = GetXmlAttributeIDString( aNode, 4 ); XNODE* cNode = aNode->GetChildren(); bool shapeIsInitialised = false; // Stop more than one Shape Object wxString location = wxString::Format( "AREA %s", ID ); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeIsInitialised && SHAPE::IsShape( cNode ) ) { Shape.Parse( cNode ); shapeIsInitialised = true; } else if( cNodeName == wxT( "FIX" ) ) { Fixed = true; } else if( cNodeName == wxT( "USAGE" ) ) { wxXmlAttribute* xmlAttribute = cNode->GetAttributes(); for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() ) { if( !IsValidAttribute( xmlAttribute ) ) continue; if( xmlAttribute->GetValue() == wxT( "PLACEMENT" ) ) Placement = true; else if( xmlAttribute->GetValue() == wxT( "ROUTING" ) ) Routing = true; else if( xmlAttribute->GetValue() == wxT( "KEEPOUT" ) ) Keepout = true; else if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) ) NoTracks = true; else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) ) NoVias = true; else THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location ); } CheckNoChildNodes( cNode ); } else if( cNodeName == wxT( "AREAHEIGHT" ) ) { AreaHeight = GetXmlAttributeIDLong( cNode, 0 ); } else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location ); } } void CADSTAR_PCB_ARCHIVE_PARSER::PIN_ATTRIBUTE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PINATTR" ) ); Pin = GetXmlAttributeIDLong( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attrVal; attrVal.Parse( cNode ); AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } } void CADSTAR_PCB_ARCHIVE_PARSER::COMPONENT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COMP" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); PartID = GetXmlAttributeIDString( aNode, 2 ); SymdefID = GetXmlAttributeIDString( aNode, 3 ); XNODE* cNode = aNode->GetChildren(); bool originParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !originParsed && cNodeName == wxT( "PT" ) ) { Origin.Parse( cNode ); originParsed = true; } else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "TESTPOINT" ) ) TestPoint = true; else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "READABILITY" ) ) { Readability = ParseReadability( cNode ); } else if( cNodeName == wxT( "ORIENT" ) ) { OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); } else if( cNodeName == wxT( "TEXTLOC" ) ) { TEXT_LOCATION textloc; textloc.Parse( cNode ); TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attrVal; attrVal.Parse( cNode ); AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) ); } else if( cNodeName == wxT( "PINATTR" ) ) { PIN_ATTRIBUTE pinAttr; pinAttr.Parse( cNode ); PinAttributes.insert( std::make_pair( pinAttr.Pin, pinAttr ) ); } else if( cNodeName == wxT( "COMPPINLABEL" ) ) { PART_DEFINITION_PIN_ID pinID = GetXmlAttributeIDLong( cNode, 0 ); wxString pinLabel = GetXmlAttributeIDString( cNode, 1 ); PinLabels.insert( std::make_pair( pinID, pinLabel ) ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } if( !originParsed ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() ); } void CADSTAR_PCB_ARCHIVE_PARSER::DOCUMENTATION_SYMBOL::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "DOCSYMBOL" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); SymdefID = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); bool originParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !originParsed && cNodeName == wxT( "PT" ) ) { Origin.Parse( cNode ); originParsed = true; } else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "READABILITY" ) ) { Readability = ParseReadability( cNode ); } else if( cNodeName == wxT( "ORIENT" ) ) { OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else if( cNodeName == wxT( "SCALE" ) ) { ScaleRatioNumerator = GetXmlAttributeIDLong( cNode, 0 ); ScaleRatioDenominator = GetXmlAttributeIDLong( cNode, 1 ); } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } if( !originParsed ) THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() ); } void CADSTAR_PCB_ARCHIVE_PARSER::ATTRIBUTE_LOCATION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ATTRLOC" ) ); TextCodeID = GetXmlAttributeIDString( aNode, 0 ); LayerID = GetXmlAttributeIDString( aNode, 1 ); //Parse child nodes XNODE* cNode = aNode->GetChildren(); if( !cNode ) THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "ATTRLOC" ) ); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PT" ) ) Position.Parse( cNode ); else if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "ALIGN" ) ) Alignment = ParseAlignment( cNode ); else if( cNodeName == wxT( "JUSTIFICATION" ) ) Justification = ParseJustification( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "ATTRLOC" ) ); } } CADSTAR_PCB_ARCHIVE_PARSER::TESTLAND_SIDE CADSTAR_PCB_ARCHIVE_PARSER::ParseTestlandSide( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TESTLAND" ) ); wxString side = GetXmlAttributeIDString( aNode, 0 ); if( side == wxT( "MIN_SIDE" ) ) return TESTLAND_SIDE::MIN; else if( side == wxT( "MAX_SIDE" ) ) return TESTLAND_SIDE::MAX; else if( side == wxT( "BOTH_SIDES" ) ) return TESTLAND_SIDE::BOTH; else THROW_UNKNOWN_PARAMETER_IO_ERROR( side, aNode->GetName() ); return TESTLAND_SIDE::NONE; } void CADSTAR_PCB_ARCHIVE_PARSER::NET::PIN::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "PIN" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); ComponentID = GetXmlAttributeIDString( aNode, 1 ); PadID = GetXmlAttributeIDLong( aNode, 2 ); CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::NET::VIA::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "VIA" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); ViaCodeID = GetXmlAttributeIDString( aNode, 1 ); LayerPairID = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PT" ) ) Location.Parse( cNode ); else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "TESTLAND" ) ) TestlandSide = ParseTestlandSide( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::NET::JUNCTION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "JPT" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LayerID = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "PT" ) ) Location.Parse( cNode ); else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::NET::COPPER_TERMINAL::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COPTERM" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); CopperID = GetXmlAttributeIDString( aNode, 1 ); CopperTermNum = GetXmlAttributeIDLong( aNode, 2 ); } XNODE* CADSTAR_PCB_ARCHIVE_PARSER::NET::ROUTE_VERTEX::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ROUTEWIDTH" ) ); RouteWidth = GetXmlAttributeIDLong( aNode, 0 ); XNODE* nextNode = aNode->GetNext(); if( nextNode->GetName() == wxT( "FIX" ) ) { Fixed = true; nextNode = nextNode->GetNext(); } if( !VERTEX::IsVertex( nextNode ) ) THROW_UNKNOWN_NODE_IO_ERROR( nextNode->GetName(), wxT( "ROUTE_VERTEX" ) ); Vertex.Parse( nextNode ); return nextNode; } void CADSTAR_PCB_ARCHIVE_PARSER::NET::ROUTE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "ROUTE" ) ); LayerID = GetXmlAttributeIDString( aNode, 0 ); //Parse child nodes XNODE* cNode = aNode->GetChildren(); bool startPointParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !startPointParsed && cNodeName == wxT( "PT" ) ) { startPointParsed = true; StartPoint.Parse( cNode ); } else if( cNodeName == wxT( "ROUTEWIDTH" ) ) { ROUTE_VERTEX rtVert; cNode = rtVert.Parse( cNode ); RouteVertices.push_back( rtVert ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "ROUTE" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::NET::CONNECTION::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "CONN" ) ); StartNode = GetXmlAttributeIDString( aNode, 0 ); EndNode = GetXmlAttributeIDString( aNode, 1 ); RouteCodeID = GetXmlAttributeIDString( aNode, 2 ); //Parse child nodes XNODE* cNode = aNode->GetChildren(); bool routeParsed = false; //assume only one route per connection for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !Unrouted && !routeParsed && cNodeName == wxT( "ROUTE" ) ) { Route.Parse( cNode ); routeParsed = true; } else if( !routeParsed && cNodeName == wxT( "UNROUTE" ) ) { Unrouted = true; UnrouteLayerID = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "HIDDEN" ) ) Hidden = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attrVal; attrVal.Parse( cNode ); AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::NET::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "NET" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); //Parse child nodes XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "NETCODE" ) ) { RouteCodeID = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "SIGNAME" ) ) { Name = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "SIGNUM" ) ) { SignalNum = GetXmlAttributeIDLong( cNode, 0 ); } else if( cNodeName == wxT( "HIGHLIT" ) ) { Highlight = true; } else if( cNodeName == wxT( "PIN" ) ) { PIN pin; pin.Parse( cNode ); Pins.insert( std::make_pair( pin.ID, pin ) ); } else if( cNodeName == wxT( "VIA" ) ) { VIA via; via.Parse( cNode ); Vias.insert( std::make_pair( via.ID, via ) ); } else if( cNodeName == wxT( "JPT" ) ) { JUNCTION jpt; jpt.Parse( cNode ); Junctions.insert( std::make_pair( jpt.ID, jpt ) ); } else if( cNodeName == wxT( "COPTERM" ) ) { COPPER_TERMINAL cterm; cterm.Parse( cNode ); CopperTerminals.insert( std::make_pair( cterm.ID, cterm ) ); } else if( cNodeName == wxT( "CONN" ) ) { CONNECTION conn; conn.Parse( cNode ); Connections.push_back( conn ); } else if( cNodeName == wxT( "NETCLASSREF" ) ) { NetClassID = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "SPACINGCLASS" ) ) { SpacingClassID = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attrVal; attrVal.Parse( cNode ); AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::TEMPLATE::POURING::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "POURING" ) ); CopperCodeID = GetXmlAttributeIDString( aNode, 0 ); ReliefCopperCodeID = GetXmlAttributeIDString( aNode, 1 ); ClearanceWidth = GetXmlAttributeIDLong( aNode, 2 ); SliverWidth = GetXmlAttributeIDLong( aNode, 3 ); AdditionalIsolation = GetXmlAttributeIDLong( aNode, 4 ); ThermalReliefPadsAngle = GetXmlAttributeIDLong( aNode, 5 ); ThermalReliefViasAngle = GetXmlAttributeIDLong( aNode, 6 ); wxString MinIsolCopStr = GetXmlAttributeIDString( aNode, 7 ); if( MinIsolCopStr == wxT( "NONE" ) ) MinIsolatedCopper = UNDEFINED_VALUE; else MinIsolatedCopper = GetXmlAttributeIDLong( aNode, 7 ); wxString MinDisjCopStr = GetXmlAttributeIDString( aNode, 8 ); if( MinDisjCopStr == wxT( "NONE" ) ) MinDisjointCopper = UNDEFINED_VALUE; else MinDisjointCopper = GetXmlAttributeIDLong( aNode, 8 ); XNODE* cNode = aNode->GetChildren(); bool fillTypeParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "NOPINRELIEF" ) ) ThermalReliefOnPads = false; else if( cNodeName == wxT( "NOVIARELIEF" ) ) ThermalReliefOnVias = false; else if( cNodeName == wxT( "IGNORETRN" ) ) AllowInNoRouting = true; else if( cNodeName == wxT( "BOXPINS" ) ) BoxIsolatedPins = true; else if( cNodeName == wxT( "REGENERATE" ) ) AutomaticRepour = true; else if( cNodeName == wxT( "AUTOROUTETARGET" ) ) TargetForAutorouting = true; else if( cNodeName == wxT( "THERMALCUTOUT" ) ) ReliefType = RELIEF_TYPE::CUTOUTS; else if( !fillTypeParsed && cNodeName == wxT( "FILLED" ) ) { FillType = COPPER_FILL_TYPE::FILLED; fillTypeParsed = true; } else if( !fillTypeParsed && cNodeName == wxT( "HATCHCODEREF" ) ) { FillType = COPPER_FILL_TYPE::HATCHED; HatchCodeID = GetXmlAttributeIDString( cNode, 0 ); fillTypeParsed = true; } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "POURING" ) ); } if( !fillTypeParsed ) THROW_MISSING_NODE_IO_ERROR( wxT( "FILLED" ), wxT( "POURING" ) ); } void CADSTAR_PCB_ARCHIVE_PARSER::TEMPLATE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TEMPLATE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LineCodeID = GetXmlAttributeIDString( aNode, 1 ); Name = GetXmlAttributeIDString( aNode, 2 ); NetID = GetXmlAttributeIDString( aNode, 3 ); LayerID = GetXmlAttributeIDString( aNode, 4 ); XNODE* cNode = aNode->GetChildren(); bool shapeParsed = false; bool pouringParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeParsed && SHAPE::IsShape( cNode ) ) { Shape.Parse( cNode ); shapeParsed = true; } else if( !pouringParsed && cNodeName == wxT( "POURING" ) ) { Pouring.Parse( cNode ); pouringParsed = true; } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::COPPER::NETREF::TERMINAL::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "TERM" ) ); ID = GetXmlAttributeIDLong( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); bool locationParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !locationParsed && cNodeName == wxT( "PT" ) ) { Location.Parse( cNode ); locationParsed = true; } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::COPPER::NETREF::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "NETREF" ) ); NetID = GetXmlAttributeIDString( aNode, 0 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "TERM" ) ) { TERMINAL term; term.Parse( cNode ); Terminals.insert( std::make_pair( term.ID, term ) ); } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NETREF" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::COPPER::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "COPPER" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); CopperCodeID = GetXmlAttributeIDString( aNode, 1 ); LayerID = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); bool shapeParsed = false; bool netRefParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !shapeParsed && SHAPE::IsShape( cNode ) ) { Shape.Parse( cNode ); shapeParsed = true; } else if( !netRefParsed && cNodeName == wxT( "NETREF" ) ) { NetRef.Parse( cNode ); netRefParsed = true; } else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else if( cNodeName == wxT( "POURED" ) ) { PouredTemplateID = GetXmlAttributeIDString( cNode, 0 ); } else if( cNodeName == wxT( "ATTR" ) ) { ATTRIBUTE_VALUE attr; attr.Parse( cNode ); AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::GROUP::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "GROUP" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "GROUP" ) ); } } void CADSTAR_PCB_ARCHIVE_PARSER::REUSEBLOCK::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "REUSEBLOCK" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); Name = GetXmlAttributeIDString( aNode, 1 ); FileName = GetXmlAttributeIDString( aNode, 2 ); XNODE* cNode = aNode->GetChildren(); for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "REUSEBLOCK" ) ); } } bool CADSTAR_PCB_ARCHIVE_PARSER::REUSEBLOCKREF::IsEmpty() { return ReuseBlockID == wxEmptyString && ItemReference == wxEmptyString; } void CADSTAR_PCB_ARCHIVE_PARSER::REUSEBLOCKREF::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "REUSEBLOCKREF" ) ); ReuseBlockID = GetXmlAttributeIDString( aNode, 0 ); ItemReference = GetXmlAttributeIDString( aNode, 1 ); CheckNoChildNodes( aNode ); } void CADSTAR_PCB_ARCHIVE_PARSER::DRILL_TABLE::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "DRILLTABLE" ) ); ID = GetXmlAttributeIDString( aNode, 0 ); LayerID = GetXmlAttributeIDString( aNode, 1 ); XNODE* cNode = aNode->GetChildren(); bool positionParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !positionParsed && cNodeName == wxT( "PT" ) ) { Position.Parse( cNode ); positionParsed = true; } else if( cNodeName == wxT( "ORIENT" ) ) OrientAngle = GetXmlAttributeIDLong( cNode, 0 ); else if( cNodeName == wxT( "MIRROR" ) ) Mirror = true; else if( cNodeName == wxT( "FIX" ) ) Fixed = true; else if( cNodeName == wxT( "READABILITY" ) ) { Readability = ParseReadability( cNode ); } else if( cNodeName == wxT( "GROUPREF" ) ) GroupID = GetXmlAttributeIDString( cNode, 0 ); else if( cNodeName == wxT( "REUSEBLOCKREF" ) ) ReuseBlockRef.Parse( cNode ); else THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } void CADSTAR_PCB_ARCHIVE_PARSER::LAYOUT::Parse( XNODE* aNode ) { wxASSERT( aNode->GetName() == wxT( "LAYOUT" ) ); XNODE* cNode = aNode->GetChildren(); bool netSynchParsed = false; bool dimensionsParsed = false; for( ; cNode; cNode = cNode->GetNext() ) { wxString cNodeName = cNode->GetName(); if( !netSynchParsed && cNodeName == wxT( "NETSYNCH" ) ) { std::map netSynchMap = { { wxT( "WARNING" ), NETSYNCH::WARNING }, { wxT( "FULL" ), NETSYNCH::FULL } }; wxString nsString = GetXmlAttributeIDString( cNode, 0 ); if( netSynchMap.find( nsString ) == netSynchMap.end() ) THROW_UNKNOWN_PARAMETER_IO_ERROR( nsString, aNode->GetName() ); NetSynch = netSynchMap[nsString]; netSynchParsed = true; } else if( cNodeName == wxT( "GROUP" ) ) { GROUP group; group.Parse( cNode ); Groups.insert( std::make_pair( group.ID, group ) ); } else if( cNodeName == wxT( "REUSEBLOCK" ) ) { REUSEBLOCK reuseblock; reuseblock.Parse( cNode ); ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) ); } else if( cNodeName == wxT( "BOARD" ) ) { BOARD board; board.Parse( cNode ); Boards.insert( std::make_pair( board.ID, board ) ); } else if( cNodeName == wxT( "FIGURE" ) ) { FIGURE figure; figure.Parse( cNode ); Figures.insert( std::make_pair( figure.ID, figure ) ); } else if( cNodeName == wxT( "AREA" ) ) { AREA area; area.Parse( cNode ); Areas.insert( std::make_pair( area.ID, area ) ); } else if( cNodeName == wxT( "COMP" ) ) { COMPONENT comp; comp.Parse( cNode ); Components.insert( std::make_pair( comp.ID, comp ) ); } else if( cNodeName == wxT( "NET" ) ) { NET net; net.Parse( cNode ); Nets.insert( std::make_pair( net.ID, net ) ); } else if( cNodeName == wxT( "TEMPLATE" ) ) { TEMPLATE temp; temp.Parse( cNode ); Templates.insert( std::make_pair( temp.ID, temp ) ); } else if( cNodeName == wxT( "COPPER" ) ) { COPPER copper; copper.Parse( cNode ); Coppers.insert( std::make_pair( copper.ID, copper ) ); } else if( cNodeName == wxT( "TEXT" ) ) { TEXT txt; txt.Parse( cNode ); Texts.insert( std::make_pair( txt.ID, txt ) ); } else if( cNodeName == wxT( "DOCSYMBOL" ) ) { DOCUMENTATION_SYMBOL docsym; docsym.Parse( cNode ); DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) ); } else if( !dimensionsParsed && cNodeName == wxT( "DIMENSIONS" ) ) { XNODE* dimensionNode = cNode->GetChildren(); for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() ) { if( DIMENSION::IsDimension( dimensionNode ) ) { DIMENSION dim; dim.Parse( dimensionNode ); Dimensions.insert( std::make_pair( dim.ID, dim ) ); } else THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName ); } dimensionsParsed = true; } else if( cNodeName == wxT( "DRILLTABLE" ) ) { DRILL_TABLE drilltable; drilltable.Parse( cNode ); DrillTables.insert( std::make_pair( drilltable.ID, drilltable ) ); } else if( cNodeName == wxT( "ERRORMARK" ) ) { //ignore (this is a DRC error marker in cadstar) continue; } else { THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() ); } } }