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 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 
30 
32 {
33  XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ) );
34 
35  XNODE* cNode = fileRootNode->GetChildren();
36 
37  if( !cNode )
38  THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARPCB" ) );
39 
40  for( ; cNode; cNode = cNode->GetNext() )
41  {
42  if( cNode->GetName() == wxT( "HEADER" ) )
43  {
44  Header.Parse( cNode, &m_context );
45 
46  switch( Header.Resolution )
47  {
50  break;
51 
52  default:
53  wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
54  break;
55  }
56 
57  if( Header.Format.Type != wxT( "LAYOUT" ) )
58  {
59  if( Header.Format.Type == wxT( "LIBRARY" ) )
60  {
62  "The selected file is a CADSTAR Library file (as opposed to a Layout "
63  "file). CADSTAR libraries cannot yet be imported into KiCad." );
64  }
65  else
66  {
68  "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 = NULL;
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 {
597  wxASSERT( aNode->GetName() == wxT( "SPACEREASSIGN" ) );
598 
599  LayerID = GetXmlAttributeIDString( aNode, 0 );
600  Spacing = GetXmlAttributeIDLong( aNode, 1 );
601 
602  CheckNoChildNodes( aNode );
603 }
604 
605 
607 {
608  wxASSERT( aNode->GetName() == wxT( "SPACINGCODE" ) );
609 
610  ID = GetXmlAttributeIDString( aNode, 0 );
611  Spacing = GetXmlAttributeIDLong( aNode, 1 );
612 
613  XNODE* cNode = aNode->GetChildren();
614 
615  for( ; cNode; cNode = cNode->GetNext() )
616  {
617  wxString cNodeName = cNode->GetName();
618 
619  if( cNodeName == wxT( "SPACEREASSIGN" ) )
620  {
621  REASSIGN reassign;
622  reassign.Parse( cNode, aContext );
623  Reassigns.push_back( reassign );
624  }
625  else
626  {
627  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
628  }
629  }
630 }
631 
632 
634 {
635  wxString aNodeName = aNode->GetName();
636 
637  if( aNodeName == wxT( "ANNULUS" ) || aNodeName == wxT( "BULLET" ) || aNodeName == wxT( "ROUND" )
638  || aNodeName == wxT( "DIAMOND" ) || aNodeName == wxT( "FINGER" )
639  || aNodeName == wxT( "OCTAGON" ) || aNodeName == wxT( "RECTANGLE" )
640  || aNodeName == wxT( "ROUNDED" ) || aNodeName == wxT( "SQUARE" ) )
641  {
642  return true;
643  }
644  else
645  {
646  return false;
647  }
648 }
649 
650 
652 {
653  wxASSERT( IsPadShape( aNode ) );
654 
655  wxString aNodeName = aNode->GetName();
656 
657  if( aNodeName == wxT( "ANNULUS" ) )
658  ShapeType = PAD_SHAPE_TYPE::ANNULUS;
659  else if( aNodeName == wxT( "BULLET" ) )
660  ShapeType = PAD_SHAPE_TYPE::BULLET;
661  else if( aNodeName == wxT( "ROUND" ) )
662  ShapeType = PAD_SHAPE_TYPE::CIRCLE;
663  else if( aNodeName == wxT( "DIAMOND" ) )
664  ShapeType = PAD_SHAPE_TYPE::DIAMOND;
665  else if( aNodeName == wxT( "FINGER" ) )
666  ShapeType = PAD_SHAPE_TYPE::FINGER;
667  else if( aNodeName == wxT( "OCTAGON" ) )
668  ShapeType = PAD_SHAPE_TYPE::OCTAGON;
669  else if( aNodeName == wxT( "RECTANGLE" ) )
670  ShapeType = PAD_SHAPE_TYPE::RECTANGLE;
671  else if( aNodeName == wxT( "ROUNDED" ) )
672  ShapeType = PAD_SHAPE_TYPE::ROUNDED_RECT;
673  else if( aNodeName == wxT( "SQUARE" ) )
674  ShapeType = PAD_SHAPE_TYPE::SQUARE;
675  else
676  wxASSERT( true );
677 
678  switch( ShapeType )
679  {
681  Size = GetXmlAttributeIDLong( aNode, 0 );
682  InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
683  break;
684 
686  InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
688 
692  RightLength = GetXmlAttributeIDLong( aNode, 2 );
693  LeftLength = GetXmlAttributeIDLong( aNode, 1 );
695 
699 
700  if( aNode->GetChildren() )
701  {
702  if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
703  {
704  OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
705  }
706  else
707  {
708  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
709  }
710 
711  CheckNoNextNodes( aNode->GetChildren() );
712  }
714 
716  Size = GetXmlAttributeIDLong( aNode, 0 );
717  break;
718  }
719 }
720 
721 
723 {
724  wxASSERT( aNode->GetName() == wxT( "PADREASSIGN" ) );
725 
726  LayerID = GetXmlAttributeIDString( aNode, 0 );
727 
729  Shape.Parse( aNode->GetChildren(), aContext );
730  else
731  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
732 
733  CheckNoNextNodes( aNode->GetChildren() );
734 }
735 
736 
738 {
739  wxASSERT( aNode->GetName() == wxT( "PADCODE" ) );
740 
741  ID = GetXmlAttributeIDString( aNode, 0 );
742  Name = GetXmlAttributeIDString( aNode, 1 );
743 
744  XNODE* cNode = aNode->GetChildren();
745  wxString location = wxString::Format( "PADCODE -> %s", Name );
746 
747  for( ; cNode; cNode = cNode->GetNext() )
748  {
749  wxString cNodeName = cNode->GetName();
750 
751  if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
752  {
753  Shape.Parse( cNode, aContext );
754  }
755  else if( cNodeName == wxT( "CLEARANCE" ) )
756  {
757  ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
758  }
759  else if( cNodeName == wxT( "RELIEFWIDTH" ) )
760  {
761  ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
762  }
763  else if( cNodeName == wxT( "DRILL" ) )
764  {
765  DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
766  XNODE* subNode = cNode->GetChildren();
767 
768  for( ; subNode; subNode = subNode->GetNext() )
769  {
770  wxString subNodeName = subNode->GetName();
771 
772  if( subNodeName == wxT( "NONPLATED" ) )
773  Plated = false;
774  else if( subNodeName == wxT( "OVERSIZE" ) )
775  DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
776  else
777  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
778  }
779  }
780  else if( cNodeName == wxT( "DRILLLENGTH" ) )
781  {
782  SlotLength = GetXmlAttributeIDLong( cNode, 0 );
783  }
784  else if( cNodeName == wxT( "DRILLORIENTATION" ) )
785  {
786  SlotOrientation = GetXmlAttributeIDLong( cNode, 0 );
787  }
788  else if( cNodeName == wxT( "DRILLXOFFSET" ) )
789  {
790  DrillXoffset = GetXmlAttributeIDLong( cNode, 0 );
791  }
792  else if( cNodeName == wxT( "DRILLYOFFSET" ) )
793  {
794  DrillYoffset = GetXmlAttributeIDLong( cNode, 0 );
795  }
796  else if( cNodeName == wxT( "PADREASSIGN" ) )
797  {
798  PADREASSIGN reassign;
799  reassign.Parse( cNode, aContext );
800  Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
801  }
802  else
803  {
804  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
805  }
806  }
807 }
808 
809 
811 {
812  wxASSERT( aNode->GetName() == wxT( "VIAREASSIGN" ) );
813 
814  LayerID = GetXmlAttributeIDString( aNode, 0 );
815 
817  Shape.Parse( aNode->GetChildren(), aContext );
818  else
819  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
820 
821  CheckNoNextNodes( aNode->GetChildren() );
822 }
823 
824 
826 {
827  wxASSERT( aNode->GetName() == wxT( "VIACODE" ) );
828 
829  ID = GetXmlAttributeIDString( aNode, 0 );
830  Name = GetXmlAttributeIDString( aNode, 1 );
831 
832  XNODE* cNode = aNode->GetChildren();
833  wxString location = wxString::Format( "VIACODE -> %s", Name );
834 
835  for( ; cNode; cNode = cNode->GetNext() )
836  {
837  wxString cNodeName = cNode->GetName();
838 
839  if( CADSTAR_PAD_SHAPE::IsPadShape( cNode ) )
840  {
841  Shape.Parse( cNode, aContext );
842  }
843  else if( cNodeName == wxT( "CLEARANCE" ) )
844  {
845  ReliefClearance = GetXmlAttributeIDLong( cNode, 0 );
846  }
847  else if( cNodeName == wxT( "RELIEFWIDTH" ) )
848  {
849  ReliefWidth = GetXmlAttributeIDLong( cNode, 0 );
850  }
851  else if( cNodeName == wxT( "DRILL" ) )
852  {
853  DrillDiameter = GetXmlAttributeIDLong( cNode, 0 );
854  XNODE* subNode = cNode->GetChildren();
855 
856  for( ; subNode; subNode = subNode->GetNext() )
857  {
858  wxString subNodeName = subNode->GetName();
859 
860  if( subNodeName == wxT( "OVERSIZE" ) )
861  DrillOversize = GetXmlAttributeIDLong( subNode, 0 );
862  else
863  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), location );
864  }
865  }
866  else if( cNodeName == wxT( "VIAREASSIGN" ) )
867  {
868  VIAREASSIGN reassign;
869  reassign.Parse( cNode, aContext );
870  Reassigns.insert( std::make_pair( reassign.LayerID, reassign.Shape ) );
871  }
872  else
873  {
874  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
875  }
876  }
877 }
878 
879 
881 {
882  wxASSERT( aNode->GetName() == wxT( "LAYERPAIR" ) );
883 
884  ID = GetXmlAttributeIDString( aNode, 0 );
885  Name = GetXmlAttributeIDString( aNode, 1 );
886 
887  PhysicalLayerStart = GetXmlAttributeIDLong( aNode, 2 );
888  PhysicalLayerEnd = GetXmlAttributeIDLong( aNode, 3 );
889 
890  wxString location = wxString::Format( "LAYERPAIR -> %s", Name );
891 
892  if( aNode->GetChildren() )
893  {
894  if( aNode->GetChildren()->GetName() == wxT( "VIACODEREF" ) )
895  {
896  ViacodeID = GetXmlAttributeIDString( aNode->GetChildren(), 0 );
897  }
898  else
899  {
900  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), location );
901  }
902 
903  CheckNoNextNodes( aNode->GetChildren() );
904  }
905 }
906 
907 
909 {
910  wxASSERT( aNode->GetName() == wxT( "SPCCLASSSPACE" ) );
911 
912  SpacingClassID1 = GetXmlAttributeIDString( aNode, 0 );
913  SpacingClassID2 = GetXmlAttributeIDString( aNode, 1 );
914  LayerID = GetXmlAttributeIDString( aNode, 2 );
915  Spacing = GetXmlAttributeIDLong( aNode, 3 );
916 }
917 
918 
920 {
921  wxASSERT( aNode->GetName() == wxT( "TECHNOLOGY" ) );
922 
923  XNODE* cNode = aNode->GetChildren();
924 
925  for( ; cNode; cNode = cNode->GetNext() )
926  {
927  wxString cNodeName = cNode->GetName();
928 
929  if( ParseSubNode( cNode, aContext ) ) //CADSTAR_ARCHIVE_PARSER::SETTINGS
930  {
931  }
932  else if( cNodeName == wxT( "MINROUTEWIDTH" ) )
933  {
934  MinRouteWidth = GetXmlAttributeIDLong( cNode, 0 );
935  }
936  else if( cNodeName == wxT( "MINNECKED" ) )
937  {
938  MinNeckedLength = GetXmlAttributeIDLong( cNode, 0 );
939  }
940  else if( cNodeName == wxT( "MINUNNECKED" ) )
941  {
942  MinUnneckedLength = GetXmlAttributeIDLong( cNode, 0 );
943  }
944  else if( cNodeName == wxT( "MINMITER" ) )
945  {
946  MinMitre = GetXmlAttributeIDLong( cNode, 0 );
947  }
948  else if( cNodeName == wxT( "MAXMITER" ) )
949  {
950  MaxMitre = GetXmlAttributeIDLong( cNode, 0 );
951  }
952  else if( cNodeName == wxT( "MAXPHYSLAYER" ) )
953  {
954  MaxPhysicalLayer = GetXmlAttributeIDLong( cNode, 0 );
955  }
956  else if( cNodeName == wxT( "TRACKGRID" ) )
957  {
958  TrackGrid = GetXmlAttributeIDLong( cNode, 0 );
959  }
960  else if( cNodeName == wxT( "VIAGRID" ) )
961  {
962  ViaGrid = GetXmlAttributeIDLong( cNode, 0 );
963  }
964  else if( cNodeName == wxT( "BACKOFFJCTS" ) )
965  {
966  BackOffJunctions = true;
967  }
968  else if( cNodeName == wxT( "BCKOFFWIDCHANGE" ) )
969  {
970  BackOffWidthChange = true;
971  }
972  else
973  {
974  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TECHNOLOGY" ) );
975  }
976  }
977 }
978 
980  const wxString& aPadSideString )
981 {
982  if( aPadSideString == wxT( "THRU" ) )
983  return PAD_SIDE::THROUGH_HOLE;
984  else if( aPadSideString == wxT( "BOTTOM" ) )
985  return PAD_SIDE::MAXIMUM;
986  else if( aPadSideString == wxT( "TOP" ) )
987  return PAD_SIDE::MINIMUM;
988  else
989  return PAD_SIDE::THROUGH_HOLE; // Assume through hole as default
990 }
991 
992 
994 {
995  wxASSERT( aNode->GetName() == wxT( "COMPCOPPER" ) );
996 
997  CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
998  LayerID = GetXmlAttributeIDString( aNode, 1 );
999 
1000  XNODE* cNode = aNode->GetChildren();
1001  bool shapeIsInitialised = false; // Stop more than one Shape Object
1002  wxString location = wxT( "COMPCOPPER" );
1003 
1004  if( !cNode )
1005  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1006 
1007  for( ; cNode; cNode = cNode->GetNext() )
1008  {
1009  wxString cNodeName = cNode->GetName();
1010 
1011  if( !shapeIsInitialised && Shape.IsShape( cNode ) )
1012  {
1013  Shape.Parse( cNode, aContext );
1014  shapeIsInitialised = true;
1015  }
1016  else if( cNodeName == wxT( "SWAPRULE" ) )
1017  {
1018  SwapRule = ParseSwapRule( cNode );
1019  }
1020  else if( cNodeName == wxT( "ASSOCPIN" ) )
1021  {
1022  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1023 
1024  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1025  {
1026  if( !IsValidAttribute( xmlAttribute ) )
1027  continue;
1028 
1029  long padId;
1030 
1031  if( !xmlAttribute->GetValue().ToLong( &padId ) )
1032  THROW_PARSING_IO_ERROR( wxT( "ASSOCPIN" ), location );
1033 
1034  AssociatedPadIDs.push_back( (PAD_ID) padId );
1035  }
1036 
1037  CheckNoChildNodes( cNode );
1038  }
1039  else
1040  {
1041  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1042  }
1043  }
1044 }
1045 
1046 
1048 {
1049  wxASSERT( aNode->GetName() == wxT( "COMPAREA" ) );
1050 
1051  ID = GetXmlAttributeIDString( aNode, 0 );
1052  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1053  LayerID = GetXmlAttributeIDString( aNode, 3 );
1054 
1055  XNODE* cNode = aNode->GetChildren();
1056  bool shapeIsInitialised = false; // Stop more than one Shape Object
1057  wxString location = wxString::Format( "COMPAREA %s", ID );
1058 
1059  if( !cNode )
1060  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1061 
1062  for( ; cNode; cNode = cNode->GetNext() )
1063  {
1064  wxString cNodeName = cNode->GetName();
1065 
1066  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1067  {
1068  Shape.Parse( cNode, aContext );
1069  shapeIsInitialised = true;
1070  }
1071  else if( cNodeName == wxT( "SWAPRULE" ) )
1072  {
1073  SwapRule = ParseSwapRule( cNode );
1074  }
1075  else if( cNodeName == wxT( "USAGE" ) )
1076  {
1077  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1078 
1079  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1080  {
1081  if( !IsValidAttribute( xmlAttribute ) )
1082  continue;
1083 
1084  if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1085  NoTracks = true;
1086  else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1087  NoVias = true;
1088  else
1089  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1090  }
1091 
1092  CheckNoChildNodes( cNode );
1093  }
1094  else
1095  {
1096  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1097  }
1098  }
1099 }
1100 
1101 
1103 {
1104  wxASSERT( aNode->GetName() == wxT( "EXITS" ) );
1105 
1106  wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
1107 
1108  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1109  {
1110  if( !IsValidAttribute( xmlAttribute ) )
1111  continue;
1112 
1113  if( xmlAttribute->GetValue() == wxT( "FREE" ) )
1114  FreeAngle = true;
1115  else if( xmlAttribute->GetValue() == wxT( "N" ) )
1116  North = true;
1117  else if( xmlAttribute->GetValue() == wxT( "S" ) )
1118  South = true;
1119  else if( xmlAttribute->GetValue() == wxT( "E" ) )
1120  East = true;
1121  else if( xmlAttribute->GetValue() == wxT( "W" ) )
1122  West = true;
1123  else if( xmlAttribute->GetValue() == wxT( "NE" ) )
1124  NorthEast = true;
1125  else if( xmlAttribute->GetValue() == wxT( "NW" ) )
1126  NorthWest = true;
1127  else if( xmlAttribute->GetValue() == wxT( "SE" ) )
1128  SouthEast = true;
1129  else if( xmlAttribute->GetValue() == wxT( "SW" ) )
1130  SouthWest = true;
1131  else
1132  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), wxT( "EXITS" ) );
1133  }
1134 
1135  CheckNoChildNodes( aNode );
1136 }
1137 
1138 
1140 {
1141  wxASSERT( aNode->GetName() == wxT( "PAD" ) );
1142 
1143  ID = GetXmlAttributeIDLong( aNode, 0 );
1144  PadCodeID = GetXmlAttributeIDString( aNode, 2 );
1145  Side = GetPadSide( GetXmlAttributeIDString( aNode, 3 ) );
1146 
1147  XNODE* cNode = aNode->GetChildren();
1148  wxString location = wxString::Format( "PAD %ld", ID );
1149 
1150  if( !cNode )
1151  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
1152 
1153  for( ; cNode; cNode = cNode->GetNext() )
1154  {
1155  wxString cNodeName = cNode->GetName();
1156 
1157  if( cNodeName == wxT( "ORIENT" ) )
1158  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1159  else if( cNodeName == wxT( "FIRSTPAD" ) )
1160  FirstPad = true;
1161  else if( cNodeName == wxT( "EXITS" ) )
1162  Exits.Parse( cNode, aContext );
1163  else if( cNodeName == wxT( "PADIDENTIFIER" ) )
1164  Identifier = GetXmlAttributeIDString( cNode, 0 );
1165  else if( cNodeName == wxT( "PCBONLYPAD" ) )
1166  PCBonlyPad = true;
1167  else if( cNodeName == wxT( "PT" ) )
1168  Position.Parse( cNode, aContext );
1169  else
1170  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1171  }
1172 }
1173 
1174 
1176 {
1177  wxASSERT( aNode->GetName() == wxT( "DIMARROW" ) );
1178  bool arrowStyleInitialised = false;
1179  bool upperAngleInitialised = false;
1180  bool lowerAngleInitialised = false;
1181 
1182  ArrowLength = GetXmlAttributeIDLong( aNode, 3 );
1183 
1184  XNODE* cNode = aNode->GetChildren();
1185 
1186 
1187  for( ; cNode; cNode = cNode->GetNext() )
1188  {
1189  wxString cNodeName = cNode->GetName();
1190 
1191  if( cNodeName == wxT( "ARROWSTYLE" ) )
1192  {
1193  wxString arrowStyleStr = GetXmlAttributeIDString( cNode, 0 );
1194  arrowStyleInitialised = true;
1195 
1196  if( arrowStyleStr == wxT( "DIMENSION_ARROWOPEN" ) )
1197  ArrowStyle = STYLE::OPEN;
1198  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSED" ) )
1199  ArrowStyle = STYLE::CLOSED;
1200  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLEAR" ) )
1201  ArrowStyle = STYLE::CLEAR;
1202  else if( arrowStyleStr == wxT( "DIMENSION_ARROWCLOSEDFILLED" ) )
1203  ArrowStyle = STYLE::CLOSED_FILLED;
1204  else
1205  THROW_UNKNOWN_PARAMETER_IO_ERROR( arrowStyleStr, cNodeName );
1206  }
1207  else if( cNodeName == wxT( "ARROWANGLEA" ) )
1208  {
1209  UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1210  upperAngleInitialised = true;
1211  }
1212  else if( cNodeName == wxT( "ARROWANGLEB" ) )
1213  {
1214  UpperAngle = GetXmlAttributeIDLong( cNode, 0 );
1215  lowerAngleInitialised = true;
1216  }
1217  else
1218  {
1219  THROW_UNKNOWN_PARAMETER_IO_ERROR( cNodeName, wxT( "DIMARROW" ) );
1220  }
1221  }
1222 
1223  if( !arrowStyleInitialised )
1224  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWSTYLE" ), wxT( "DIMARROW" ) );
1225 
1226  if( !upperAngleInitialised )
1227  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEA" ), wxT( "DIMARROW" ) );
1228 
1229  if( !lowerAngleInitialised )
1230  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "ARROWANGLEB" ), wxT( "DIMARROW" ) );
1231 }
1232 
1233 
1235 {
1236  wxASSERT( aNode->GetName() == wxT( "DIMTEXT" ) );
1237 
1238  TextGap = GetXmlAttributeIDLong( aNode, 1 );
1239  TextOffset = GetXmlAttributeIDLong( aNode, 2 );
1240 
1241  XNODE* cNode = aNode->GetChildren();
1242 
1243  if( cNode->GetName() != wxT( "TXTSTYLE" ) )
1244  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "DIMTEXT" ) );
1245 
1246  wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1247 
1248  if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1249  Style = STYLE::INSIDE;
1250  else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1251  Style = STYLE::OUTSIDE;
1252  else
1253  THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, wxT( "TXTSTYLE" ) );
1254 
1255  CheckNoNextNodes( cNode );
1256 }
1257 
1258 
1260 {
1261  wxASSERT( aNode->GetName() == wxT( "EXTLINE" ) );
1262 
1263  LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1264  Overshoot = GetXmlAttributeIDLong( aNode, 3 );
1265  Offset = GetXmlAttributeIDLong( aNode, 4 );
1266 
1267  XNODE* cNode = aNode->GetChildren();
1268  int noOfPoints = 0;
1269 
1270  for( ; cNode; cNode = cNode->GetNext() )
1271  {
1272  wxString cNodeName = cNode->GetName();
1273 
1274  if( noOfPoints < 2 && cNodeName == wxT( "PT" ) )
1275  {
1276  ++noOfPoints;
1277 
1278  if( noOfPoints == 1 )
1279  Start.Parse( cNode, aContext );
1280  else
1281  End.Parse( cNode, aContext );
1282  }
1283  else if( cNodeName == wxT( "SUPPRESSFIRST" ) )
1284  {
1285  SuppressFirst = true;
1286  }
1287  else
1288  {
1289  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "EXTLINE" ) );
1290  }
1291  }
1292 
1293  if( noOfPoints != 2 )
1294  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), wxT( "EXTLINE" ) );
1295 }
1296 
1297 
1299 {
1300  if( aNode->GetName() == wxT( "LEADERLINE" ) || aNode->GetName() == wxT( "LINEARLINE" )
1301  || aNode->GetName() == wxT( "ANGULARLINE" ) )
1302  {
1303  return true;
1304  }
1305  else
1306  {
1307  return false;
1308  }
1309 }
1310 
1311 
1313 {
1314  wxASSERT( IsLine( aNode ) );
1315 
1316  if( aNode->GetName() == wxT( "LINEARLINE" ) )
1317  Type = TYPE::LINEARLINE;
1318  else if( aNode->GetName() == wxT( "LEADERLINE" ) )
1319  Type = TYPE::LEADERLINE;
1320  else if( aNode->GetName() == wxT( "ANGULARLINE" ) )
1321  Type = TYPE::ANGULARLINE;
1322  else
1323  wxASSERT_MSG( true, "Not a valid type. What happened to the node Name?" );
1324 
1325  LineCodeID = GetXmlAttributeIDString( aNode, 0 );
1326 
1327  if( Type == TYPE::LEADERLINE )
1328  {
1329  LeaderLineLength = GetXmlAttributeIDLong( aNode, 5 );
1330  LeaderLineExtensionLength = GetXmlAttributeIDLong( aNode, 6 );
1331  }
1332 
1333  XNODE* cNode = aNode->GetChildren();
1334  int noOfPoints = 0;
1335  int requiredNoOfPoints = 2;
1336 
1337  if( Type == TYPE::ANGULARLINE )
1338  requiredNoOfPoints = 3;
1339 
1340  for( ; cNode; cNode = cNode->GetNext() )
1341  {
1342  wxString cNodeName = cNode->GetName();
1343 
1344  if( cNodeName == wxT( "DIMLINETYPE" ) )
1345  {
1346  wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
1347 
1348  if( styleStr == wxT( "DIMENSION_INTERNAL" ) )
1349  Style = STYLE::INTERNAL;
1350  else if( styleStr == wxT( "DIMENSION_EXTERNAL" ) )
1351  Style = STYLE::EXTERNAL;
1352  else
1353  THROW_UNKNOWN_PARAMETER_IO_ERROR( styleStr, cNodeName );
1354  }
1355  else if( noOfPoints < requiredNoOfPoints && cNodeName == wxT( "PT" ) )
1356  {
1357  ++noOfPoints;
1358 
1359  if( noOfPoints == 1 )
1360  Start.Parse( cNode, aContext );
1361  else if( noOfPoints == 2 )
1362  End.Parse( cNode, aContext );
1363  else
1364  Centre.Parse( cNode, aContext );
1365  }
1366  else if( Type == TYPE::LEADERLINE && cNodeName == wxT( "LEADERANG" ) )
1367  {
1368  LeaderAngle = GetXmlAttributeIDLong( cNode, 0 );
1369  }
1370  else
1371  {
1372  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1373  }
1374  }
1375 
1376  if( noOfPoints != requiredNoOfPoints )
1377  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1378 }
1379 
1380 
1382 {
1383  if( aNode->GetName() == wxT( "LINEARDIM" ) || aNode->GetName() == wxT( "LEADERDIM" )
1384  || aNode->GetName() == wxT( "ANGLEDIM" ) )
1385  {
1386  return true;
1387  }
1388  else
1389  {
1390  return false;
1391  }
1392 }
1393 
1394 
1396 {
1397  wxASSERT( IsDimension( aNode ) );
1398 
1399  std::map<wxString, TYPE> typeMap = { { wxT( "LINEARDIM" ), TYPE::LINEARDIM },
1400  { wxT( "LEADERDIM" ), TYPE::LEADERDIM }, { wxT( "ANGLEDIM" ), TYPE::ANGLEDIM } };
1401 
1402  //make sure aNode is valid TYPE
1403  wxASSERT_MSG( typeMap.find( aNode->GetName() ) != typeMap.end(),
1404  "Not a valid type. What happened to the node Name?" );
1405 
1406  Type = typeMap[aNode->GetName()];
1407  LayerID = GetXmlAttributeIDString( aNode, 1 );
1408  wxString subTypeStr = GetXmlAttributeIDString( aNode, 2 );
1409 
1410  std::map<wxString, SUBTYPE> subTypeMap = {
1411  { wxT( "DIMENSION_ORTHOGONAL" ), SUBTYPE::ORTHOGONAL },
1412  { wxT( "DIMENSION_DIRECT" ), SUBTYPE::DIRECT },
1413  { wxT( "DIMENSION_ANGLED" ), SUBTYPE::ANGLED },
1414  { wxT( "DIMENSION_DIAMETER" ), SUBTYPE::DIAMETER },
1415  { wxT( "DIMENSION_RADIUS" ), SUBTYPE::RADIUS },
1416  { wxT( "DIMENSION_ANGULAR" ), SUBTYPE::ANGULAR } };
1417 
1418  if( subTypeMap.find( subTypeStr ) == subTypeMap.end() )
1419  THROW_UNKNOWN_PARAMETER_IO_ERROR( subTypeStr, aNode->GetName() );
1420 
1421  Subtype = subTypeMap[subTypeStr];
1422  Precision = GetXmlAttributeIDLong( aNode, 3 );
1423 
1424  XNODE* cNode = aNode->GetChildren();
1425 
1426  bool idParsed = false;
1427  bool unitsParsed = false; //UNITS or ANGUNITS
1428  bool arrowParsed = false;
1429  bool textFormatParsed = false;
1430  bool extLineParsed = false;
1431  bool lineParsed = false;
1432  bool textParsed = false;
1433 
1434  for( ; cNode; cNode = cNode->GetNext() )
1435  {
1436  wxString cNodeName = cNode->GetName();
1437 
1438  if( !idParsed && cNodeName == wxT( "DIMREF" ) )
1439  {
1440  ID = GetXmlAttributeIDString( cNode, 0 );
1441  idParsed = true;
1442  }
1443  else if( !unitsParsed && cNodeName == wxT( "UNITS" ) )
1444  {
1445  LinearUnits = ParseUnits( cNode );
1446  unitsParsed = true;
1447  }
1448  else if( !unitsParsed && cNodeName == wxT( "ANGUNITS" ) )
1449  {
1450  AngularUnits = ParseAngunits( cNode );
1451  unitsParsed = true;
1452  }
1453  else if( !arrowParsed && cNodeName == wxT( "DIMARROW" ) )
1454  {
1455  Arrow.Parse( cNode, aContext );
1456  arrowParsed = true;
1457  }
1458  else if( !textFormatParsed && cNodeName == wxT( "DIMTEXT" ) )
1459  {
1460  TextParams.Parse( cNode, aContext );
1461  textFormatParsed = true;
1462  }
1463  else if( !extLineParsed && cNodeName == wxT( "EXTLINE" ) )
1464  {
1465  ExtensionLineParams.Parse( cNode, aContext );
1466  extLineParsed = true;
1467  }
1468  else if( !lineParsed && LINE::IsLine( cNode ) )
1469  {
1470  Line.Parse( cNode, aContext );
1471  lineParsed = true;
1472  }
1473  else if( !textParsed && cNodeName == wxT( "TEXT" ) )
1474  {
1475  // Do not parse the fields in dimension text (will be done when loading, if required)
1476  Text.Parse( cNode, aContext, false );
1477  textParsed = true;
1478  }
1479  else if( cNodeName == wxT( "FIX" ) )
1480  {
1481  Fixed = true;
1482  }
1483  else if( cNodeName == wxT( "GROUPREF" ) )
1484  {
1485  GroupID = GetXmlAttributeIDString( cNode, 0 );
1486  }
1487  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1488  {
1489  ReuseBlockRef.Parse( cNode, aContext );
1490  }
1491  else
1492  {
1493  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1494  }
1495  }
1496 }
1497 
1498 
1500 {
1501  wxASSERT( aNode->GetName() == wxT( "SYMDEF" ) );
1502 
1503  ParseIdentifiers( aNode, aContext );
1504 
1505  wxString rest;
1506 
1507  if( ReferenceName.StartsWith( wxT( "JUMPERNF" ), &rest ) )
1508  Type = SYMDEF_TYPE::JUMPER;
1509  else if( ReferenceName.StartsWith( wxT( "STARPOINTNF" ), &rest ) )
1510  Type = SYMDEF_TYPE::STARPOINT;
1511  else if( ReferenceName == wxT( "TESTPOINT" ) )
1512  Type = SYMDEF_TYPE::TESTPOINT;
1513  else
1514  Type = SYMDEF_TYPE::COMPONENT;
1515 
1516  XNODE* cNode = aNode->GetChildren();
1517 
1518  for( ; cNode; cNode = cNode->GetNext() )
1519  {
1520  wxString cNodeName = cNode->GetName();
1521 
1522  if( ParseSubNode( cNode, aContext ) )
1523  {
1524  continue;
1525  }
1526  else if( cNodeName == wxT( "SYMHEIGHT" ) )
1527  {
1528  SymHeight = GetXmlAttributeIDLong( cNode, 0 );
1529  }
1530  else if( cNodeName == wxT( "COMPCOPPER" ) )
1531  {
1532  COMPONENT_COPPER compcopper;
1533  compcopper.Parse( cNode, aContext );
1534  ComponentCoppers.push_back( compcopper );
1535  }
1536  else if( cNodeName == wxT( "COMPAREA" ) )
1537  {
1538  COMPONENT_AREA area;
1539  area.Parse( cNode, aContext );
1540  ComponentAreas.insert( std::make_pair( area.ID, area ) );
1541  }
1542  else if( cNodeName == wxT( "PAD" ) )
1543  {
1545  pad.Parse( cNode, aContext );
1546  ComponentPads.insert( std::make_pair( pad.ID, pad ) );
1547  }
1548  else if( cNodeName == wxT( "DIMENSIONS" ) )
1549  {
1550  XNODE* dimensionNode = cNode->GetChildren();
1551 
1552  for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
1553  {
1554  if( DIMENSION::IsDimension( dimensionNode ) )
1555  {
1556  DIMENSION dim;
1557  dim.Parse( dimensionNode, aContext );
1558  Dimensions.insert( std::make_pair( dim.ID, dim ) );
1559  }
1560  else
1561  {
1562  THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
1563  }
1564  }
1565  }
1566  else
1567  {
1568  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1569  }
1570  }
1571 
1572  if( !Stub && !Origin.IsFullySpecified() )
1573  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1574 }
1575 
1576 
1578 {
1579  wxASSERT( aNode->GetName() == wxT( "LIBRARY" ) );
1580 
1581  XNODE* cNode = aNode->GetChildren();
1582 
1583  for( ; cNode; cNode = cNode->GetNext() )
1584  {
1585  wxString cNodeName = cNode->GetName();
1586 
1587  if( cNodeName == wxT( "SYMDEF" ) )
1588  {
1589  SYMDEF_PCB symdef;
1590  symdef.Parse( cNode, aContext );
1591  ComponentDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
1592  }
1593  else
1594  {
1595  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1596  }
1597  }
1598 }
1599 
1600 
1602 {
1603  wxASSERT( aNode->GetName() == wxT( "BOARD" ) );
1604 
1605  ID = GetXmlAttributeIDString( aNode, 0 );
1606  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1607 
1608  XNODE* cNode = aNode->GetChildren();
1609  bool shapeIsInitialised = false; // Stop more than one Shape Object
1610  wxString location = wxString::Format( "BOARD %s", ID );
1611 
1612  if( !cNode )
1613  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1614 
1615  for( ; cNode; cNode = cNode->GetNext() )
1616  {
1617  wxString cNodeName = cNode->GetName();
1618 
1619  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1620  {
1621  Shape.Parse( cNode, aContext );
1622  shapeIsInitialised = true;
1623  }
1624  else if( cNodeName == wxT( "ATTR" ) )
1625  {
1626  ATTRIBUTE_VALUE attr;
1627  attr.Parse( cNode, aContext );
1628  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1629  }
1630  else if( cNodeName == wxT( "FIX" ) )
1631  {
1632  Fixed = true;
1633  }
1634  else if( cNodeName == wxT( "GROUPREF" ) )
1635  {
1636  GroupID = GetXmlAttributeIDString( cNode, 0 );
1637  }
1638  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1639  {
1640  ReuseBlockRef.Parse( cNode, aContext );
1641  }
1642  else
1643  {
1644  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1645  }
1646  }
1647 }
1648 
1649 
1651 {
1652  wxASSERT( aNode->GetName() == wxT( "AREA" ) );
1653 
1654  ID = GetXmlAttributeIDString( aNode, 0 );
1655  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
1656  Name = GetXmlAttributeIDString( aNode, 2 );
1657  LayerID = GetXmlAttributeIDString( aNode, 4 );
1658 
1659  XNODE* cNode = aNode->GetChildren();
1660  bool shapeIsInitialised = false; // Stop more than one Shape Object
1661  wxString location = wxString::Format( "AREA %s", ID );
1662 
1663  if( !cNode )
1664  THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
1665 
1666  for( ; cNode; cNode = cNode->GetNext() )
1667  {
1668  wxString cNodeName = cNode->GetName();
1669 
1670  if( !shapeIsInitialised && SHAPE::IsShape( cNode ) )
1671  {
1672  Shape.Parse( cNode, aContext );
1673  shapeIsInitialised = true;
1674  }
1675  else if( cNodeName == wxT( "FIX" ) )
1676  {
1677  Fixed = true;
1678  }
1679  else if( cNodeName == wxT( "USAGE" ) )
1680  {
1681  wxXmlAttribute* xmlAttribute = cNode->GetAttributes();
1682 
1683  for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
1684  {
1685  if( !IsValidAttribute( xmlAttribute ) )
1686  continue;
1687 
1688  if( xmlAttribute->GetValue() == wxT( "PLACEMENT" ) )
1689  Placement = true;
1690  else if( xmlAttribute->GetValue() == wxT( "ROUTING" ) )
1691  Routing = true;
1692  else if( xmlAttribute->GetValue() == wxT( "KEEPOUT" ) )
1693  Keepout = true;
1694  else if( xmlAttribute->GetValue() == wxT( "NO_TRACKS" ) )
1695  NoTracks = true;
1696  else if( xmlAttribute->GetValue() == wxT( "NO_VIAS" ) )
1697  NoVias = true;
1698  else
1699  THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), location );
1700  }
1701 
1702  CheckNoChildNodes( cNode );
1703  }
1704  else if( cNodeName == wxT( "AREAHEIGHT" ) )
1705  {
1706  AreaHeight = GetXmlAttributeIDLong( cNode, 0 );
1707  }
1708  else if( cNodeName == wxT( "GROUPREF" ) )
1709  {
1710  GroupID = GetXmlAttributeIDString( cNode, 0 );
1711  }
1712  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1713  {
1714  ReuseBlockRef.Parse( cNode, aContext );
1715  }
1716  else if( cNodeName == wxT( "ATTR" ) )
1717  {
1718  ATTRIBUTE_VALUE attr;
1719  attr.Parse( cNode, aContext );
1720  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
1721  }
1722  else
1723  {
1724  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
1725  }
1726  }
1727 }
1728 
1729 
1731 {
1732  wxASSERT( aNode->GetName() == wxT( "PINATTR" ) );
1733 
1734  Pin = GetXmlAttributeIDLong( aNode, 0 );
1735 
1736  XNODE* cNode = aNode->GetChildren();
1737 
1738  for( ; cNode; cNode = cNode->GetNext() )
1739  {
1740  wxString cNodeName = cNode->GetName();
1741 
1742  if( cNodeName == wxT( "ATTR" ) )
1743  {
1744  ATTRIBUTE_VALUE attrVal;
1745  attrVal.Parse( cNode, aContext );
1746  AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1747  }
1748  else if( cNodeName == wxT( "TESTLAND" ) )
1749  {
1750  TestlandSide = ParseTestlandSide( cNode );
1751  }
1752  else
1753  {
1754  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1755  }
1756  }
1757 }
1758 
1759 
1761 {
1762  wxASSERT( aNode->GetName() == wxT( "PADEXCEPTION" ) );
1763 
1764  ID = GetXmlAttributeIDLong( aNode, 0 );
1765 
1766  XNODE* cNode = aNode->GetChildren();
1767 
1768  for( ; cNode; cNode = cNode->GetNext() )
1769  {
1770  wxString cNodeName = cNode->GetName();
1771 
1772  if( cNodeName == wxT( "PADCODEREF" ) )
1773  {
1774  PadCode = GetXmlAttributeIDString( cNode, 0 );
1775  }
1776  else if( cNodeName == wxT( "EXITS" ) )
1777  {
1778  OverrideExits = true;
1779  Exits.Parse( cNode, aContext );
1780  }
1781  else if( cNodeName == wxT( "SIDE" ) )
1782  {
1783  OverrideSide = true;
1784  Side = GetPadSide( GetXmlAttributeIDString( cNode, 0 ) );
1785  }
1786  else if( cNodeName == wxT( "ORIENT" ) )
1787  {
1788  OverrideOrientation = true;
1789  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1790  }
1791  else
1792  {
1793  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1794  }
1795  }
1796 }
1797 
1798 
1800 {
1801  wxASSERT( aNode->GetName() == wxT( "COMP" ) );
1802 
1803  ID = GetXmlAttributeIDString( aNode, 0 );
1804  Name = GetXmlAttributeIDString( aNode, 1 );
1805  PartID = GetXmlAttributeIDString( aNode, 2 );
1806  SymdefID = GetXmlAttributeIDString( aNode, 3 );
1807 
1808  XNODE* cNode = aNode->GetChildren();
1809  bool originParsed = false;
1810 
1811  for( ; cNode; cNode = cNode->GetNext() )
1812  {
1813  wxString cNodeName = cNode->GetName();
1814 
1815  if( !originParsed && cNodeName == wxT( "PT" ) )
1816  {
1817  Origin.Parse( cNode, aContext );
1818  originParsed = true;
1819  }
1820  else if( cNodeName == wxT( "GROUPREF" ) )
1821  {
1822  GroupID = GetXmlAttributeIDString( cNode, 0 );
1823  }
1824  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1825  {
1826  ReuseBlockRef.Parse( cNode, aContext );
1827  }
1828  else if( cNodeName == wxT( "TESTPOINT" ) )
1829  {
1830  TestPoint = true;
1831  }
1832  else if( cNodeName == wxT( "FIX" ) )
1833  {
1834  Fixed = true;
1835  }
1836  else if( cNodeName == wxT( "MIRROR" ) )
1837  {
1838  Mirror = true;
1839  }
1840  else if( cNodeName == wxT( "READABILITY" ) )
1841  {
1842  Readability = ParseReadability( cNode );
1843  }
1844  else if( cNodeName == wxT( "ORIENT" ) )
1845  {
1846  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
1847  }
1848  else if( cNodeName == wxT( "VCOMPMASTER" ) )
1849  {
1850  VariantParentComponentID = GetXmlAttributeIDString( cNode, 0 );
1851  VariantID = GetXmlAttributeIDString( cNode, 1 );
1852  }
1853  else if( cNodeName == wxT( "TEXTLOC" ) )
1854  {
1855  TEXT_LOCATION textloc;
1856  textloc.Parse( cNode, aContext );
1857  TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) );
1858  }
1859  else if( cNodeName == wxT( "ATTR" ) )
1860  {
1861  ATTRIBUTE_VALUE attrVal;
1862  attrVal.Parse( cNode, aContext );
1863  AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
1864  }
1865  else if( cNodeName == wxT( "PINATTR" ) )
1866  {
1867  PIN_ATTRIBUTE pinAttr;
1868  pinAttr.Parse( cNode, aContext );
1869  PinAttributes.insert( std::make_pair( pinAttr.Pin, pinAttr ) );
1870  }
1871  else if( cNodeName == wxT( "COMPPINLABEL" ) )
1872  {
1873  PART_DEFINITION_PIN_ID pinID = GetXmlAttributeIDLong( cNode, 0 );
1874  wxString pinLabel = GetXmlAttributeIDString( cNode, 1 );
1875  PinLabels.insert( std::make_pair( pinID, pinLabel ) );
1876  }
1877  else if( cNodeName == wxT( "PADEXCEPTION" ) )
1878  {
1879  PADEXCEPTION padExcept;
1880  padExcept.Parse( cNode, aContext );
1881  PadExceptions.insert( std::make_pair( padExcept.ID, padExcept ) );
1882  }
1883  else
1884  {
1885  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1886  }
1887  }
1888 
1889  if( !originParsed )
1890  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1891 }
1892 
1893 
1895  XNODE* aNode )
1896 {
1897  wxASSERT( aNode->GetName() == wxT( "TESTLAND" ) );
1898 
1899  wxString side = GetXmlAttributeIDString( aNode, 0 );
1900 
1901  if( side == wxT( "MIN_SIDE" ) )
1902  return TESTLAND_SIDE::MIN;
1903  else if( side == wxT( "MAX_SIDE" ) )
1904  return TESTLAND_SIDE::MAX;
1905  else if( side == wxT( "BOTH_SIDES" ) )
1906  return TESTLAND_SIDE::BOTH;
1907  else
1908  THROW_UNKNOWN_PARAMETER_IO_ERROR( side, aNode->GetName() );
1909 
1910  return TESTLAND_SIDE::NONE;
1911 }
1912 
1913 
1915 {
1916  wxASSERT( aNode->GetName() == wxT( "TRUNK" ) );
1917 
1918  ID = GetXmlAttributeIDString( aNode, 0 );
1919  Definition = GetXmlAttributeIDString( aNode, 1 );
1920 }
1921 
1922 
1924 {
1925  wxASSERT( aNode->GetName() == wxT( "PIN" ) );
1926 
1927  ID = GetXmlAttributeIDString( aNode, 0 );
1928  ComponentID = GetXmlAttributeIDString( aNode, 1 );
1929  PadID = GetXmlAttributeIDLong( aNode, 2 );
1930  CheckNoChildNodes( aNode );
1931 }
1932 
1933 
1935 {
1936  ParseIdentifiers( aNode, aContext );
1937  XNODE* cNode = aNode->GetChildren();
1938 
1939  for( ; cNode; cNode = cNode->GetNext() )
1940  {
1941  if( ParseSubNode( cNode, aContext ) )
1942  continue;
1943  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
1944  TrunkID = GetXmlAttributeIDString( cNode, 0 );
1945  else
1946  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1947  }
1948 }
1949 
1950 
1952 {
1953  wxASSERT( aNode->GetName() == wxT( "VIA" ) );
1954 
1955  ID = GetXmlAttributeIDString( aNode, 0 );
1956  ViaCodeID = GetXmlAttributeIDString( aNode, 1 );
1957  LayerPairID = GetXmlAttributeIDString( aNode, 2 );
1958 
1959  XNODE* cNode = aNode->GetChildren();
1960 
1961  for( ; cNode; cNode = cNode->GetNext() )
1962  {
1963  wxString cNodeName = cNode->GetName();
1964 
1965  if( cNodeName == wxT( "PT" ) )
1966  Location.Parse( cNode, aContext );
1967  else if( cNodeName == wxT( "FIX" ) )
1968  Fixed = true;
1969  else if( cNodeName == wxT( "GROUPREF" ) )
1970  GroupID = GetXmlAttributeIDString( cNode, 0 );
1971  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1972  ReuseBlockRef.Parse( cNode, aContext );
1973  else if( cNodeName == wxT( "TESTLAND" ) )
1974  TestlandSide = ParseTestlandSide( cNode );
1975  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
1976  TrunkID = GetXmlAttributeIDString( cNode, 0 );
1977  else
1978  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1979  }
1980 }
1981 
1982 
1984 {
1985  wxASSERT( aNode->GetName() == wxT( "COPTERM" ) );
1986 
1987  ID = GetXmlAttributeIDString( aNode, 0 );
1988  CopperID = GetXmlAttributeIDString( aNode, 1 );
1989  CopperTermNum = GetXmlAttributeIDLong( aNode, 2 );
1990 }
1991 
1992 
1994 {
1995  wxASSERT( aNode->GetName() == wxT( "ROUTEWIDTH" ) );
1996 
1997  RouteWidth = GetXmlAttributeIDLong( aNode, 0 );
1998  XNODE* nextNode = aNode->GetNext();
1999 
2000  if( nextNode->GetName() == wxT( "FIX" ) )
2001  {
2002  Fixed = true;
2003  nextNode = nextNode->GetNext();
2004  }
2005 
2006  if( !VERTEX::IsVertex( nextNode ) )
2007  THROW_UNKNOWN_NODE_IO_ERROR( nextNode->GetName(), wxT( "ROUTE_VERTEX" ) );
2008 
2009  Vertex.Parse( nextNode, aContext );
2010 
2011  return nextNode;
2012 }
2013 
2014 
2016 {
2017  wxASSERT( aNode->GetName() == wxT( "ROUTE" ) );
2018 
2019  LayerID = GetXmlAttributeIDString( aNode, 0 );
2020 
2021  //Parse child nodes
2022  XNODE* cNode = aNode->GetChildren();
2023  bool startPointParsed = false;
2024 
2025  for( ; cNode; cNode = cNode->GetNext() )
2026  {
2027  wxString cNodeName = cNode->GetName();
2028 
2029  if( !startPointParsed && cNodeName == wxT( "PT" ) )
2030  {
2031  startPointParsed = true;
2032  StartPoint.Parse( cNode, aContext );
2033  }
2034  else if( cNodeName == wxT( "ROUTEWIDTH" ) )
2035  {
2036  ROUTE_VERTEX rtVert;
2037  cNode = rtVert.Parse( cNode, aContext );
2038  RouteVertices.push_back( rtVert );
2039  }
2040  else
2041  {
2042  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "ROUTE" ) );
2043  }
2044  }
2045 }
2046 
2047 
2049 {
2050  ParseIdentifiers( aNode, aContext );
2051 
2052  //Parse child nodes
2053  XNODE* cNode = aNode->GetChildren();
2054  bool routeParsed = false; //assume only one route per connection
2055 
2056  for( ; cNode; cNode = cNode->GetNext() )
2057  {
2058  wxString cNodeName = cNode->GetName();
2059 
2060  if( ParseSubNode( cNode, aContext ) )
2061  {
2062  continue;
2063  }
2064  else if( !Unrouted && !routeParsed && cNodeName == wxT( "ROUTE" ) )
2065  {
2066  Route.Parse( cNode, aContext );
2067  routeParsed = true;
2068  }
2069  else if( !routeParsed && cNodeName == wxT( "UNROUTE" ) )
2070  {
2071  Unrouted = true;
2072  UnrouteLayerID = GetXmlAttributeIDString( cNode, 0 );
2073  }
2074  else if( cNode->GetName() == wxT( "TRUNKREF" ) )
2075  {
2076  TrunkID = GetXmlAttributeIDString( cNode, 0 );
2077  }
2078  else
2079  {
2080  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
2081  }
2082  }
2083 }
2084 
2085 
2087 {
2088  ParseIdentifiers( aNode, aContext );
2089 
2090  //Parse child nodes
2091  XNODE* cNode = aNode->GetChildren();
2092 
2093  for( ; cNode; cNode = cNode->GetNext() )
2094  {
2095  wxString cNodeName = cNode->GetName();
2096 
2097  if( cNodeName == wxT( "JPT" ) )
2098  {
2099  JUNCTION_PCB jpt;
2100  jpt.Parse( cNode, aContext );
2101  Junctions.insert( std::make_pair( jpt.ID, jpt ) );
2102  }
2103  else if( ParseSubNode( cNode, aContext ) )
2104  {
2105  continue;
2106  }
2107  else if( cNodeName == wxT( "PIN" ) )
2108  {
2109  PIN pin;
2110  pin.Parse( cNode, aContext );
2111  Pins.insert( std::make_pair( pin.ID, pin ) );
2112  }
2113  else if( cNodeName == wxT( "VIA" ) )
2114  {
2115  VIA via;
2116  via.Parse( cNode, aContext );
2117  Vias.insert( std::make_pair( via.ID, via ) );
2118  }
2119  else if( cNodeName == wxT( "COPTERM" ) )
2120  {
2121  COPPER_TERMINAL cterm;
2122  cterm.Parse( cNode, aContext );
2123  CopperTerminals.insert( std::make_pair( cterm.ID, cterm ) );
2124  }
2125  else if( cNodeName == wxT( "CONN" ) )
2126  {
2127  CONNECTION_PCB conn;
2128  conn.Parse( cNode, aContext );
2129  Connections.push_back( conn );
2130  }
2131  else
2132  {
2133  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
2134  }
2135  }
2136 }
2137 
2138 
2140 {
2141  wxASSERT( aNode->GetName() == wxT( "POURING" ) );
2142 
2143  CopperCodeID = GetXmlAttributeIDString( aNode, 0 );
2144  ReliefCopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2145  ClearanceWidth = GetXmlAttributeIDLong( aNode, 2 );
2146  SliverWidth = GetXmlAttributeIDLong( aNode, 3 );
2147  AdditionalIsolation = GetXmlAttributeIDLong( aNode, 4 );
2148  ThermalReliefPadsAngle = GetXmlAttributeIDLong( aNode, 5 );
2149  ThermalReliefViasAngle = GetXmlAttributeIDLong( aNode, 6 );
2150 
2151  wxString MinIsolCopStr = GetXmlAttributeIDString( aNode, 7 );
2152 
2153  if( MinIsolCopStr == wxT( "NONE" ) )
2154  MinIsolatedCopper = UNDEFINED_VALUE;
2155  else
2156  MinIsolatedCopper = GetXmlAttributeIDLong( aNode, 7 );
2157 
2158  wxString MinDisjCopStr = GetXmlAttributeIDString( aNode, 8 );
2159 
2160  if( MinDisjCopStr == wxT( "NONE" ) )
2161  MinDisjointCopper = UNDEFINED_VALUE;
2162  else
2163  MinDisjointCopper = GetXmlAttributeIDLong( aNode, 8 );
2164 
2165  XNODE* cNode = aNode->GetChildren();
2166 
2167  for( ; cNode; cNode = cNode->GetNext() )
2168  {
2169  wxString cNodeName = cNode->GetName();
2170 
2171  if( cNodeName == wxT( "NOPINRELIEF" ) )
2172  {
2173  ThermalReliefOnPads = false;
2174  }
2175  else if( cNodeName == wxT( "NOVIARELIEF" ) )
2176  {
2177  ThermalReliefOnVias = false;
2178  }
2179  else if( cNodeName == wxT( "IGNORETRN" ) )
2180  {
2181  AllowInNoRouting = true;
2182  }
2183  else if( cNodeName == wxT( "BOXPINS" ) )
2184  {
2185  BoxIsolatedPins = true;
2186  }
2187  else if( cNodeName == wxT( "REGENERATE" ) )
2188  {
2189  AutomaticRepour = true;
2190  }
2191  else if( cNodeName == wxT( "AUTOROUTETARGET" ) )
2192  {
2193  TargetForAutorouting = true;
2194  }
2195  else if( cNodeName == wxT( "THERMALCUTOUT" ) )
2196  {
2197  ReliefType = RELIEF_TYPE::CUTOUTS;
2198  }
2199  else if( cNodeName == wxT( "FILLED" ) )
2200  {
2201  FillType = COPPER_FILL_TYPE::FILLED;
2202  }
2203  else if( cNodeName == wxT( "HATCHCODEREF" ) )
2204  {
2205  FillType = COPPER_FILL_TYPE::HATCHED;
2206  HatchCodeID = GetXmlAttributeIDString( cNode, 0 );
2207  }
2208  else
2209  {
2210  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "POURING" ) );
2211  }
2212  }
2213 }
2214 
2215 
2217 {
2218  wxASSERT( aNode->GetName() == wxT( "TEMPLATE" ) );
2219 
2220  ID = GetXmlAttributeIDString( aNode, 0 );
2221  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
2222  Name = GetXmlAttributeIDString( aNode, 2 );
2223  NetID = GetXmlAttributeIDString( aNode, 3 );
2224  LayerID = GetXmlAttributeIDString( aNode, 4 );
2225 
2226  XNODE* cNode = aNode->GetChildren();
2227  bool shapeParsed = false;
2228  bool pouringParsed = false;
2229 
2230  for( ; cNode; cNode = cNode->GetNext() )
2231  {
2232  wxString cNodeName = cNode->GetName();
2233 
2234  if( !shapeParsed && SHAPE::IsShape( cNode ) )
2235  {
2236  Shape.Parse( cNode, aContext );
2237  shapeParsed = true;
2238  }
2239  else if( !pouringParsed && cNodeName == wxT( "POURING" ) )
2240  {
2241  Pouring.Parse( cNode, aContext );
2242  pouringParsed = true;
2243  }
2244  else if( cNodeName == wxT( "FIX" ) )
2245  {
2246  Fixed = true;
2247  }
2248  else if( cNodeName == wxT( "GROUPREF" ) )
2249  {
2250  GroupID = GetXmlAttributeIDString( cNode, 0 );
2251  }
2252  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2253  {
2254  ReuseBlockRef.Parse( cNode, aContext );
2255  }
2256  else if( cNodeName == wxT( "ATTR" ) )
2257  {
2258  ATTRIBUTE_VALUE attr;
2259  attr.Parse( cNode, aContext );
2260  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2261  }
2262  else
2263  {
2264  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2265  }
2266  }
2267 }
2268 
2269 
2271 {
2272  wxASSERT( aNode->GetName() == wxT( "TERM" ) );
2273 
2274  ID = GetXmlAttributeIDLong( aNode, 0 );
2275 
2276  XNODE* cNode = aNode->GetChildren();
2277  bool locationParsed = false;
2278 
2279  for( ; cNode; cNode = cNode->GetNext() )
2280  {
2281  wxString cNodeName = cNode->GetName();
2282 
2283  if( !locationParsed && cNodeName == wxT( "PT" ) )
2284  {
2285  Location.Parse( cNode, aContext );
2286  locationParsed = true;
2287  }
2288  else if( cNodeName == wxT( "FIX" ) )
2289  {
2290  Fixed = true;
2291  }
2292  else
2293  {
2294  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2295  }
2296  }
2297 }
2298 
2299 
2301 {
2302  wxASSERT( aNode->GetName() == wxT( "NETREF" ) );
2303 
2304  NetID = GetXmlAttributeIDString( aNode, 0 );
2305 
2306  XNODE* cNode = aNode->GetChildren();
2307 
2308  for( ; cNode; cNode = cNode->GetNext() )
2309  {
2310  wxString cNodeName = cNode->GetName();
2311 
2312  if( cNodeName == wxT( "TERM" ) )
2313  {
2314  COPPER_TERM term;
2315  term.Parse( cNode, aContext );
2316  CopperTerminals.insert( std::make_pair( term.ID, term ) );
2317  }
2318  else if( cNodeName == wxT( "FIX" ) )
2319  {
2320  Fixed = true;
2321  }
2322  else
2323  {
2324  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NETREF" ) );
2325  }
2326  }
2327 }
2328 
2329 
2331 {
2332  wxASSERT( aNode->GetName() == wxT( "COPPER" ) );
2333 
2334  ID = GetXmlAttributeIDString( aNode, 0 );
2335  CopperCodeID = GetXmlAttributeIDString( aNode, 1 );
2336  LayerID = GetXmlAttributeIDString( aNode, 2 );
2337 
2338  XNODE* cNode = aNode->GetChildren();
2339  bool shapeParsed = false;
2340  bool netRefParsed = false;
2341 
2342  for( ; cNode; cNode = cNode->GetNext() )
2343  {
2344  wxString cNodeName = cNode->GetName();
2345 
2346  if( !shapeParsed && SHAPE::IsShape( cNode ) )
2347  {
2348  Shape.Parse( cNode, aContext );
2349  shapeParsed = true;
2350  }
2351  else if( !netRefParsed && cNodeName == wxT( "NETREF" ) )
2352  {
2353  NetRef.Parse( cNode, aContext );
2354  netRefParsed = true;
2355  }
2356  else if( cNodeName == wxT( "FIX" ) )
2357  {
2358  Fixed = true;
2359  }
2360  else if( cNodeName == wxT( "GROUPREF" ) )
2361  {
2362  GroupID = GetXmlAttributeIDString( cNode, 0 );
2363  }
2364  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2365  {
2366  ReuseBlockRef.Parse( cNode, aContext );
2367  }
2368  else if( cNodeName == wxT( "POURED" ) )
2369  {
2370  PouredTemplateID = GetXmlAttributeIDString( cNode, 0 );
2371  }
2372  else if( cNodeName == wxT( "ATTR" ) )
2373  {
2374  ATTRIBUTE_VALUE attr;
2375  attr.Parse( cNode, aContext );
2376  AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
2377  }
2378  else
2379  {
2380  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEMPLATE" ) );
2381  }
2382  }
2383 }
2384 
2385 
2387 {
2388  wxASSERT( aNode->GetName() == wxT( "DRILLTABLE" ) );
2389 
2390  ID = GetXmlAttributeIDString( aNode, 0 );
2391  LayerID = GetXmlAttributeIDString( aNode, 1 );
2392 
2393  XNODE* cNode = aNode->GetChildren();
2394  bool positionParsed = false;
2395 
2396  for( ; cNode; cNode = cNode->GetNext() )
2397  {
2398  wxString cNodeName = cNode->GetName();
2399 
2400  if( !positionParsed && cNodeName == wxT( "PT" ) )
2401  {
2402  Position.Parse( cNode, aContext );
2403  positionParsed = true;
2404  }
2405  else if( cNodeName == wxT( "ORIENT" ) )
2406  {
2407  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
2408  }
2409  else if( cNodeName == wxT( "MIRROR" ) )
2410  {
2411  Mirror = true;
2412  }
2413  else if( cNodeName == wxT( "FIX" ) )
2414  {
2415  Fixed = true;
2416  }
2417  else if( cNodeName == wxT( "READABILITY" ) )
2418  {
2419  Readability = ParseReadability( cNode );
2420  }
2421  else if( cNodeName == wxT( "GROUPREF" ) )
2422  {
2423  GroupID = GetXmlAttributeIDString( cNode, 0 );
2424  }
2425  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
2426  {
2427  ReuseBlockRef.Parse( cNode, aContext );
2428  }
2429  else
2430  {
2431  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2432  }
2433  }
2434 }
2435 
2436 
2438 {
2439  wxASSERT( aNode->GetName() == wxT( "LAYOUT" ) );
2440 
2441  XNODE* cNode = aNode->GetChildren();
2442  bool netSynchParsed = false;
2443  bool dimensionsParsed = false;
2444 
2445  for( ; cNode; cNode = cNode->GetNext() )
2446  {
2447  wxString cNodeName = cNode->GetName();
2448 
2449  if( !netSynchParsed && cNodeName == wxT( "NETSYNCH" ) )
2450  {
2451  std::map<wxString, NETSYNCH> netSynchMap = { { wxT( "WARNING" ), NETSYNCH::WARNING },
2452  { wxT( "FULL" ), NETSYNCH::FULL } };
2453 
2454  wxString nsString = GetXmlAttributeIDString( cNode, 0 );
2455 
2456  if( netSynchMap.find( nsString ) == netSynchMap.end() )
2457  THROW_UNKNOWN_PARAMETER_IO_ERROR( nsString, aNode->GetName() );
2458 
2459  NetSynch = netSynchMap[nsString];
2460  netSynchParsed = true;
2461  }
2462  else if( cNodeName == wxT( "GROUP" ) )
2463  {
2464  GROUP group;
2465  group.Parse( cNode, aContext );
2466  Groups.insert( std::make_pair( group.ID, group ) );
2467  }
2468  else if( cNodeName == wxT( "REUSEBLOCK" ) )
2469  {
2470  REUSEBLOCK reuseblock;
2471  reuseblock.Parse( cNode, aContext );
2472  ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
2473  }
2474  else if( cNodeName == wxT( "BOARD" ) )
2475  {
2476  CADSTAR_BOARD board;
2477  board.Parse( cNode, aContext );
2478  Boards.insert( std::make_pair( board.ID, board ) );
2479  }
2480  else if( cNodeName == wxT( "FIGURE" ) )
2481  {
2482  FIGURE figure;
2483  figure.Parse( cNode, aContext );
2484  Figures.insert( std::make_pair( figure.ID, figure ) );
2485  }
2486  else if( cNodeName == wxT( "AREA" ) )
2487  {
2488  AREA area;
2489  area.Parse( cNode, aContext );
2490  Areas.insert( std::make_pair( area.ID, area ) );
2491  }
2492  else if( cNodeName == wxT( "COMP" ) )
2493  {
2494  COMPONENT comp;
2495  comp.Parse( cNode, aContext );
2496  Components.insert( std::make_pair( comp.ID, comp ) );
2497  }
2498  else if( cNodeName == wxT( "TRUNK" ) )
2499  {
2500  TRUNK trunk;
2501  trunk.Parse( cNode, aContext );
2502  Trunks.insert( std::make_pair( trunk.ID, trunk ) );
2503  }
2504  else if( cNodeName == wxT( "NET" ) )
2505  {
2506  NET_PCB net;
2507  net.Parse( cNode, aContext );
2508  Nets.insert( std::make_pair( net.ID, net ) );
2509  }
2510  else if( cNodeName == wxT( "TEMPLATE" ) )
2511  {
2512  TEMPLATE temp;
2513  temp.Parse( cNode, aContext );
2514  Templates.insert( std::make_pair( temp.ID, temp ) );
2515  }
2516  else if( cNodeName == wxT( "COPPER" ) )
2517  {
2518  COPPER copper;
2519  copper.Parse( cNode, aContext );
2520  Coppers.insert( std::make_pair( copper.ID, copper ) );
2521  }
2522  else if( cNodeName == wxT( "TEXT" ) )
2523  {
2524  TEXT txt;
2525  txt.Parse( cNode, aContext );
2526  Texts.insert( std::make_pair( txt.ID, txt ) );
2527  }
2528  else if( cNodeName == wxT( "DOCSYMBOL" ) )
2529  {
2530  DOCUMENTATION_SYMBOL docsym;
2531  docsym.Parse( cNode, aContext );
2532  DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
2533  }
2534  else if( !dimensionsParsed && cNodeName == wxT( "DIMENSIONS" ) )
2535  {
2536  XNODE* dimensionNode = cNode->GetChildren();
2537 
2538  for( ; dimensionNode; dimensionNode = dimensionNode->GetNext() )
2539  {
2540  if( DIMENSION::IsDimension( dimensionNode ) )
2541  {
2542  DIMENSION dim;
2543  dim.Parse( dimensionNode, aContext );
2544  Dimensions.insert( std::make_pair( dim.ID, dim ) );
2545  }
2546  else
2547  {
2548  THROW_UNKNOWN_NODE_IO_ERROR( dimensionNode->GetName(), cNodeName );
2549  }
2550  }
2551 
2552  dimensionsParsed = true;
2553  }
2554  else if( cNodeName == wxT( "DRILLTABLE" ) )
2555  {
2556  DRILL_TABLE drilltable;
2557  drilltable.Parse( cNode, aContext );
2558  DrillTables.insert( std::make_pair( drilltable.ID, drilltable ) );
2559  }
2560  else if( cNodeName == wxT( "VHIERARCHY" ) )
2561  {
2562  VariantHierarchy.Parse( cNode, aContext );
2563  }
2564  else if( cNodeName == wxT( "ERRORMARK" ) )
2565  {
2566  //ignore (this is a DRC error marker in cadstar)
2567  continue;
2568  }
2569  else
2570  {
2571  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
2572  }
2573  }
2574 }
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
#define NULL
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)
Returns a pointer to the last node.
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: