KiCad PCB EDA Suite
cadstar_pcb_archive_parser.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
5  * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
27 #include <convert_to_biu.h> // PCB_IU_PER_MM
28 #include <macros.h>
29 #include <wx/translation.h>
30 
31 
33 {
34  XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ) );
35 
36  XNODE* cNode = fileRootNode->GetChildren();
37 
38  if( !cNode )
39  THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARPCB" ) );
40 
41  for( ; cNode; cNode = cNode->GetNext() )
42  {
43  if( cNode->GetName() == wxT( "HEADER" ) )
44  {
45  Header.Parse( cNode, &m_context );
46 
47  switch( Header.Resolution )
48  {
51  break;
52 
53  default:
54  wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
55  break;
56  }
57 
58  if( Header.Format.Type != wxT( "LAYOUT" ) )
59  {
60  if( Header.Format.Type == wxT( "LIBRARY" ) )
61  {
62  THROW_IO_ERROR( "The selected file is a CADSTAR library file (as opposed to a "
63  "layout file). CADSTAR libraries cannot yet be imported into "
64  "KiCad." );
65  }
66  else
67  {
68  THROW_IO_ERROR( "The selected file is an unknown CADSTAR format so cannot be "
69  "imported into KiCad." );
70  }
71  }
72  }
73  else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
74  {
75  Assignments.Parse( cNode, &m_context );
76  }
77  else if( cNode->GetName() == wxT( "LIBRARY" ) )
78  {
79  Library.Parse( cNode, &m_context );
80  }
81  else if( cNode->GetName() == wxT( "DEFAULTS" ) )
82  {
83  // No design information here (no need to parse)
84  // Only contains CADSTAR configuration data such as default shapes, text and units
85  // In future some of this could be converted to KiCad but limited value
86  }
87  else if( cNode->GetName() == wxT( "PARTS" ) )
88  {
89  Parts.Parse( cNode, &m_context );
90  }
91  else if( cNode->GetName() == wxT( "LAYOUT" ) )
92  {
93  Layout.Parse( cNode, &m_context );
94  }
95  else if( cNode->GetName() == wxT( "DISPLAY" ) )
96  {
97  // No design information here (no need to parse)
98  // Contains CADSTAR Display settings such as layer/element colours and visibility.
99  // In the future these settings could be converted to KiCad
100  }
101  else
102  {
103  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) );
104  }
105  }
106 
107  delete fileRootNode;
108 }
109 
110 
112 {
113  wxASSERT( aNode->GetName() == wxT( "ASSIGNMENTS" ) );
114 
115  XNODE* cNode = aNode->GetChildren();
116 
117  if( !cNode )
118  THROW_MISSING_NODE_IO_ERROR( wxT( "TECHNOLOGY" ), wxT( "ASSIGNMENTS" ) );
119 
120  for( ; cNode; cNode = cNode->GetNext() )
121  {
122  if( cNode->GetName() == wxT( "LAYERDEFS" ) )
123  Layerdefs.Parse( cNode, aContext );
124  else if( cNode->GetName() == wxT( "CODEDEFS" ) )
125  Codedefs.Parse( cNode, aContext );
126  else if( cNode->GetName() == wxT( "TECHNOLOGY" ) )
127  Technology.Parse( cNode, aContext );
128  else if( cNode->GetName() == wxT( "GRIDS" ) )
129  Grids.Parse( cNode, aContext );
130  else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
132  else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
134  else
135  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
136  }
137 }
138 
139 
141 {
142  wxASSERT( aNode->GetName() == wxT( "LAYERDEFS" ) );
143 
144  wxXmlAttribute* xmlAttribute = nullptr;
145 
146  XNODE* cNode = aNode->GetChildren();
147 
148  if( !cNode )
149  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "LAYERSTACK" ), wxT( "LAYERDEFS" ) );
150 
151  for( ; cNode; cNode = cNode->GetNext() )
152  {
153  wxString nodeName = cNode->GetName();
154 
155  if( nodeName == wxT( "LAYERSTACK" ) )
156  {
157  xmlAttribute = cNode->GetAttributes();
158 
159  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
160  {
161  if( !IsValidAttribute( xmlAttribute ) )
162  continue;
163  else
164  LayerStack.push_back( (LAYER_ID) xmlAttribute->GetValue() );
165  }
166 
167  CheckNoChildNodes( cNode );
168  }
169  else if( nodeName == wxT( "MATERIAL" ) )
170  {
171  MATERIAL material;
172  material.Parse( cNode, aContext );
173  Materials.insert( std::make_pair( material.ID, material ) );
174  }
175  else if( nodeName == wxT( "LAYER" ) )
176  {
177  LAYER layer;
178  layer.Parse( cNode, aContext );
179  Layers.insert( std::make_pair( layer.ID, layer ) );
180  }
181  else if( nodeName == wxT( "SWAPPAIR" ) )
182  {
183  LAYER_ID layerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 0 );
184  LAYER_ID swapLayerId = (LAYER_ID) GetXmlAttributeIDString( cNode, 1 );
185 
186  Layers[layerId].SwapLayerID = swapLayerId;
187  }
188  else
189  {
190  THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
191  }
192  }
193 }
194 
195 
197 {
198  wxASSERT( aNode->GetName() == wxT( "RULESET" ) );
199 
200  ID = GetXmlAttributeIDString( aNode, 0 );
201  Name = GetXmlAttributeIDString( aNode, 1 );
202 
203  XNODE* cNode = aNode->GetChildren();
204 
205  for( ; cNode; cNode = cNode->GetNext() )
206  {
207  wxString nodeName = cNode->GetName();
208 
209  if( nodeName == wxT( "ROUCODEREF" ) )
210  {
211  AreaRouteCodeID = GetXmlAttributeIDString( cNode, 0 );
212  }
213  else if( nodeName == wxT( "VIACODEREF" ) )
214  {
215  AreaViaCodeID = GetXmlAttributeIDString( cNode, 0 );
216  }
217  else if( nodeName == wxT( "SPACINGCODE" ) )
218  {
219  SPACINGCODE spacingcode;
220  spacingcode.Parse( cNode, aContext );
221  SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
222  }
223  else
224  {
225  THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
226  }
227  }
228 }
229 
230 
232 {
233  wxASSERT( aNode->GetName() == wxT( "CODEDEFS" ) );
234 
235  XNODE* cNode = aNode->GetChildren();
236 
237  for( ; cNode; cNode = cNode->GetNext() )
238  {
239  wxString nodeName = cNode->GetName();
240 
241  if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
242  {
243  }
244  else if( nodeName == wxT( "COPPERCODE" ) )
245  {
246  COPPERCODE coppercode;
247  coppercode.Parse( cNode, aContext );
248  CopperCodes.insert( std::make_pair( coppercode.ID, coppercode ) );
249  }
250  else if( nodeName == wxT( "SPACINGCODE" ) )
251  {
252  SPACINGCODE spacingcode;
253  spacingcode.Parse( cNode, aContext );
254  SpacingCodes.insert( std::make_pair( spacingcode.ID, spacingcode ) );
255  }
256  else if( nodeName == wxT( "RULESET" ) )
257  {
258  RULESET ruleset;
259  ruleset.Parse( cNode, aContext );
260  Rulesets.insert( std::make_pair( ruleset.ID, ruleset ) );
261  }
262  else if( nodeName == wxT( "PADCODE" ) )
263  {
264  PADCODE padcode;
265  padcode.Parse( cNode, aContext );
266  PadCodes.insert( std::make_pair( padcode.ID, padcode ) );
267  }
268  else if( nodeName == wxT( "VIACODE" ) )
269  {
270  VIACODE viacode;
271  viacode.Parse( cNode, aContext );
272  ViaCodes.insert( std::make_pair( viacode.ID, viacode ) );
273  }
274  else if( nodeName == wxT( "LAYERPAIR" ) )
275  {
276  LAYERPAIR layerpair;
277  layerpair.Parse( cNode, aContext );
278  LayerPairs.insert( std::make_pair( layerpair.ID, layerpair ) );
279  }
280  else if( nodeName == wxT( "SPCCLASSSPACE" ) )
281  {
282  SPCCLASSSPACE spcclassspace;
283  spcclassspace.Parse( cNode, aContext );
284  SpacingClasses.push_back( spcclassspace );
285  }
286  else
287  {
288  THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
289  }
290  }
291 }
292 
293 
295 {
296  wxASSERT( aNode->GetName() == wxT( "MATERIAL" ) );
297 
298  ID = GetXmlAttributeIDString( aNode, 0 );
299  Name = GetXmlAttributeIDString( aNode, 1 );
300 
301  wxString sType = GetXmlAttributeIDString( aNode, 2 );
302 
303  if( sType == wxT( "CONSTRUCTION" ) )
304  {
306  }
307  else if( sType == wxT( "ELECTRICAL" ) )
308  {
310  }
311  else if( sType == wxT( "NONELEC" ) )
312  {
314  }
315  else
316  {
317  THROW_UNKNOWN_PARAMETER_IO_ERROR( sType, wxString::Format( "MATERIAL %s", Name ) );
318  }
319 
320  XNODE* iNode = aNode->GetChildren();
321 
322  if( !iNode )
323  {
325  wxT( "RESISTIVITY" ), wxString::Format( "MATERIAL %s", Name ) );
326  }
327 
328  for( ; iNode; iNode = iNode->GetNext() )
329  {
330  wxString nodeName = iNode->GetName();
331 
332  if( nodeName == wxT( "RELPERMIT" ) )
333  {
334  ParseChildEValue( iNode, aContext, Permittivity );
335  }
336  else if( nodeName == wxT( "LOSSTANGENT" ) )
337  {
338  ParseChildEValue( iNode, aContext, LossTangent );
339  }
340  else if( nodeName == wxT( "RESISTIVITY" ) )
341  {
342  ParseChildEValue( iNode, aContext, Resistivity );
343  }
344  else
345  {
346  THROW_UNKNOWN_NODE_IO_ERROR( nodeName, wxString::Format( "MATERIAL %s", Name ) );
347  }
348  }
349 }
350 
351 
353 {
354  wxASSERT( aNode->GetName() == wxT( "LAYER" ) );
355 
356  ID = GetXmlAttributeIDString( aNode, 0 );
357  Name = GetXmlAttributeIDString( aNode, 1 );
358 
359  XNODE* cNode = aNode->GetChildren();
360  auto processLayerMaterialDetails = [&]() {
361  XNODE* tempNode = cNode->GetChildren();
362  for( ; tempNode; tempNode = tempNode->GetNext() )
363  {
364  wxString tempNodeName = tempNode->GetName();
365 
366  if( tempNodeName == wxT( "MAKE" ) || tempNodeName == wxT( "LAYERHEIGHT" ) )
367  {
368  if( tempNodeName == wxT( "LAYERHEIGHT" ) )
369  {
370  Thickness = GetXmlAttributeIDLong( tempNode, 0 );
371  }
372  else
373  {
374  MaterialId = GetXmlAttributeIDString( tempNode, 0 );
375  Thickness = GetXmlAttributeIDLong( tempNode, 1 );
376  }
377 
378  XNODE* childOfTempNode = tempNode->GetChildren();
379 
380  if( childOfTempNode )
381  {
382  if( childOfTempNode->GetName() == wxT( "EMBEDS" ) )
383  {
384  wxString embedsValue = GetXmlAttributeIDString( childOfTempNode, 0 );
385 
386  if( embedsValue == wxT( "UPWARDS" ) )
387  {
388  Embedding = EMBEDDING::ABOVE;
389  }
390  else if( embedsValue == wxT( "DOWNWARDS" ) )
391  {
392  Embedding = EMBEDDING::BELOW;
393  }
394  else
395  {
397  embedsValue, wxString::Format( "LAYER %s -> EMBEDS", Name ) );
398  }
399  }
400  else
401  {
402  THROW_UNKNOWN_NODE_IO_ERROR( childOfTempNode->GetName(),
403  wxString::Format( "LAYER %s->MAKE", Name ) );
404  }
405  }
406  }
407  else if( tempNodeName == wxT( "BIAS" ) )
408  {
409  wxString bias = GetXmlAttributeIDString( tempNode, 0 );
410 
411  if( bias == wxT( "X_BIASED" ) )
412  {
413  RoutingBias = ROUTING_BIAS::X;
414  }
415  else if( bias == wxT( "Y_BIASED" ) )
416  {
417  RoutingBias = ROUTING_BIAS::Y;
418  }
419  else if( bias == wxT( "ANTITRACK" ) )
420  {
421  RoutingBias = ROUTING_BIAS::ANTI_ROUTE;
422  }
423  else if( bias == wxT( "OBSTACLE" ) )
424  {
425  RoutingBias = ROUTING_BIAS::OBSTACLE;
426  }
427  else if( bias == wxT( "UNBIASED" ) )
428  {
429  RoutingBias = ROUTING_BIAS::UNBIASED;
430  }
431  else
432  {
434  bias, wxString::Format( "LAYER %s -> BIAS", Name ) );
435  }
436  }
437  else
438  {
439  THROW_UNKNOWN_NODE_IO_ERROR( tempNodeName, wxString::Format( "LAYER %s", Name ) );
440  }
441  }
442  };
443 
444  for( ; cNode; cNode = cNode->GetNext() )
445  {
446  wxString cNodeName = cNode->GetName();
447 
448  if( cNodeName == wxT( "ALLDOC" ) )
449  {
450  Type = LAYER_TYPE::ALLDOC;
451  }
452  else if( cNodeName == wxT( "ALLELEC" ) )
453  {
454  Type = LAYER_TYPE::ALLELEC;
455  }
456  else if( cNodeName == wxT( "ALLLAYER" ) )
457  {
458  Type = LAYER_TYPE::ALLLAYER;
459  }
460  else if( cNodeName == wxT( "ASSCOMPCOPP" ) )
461  {
463  }
464  else if( cNodeName == wxT( "JUMPERLAYER" ) )
465  {
467  }
468  else if( cNodeName == wxT( "NOLAYER" ) )
469  {
470  Type = LAYER_TYPE::NOLAYER;
471  }
472  else if( cNodeName == wxT( "POWER" ) )
473  {
474  Type = LAYER_TYPE::POWER;
475  PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
476  processLayerMaterialDetails();
477  }
478  else if( cNodeName == wxT( "DOC" ) )
479  {
480  Type = LAYER_TYPE::DOC;
481  }
482  else if( cNodeName == wxT( "CONSTRUCTION" ) )
483  {
485  processLayerMaterialDetails();
486  }
487  else if( cNodeName == wxT( "ELEC" ) )
488  {
489  Type = LAYER_TYPE::ELEC;
490  PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
491  processLayerMaterialDetails();
492  }
493  else if( cNodeName == wxT( "NONELEC" ) )
494  {
495  Type = LAYER_TYPE::NONELEC;
496  PhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
497  processLayerMaterialDetails();
498  }
499  else if( cNodeName == wxT( "DESCRIPTION" ) )
500  {
501  Description = GetXmlAttributeIDString( cNode, 0 );
502  }
503  else if( cNodeName == wxT( "REFPLANE" ) )
504  {
505  ReferencePlane = true;
506  }
507  else if( cNodeName == wxT( "VLAYER" ) )
508  {
509  VariantLayer = true;
510  }
511  else if( cNodeName == wxT( "LASUBTYP" ) )
512  {
513  //Process subtype
514  wxString sSubType = GetXmlAttributeIDString( cNode, 0 );
515 
516  if( sSubType == wxT( "LAYERSUBTYPE_ASSEMBLY" ) )
517  {
518  this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_ASSEMBLY;
519  }
520  else if( sSubType == wxT( "LAYERSUBTYPE_PASTE" ) )
521  {
522  this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_PASTE;
523  }
524  else if( sSubType == wxT( "LAYERSUBTYPE_PLACEMENT" ) )
525  {
527  }
528  else if( sSubType == wxT( "LAYERSUBTYPE_SILKSCREEN" ) )
529  {
531  }
532  else if( sSubType == wxT( "LAYERSUBTYPE_SOLDERRESIST" ) )
533  {
535  }
536  else if( sSubType == wxT( "LAYERSUBTYPE_CLEARANCE" ) )
537  {
539  }
540  else if( sSubType == wxT( "LAYERSUBTYPE_ROUT" ) )
541  {
542  this->SubType = LAYER_SUBTYPE::LAYERSUBTYPE_ROUT;
543  }
544  else
545  {
547  sSubType, wxString::Format( "LAYER %s %s", Name, cNodeName ) );
548  }
549  }
550  else
551  {
552  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxString::Format( "LAYER %s", Name ) );
553  }
554  }
555 }
556 
557 
559 {
560  wxASSERT( aNode->GetName() == wxT( "COPREASSIGN" ) );
561 
562  LayerID = GetXmlAttributeIDString( aNode, 0 );
563 
564  CopperWidth = GetXmlAttributeIDLong( aNode, 1 );
565 }
566 
567 
569 {
570  wxASSERT( aNode->GetName() == wxT( "COPPERCODE" ) );
571 
572  ID = GetXmlAttributeIDString( aNode, 0 );
573  Name = GetXmlAttributeIDString( aNode, 1 );
574 
575  CopperWidth = GetXmlAttributeIDLong( aNode, 2 );
576 
577  XNODE* cNode = aNode->GetChildren();
578 
579  for( ; cNode; cNode = cNode->GetNext() )
580  {
581  if( cNode->GetName() == wxT( "COPREASSIGN" ) )
582  {
584  reassign.Parse( cNode, aContext );
585  Reassigns.push_back( reassign );
586  }
587  else
588  {
589  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
590  }
591  }
592 }
593 
594 
596  PARSER_CONTEXT* aContext )
597 {
598  wxASSERT( aNode->GetName() == wxT( "SPACEREASSIGN" ) );
599 
600  LayerID = GetXmlAttributeIDString( aNode, 0 );
601  Spacing = GetXmlAttributeIDLong( aNode, 1 );
602 
603  CheckNoChildNodes( aNode );
604 }
605 
606 
608 {
609  wxASSERT( aNode->GetName() == wxT( "SPACINGCODE" ) );
610 
611  ID = GetXmlAttributeIDString( aNode, 0 );
612  Spacing = GetXmlAttributeIDLong( aNode, 1 );
613 
614  XNODE* cNode = aNode->GetChildren();
615 
616  for( ; cNode; cNode = cNode->GetNext() )
617  {
618  wxString cNodeName = cNode->GetName();
619 
620  if( cNodeName == wxT( "SPACEREASSIGN" ) )
621  {
622  REASSIGN reassign;
623  reassign.Parse( cNode, aContext );
624  Reassigns.push_back( reassign );
625  }
626  else
627  {
628  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
629  }
630  }
631 }
632 
633 
635 {
636  wxString aNodeName = aNode->GetName();
637 
638  if( aNodeName == wxT( "ANNULUS" ) || aNodeName == wxT( "BULLET" ) || aNodeName == wxT( "ROUND" )
639  || aNodeName == wxT( "DIAMOND" ) || aNodeName == wxT( "FINGER" )
640  || aNodeName == wxT( "OCTAGON" ) || aNodeName == wxT( "RECTANGLE" )
641  || aNodeName == wxT( "ROUNDED" ) || aNodeName == wxT( "SQUARE" ) )
642  {
643  return true;
644  }
645  else
646  {
647  return false;
648  }
649 }
650 
651 
653 {
654  wxASSERT( IsPadShape( aNode ) );
655 
656  wxString aNodeName = aNode->GetName();
657 
658  if( aNodeName == wxT( "ANNULUS" ) )
659  ShapeType = PAD_SHAPE_TYPE::ANNULUS;
660  else if( aNodeName == wxT( "BULLET" ) )
661  ShapeType = PAD_SHAPE_TYPE::BULLET;
662  else if( aNodeName == wxT( "ROUND" ) )
663  ShapeType = PAD_SHAPE_TYPE::CIRCLE;
664  else if( aNodeName == wxT( "DIAMOND" ) )
665  ShapeType = PAD_SHAPE_TYPE::DIAMOND;
666  else if( aNodeName == wxT( "FINGER" ) )
667  ShapeType = PAD_SHAPE_TYPE::FINGER;
668  else if( aNodeName == wxT( "OCTAGON" ) )
669  ShapeType = PAD_SHAPE_TYPE::OCTAGON;
670  else if( aNodeName == wxT( "RECTANGLE" ) )
671  ShapeType = PAD_SHAPE_TYPE::RECTANGLE;
672  else if( aNodeName == wxT( "ROUNDED" ) )
673  ShapeType = PAD_SHAPE_TYPE::ROUNDED_RECT;
674  else if( aNodeName == wxT( "SQUARE" ) )
675  ShapeType = PAD_SHAPE_TYPE::SQUARE;
676  else
677  wxASSERT( true );
678 
679  switch( ShapeType )
680  {
682  Size = GetXmlAttributeIDLong( aNode, 0 );
683  InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
684  break;
685 
687  InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
689 
693  RightLength = GetXmlAttributeIDLong( aNode, 2 );
694  LeftLength = GetXmlAttributeIDLong( aNode, 1 );
696 
700 
701  if( aNode->GetChildren() )
702  {
703  if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
704  {
705  OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
706  }
707  else
708  {
709  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
710  }
711 
712  CheckNoNextNodes( aNode->GetChildren() );
713  }
715 
717  Size = GetXmlAttributeIDLong( aNode, 0 );
718  break;
719  }
720 }
721 
722 
724 {
725  wxASSERT( aNode->GetName() == wxT( "PADREASSIGN" ) );
726 
727  LayerID = GetXmlAttributeIDString( aNode, 0 );
728 
730  Shape.Parse( aNode->GetChildren(), aContext );
731  else
732  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
733 
734  CheckNoNextNodes( aNode->GetChildren() );
735 }
736 
737 
739 {
740  wxASSERT( aNode->GetName() == wxT( "PADCODE" ) );
741 
742  ID = GetXmlAttributeIDString( aNode, 0 );
743  Name = GetXmlAttributeIDString( aNode, 1 );
744 
745  XNODE* cNode = aNode->GetChildren();
746  wxString location = wxString::Format( "PADCODE -> %s", Name );
747 
748  for( ; cNode; cNode = cNode->GetNext() )
749  {
750  wxString cNodeName = cNode->GetName();
751 
752  if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
753  {
754  Shape.Parse( cNode, aContext );
755  }
756  else if( cNodeName == wxT( "CLEARANCE" ) )
757  {
758  ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
759  }
760  else if( cNodeName == wxT( "RELIEFWIDTH" ) )
761  {
762  ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
763  }
764  else if( cNodeName == wxT( "DRILL" ) )
765  {
766  DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
767  XNODE* subNode = cNode->GetChildren();
768 
769  for( ; subNode; subNode = subNode->GetNext() )
770  {
771  wxString subNodeName = subNode->GetName();
772 
773  if( subNodeName == wxT( "NONPLATED" ) )
774  Plated = false;
775  else if( subNodeName == wxT( "OVERSIZE" ) )
776  DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
777  else
778  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
779  }
780  }
781  else if( cNodeName == wxT( "DRILLLENGTH" ) )
782  {
783  SlotLength = GetXmlAttributeIDLong( cNode, 0 );
784  }
785  else if( cNodeName == wxT( "DRILLORIENTATION" ) )
786  {
787  SlotOrientation = GetXmlAttributeIDLong( cNode, 0 );
788  }
789  else if( cNodeName == wxT( "DRILLXOFFSET" ) )
790  {
791  DrillXoffset = GetXmlAttributeIDLong( cNode, 0 );
792  }
793  else if( cNodeName == wxT( "DRILLYOFFSET" ) )
794  {
795  DrillYoffset = GetXmlAttributeIDLong( cNode, 0 );
796  }
797  else if( cNodeName == wxT( "PADREASSIGN" ) )
798  {
799  PADREASSIGN reassign;
800  reassign.Parse( cNode, aContext );
801  Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
802  }
803  else
804  {
805  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
806  }
807  }
808 }
809 
810 
812 {
813  wxASSERT( aNode->GetName() == wxT( "VIAREASSIGN" ) );
814 
815  LayerID = GetXmlAttributeIDString( aNode, 0 );
816 
818  Shape.Parse( aNode->GetChildren(), aContext );
819  else
820  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
821 
822  CheckNoNextNodes( aNode->GetChildren() );
823 }
824 
825 
827 {
828  wxASSERT( aNode->GetName() == wxT( "VIACODE" ) );
829 
830  ID = GetXmlAttributeIDString( aNode, 0 );
831  Name = GetXmlAttributeIDString( aNode, 1 );
832 
833  XNODE* cNode = aNode->GetChildren();
834  wxString location = wxString::Format( "VIACODE -> %s", Name );
835 
836  for( ; cNode; cNode = cNode->GetNext() )
837  {
838  wxString cNodeName = cNode->GetName();
839 
840  if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
841  {
842  Shape.Parse( cNode, aContext );
843  }
844  else if( cNodeName == wxT( "CLEARANCE" ) )
845  {
846  ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
847  }
848  else if( cNodeName == wxT( "RELIEFWIDTH" ) )
849  {
850  ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
851  }
852  else if( cNodeName == wxT( "DRILL" ) )
853  {
854  DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
855  XNODE* subNode = cNode->GetChildren();
856 
857  for( ; subNode; subNode = subNode->GetNext() )
858  {
859  wxString subNodeName = subNode->GetName();
860 
861  if( subNodeName == wxT( "OVERSIZE" ) )
862  DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
863  else
864  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
865  }
866  }
867  else if( cNodeName == wxT( "VIAREASSIGN" ) )
868  {
869  VIAREASSIGN reassign;
870  reassign.Parse( cNode, aContext );
871  Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
872  }
873  else
874  {
875  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
876  }
877  }
878 }
879 
880 
882 {
883  wxASSERT( aNode->GetName() == wxT( "LAYERPAIR" ) );
884 
885  ID = GetXmlAttributeIDString( aNode, 0 );
886  Name = GetXmlAttributeIDString( aNode, 1 );
887 
888  PhysicalLayerStart = GetXmlAttributeIDLong( aNode, 2 );
889  PhysicalLayerEnd = GetXmlAttributeIDLong( aNode, 3 );
890 
891  wxString location = wxString::Format( "LAYERPAIR -> %s", Name );
892 
893  if( aNode->GetChildren() )
894  {
895  if( aNode->GetChildren()->GetName() == wxT( "VIACODEREF" ) )
896  {
897  ViacodeID = GetXmlAttributeIDString( aNode->GetChildren(), 0 );
898  }
899  else
900  {
901  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), location );
902  }
903 
904  CheckNoNextNodes( aNode->GetChildren() );
905  }
906 }
907 
908 
910 {
911  wxASSERT( aNode->GetName() == wxT( "SPCCLASSSPACE" ) );
912 
913  SpacingClassID1 = GetXmlAttributeIDString( aNode, 0 );
914  SpacingClassID2 = GetXmlAttributeIDString( aNode, 1 );
915  LayerID = GetXmlAttributeIDString( aNode, 2 );
916  Spacing = GetXmlAttributeIDLong( aNode, 3 );
917 }
918 
919 
921 {
922  wxASSERT( aNode->GetName() == wxT( "TECHNOLOGY" ) );
923 
924  XNODE* cNode = aNode->GetChildren();
925 
926  for( ; cNode; cNode = cNode->GetNext() )
927  {
928  wxString cNodeName = cNode->GetName();
929 
930  if( ParseSubNode( cNode, aContext ) ) //CADSTAR_ARCHIVE_PARSER::SETTINGS
931  {
932  }
933  else if( cNodeName == wxT( "MINROUTEWIDTH" ) )
934  {
935  MinRouteWidth = GetXmlAttributeIDLong( cNode, 0 );
936  }
937  else if( cNodeName == wxT( "MINNECKED" ) )
938  {
939  MinNeckedLength = GetXmlAttributeIDLong( cNode, 0 );
940  }
941  else if( cNodeName == wxT( "MINUNNECKED" ) )
942  {
943  MinUnneckedLength = GetXmlAttributeIDLong( cNode, 0 );
944  }
945  else if( cNodeName == wxT( "MINMITER" ) )
946  {
947  MinMitre = GetXmlAttributeIDLong( cNode, 0 );
948  }
949  else if( cNodeName == wxT( "MAXMITER" ) )
950  {
951  MaxMitre = GetXmlAttributeIDLong( cNode, 0 );
952  }
953  else if( cNodeName == wxT( "MAXPHYSLAYER" ) )
954  {
955  MaxPhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
956  }
957  else if( cNodeName == wxT( "TRACKGRID" ) )
958  {
959  TrackGrid = GetXmlAttributeIDLong( cNode, 0 );
960  }
961  else if( cNodeName == wxT( "VIAGRID" ) )
962  {
963  ViaGrid = GetXmlAttributeIDLong( cNode, 0 );
964  }
965  else if( cNodeName == wxT( "BACKOFFJCTS" ) )
966  {
967  BackOffJunctions = true;
968  }
969  else if( cNodeName == wxT( "BCKOFFWIDCHANGE" ) )
970  {
971  BackOffWidthChange = true;
972  }
973  else
974  {
975  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TECHNOLOGY" ) );
976  }
977  }
978 }
979 
980 
982  const wxString& aPadSideString )
983 {
984  if( aPadSideString == wxT( "THRU" ) )
985  return PAD_SIDE::THROUGH_HOLE;
986  else if( aPadSideString == wxT( "BOTTOM" ) )
987  return PAD_SIDE::MAXIMUM;
988  else if( aPadSideString == wxT( "TOP" ) )
989  return PAD_SIDE::MINIMUM;
990  else
991  return PAD_SIDE::THROUGH_HOLE; // Assume through hole as default
992 }
993 
994 
996 {
997  wxASSERT( aNode->GetName() == wxT( "COMPCOPPER" ) );
998 
999  CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
1000  LayerID = GetXmlAttributeIDString( aNode, 1 );
1001 
1002  XNODE* cNode = aNode->GetChildren();
1003  bool shapeIsInitialised = false; // Stop more than one Shape Object
1004  wxString location = wxT( "COMPCOPPER" );
1005 
1006  if( !cNode )
1007  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1008 
1009  for( ; cNode; cNode = cNode->GetNext() )
1010  {
1011  wxString cNodeName = cNode->GetName();
1012 
1013  if( !shapeIsInitialised && Shape.IsShape( cNode ) )
1014  {
1015  Shape.Parse( cNode, aContext );
1016  shapeIsInitialised = true;
1017  }
1018  else if( cNodeName == wxT( "SWAPRULE" ) )
1019  {
1020  SwapRule = ParseSwapRule( cNode );
1021  }
1022  else if( cNodeName == wxT( "ASSOCPIN" ) )
1023  {
1024  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1025 
1026  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1027  {
1028  if( !IsValidAttribute( xmlAttribute ) )
1029  continue;
1030 
1031  long padId;
1032 
1033  if( !xmlAttribute->GetValue().ToLong( &padId ) )
1034  THROW_PARSING_IO_ERROR( wxT( "ASSOCPIN" ), location );
1035 
1036  AssociatedPadIDs.push_back( (PAD_ID) padId );
1037  }
1038 
1039  CheckNoChildNodes( cNode );
1040  }
1041  else
1042  {
1043  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1044  }
1045  }
1046 }
1047 
1048 
1050 {
1051  wxASSERT( aNode->GetName() == wxT( "COMPAREA" ) );
1052 
1053  ID = GetXmlAttributeIDString( aNode, 0 );
1054  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1055  LayerID = GetXmlAttributeIDString( aNode, 3 );
1056 
1057  XNODE* cNode = aNode->GetChildren();
1058  bool shapeIsInitialised = false; // Stop more than one Shape Object
1059  wxString location = wxString::Format( "COMPAREA %s", ID );
1060 
1061  if( !cNode )
1062  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1063 
1064  for( ; cNode; cNode = cNode->GetNext() )
1065  {
1066  wxString cNodeName = cNode->GetName();
1067 
1068  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1069  {
1070  Shape.Parse( cNode, aContext );
1071  shapeIsInitialised = true;
1072  }
1073  else if( cNodeName == wxT( "SWAPRULE" ) )
1074  {
1075  SwapRule = ParseSwapRule( cNode );
1076  }
1077  else if( cNodeName == wxT( "USAGE" ) )
1078  {
1079  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1080 
1081  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1082  {
1083  if( !IsValidAttribute( xmlAttribute ) )
1084  continue;
1085 
1086  if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1087  NoTracks = true;
1088  else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1089  NoVias = true;
1090  else
1091  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1092  }
1093 
1094  CheckNoChildNodes( cNode );
1095  }
1096  else
1097  {
1098  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1099  }
1100  }
1101 }
1102 
1103 
1105 {
1106  wxASSERT( aNode->GetName() == wxT( "EXITS" ) );
1107 
1108  wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1109 
1110  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1111  {
1112  if( !IsValidAttribute( xmlAttribute ) )
1113  continue;
1114 
1115  if( xmlAttribute->GetValue() == wxT( "FREE" ) )
1116  FreeAngle = true;
1117  else if( xmlAttribute->GetValue() == wxT( "N" ) )
1118  North = true;
1119  else if( xmlAttribute->GetValue() == wxT( "S" ) )
1120  South = true;
1121  else if( xmlAttribute->GetValue() == wxT( "E" ) )
1122  East = true;
1123  else if( xmlAttribute->GetValue() == wxT( "W" ) )
1124  West = true;
1125  else if( xmlAttribute->GetValue() == wxT( "NE" ) )
1126  NorthEast = true;
1127  else if( xmlAttribute->GetValue() == wxT( "NW" ) )
1128  NorthWest = true;
1129  else if( xmlAttribute->GetValue() == wxT( "SE" ) )
1130  SouthEast = true;
1131  else if( xmlAttribute->GetValue() == wxT( "SW" ) )
1132  SouthWest = true;
1133  else
1134  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), wxT( "EXITS" ) );
1135  }
1136 
1137  CheckNoChildNodes( aNode );
1138 }
1139 
1140 
1142 {
1143  wxASSERT( aNode->GetName() == wxT( "PAD" ) );
1144 
1145  ID = GetXmlAttributeIDLong( aNode, 0 );
1146  PadCodeID = GetXmlAttributeIDString( aNode, 2 );
1147  Side = GetPadSide( GetXmlAttributeIDString( aNode, 3 ) );
1148 
1149  XNODE* cNode = aNode->GetChildren();
1150  wxString location = wxString::Format( "PAD %ld", ID );
1151 
1152  if( !cNode )
1153  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
1154 
1155  for( ; cNode; cNode = cNode->GetNext() )
1156  {
1157  wxString cNodeName = cNode->GetName();
1158 
1159  if( cNodeName == wxT( "ORIENT" ) )
1160  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1161  else if( cNodeName == wxT( "FIRSTPAD" ) )
1162  FirstPad = true;
1163  else if( cNodeName == wxT( "EXITS" ) )
1164  Exits.Parse( cNode, aContext );
1165  else if( cNodeName == wxT( "PADIDENTIFIER" ) )
1166  Identifier = GetXmlAttributeIDString( cNode, 0 );
1167  else if( cNodeName == wxT( "PCBONLYPAD" ) )
1168  PCBonlyPad = true;
1169  else if( cNodeName == wxT( "PT" ) )
1170  Position.Parse( cNode, aContext );
1171  else
1172  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1173  }
1174 }
1175 
1176 
1178 {
1179  wxASSERT( aNode->GetName() == wxT( "DIMARROW" ) );
1180  bool arrowStyleInitialised = false;
1181  bool upperAngleInitialised = false;
1182  bool lowerAngleInitialised = false;
1183 
1184  ArrowLength = GetXmlAttributeIDLong( aNode, 3 );
1185 
1186  XNODE* cNode = aNode->GetChildren();
1187 
1188 
1189  for( ; cNode; cNode = cNode->GetNext() )
1190  {
1191  wxString cNodeName = cNode->GetName();
1192 
1193  if( cNodeName == wxT( "ARROWSTYLE" ) )
1194  {
1195  wxString arrowStyleStr = GetXmlAttributeIDString( cNode, 0 );
1196  arrowStyleInitialised = true;
1197 
1198  if( arrowStyleStr == wxT( "DIMENSION_ARROWOPEN" ) )
1199  ArrowStyle = STYLE::OPEN;
1200  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSED" ) )
1201  ArrowStyle = STYLE::CLOSED;
1202  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLEAR" ) )
1203  ArrowStyle = STYLE::CLEAR;
1204  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSEDFILLED" ) )
1205  ArrowStyle = STYLE::CLOSED_FILLED;
1206  else
1207  THROW_UNKNOWN_PARAMETER_IO_ERROR( arrowStyleStr, cNodeName );
1208  }
1209  else if( cNodeName == wxT( "ARROWANGLEA" ) )
1210  {
1211  UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1212  upperAngleInitialised = true;
1213  }
1214  else if( cNodeName == wxT( "ARROWANGLEB" ) )
1215  {
1216  UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1217  lowerAngleInitialised = true;
1218  }
1219  else
1220  {
1221  THROW_UNKNOWN_PARAMETER_IO_ERROR( cNodeName, wxT( "DIMARROW" ) );
1222  }
1223  }
1224 
1225  if( !arrowStyleInitialised )
1226  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWSTYLE" ), wxT( "DIMARROW" ) );
1227 
1228  if( !upperAngleInitialised )
1229  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEA" ), wxT( "DIMARROW" ) );
1230 
1231  if( !lowerAngleInitialised )
1232  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEB" ), wxT( "DIMARROW" ) );
1233 }
1234 
1235 
1237  PARSER_CONTEXT* aContext )
1238 {
1239  wxASSERT( aNode->GetName() == wxT( "DIMTEXT" ) );
1240 
1241  TextGap = GetXmlAttributeIDLong( aNode, 1 );
1242  TextOffset = GetXmlAttributeIDLong( aNode, 2 );
1243 
1244  XNODE* cNode = aNode->GetChildren();
1245 
1246  if( cNode->GetName() != wxT( "TXTSTYLE" ) )
1247  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "DIMTEXT" ) );
1248 
1249  wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1250 
1251  if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1252  Style = STYLE::INSIDE;
1253  else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1254  Style = STYLE::OUTSIDE;
1255  else
1256  THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, wxT( "TXTSTYLE" ) );
1257 
1258  CheckNoNextNodes( cNode );
1259 }
1260 
1261 
1263  PARSER_CONTEXT* aContext )
1264 {
1265  wxASSERT( aNode->GetName() == wxT( "EXTLINE" ) );
1266 
1267  LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1268  Overshoot = GetXmlAttributeIDLong( aNode, 3 );
1269  Offset = GetXmlAttributeIDLong( aNode, 4 );
1270 
1271  XNODE* cNode = aNode->GetChildren();
1272  int noOfPoints = 0;
1273 
1274  for( ; cNode; cNode = cNode->GetNext() )
1275  {
1276  wxString cNodeName = cNode->GetName();
1277 
1278  if( noOfPoints < 2 && cNodeName == wxT( "PT" ) )
1279  {
1280  ++noOfPoints;
1281 
1282  if( noOfPoints == 1 )
1283  Start.Parse( cNode, aContext );
1284  else
1285  End.Parse( cNode, aContext );
1286  }
1287  else if( cNodeName == wxT( "SUPPRESSFIRST" ) )
1288  {
1289  SuppressFirst = true;
1290  }
1291  else
1292  {
1293  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "EXTLINE" ) );
1294  }
1295  }
1296 
1297  if( noOfPoints != 2 )
1298  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), wxT( "EXTLINE" ) );
1299 }
1300 
1301 
1303 {
1304  if( aNode->GetName() == wxT( "LEADERLINE" ) || aNode->GetName() == wxT( "LINEARLINE" )
1305  || aNode->GetName() == wxT( "ANGULARLINE" ) )
1306  {
1307  return true;
1308  }
1309  else
1310  {
1311  return false;
1312  }
1313 }
1314 
1315 
1317 {
1318  wxASSERT( IsLine( aNode ) );
1319 
1320  if( aNode->GetName() == wxT( "LINEARLINE" ) )
1321  Type = TYPE::LINEARLINE;
1322  else if( aNode->GetName() == wxT( "LEADERLINE" ) )
1323  Type = TYPE::LEADERLINE;
1324  else if( aNode->GetName() == wxT( "ANGULARLINE" ) )
1325  Type = TYPE::ANGULARLINE;
1326  else
1327  wxASSERT_MSG( true, "Not a valid type. What happened to the node Name?" );
1328 
1329  LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1330 
1331  if( Type == TYPE::LEADERLINE )
1332  {
1333  LeaderLineLength = GetXmlAttributeIDLong( aNode, 5 );
1334  LeaderLineExtensionLength = GetXmlAttributeIDLong( aNode, 6 );
1335  }
1336 
1337  XNODE* cNode = aNode->GetChildren();
1338  int noOfPoints = 0;
1339  int requiredNoOfPoints = 2;
1340 
1341  if( Type == TYPE::ANGULARLINE )
1342  requiredNoOfPoints = 3;
1343 
1344  for( ; cNode; cNode = cNode->GetNext() )
1345  {
1346  wxString cNodeName = cNode->GetName();
1347 
1348  if( cNodeName == wxT( "DIMLINETYPE" ) )
1349  {
1350  wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1351 
1352  if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1353  Style = STYLE::INTERNAL;
1354  else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1355  Style = STYLE::EXTERNAL;
1356  else
1357  THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, cNodeName );
1358  }
1359  else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT( "PT" ) )
1360  {
1361  ++noOfPoints;
1362 
1363  if( noOfPoints == 1 )
1364  Start.Parse( cNode, aContext );
1365  else if( noOfPoints == 2 )
1366  End.Parse( cNode, aContext );
1367  else
1368  Centre.Parse( cNode, aContext );
1369  }
1370  else if( Type == TYPE::LEADERLINE && cNodeName == wxT( "LEADERANG" ) )
1371  {
1372  LeaderAngle = GetXmlAttributeIDLong( cNode, 0 );
1373  }
1374  else
1375  {
1376  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1377  }
1378  }
1379 
1380  if( noOfPoints != requiredNoOfPoints )
1381  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1382 }
1383 
1384 
1386 {
1387  if( aNode->GetName() == wxT( "LINEARDIM" ) || aNode->GetName() == wxT( "LEADERDIM" )
1388  || aNode->GetName() == wxT( "ANGLEDIM" ) )
1389  {
1390  return true;
1391  }
1392  else
1393  {
1394  return false;
1395  }
1396 }
1397 
1398 
1400 {
1401  wxASSERT( IsDimension( aNode ) );
1402 
1403  std::map<wxString, TYPE> typeMap = { { wxT( "LINEARDIM" ), TYPE::LINEARDIM },
1404  { wxT( "LEADERDIM" ), TYPE::LEADERDIM }, { wxT( "ANGLEDIM" ), TYPE::ANGLEDIM } };
1405 
1406  //make sure aNode is valid TYPE
1407  wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1408  "Not a valid type. What happened to the node Name?" );
1409 
1410  Type = typeMap[aNode->GetName()];
1411  LayerID = GetXmlAttributeIDString( aNode, 1 );
1412  wxString subTypeStr = GetXmlAttributeIDString( aNode, 2 );
1413 
1414  std::map<wxString, SUBTYPE> subTypeMap = {
1415  { wxT( "DIMENSION_ORTHOGONAL" ), SUBTYPE::ORTHOGONAL },
1416  { wxT( "DIMENSION_DIRECT" ), SUBTYPE::DIRECT },
1417  { wxT( "DIMENSION_ANGLED" ), SUBTYPE::ANGLED },
1418  { wxT( "DIMENSION_DIAMETER" ), SUBTYPE::DIAMETER },
1419  { wxT( "DIMENSION_RADIUS" ), SUBTYPE::RADIUS },
1420  { wxT( "DIMENSION_ANGULAR" ), SUBTYPE::ANGULAR } };
1421 
1422  if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1423  THROW_UNKNOWN_PARAMETER_IO_ERROR( subTypeStr, aNode->GetName() );
1424 
1425  Subtype = subTypeMap[subTypeStr];
1426  Precision = GetXmlAttributeIDLong( aNode, 3 );
1427 
1428  XNODE* cNode = aNode->GetChildren();
1429 
1430  bool idParsed = false;
1431  bool unitsParsed = false; //UNITS or ANGUNITS
1432  bool arrowParsed = false;
1433  bool textFormatParsed = false;
1434  bool extLineParsed = false;
1435  bool lineParsed = false;
1436  bool textParsed = false;
1437 
1438  for( ; cNode; cNode = cNode->GetNext() )
1439  {
1440  wxString cNodeName = cNode->GetName();
1441 
1442  if( !idParsed && cNodeName == wxT( "DIMREF" ) )
1443  {
1444  ID = GetXmlAttributeIDString( cNode, 0 );
1445  idParsed = true;
1446  }
1447  else if( !unitsParsed && cNodeName == wxT( "UNITS" ) )
1448  {
1449  LinearUnits = ParseUnits( cNode );
1450  unitsParsed = true;
1451  }
1452  else if( !unitsParsed && cNodeName == wxT( "ANGUNITS" ) )
1453  {
1454  AngularUnits = ParseAngunits( cNode );
1455  unitsParsed = true;
1456  }
1457  else if( !arrowParsed && cNodeName == wxT( "DIMARROW" ) )
1458  {
1459  Arrow.Parse( cNode, aContext );
1460  arrowParsed = true;
1461  }
1462  else if( !textFormatParsed && cNodeName == wxT( "DIMTEXT" ) )
1463  {
1464  TextParams.Parse( cNode, aContext );
1465  textFormatParsed = true;
1466  }
1467  else if( !extLineParsed && cNodeName == wxT( "EXTLINE" ) )
1468  {
1469  ExtensionLineParams.Parse( cNode, aContext );
1470  extLineParsed = true;
1471  }
1472  else if( !lineParsed && LINE::IsLine( cNode ) )
1473  {
1474  Line.Parse( cNode, aContext );
1475  lineParsed = true;
1476  }
1477  else if( !textParsed && cNodeName == wxT( "TEXT" ) )
1478  {
1479  // Do not parse the fields in dimension text (will be done when loading, if required)
1480  Text.Parse( cNode, aContext, false );
1481  textParsed = true;
1482  }
1483  else if( cNodeName == wxT( "FIX" ) )
1484  {
1485  Fixed = true;
1486  }
1487  else if( cNodeName == wxT( "GROUPREF" ) )
1488  {
1489  GroupID = GetXmlAttributeIDString( cNode, 0 );
1490  }
1491  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1492  {
1493  ReuseBlockRef.Parse( cNode, aContext );
1494  }
1495  else
1496  {
1497  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1498  }
1499  }
1500 }
1501 
1502 
1504 {
1505  wxASSERT( aNode->GetName() == wxT( "SYMDEF" ) );
1506 
1507  ParseIdentifiers( aNode, aContext );
1508 
1509  wxString rest;
1510 
1511  if( ReferenceName.StartsWith( wxT( "JUMPERNF" ), &rest ) )
1512  Type = SYMDEF_TYPE::JUMPER;
1513  else if( ReferenceName.StartsWith( wxT( "STARPOINTNF" ), &rest ) )
1514  Type = SYMDEF_TYPE::STARPOINT;
1515  else if( ReferenceName == wxT( "TESTPOINT" ) )
1516  Type = SYMDEF_TYPE::TESTPOINT;
1517  else
1518  Type = SYMDEF_TYPE::COMPONENT;
1519 
1520  XNODE* cNode = aNode->GetChildren();
1521 
1522  for( ; cNode; cNode = cNode->GetNext() )
1523  {
1524  wxString cNodeName = cNode->GetName();
1525 
1526  if( ParseSubNode( cNode, aContext ) )
1527  {
1528  continue;
1529  }
1530  else if( cNodeName == wxT( "SYMHEIGHT" ) )
1531  {
1532  SymHeight = GetXmlAttributeIDLong( cNode, 0 );
1533  }
1534  else if( cNodeName == wxT( "COMPCOPPER" ) )
1535  {
1536  COMPONENT_COPPER compcopper;
1537  compcopper.Parse( cNode, aContext );
1538  ComponentCoppers.push_back( compcopper );
1539  }
1540  else if( cNodeName == wxT( "COMPAREA" ) )
1541  {
1542  COMPONENT_AREA area;
1543  area.Parse( cNode, aContext );
1544  ComponentAreas.insert( std::make_pair( area.ID, area ) );
1545  }
1546  else if( cNodeName == wxT( "PAD" ) )
1547  {
1549  pad.Parse( cNode, aContext );
1550  ComponentPads.insert( std::make_pair( pad.ID, pad ) );
1551  }
1552  else if( cNodeName == wxT( "DIMENSIONS" ) )
1553  {
1554  XNODE* dimensionNode = cNode->GetChildren();
1555 
1556  for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
1557  {
1558  if( DIMENSION::IsDimension( dimensionNode ) )
1559  {
1560  DIMENSION dim;
1561  dim.Parse( dimensionNode, aContext );
1562  Dimensions.insert( std::make_pair( dim.ID, dim ) );
1563  }
1564  else
1565  {
1566  THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
1567  }
1568  }
1569  }
1570  else
1571  {
1572  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1573  }
1574  }
1575 
1576  if( !Stub && !Origin.IsFullySpecified() )
1577  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1578 }
1579 
1580 
1582 {
1583  wxASSERT( aNode->GetName() == wxT( "LIBRARY" ) );
1584 
1585  XNODE* cNode = aNode->GetChildren();
1586 
1587  for( ; cNode; cNode = cNode->GetNext() )
1588  {
1589  wxString cNodeName = cNode->GetName();
1590 
1591  if( cNodeName == wxT( "SYMDEF" ) )
1592  {
1593  SYMDEF_PCB symdef;
1594  symdef.Parse( cNode, aContext );
1595  ComponentDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
1596  }
1597  else
1598  {
1599  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1600  }
1601  }
1602 }
1603 
1604 
1606 {
1607  wxASSERT( aNode->GetName() == wxT( "BOARD" ) );
1608 
1609  ID = GetXmlAttributeIDString( aNode, 0 );
1610  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1611 
1612  XNODE* cNode = aNode->GetChildren();
1613  bool shapeIsInitialised = false; // Stop more than one Shape Object
1614  wxString location = wxString::Format( "BOARD %s", ID );
1615 
1616  if( !cNode )
1617  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1618 
1619  for( ; cNode; cNode = cNode->GetNext() )
1620  {
1621  wxString cNodeName = cNode->GetName();
1622 
1623  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1624  {
1625  Shape.Parse( cNode, aContext );
1626  shapeIsInitialised = true;
1627  }
1628  else if( cNodeName == wxT( "ATTR" ) )
1629  {
1630  ATTRIBUTE_VALUE attr;
1631  attr.Parse( cNode, aContext );
1632  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1633  }
1634  else if( cNodeName == wxT( "FIX" ) )
1635  {
1636  Fixed = true;
1637  }
1638  else if( cNodeName == wxT( "GROUPREF" ) )
1639  {
1640  GroupID = GetXmlAttributeIDString( cNode, 0 );
1641  }
1642  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1643  {
1644  ReuseBlockRef.Parse( cNode, aContext );
1645  }
1646  else
1647  {
1648  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1649  }
1650  }
1651 }
1652 
1653 
1655 {
1656  wxASSERT( aNode->GetName() == wxT( "AREA" ) );
1657 
1658  ID = GetXmlAttributeIDString( aNode, 0 );
1659  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1660  Name = GetXmlAttributeIDString( aNode, 2 );
1661  LayerID = GetXmlAttributeIDString( aNode, 4 );
1662 
1663  XNODE* cNode = aNode->GetChildren();
1664  bool shapeIsInitialised = false; // Stop more than one Shape Object
1665  wxString location = wxString::Format( "AREA %s", ID );
1666 
1667  if( !cNode )
1668  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1669 
1670  for( ; cNode; cNode = cNode->GetNext() )
1671  {
1672  wxString cNodeName = cNode->GetName();
1673 
1674  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1675  {
1676  Shape.Parse( cNode, aContext );
1677  shapeIsInitialised = true;
1678  }
1679  else if( cNodeName == wxT( "FIX" ) )
1680  {
1681  Fixed = true;
1682  }
1683  else if( cNodeName == wxT( "USAGE" ) )
1684  {
1685  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1686 
1687  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1688  {
1689  if( !IsValidAttribute( xmlAttribute ) )
1690  continue;
1691 
1692  if( xmlAttribute->GetValue() == wxT( "PLACEMENT" ) )
1693  Placement = true;
1694  else if( xmlAttribute->GetValue() == wxT( "ROUTING" ) )
1695  Routing = true;
1696  else if( xmlAttribute->GetValue() == wxT( "KEEPOUT" ) )
1697  Keepout = true;
1698  else if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1699  NoTracks = true;
1700  else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1701  NoVias = true;
1702  else
1703  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1704  }
1705 
1706  CheckNoChildNodes( cNode );
1707  }
1708  else if( cNodeName == wxT( "AREAHEIGHT" ) )
1709  {
1710  AreaHeight = GetXmlAttributeIDLong( cNode, 0 );
1711  }
1712  else if( cNodeName == wxT( "GROUPREF" ) )
1713  {
1714  GroupID = GetXmlAttributeIDString( cNode, 0 );
1715  }
1716  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1717  {
1718  ReuseBlockRef.Parse( cNode, aContext );
1719  }
1720  else if( cNodeName == wxT( "ATTR" ) )
1721  {
1722  ATTRIBUTE_VALUE attr;
1723  attr.Parse( cNode, aContext );
1724  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1725  }
1726  else
1727  {
1728  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1729  }
1730  }
1731 }
1732 
1733 
1735 {
1736  wxASSERT( aNode->GetName() == wxT( "PINATTR" ) );
1737 
1738  Pin = GetXmlAttributeIDLong( aNode, 0 );
1739 
1740  XNODE* cNode = aNode->GetChildren();
1741 
1742  for( ; cNode; cNode = cNode->GetNext() )
1743  {
1744  wxString cNodeName = cNode->GetName();
1745 
1746  if( cNodeName == wxT( "ATTR" ) )
1747  {
1748  ATTRIBUTE_VALUE attrVal;
1749  attrVal.Parse( cNode, aContext );
1750  AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1751  }
1752  else if( cNodeName == wxT( "TESTLAND" ) )
1753  {
1754  TestlandSide = ParseTestlandSide( cNode );
1755  }
1756  else
1757  {
1758  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1759  }
1760  }
1761 }
1762 
1763 
1765 {
1766  wxASSERT( aNode->GetName() == wxT( "PADEXCEPTION" ) );
1767 
1768  ID = GetXmlAttributeIDLong( aNode, 0 );
1769 
1770  XNODE* cNode = aNode->GetChildren();
1771 
1772  for( ; cNode; cNode = cNode->GetNext() )
1773  {
1774  wxString cNodeName = cNode->GetName();
1775 
1776  if( cNodeName == wxT( "PADCODEREF" ) )
1777  {
1778  PadCode = GetXmlAttributeIDString( cNode, 0 );
1779  }
1780  else if( cNodeName == wxT( "EXITS" ) )
1781  {
1782  OverrideExits = true;
1783  Exits.Parse( cNode, aContext );
1784  }
1785  else if( cNodeName == wxT( "SIDE" ) )
1786  {
1787  OverrideSide = true;
1788  Side = GetPadSide( GetXmlAttributeIDString( cNode, 0 ) );
1789  }
1790  else if( cNodeName == wxT( "ORIENT" ) )
1791  {
1792  OverrideOrientation = true;
1793  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1794  }
1795  else
1796  {
1797  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1798  }
1799  }
1800 }
1801 
1802 
1804 {
1805  wxASSERT( aNode->GetName() == wxT( "COMP" ) );
1806 
1807  ID = GetXmlAttributeIDString( aNode, 0 );
1808  Name = GetXmlAttributeIDString( aNode, 1 );
1809  PartID = GetXmlAttributeIDString( aNode, 2 );
1810  SymdefID = GetXmlAttributeIDString( aNode, 3 );
1811 
1812  XNODE* cNode = aNode->GetChildren();
1813  bool originParsed = false;
1814 
1815  for( ; cNode; cNode = cNode->GetNext() )
1816  {
1817  wxString cNodeName = cNode->GetName();
1818 
1819  if( !originParsed && cNodeName == wxT( "PT" ) )
1820  {
1821  Origin.Parse( cNode, aContext );
1822  originParsed = true;
1823  }
1824  else if( cNodeName == wxT( "GROUPREF" ) )
1825  {
1826  GroupID = GetXmlAttributeIDString( cNode, 0 );
1827  }
1828  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1829  {
1830  ReuseBlockRef.Parse( cNode, aContext );
1831  }
1832  else if( cNodeName == wxT( "TESTPOINT" ) )
1833  {
1834  TestPoint = true;
1835  }
1836  else if( cNodeName == wxT( "FIX" ) )
1837  {
1838  Fixed = true;
1839  }
1840  else if( cNodeName == wxT( "MIRROR" ) )
1841  {
1842  Mirror = true;
1843  }
1844  else if( cNodeName == wxT( "READABILITY" ) )
1845  {
1846  Readability = ParseReadability( cNode );
1847  }
1848  else if( cNodeName == wxT( "ORIENT" ) )
1849  {
1850  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1851  }
1852  else if( cNodeName == wxT( "VCOMPMASTER" ) )
1853  {
1854  VariantParentComponentID = GetXmlAttributeIDString( cNode, 0 );
1855  VariantID = GetXmlAttributeIDString( cNode, 1 );
1856  }
1857  else if( cNodeName == wxT( "TEXTLOC" ) )
1858  {
1859  TEXT_LOCATION textloc;
1860  textloc.Parse( cNode, aContext );
1861  TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) );
1862  }
1863  else if( cNodeName == wxT( "ATTR" ) )
1864  {
1865  ATTRIBUTE_VALUE attrVal;
1866  attrVal.Parse( cNode, aContext );
1867  AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1868  }
1869  else if( cNodeName == wxT( "PINATTR" ) )
1870  {
1871  PIN_ATTRIBUTE pinAttr;
1872  pinAttr.Parse( cNode, aContext );
1873  PinAttributes.insert( std::make_pair( pinAttr.Pin, pinAttr ) );
1874  }
1875  else if( cNodeName == wxT( "COMPPINLABEL" ) )
1876  {
1877  PART_DEFINITION_PIN_ID pinID = GetXmlAttributeIDLong( cNode, 0 );
1878  wxString pinLabel = GetXmlAttributeIDString( cNode, 1 );
1879  PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1880  }
1881  else if( cNodeName == wxT( "PADEXCEPTION" ) )
1882  {
1883  PADEXCEPTION padExcept;
1884  padExcept.Parse( cNode, aContext );
1885  PadExceptions.insert( std::make_pair( padExcept.ID, padExcept ) );
1886  }
1887  else
1888  {
1889  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1890  }
1891  }
1892 
1893  if( !originParsed )
1894  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1895 }
1896 
1897 
1899  XNODE* aNode )
1900 {
1901  wxASSERT( aNode->GetName() == wxT( "TESTLAND" ) );
1902 
1903  wxString side = GetXmlAttributeIDString( aNode, 0 );
1904 
1905  if( side == wxT( "MIN_SIDE" ) )
1906  return TESTLAND_SIDE::MIN;
1907  else if( side == wxT( "MAX_SIDE" ) )
1908  return TESTLAND_SIDE::MAX;
1909  else if( side == wxT( "BOTH_SIDES" ) )
1910  return TESTLAND_SIDE::BOTH;
1911  else
1912  THROW_UNKNOWN_PARAMETER_IO_ERROR( side, aNode->GetName() );
1913 
1914  return TESTLAND_SIDE::NONE;
1915 }
1916 
1917 
1919 {
1920  wxASSERT( aNode->GetName() == wxT( "TRUNK" ) );
1921 
1922  ID = GetXmlAttributeIDString( aNode, 0 );
1923  Definition = GetXmlAttributeIDString( aNode, 1 );
1924 }
1925 
1926 
1928 {
1929  wxASSERT( aNode->GetName() == wxT( "PIN" ) );
1930 
1931  ID = GetXmlAttributeIDString( aNode, 0 );
1932  ComponentID = GetXmlAttributeIDString( aNode, 1 );
1933  PadID = GetXmlAttributeIDLong( aNode, 2 );
1934  CheckNoChildNodes( aNode );
1935 }
1936 
1937 
1939  PARSER_CONTEXT* aContext )
1940 {
1941  ParseIdentifiers( aNode, aContext );
1942  XNODE* cNode = aNode->GetChildren();
1943 
1944  for( ; cNode; cNode = cNode->GetNext() )
1945  {
1946  if( ParseSubNode( cNode, aContext ) )
1947  continue;
1948  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
1949  TrunkID = GetXmlAttributeIDString( cNode, 0 );
1950  else
1951  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1952  }
1953 }
1954 
1955 
1957 {
1958  wxASSERT( aNode->GetName() == wxT( "VIA" ) );
1959 
1960  ID = GetXmlAttributeIDString( aNode, 0 );
1961  ViaCodeID = GetXmlAttributeIDString( aNode, 1 );
1962  LayerPairID = GetXmlAttributeIDString( aNode, 2 );
1963 
1964  XNODE* cNode = aNode->GetChildren();
1965 
1966  for( ; cNode; cNode = cNode->GetNext() )
1967  {
1968  wxString cNodeName = cNode->GetName();
1969 
1970  if( cNodeName == wxT( "PT" ) )
1971  Location.Parse( cNode, aContext );
1972  else if( cNodeName == wxT( "FIX" ) )
1973  Fixed = true;
1974  else if( cNodeName == wxT( "GROUPREF" ) )
1975  GroupID = GetXmlAttributeIDString( cNode, 0 );
1976  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1977  ReuseBlockRef.Parse( cNode, aContext );
1978  else if( cNodeName == wxT( "TESTLAND" ) )
1979  TestlandSide = ParseTestlandSide( cNode );
1980  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
1981  TrunkID = GetXmlAttributeIDString( cNode, 0 );
1982  else
1983  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1984  }
1985 }
1986 
1987 
1989  PARSER_CONTEXT* aContext )
1990 {
1991  wxASSERT( aNode->GetName() == wxT( "COPTERM" ) );
1992 
1993  ID = GetXmlAttributeIDString( aNode, 0 );
1994  CopperID = GetXmlAttributeIDString( aNode, 1 );
1995  CopperTermNum = GetXmlAttributeIDLong( aNode, 2 );
1996 }
1997 
1998 
2000  PARSER_CONTEXT* aContext )
2001 {
2002  wxASSERT( aNode->GetName() == wxT( "ROUTEWIDTH" ) );
2003 
2004  RouteWidth = GetXmlAttributeIDLong( aNode, 0 );
2005  XNODE* nextNode = aNode->GetNext();
2006 
2007  if( nextNode->GetName() == wxT( "FIX" ) )
2008  {
2009  Fixed = true;
2010  nextNode = nextNode->GetNext();
2011  }
2012 
2013  if( !VERTEX::IsVertex( nextNode ) )
2014  THROW_UNKNOWN_NODE_IO_ERROR( nextNode->GetName(), wxT( "ROUTE_VERTEX" ) );
2015 
2016  Vertex.Parse( nextNode, aContext );
2017 
2018  return nextNode;
2019 }
2020 
2021 
2023 {
2024  wxASSERT( aNode->GetName() == wxT( "ROUTE" ) );
2025 
2026  LayerID = GetXmlAttributeIDString( aNode, 0 );
2027 
2028  //Parse child nodes
2029  XNODE* cNode = aNode->GetChildren();
2030  bool startPointParsed = false;
2031 
2032  for( ; cNode; cNode = cNode->GetNext() )
2033  {
2034  wxString cNodeName = cNode->GetName();
2035 
2036  if( !startPointParsed && cNodeName == wxT( "PT" ) )
2037  {
2038  startPointParsed = true;
2039  StartPoint.Parse( cNode, aContext );
2040  }
2041  else if( cNodeName == wxT( "ROUTEWIDTH" ) )
2042  {
2043  ROUTE_VERTEX rtVert;
2044  cNode = rtVert.Parse( cNode, aContext );
2045  RouteVertices.push_back( rtVert );
2046  }
2047  else
2048  {
2049  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "ROUTE" ) );
2050  }
2051  }
2052 }
2053 
2054 
2056  PARSER_CONTEXT* aContext )
2057 {
2058  ParseIdentifiers( aNode, aContext );
2059 
2060  //Parse child nodes
2061  XNODE* cNode = aNode->GetChildren();
2062  bool routeParsed = false; //assume only one route per connection
2063 
2064  for( ; cNode; cNode = cNode->GetNext() )
2065  {
2066  wxString cNodeName = cNode->GetName();
2067 
2068  if( ParseSubNode( cNode, aContext ) )
2069  {
2070  continue;
2071  }
2072  else if( !Unrouted && !routeParsed && cNodeName == wxT( "ROUTE" ) )
2073  {
2074  Route.Parse( cNode, aContext );
2075  routeParsed = true;
2076  }
2077  else if( !routeParsed && cNodeName == wxT( "UNROUTE" ) )
2078  {
2079  Unrouted = true;
2080  UnrouteLayerID = GetXmlAttributeIDString( cNode, 0 );
2081  }
2082  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
2083  {
2084  TrunkID = GetXmlAttributeIDString( cNode, 0 );
2085  }
2086  else
2087  {
2088  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
2089  }
2090  }
2091 }
2092 
2093 
2095 {
2096  ParseIdentifiers( aNode, aContext );
2097 
2098  //Parse child nodes
2099  XNODE* cNode = aNode->GetChildren();
2100 
2101  for( ; cNode; cNode = cNode->GetNext() )
2102  {
2103  wxString cNodeName = cNode->GetName();
2104 
2105  if( cNodeName == wxT( "JPT" ) )
2106  {
2107  JUNCTION_PCB jpt;
2108  jpt.Parse( cNode, aContext );
2109  Junctions.insert( std::make_pair( jpt.ID, jpt ) );
2110  }
2111  else if( ParseSubNode( cNode, aContext ) )
2112  {
2113  continue;
2114  }
2115  else if( cNodeName == wxT( "PIN" ) )
2116  {
2117  PIN pin;
2118  pin.Parse( cNode, aContext );
2119  Pins.insert( std::make_pair( pin.ID, pin ) );
2120  }
2121  else if( cNodeName == wxT( "VIA" ) )
2122  {
2123  VIA via;
2124  via.Parse( cNode, aContext );
2125  Vias.insert( std::make_pair( via.ID, via ) );
2126  }
2127  else if( cNodeName == wxT( "COPTERM" ) )
2128  {
2129  COPPER_TERMINAL cterm;
2130  cterm.Parse( cNode, aContext );
2131  CopperTerminals.insert( std::make_pair( cterm.ID, cterm ) );
2132  }
2133  else if( cNodeName == wxT( "CONN" ) )
2134  {
2135  CONNECTION_PCB conn;
2136  conn.Parse( cNode, aContext );
2137  Connections.push_back( conn );
2138  }
2139  else
2140  {
2141  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
2142  }
2143  }
2144 }
2145 
2146 
2148 {
2149  wxASSERT( aNode->GetName() == wxT( "POURING" ) );
2150 
2151  CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
2152  ReliefCopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2153  ClearanceWidth = GetXmlAttributeIDLong( aNode, 2 );
2154  SliverWidth = GetXmlAttributeIDLong( aNode, 3 );
2155  AdditionalIsolation = GetXmlAttributeIDLong( aNode, 4 );
2156  ThermalReliefPadsAngle = GetXmlAttributeIDLong( aNode, 5 );
2157  ThermalReliefViasAngle = GetXmlAttributeIDLong( aNode, 6 );
2158 
2159  wxString MinIsolCopStr = GetXmlAttributeIDString( aNode, 7 );
2160 
2161  if( MinIsolCopStr == wxT( "NONE" ) )
2162  MinIsolatedCopper = UNDEFINED_VALUE;
2163  else
2164  MinIsolatedCopper = GetXmlAttributeIDLong( aNode, 7 );
2165 
2166  wxString MinDisjCopStr = GetXmlAttributeIDString( aNode, 8 );
2167 
2168  if( MinDisjCopStr == wxT( "NONE" ) )
2169  MinDisjointCopper = UNDEFINED_VALUE;
2170  else
2171  MinDisjointCopper = GetXmlAttributeIDLong( aNode, 8 );
2172 
2173  XNODE* cNode = aNode->GetChildren();
2174 
2175  for( ; cNode; cNode = cNode->GetNext() )
2176  {
2177  wxString cNodeName = cNode->GetName();
2178 
2179  if( cNodeName == wxT( "NOPINRELIEF" ) )
2180  {
2181  ThermalReliefOnPads = false;
2182  }
2183  else if( cNodeName == wxT( "NOVIARELIEF" ) )
2184  {
2185  ThermalReliefOnVias = false;
2186  }
2187  else if( cNodeName == wxT( "IGNORETRN" ) )
2188  {
2189  AllowInNoRouting = true;
2190  }
2191  else if( cNodeName == wxT( "BOXPINS" ) )
2192  {
2193  BoxIsolatedPins = true;
2194  }
2195  else if( cNodeName == wxT( "REGENERATE" ) )
2196  {
2197  AutomaticRepour = true;
2198  }
2199  else if( cNodeName == wxT( "AUTOROUTETARGET" ) )
2200  {
2201  TargetForAutorouting = true;
2202  }
2203  else if( cNodeName == wxT( "THERMALCUTOUT" ) )
2204  {
2205  ReliefType = RELIEF_TYPE::CUTOUTS;
2206  }
2207  else if( cNodeName == wxT( "FILLED" ) )
2208  {
2209  FillType = COPPER_FILL_TYPE::FILLED;
2210  }
2211  else if( cNodeName == wxT( "HATCHCODEREF" ) )
2212  {
2213  FillType = COPPER_FILL_TYPE::HATCHED;
2214  HatchCodeID = GetXmlAttributeIDString( cNode, 0 );
2215  }
2216  else
2217  {
2218  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "POURING" ) );
2219  }
2220  }
2221 }
2222 
2223 
2225 {
2226  wxASSERT( aNode->GetName() == wxT( "TEMPLATE" ) );
2227 
2228  ID = GetXmlAttributeIDString( aNode, 0 );
2229  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
2230  Name = GetXmlAttributeIDString( aNode, 2 );
2231  NetID = GetXmlAttributeIDString( aNode, 3 );
2232  LayerID = GetXmlAttributeIDString( aNode, 4 );
2233 
2234  XNODE* cNode = aNode->GetChildren();
2235  bool shapeParsed = false;
2236  bool pouringParsed = false;
2237 
2238  for( ; cNode; cNode = cNode->GetNext() )
2239  {
2240  wxString cNodeName = cNode->GetName();
2241 
2242  if( !shapeParsed && SHAPE::IsShape( cNode ) )
2243  {
2244  Shape.Parse( cNode, aContext );
2245  shapeParsed = true;
2246  }
2247  else if( !pouringParsed && cNodeName == wxT( "POURING" ) )
2248  {
2249  Pouring.Parse( cNode, aContext );
2250  pouringParsed = true;
2251  }
2252  else if( cNodeName == wxT( "FIX" ) )
2253  {
2254  Fixed = true;
2255  }
2256  else if( cNodeName == wxT( "GROUPREF" ) )
2257  {
2258  GroupID = GetXmlAttributeIDString( cNode, 0 );
2259  }
2260  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2261  {
2262  ReuseBlockRef.Parse( cNode, aContext );
2263  }
2264  else if( cNodeName == wxT( "ATTR" ) )
2265  {
2266  ATTRIBUTE_VALUE attr;
2267  attr.Parse( cNode, aContext );
2268  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2269  }
2270  else
2271  {
2272  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2273  }
2274  }
2275 }
2276 
2277 
2279  PARSER_CONTEXT* aContext )
2280 {
2281  wxASSERT( aNode->GetName() == wxT( "TERM" ) );
2282 
2283  ID = GetXmlAttributeIDLong( aNode, 0 );
2284 
2285  XNODE* cNode = aNode->GetChildren();
2286  bool locationParsed = false;
2287 
2288  for( ; cNode; cNode = cNode->GetNext() )
2289  {
2290  wxString cNodeName = cNode->GetName();
2291 
2292  if( !locationParsed && cNodeName == wxT( "PT" ) )
2293  {
2294  Location.Parse( cNode, aContext );
2295  locationParsed = true;
2296  }
2297  else if( cNodeName == wxT( "FIX" ) )
2298  {
2299  Fixed = true;
2300  }
2301  else
2302  {
2303  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2304  }
2305  }
2306 }
2307 
2308 
2310 {
2311  wxASSERT( aNode->GetName() == wxT( "NETREF" ) );
2312 
2313  NetID = GetXmlAttributeIDString( aNode, 0 );
2314 
2315  XNODE* cNode = aNode->GetChildren();
2316 
2317  for( ; cNode; cNode = cNode->GetNext() )
2318  {
2319  wxString cNodeName = cNode->GetName();
2320 
2321  if( cNodeName == wxT( "TERM" ) )
2322  {
2323  COPPER_TERM term;
2324  term.Parse( cNode, aContext );
2325  CopperTerminals.insert( std::make_pair( term.ID, term ) );
2326  }
2327  else if( cNodeName == wxT( "FIX" ) )
2328  {
2329  Fixed = true;
2330  }
2331  else
2332  {
2333  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NETREF" ) );
2334  }
2335  }
2336 }
2337 
2338 
2340 {
2341  wxASSERT( aNode->GetName() == wxT( "COPPER" ) );
2342 
2343  ID = GetXmlAttributeIDString( aNode, 0 );
2344  CopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2345  LayerID = GetXmlAttributeIDString( aNode, 2 );
2346 
2347  XNODE* cNode = aNode->GetChildren();
2348  bool shapeParsed = false;
2349  bool netRefParsed = false;
2350 
2351  for( ; cNode; cNode = cNode->GetNext() )
2352  {
2353  wxString cNodeName = cNode->GetName();
2354 
2355  if( !shapeParsed && SHAPE::IsShape( cNode ) )
2356  {
2357  Shape.Parse( cNode, aContext );
2358  shapeParsed = true;
2359  }
2360  else if( !netRefParsed && cNodeName == wxT( "NETREF" ) )
2361  {
2362  NetRef.Parse( cNode, aContext );
2363  netRefParsed = true;
2364  }
2365  else if( cNodeName == wxT( "FIX" ) )
2366  {
2367  Fixed = true;
2368  }
2369  else if( cNodeName == wxT( "GROUPREF" ) )
2370  {
2371  GroupID = GetXmlAttributeIDString( cNode, 0 );
2372  }
2373  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2374  {
2375  ReuseBlockRef.Parse( cNode, aContext );
2376  }
2377  else if( cNodeName == wxT( "POURED" ) )
2378  {
2379  PouredTemplateID = GetXmlAttributeIDString( cNode, 0 );
2380  }
2381  else if( cNodeName == wxT( "ATTR" ) )
2382  {
2383  ATTRIBUTE_VALUE attr;
2384  attr.Parse( cNode, aContext );
2385  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2386  }
2387  else
2388  {
2389  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2390  }
2391  }
2392 }
2393 
2394 
2396 {
2397  wxASSERT( aNode->GetName() == wxT( "DRILLTABLE" ) );
2398 
2399  ID = GetXmlAttributeIDString( aNode, 0 );
2400  LayerID = GetXmlAttributeIDString( aNode, 1 );
2401 
2402  XNODE* cNode = aNode->GetChildren();
2403  bool positionParsed = false;
2404 
2405  for( ; cNode; cNode = cNode->GetNext() )
2406  {
2407  wxString cNodeName = cNode->GetName();
2408 
2409  if( !positionParsed && cNodeName == wxT( "PT" ) )
2410  {
2411  Position.Parse( cNode, aContext );
2412  positionParsed = true;
2413  }
2414  else if( cNodeName == wxT( "ORIENT" ) )
2415  {
2416  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
2417  }
2418  else if( cNodeName == wxT( "MIRROR" ) )
2419  {
2420  Mirror = true;
2421  }
2422  else if( cNodeName == wxT( "FIX" ) )
2423  {
2424  Fixed = true;
2425  }
2426  else if( cNodeName == wxT( "READABILITY" ) )
2427  {
2428  Readability = ParseReadability( cNode );
2429  }
2430  else if( cNodeName == wxT( "GROUPREF" ) )
2431  {
2432  GroupID = GetXmlAttributeIDString( cNode, 0 );
2433  }
2434  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2435  {
2436  ReuseBlockRef.Parse( cNode, aContext );
2437  }
2438  else
2439  {
2440  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2441  }
2442  }
2443 }
2444 
2445 
2447 {
2448  wxASSERT( aNode->GetName() == wxT( "LAYOUT" ) );
2449 
2450  XNODE* cNode = aNode->GetChildren();
2451  bool netSynchParsed = false;
2452  bool dimensionsParsed = false;
2453 
2454  for( ; cNode; cNode = cNode->GetNext() )
2455  {
2456  wxString cNodeName = cNode->GetName();
2457 
2458  if( !netSynchParsed && cNodeName == wxT( "NETSYNCH" ) )
2459  {
2460  std::map<wxString, NETSYNCH> netSynchMap = { { wxT( "WARNING" ), NETSYNCH::WARNING },
2461  { wxT( "FULL" ), NETSYNCH::FULL } };
2462 
2463  wxString nsString = GetXmlAttributeIDString( cNode, 0 );
2464 
2465  if( netSynchMap.find( nsString ) == netSynchMap.end() )
2466  THROW_UNKNOWN_PARAMETER_IO_ERROR( nsString, aNode->GetName() );
2467 
2468  NetSynch = netSynchMap[nsString];
2469  netSynchParsed = true;
2470  }
2471  else if( cNodeName == wxT( "GROUP" ) )
2472  {
2473  GROUP group;
2474  group.Parse( cNode, aContext );
2475  Groups.insert( std::make_pair( group.ID, group ) );
2476  }
2477  else if( cNodeName == wxT( "REUSEBLOCK" ) )
2478  {
2479  REUSEBLOCK reuseblock;
2480  reuseblock.Parse( cNode, aContext );
2481  ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
2482  }
2483  else if( cNodeName == wxT( "BOARD" ) )
2484  {
2485  CADSTAR_BOARD board;
2486  board.Parse( cNode, aContext );
2487  Boards.insert( std::make_pair( board.ID, board ) );
2488  }
2489  else if( cNodeName == wxT( "FIGURE" ) )
2490  {
2491  FIGURE figure;
2492  figure.Parse( cNode, aContext );
2493  Figures.insert( std::make_pair( figure.ID, figure ) );
2494  }
2495  else if( cNodeName == wxT( "AREA" ) )
2496  {
2497  AREA area;
2498  area.Parse( cNode, aContext );
2499  Areas.insert( std::make_pair( area.ID, area ) );
2500  }
2501  else if( cNodeName == wxT( "COMP" ) )
2502  {
2503  COMPONENT comp;
2504  comp.Parse( cNode, aContext );
2505  Components.insert( std::make_pair( comp.ID, comp ) );
2506  }
2507  else if( cNodeName == wxT( "TRUNK" ) )
2508  {
2509  TRUNK trunk;
2510  trunk.Parse( cNode, aContext );
2511  Trunks.insert( std::make_pair( trunk.ID, trunk ) );
2512  }
2513  else if( cNodeName == wxT( "NET" ) )
2514  {
2515  NET_PCB net;
2516  net.Parse( cNode, aContext );
2517  Nets.insert( std::make_pair( net.ID, net ) );
2518  }
2519  else if( cNodeName == wxT( "TEMPLATE" ) )
2520  {
2521  TEMPLATE temp;
2522  temp.Parse( cNode, aContext );
2523  Templates.insert( std::make_pair( temp.ID, temp ) );
2524  }
2525  else if( cNodeName == wxT( "COPPER" ) )
2526  {
2527  COPPER copper;
2528  copper.Parse( cNode, aContext );
2529  Coppers.insert( std::make_pair( copper.ID, copper ) );
2530  }
2531  else if( cNodeName == wxT( "TEXT" ) )
2532  {
2533  TEXT txt;
2534  txt.Parse( cNode, aContext );
2535  Texts.insert( std::make_pair( txt.ID, txt ) );
2536  }
2537  else if( cNodeName == wxT( "DOCSYMBOL" ) )
2538  {
2539  DOCUMENTATION_SYMBOL docsym;
2540  docsym.Parse( cNode, aContext );
2541  DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
2542  }
2543  else if( !dimensionsParsed && cNodeName == wxT( "DIMENSIONS" ) )
2544  {
2545  XNODE* dimensionNode = cNode->GetChildren();
2546 
2547  for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
2548  {
2549  if( DIMENSION::IsDimension( dimensionNode ) )
2550  {
2551  DIMENSION dim;
2552  dim.Parse( dimensionNode, aContext );
2553  Dimensions.insert( std::make_pair( dim.ID, dim ) );
2554  }
2555  else
2556  {
2557  THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
2558  }
2559  }
2560 
2561  dimensionsParsed = true;
2562  }
2563  else if( cNodeName == wxT( "DRILLTABLE" ) )
2564  {
2565  DRILL_TABLE drilltable;
2566  drilltable.Parse( cNode, aContext );
2567  DrillTables.insert( std::make_pair( drilltable.ID, drilltable ) );
2568  }
2569  else if( cNodeName == wxT( "VHIERARCHY" ) )
2570  {
2571  VariantHierarchy.Parse( cNode, aContext );
2572  }
2573  else if( cNodeName == wxT( "ERRORMARK" ) )
2574  {
2575  //ignore (this is a DRC error marker in cadstar)
2576  continue;
2577  }
2578  else
2579  {
2580  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2581  }
2582  }
2583 }
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long PART_DEFINITION_PIN_ID
Pin identifier in the part definition.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Inbuilt layer type (cannot be assigned to user layers)
Inbuilt layer type (cannot be assigned to user layers)
Inbuilt layer type (cannot be assigned to user layers)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
The highest PHYSICAL_LAYER_ID currently defined (i.e. back / bottom side).
static ANGUNITS ParseAngunits(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
From CADSTAR Help: "A testpoint is an area of copper connected to a net.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static bool IsValidAttribute(wxXmlAttribute *aAttribute)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
long PAD_ID
Pad identifier (pin) in the PCB.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
static SWAP_RULE ParseSwapRule(XNODE *aNode)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static void CheckNoChildNodes(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
From CADSTAR Help: "Jumpers are components used primarily for the purpose of routing.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
This file contains miscellaneous commonly used macros and functions.
static PAD_SIDE GetPadSide(const wxString &aPadSideString)
From CADSTAR Help: "Area is for creating areas within which, and nowhere else, certain operations are...
A shape of copper in the component footprint.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< Two sibbling nodes: first node being "ROUTEWIDTH" and next node being a VERTEX (e....
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
XNODE * GetChildren() const
Definition: xnode.h:62
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier)
Reads a CADSTAR Archive file (S-parameter format)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
DIMENSION_ID ID
Some ID (doesn't seem to be used) subnode="DIMREF".
constexpr double PCB_IU_PER_MM
Inbuilt layer type (cannot be assigned to user layers)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
The highest PHYSICAL_LAYER_ID currently defined (i.e.
XNODE * Parse(XNODE *aNode, PARSER_CONTEXT *aContext)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
#define THROW_PARSING_IO_ERROR(param, location)
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
From CADSTAR Help: "Starpoints are special symbols/components that can be used to electrically connec...
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Standard PCB Component definition.
All physical layers currently defined.
static VECTOR2D CLEAR
static const long UNDEFINED_VALUE
The lowest PHYSICAL_LAYER_ID currently defined (i.e. front / top side).
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Hold an XML or S-expression element.
Definition: xnode.h:43
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
XNODE * GetNext() const
Definition: xnode.h:67
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static READABILITY ParseReadability(XNODE *aNode)
static void CheckNoNextNodes(XNODE *aNode)
Inbuilt layer type (cannot be assigned to user layers)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static void ParseChildEValue(XNODE *aNode, PARSER_CONTEXT *aContext, EVALUE &aValueToParse)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static UNITS ParseUnits(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First character is "J".
static TESTLAND_SIDE ParseTestlandSide(XNODE *aNode)
Inbuilt layer type (cannot be assigned to user layers)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
Templates are CADSTAR's equivalent to a "filled zone".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "PIN" nodename (represents a PAD in a PCB component)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
#define THROW_UNKNOWN_PARAMETER_IO_ERROR(param, location)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
int KiCadUnitMultiplier
Use this value to convert units in this CPA file to KiCad units.
Linear, leader (radius/diameter) or angular dimension.
PAD_SIDE
From CADSTAR Help: "This parameter indicates the physical layers on which the selected pad is placed.
SPACINGCODE_ID ID
Possible spacing rules: