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