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