You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2133 lines
60 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
  5. * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * @file cadstar_archive_parser.cpp
  22. * @brief Helper functions and common defines between schematic and PCB Archive files
  23. */
  24. #include <plugins/cadstar/cadstar_archive_parser.h>
  25. void CADSTAR_ARCHIVE_PARSER::FORMAT::Parse( XNODE* aNode )
  26. {
  27. wxASSERT( aNode->GetName() == wxT( "FORMAT" ) );
  28. Type = GetXmlAttributeIDString( aNode, 0 );
  29. SomeInt = GetXmlAttributeIDLong( aNode, 1 );
  30. Version = GetXmlAttributeIDLong( aNode, 2 );
  31. }
  32. void CADSTAR_ARCHIVE_PARSER::TIMESTAMP::Parse( XNODE* aNode )
  33. {
  34. wxASSERT( aNode->GetName() == wxT( "TIMESTAMP" ) );
  35. if( !GetXmlAttributeIDString( aNode, 0 ).ToLong( &Year )
  36. || !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Month )
  37. || !GetXmlAttributeIDString( aNode, 2 ).ToLong( &Day )
  38. || !GetXmlAttributeIDString( aNode, 3 ).ToLong( &Hour )
  39. || !GetXmlAttributeIDString( aNode, 4 ).ToLong( &Minute )
  40. || !GetXmlAttributeIDString( aNode, 5 ).ToLong( &Second ) )
  41. THROW_PARSING_IO_ERROR( wxT( "TIMESTAMP" ), wxString::Format( "HEADER" ) );
  42. }
  43. void CADSTAR_ARCHIVE_PARSER::HEADER::Parse( XNODE* aNode )
  44. {
  45. wxASSERT( aNode->GetName() == wxT( "HEADER" ) );
  46. XNODE* cNode = aNode->GetChildren();
  47. for( ; cNode; cNode = cNode->GetNext() )
  48. {
  49. wxString nodeName = cNode->GetName();
  50. if( nodeName == wxT( "FORMAT" ) )
  51. {
  52. Format.Parse( cNode );
  53. }
  54. else if( nodeName == wxT( "JOBFILE" ) )
  55. {
  56. JobFile = GetXmlAttributeIDString( cNode, 0 );
  57. }
  58. else if( nodeName == wxT( "JOBTITLE" ) )
  59. {
  60. JobTitle = GetXmlAttributeIDString( cNode, 0 );
  61. }
  62. else if( nodeName == wxT( "GENERATOR" ) )
  63. {
  64. Generator = GetXmlAttributeIDString( cNode, 0 );
  65. }
  66. else if( nodeName == wxT( "RESOLUTION" ) )
  67. {
  68. XNODE* subNode = cNode->GetChildren();
  69. if( ( subNode->GetName() == wxT( "METRIC" ) )
  70. && ( GetXmlAttributeIDString( subNode, 0 ) == wxT( "HUNDREDTH" ) )
  71. && ( GetXmlAttributeIDString( subNode, 1 ) == wxT( "MICRON" ) ) )
  72. {
  73. Resolution = RESOLUTION::HUNDREDTH_MICRON;
  74. }
  75. else
  76. {
  77. // TODO Need to find out if there are other possible resolutions. Logically
  78. // there must be other base units that could be used, such as "IMPERIAL INCH"
  79. // or "METRIC MM" but so far none of settings in CADSTAR generated a different
  80. // output resolution to "HUNDREDTH MICRON"
  81. THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), wxT( "HEADER->RESOLUTION" ) );
  82. }
  83. }
  84. else if( nodeName == wxT( "TIMESTAMP" ) )
  85. {
  86. Timestamp.Parse( cNode );
  87. }
  88. else
  89. {
  90. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "HEADER" ) );
  91. }
  92. }
  93. }
  94. void CADSTAR_ARCHIVE_PARSER::VARIANT::Parse( XNODE* aNode )
  95. {
  96. wxASSERT( aNode->GetName() == wxT( "VMASTER" ) || aNode->GetName() == wxT( "VARIANT" ) );
  97. ID = GetXmlAttributeIDString( aNode, 0 );
  98. if( aNode->GetName() == wxT( "VMASTER" ) )
  99. {
  100. Name = GetXmlAttributeIDString( aNode, 1 );
  101. Description = GetXmlAttributeIDString( aNode, 2 );
  102. }
  103. else
  104. {
  105. ParentID = GetXmlAttributeIDString( aNode, 1 );
  106. Name = GetXmlAttributeIDString( aNode, 2 );
  107. Description = GetXmlAttributeIDString( aNode, 3 );
  108. }
  109. }
  110. void CADSTAR_ARCHIVE_PARSER::VARIANT_HIERARCHY::Parse( XNODE* aNode )
  111. {
  112. wxASSERT( aNode->GetName() == wxT( "VHIERARCHY" ) );
  113. XNODE* cNode = aNode->GetChildren();
  114. for( ; cNode; cNode = cNode->GetNext() )
  115. {
  116. if( cNode->GetName() == wxT( "VMASTER" ) || cNode->GetName() == wxT( "VARIANT" ) )
  117. {
  118. VARIANT variant;
  119. variant.Parse( cNode );
  120. Variants.insert( std::make_pair( variant.ID, variant ) );
  121. }
  122. else
  123. {
  124. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), cNode->GetName() );
  125. }
  126. }
  127. }
  128. void CADSTAR_ARCHIVE_PARSER::LINECODE::Parse( XNODE* aNode )
  129. {
  130. wxASSERT( aNode->GetName() == wxT( "LINECODE" ) );
  131. ID = GetXmlAttributeIDString( aNode, 0 );
  132. Name = GetXmlAttributeIDString( aNode, 1 );
  133. if( !GetXmlAttributeIDString( aNode, 2 ).ToLong( &Width ) )
  134. THROW_PARSING_IO_ERROR( wxT( "Line Width" ), wxString::Format( "LINECODE -> %s", Name ) );
  135. XNODE* cNode = aNode->GetChildren();
  136. if( cNode->GetName() != wxT( "STYLE" ) )
  137. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxString::Format( "LINECODE -> %s", Name ) );
  138. wxString styleStr = GetXmlAttributeIDString( cNode, 0 );
  139. if( styleStr == wxT( "SOLID" ) )
  140. {
  141. Style = LINESTYLE::SOLID;
  142. }
  143. else if( styleStr == wxT( "DASH" ) )
  144. {
  145. Style = LINESTYLE::DASH;
  146. }
  147. else if( styleStr == wxT( "DASHDOT" ) )
  148. {
  149. Style = LINESTYLE::DASHDOT;
  150. }
  151. else if( styleStr == wxT( "DASHDOTDOT" ) )
  152. {
  153. Style = LINESTYLE::DASHDOTDOT;
  154. }
  155. else if( styleStr == wxT( "DOT" ) )
  156. {
  157. Style = LINESTYLE::DOT;
  158. }
  159. else
  160. {
  161. THROW_UNKNOWN_PARAMETER_IO_ERROR( wxString::Format( "STYLE %s", styleStr ),
  162. wxString::Format( "LINECODE -> %s", Name ) );
  163. }
  164. }
  165. void CADSTAR_ARCHIVE_PARSER::HATCH::Parse( XNODE* aNode )
  166. {
  167. wxASSERT( aNode->GetName() == wxT( "HATCH" ) );
  168. Step = GetXmlAttributeIDLong( aNode, 0 );
  169. LineWidth = GetXmlAttributeIDLong( aNode, 2 );
  170. XNODE* cNode = aNode->GetChildren();
  171. if( !cNode || cNode->GetName() != wxT( "ORIENT" ) )
  172. THROW_MISSING_NODE_IO_ERROR( wxT( "ORIENT" ), wxT( "HATCH" ) );
  173. OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
  174. }
  175. void CADSTAR_ARCHIVE_PARSER::HATCHCODE::Parse( XNODE* aNode )
  176. {
  177. wxASSERT( aNode->GetName() == wxT( "HATCHCODE" ) );
  178. ID = GetXmlAttributeIDString( aNode, 0 );
  179. Name = GetXmlAttributeIDString( aNode, 1 );
  180. XNODE* cNode = aNode->GetChildren();
  181. wxString location = wxString::Format( "HATCHCODE -> %s", Name );
  182. for( ; cNode; cNode = cNode->GetNext() )
  183. {
  184. if( cNode->GetName() != wxT( "HATCH" ) )
  185. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), location );
  186. HATCH hatch;
  187. hatch.Parse( cNode );
  188. Hatches.push_back( hatch );
  189. }
  190. }
  191. void CADSTAR_ARCHIVE_PARSER::FONT::Parse( XNODE* aNode )
  192. {
  193. wxASSERT( aNode->GetName() == wxT( "FONT" ) );
  194. Name = GetXmlAttributeIDString( aNode, 0 );
  195. Modifier1 = GetXmlAttributeIDLong( aNode, 1 );
  196. Modifier2 = GetXmlAttributeIDLong( aNode, 2 );
  197. XNODE* cNode = aNode->GetChildren();
  198. for( ; cNode; cNode = cNode->GetNext() )
  199. {
  200. wxString cNodeName = cNode->GetName();
  201. if( cNodeName == wxT( "ITALIC" ) )
  202. Italic = true;
  203. else if( cNodeName == wxT( "KERNING" ) )
  204. KerningPairs = true;
  205. else
  206. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  207. }
  208. }
  209. void CADSTAR_ARCHIVE_PARSER::TEXTCODE::Parse( XNODE* aNode )
  210. {
  211. wxASSERT( aNode->GetName() == wxT( "TEXTCODE" ) );
  212. ID = GetXmlAttributeIDString( aNode, 0 );
  213. Name = GetXmlAttributeIDString( aNode, 1 );
  214. LineWidth = GetXmlAttributeIDLong( aNode, 2 );
  215. Height = GetXmlAttributeIDLong( aNode, 3 );
  216. Width = GetXmlAttributeIDLong( aNode, 4 );
  217. XNODE* cNode = aNode->GetChildren();
  218. if( cNode )
  219. {
  220. if( cNode->GetName() == wxT( "FONT" ) )
  221. Font.Parse( cNode );
  222. else
  223. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
  224. }
  225. }
  226. void CADSTAR_ARCHIVE_PARSER::ROUTECODE::Parse( XNODE* aNode )
  227. {
  228. wxASSERT( aNode->GetName() == wxT( "ROUTECODE" ) );
  229. ID = GetXmlAttributeIDString( aNode, 0 );
  230. Name = GetXmlAttributeIDString( aNode, 1 );
  231. OptimalWidth = GetXmlAttributeIDLong( aNode, 2, false );
  232. XNODE* cNode = aNode->GetChildren();
  233. for( ; cNode; cNode = cNode->GetNext() )
  234. {
  235. wxString cNodeName = cNode->GetName();
  236. if( cNodeName == wxT( "NECKWIDTH" ) )
  237. NeckedWidth = GetXmlAttributeIDLong( cNode, 0 );
  238. else if( cNodeName == wxT( "SROUTEWIDTH" ) )
  239. OptimalWidth = GetXmlAttributeIDLong( cNode, 0 );
  240. else if( cNodeName == wxT( "MINWIDTH" ) )
  241. MinWidth = GetXmlAttributeIDLong( cNode, 0 );
  242. else if( cNodeName == wxT( "MAXWIDTH" ) )
  243. MaxWidth = GetXmlAttributeIDLong( cNode, 0 );
  244. else
  245. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  246. }
  247. }
  248. double CADSTAR_ARCHIVE_PARSER::EVALUE::GetDouble()
  249. {
  250. return Base * std::pow( 10.0, Exponent );
  251. }
  252. void CADSTAR_ARCHIVE_PARSER::EVALUE::Parse( XNODE* aNode )
  253. {
  254. wxASSERT( aNode->GetName() == wxT( "E" ) );
  255. if( ( !GetXmlAttributeIDString( aNode, 0 ).ToLong( &Base ) )
  256. || ( !GetXmlAttributeIDString( aNode, 1 ).ToLong( &Exponent ) ) )
  257. {
  258. THROW_PARSING_IO_ERROR( wxT( "Base and Exponent" ),
  259. wxString::Format(
  260. "%s->%s", aNode->GetParent()->GetName(), aNode->GetParent()->GetName() ) );
  261. }
  262. }
  263. void CADSTAR_ARCHIVE_PARSER::POINT::Parse( XNODE* aNode )
  264. {
  265. wxASSERT( aNode->GetName() == wxT( "PT" ) );
  266. x = GetXmlAttributeIDLong( aNode, 0 );
  267. y = GetXmlAttributeIDLong( aNode, 1 );
  268. }
  269. void CADSTAR_ARCHIVE_PARSER::LONGPOINT::Parse( XNODE* aNode )
  270. {
  271. wxASSERT( aNode->GetName() == wxT( "PT" ) );
  272. x = GetXmlAttributeIDLong( aNode, 0 );
  273. y = GetXmlAttributeIDLong( aNode, 1 );
  274. }
  275. bool CADSTAR_ARCHIVE_PARSER::VERTEX::IsVertex( XNODE* aNode )
  276. {
  277. wxString aNodeName = aNode->GetName();
  278. if( aNodeName == wxT( "PT" ) || aNodeName == wxT( "ACWARC" ) || aNodeName == wxT( "CWARC" )
  279. || aNodeName == wxT( "CWSEMI" ) || aNodeName == wxT( "ACWSEMI" ) )
  280. {
  281. return true;
  282. }
  283. else
  284. {
  285. return false;
  286. }
  287. }
  288. void CADSTAR_ARCHIVE_PARSER::VERTEX::Parse( XNODE* aNode )
  289. {
  290. wxASSERT( IsVertex( aNode ) );
  291. wxString aNodeName = aNode->GetName();
  292. if( aNodeName == wxT( "PT" ) )
  293. {
  294. Type = VERTEX_TYPE::POINT;
  295. Center.x = UNDEFINED_VALUE;
  296. Center.y = UNDEFINED_VALUE;
  297. End.Parse( aNode );
  298. }
  299. else if( aNodeName == wxT( "ACWARC" ) || aNodeName == wxT( "CWARC" ) )
  300. {
  301. if( aNodeName == wxT( "ACWARC" ) )
  302. Type = VERTEX_TYPE::ANTICLOCKWISE_ARC;
  303. else
  304. Type = VERTEX_TYPE::CLOCKWISE_ARC;
  305. std::vector<POINT> pts = ParseAllChildPoints( aNode, true, 2 );
  306. Center = pts[0];
  307. End = pts[1];
  308. }
  309. else if( aNodeName == wxT( "ACWSEMI" ) || aNodeName == wxT( "CWSEMI" ) )
  310. {
  311. if( aNodeName == wxT( "ACWSEMI" ) )
  312. Type = VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE;
  313. else
  314. Type = VERTEX_TYPE::CLOCKWISE_SEMICIRCLE;
  315. Center.x = UNDEFINED_VALUE;
  316. Center.y = UNDEFINED_VALUE;
  317. std::vector<POINT> pts = ParseAllChildPoints( aNode, true, 1 );
  318. End = pts[0];
  319. }
  320. else
  321. {
  322. wxASSERT_MSG( true, wxT( "Unknown VERTEX type" ) );
  323. }
  324. }
  325. void CADSTAR_ARCHIVE_PARSER::CUTOUT::Parse( XNODE* aNode )
  326. {
  327. wxASSERT( aNode->GetName() == wxT( "CUTOUT" ) );
  328. Vertices = ParseAllChildVertices( aNode, true );
  329. }
  330. bool CADSTAR_ARCHIVE_PARSER::SHAPE::IsShape( XNODE* aNode )
  331. {
  332. wxString aNodeName = aNode->GetName();
  333. if( aNodeName == wxT( "OPENSHAPE" ) || aNodeName == wxT( "OUTLINE" )
  334. || aNodeName == wxT( "SOLID" ) || aNodeName == wxT( "HATCHED" ) )
  335. {
  336. return true;
  337. }
  338. else
  339. {
  340. return false;
  341. }
  342. }
  343. void CADSTAR_ARCHIVE_PARSER::SHAPE::Parse( XNODE* aNode )
  344. {
  345. wxASSERT( IsShape( aNode ) );
  346. wxString aNodeName = aNode->GetName();
  347. if( aNodeName == wxT( "OPENSHAPE" ) )
  348. {
  349. Type = SHAPE_TYPE::OPENSHAPE;
  350. Vertices = ParseAllChildVertices( aNode, true );
  351. Cutouts.clear();
  352. HatchCodeID = wxEmptyString;
  353. }
  354. else if( aNodeName == wxT( "OUTLINE" ) )
  355. {
  356. Type = SHAPE_TYPE::OUTLINE;
  357. Vertices = ParseAllChildVertices( aNode, false );
  358. Cutouts = ParseAllChildCutouts( aNode, false );
  359. HatchCodeID = wxEmptyString;
  360. }
  361. else if( aNodeName == wxT( "SOLID" ) )
  362. {
  363. Type = SHAPE_TYPE::SOLID;
  364. Vertices = ParseAllChildVertices( aNode, false );
  365. Cutouts = ParseAllChildCutouts( aNode, false );
  366. HatchCodeID = wxEmptyString;
  367. }
  368. else if( aNodeName == wxT( "HATCHED" ) )
  369. {
  370. Type = SHAPE_TYPE::HATCHED;
  371. Vertices = ParseAllChildVertices( aNode, false );
  372. Cutouts = ParseAllChildCutouts( aNode, false );
  373. HatchCodeID = GetXmlAttributeIDString( aNode, 0 );
  374. }
  375. else
  376. {
  377. wxASSERT_MSG( true, wxT( "Unknown SHAPE type" ) );
  378. }
  379. }
  380. CADSTAR_ARCHIVE_PARSER::UNITS CADSTAR_ARCHIVE_PARSER::ParseUnits( XNODE* aNode )
  381. {
  382. wxASSERT( aNode->GetName() == wxT( "UNITS" ) );
  383. wxString unit = GetXmlAttributeIDString( aNode, 0 );
  384. if( unit == wxT( "CENTIMETER" ) )
  385. return UNITS::CENTIMETER;
  386. else if( unit == wxT( "INCH" ) )
  387. return UNITS::INCH;
  388. else if( unit == wxT( "METER" ) )
  389. return UNITS::METER;
  390. else if( unit == wxT( "MICROMETRE" ) )
  391. return UNITS::MICROMETRE;
  392. else if( unit == wxT( "MM" ) )
  393. return UNITS::MM;
  394. else if( unit == wxT( "THOU" ) )
  395. return UNITS::THOU;
  396. else if( unit == wxT( "DESIGN" ) )
  397. return UNITS::DESIGN;
  398. else
  399. THROW_UNKNOWN_PARAMETER_IO_ERROR( unit, wxT( "UNITS" ) );
  400. return UNITS();
  401. }
  402. CADSTAR_ARCHIVE_PARSER::ANGUNITS CADSTAR_ARCHIVE_PARSER::ParseAngunits( XNODE* aNode )
  403. {
  404. wxASSERT( aNode->GetName() == wxT( "ANGUNITS" ) );
  405. wxString angUnitStr = GetXmlAttributeIDString( aNode, 0 );
  406. if( angUnitStr == wxT( "DEGREES" ) )
  407. return ANGUNITS::DEGREES;
  408. else if( angUnitStr == wxT( "RADIANS" ) )
  409. return ANGUNITS::RADIANS;
  410. else
  411. THROW_UNKNOWN_PARAMETER_IO_ERROR( angUnitStr, aNode->GetName() );
  412. return ANGUNITS();
  413. }
  414. bool CADSTAR_ARCHIVE_PARSER::GRID::IsGrid( XNODE* aNode )
  415. {
  416. wxString aNodeName = aNode->GetName();
  417. if( aNodeName == wxT( "FRACTIONALGRID" ) || aNodeName == wxT( "STEPGRID" ) )
  418. return true;
  419. else
  420. return false;
  421. }
  422. void CADSTAR_ARCHIVE_PARSER::GRID::Parse( XNODE* aNode )
  423. {
  424. wxASSERT( IsGrid( aNode ) );
  425. wxString aNodeName = aNode->GetName();
  426. if( aNodeName == wxT( "FRACTIONALGRID" ) )
  427. Type = GRID_TYPE::FRACTIONALGRID;
  428. else if( aNodeName == wxT( "STEPGRID" ) )
  429. Type = GRID_TYPE::STEPGRID;
  430. else
  431. wxASSERT_MSG( true, wxT( "Unknown Grid Type" ) );
  432. Name = GetXmlAttributeIDString( aNode, 0 );
  433. Param1 = GetXmlAttributeIDLong( aNode, 1 );
  434. Param2 = GetXmlAttributeIDLong( aNode, 2 );
  435. }
  436. void CADSTAR_ARCHIVE_PARSER::GRIDS::Parse( XNODE* aNode )
  437. {
  438. wxASSERT( aNode->GetName() == wxT( "GRIDS" ) );
  439. XNODE* cNode = aNode->GetChildren();
  440. for( ; cNode; cNode = cNode->GetNext() )
  441. {
  442. wxString cNodeName = cNode->GetName();
  443. if( cNodeName == wxT( "WORKINGGRID" ) )
  444. {
  445. XNODE* workingGridNode = cNode->GetChildren();
  446. if( !GRID::IsGrid( workingGridNode ) )
  447. {
  448. THROW_UNKNOWN_NODE_IO_ERROR(
  449. workingGridNode->GetName(), wxT( "GRIDS -> WORKINGGRID" ) );
  450. }
  451. else
  452. {
  453. WorkingGrid.Parse( workingGridNode );
  454. }
  455. }
  456. else if( cNodeName == wxT( "SCREENGRID" ) )
  457. {
  458. XNODE* screenGridNode = cNode->GetChildren();
  459. if( !GRID::IsGrid( screenGridNode ) )
  460. {
  461. THROW_UNKNOWN_NODE_IO_ERROR(
  462. screenGridNode->GetName(), wxT( "GRIDS -> SCREENGRID" ) );
  463. }
  464. else
  465. {
  466. ScreenGrid.Parse( screenGridNode );
  467. }
  468. }
  469. else if( GRID::IsGrid( cNode ) )
  470. {
  471. GRID userGrid;
  472. userGrid.Parse( cNode );
  473. UserGrids.push_back( userGrid );
  474. }
  475. }
  476. }
  477. bool CADSTAR_ARCHIVE_PARSER::SETTINGS::ParseSubNode( XNODE* aChildNode )
  478. {
  479. wxString cNodeName = aChildNode->GetName();
  480. if( cNodeName == wxT( "UNITS" ) )
  481. {
  482. Units = ParseUnits( aChildNode );
  483. }
  484. else if( cNodeName == wxT( "UNITSPRECISION" ) )
  485. {
  486. UnitDisplPrecision = GetXmlAttributeIDLong( aChildNode, 0 );
  487. }
  488. else if( cNodeName == wxT( "INTERLINEGAP" ) )
  489. {
  490. InterlineGap = GetXmlAttributeIDLong( aChildNode, 0 );
  491. }
  492. else if( cNodeName == wxT( "BARLINEGAP" ) )
  493. {
  494. BarlineGap = GetXmlAttributeIDLong( aChildNode, 0 );
  495. }
  496. else if( cNodeName == wxT( "ALLOWBARTEXT" ) )
  497. {
  498. AllowBarredText = true;
  499. }
  500. else if( cNodeName == wxT( "ANGULARPRECISION" ) )
  501. {
  502. AngularPrecision = GetXmlAttributeIDLong( aChildNode, 0 );
  503. }
  504. else if( cNodeName == wxT( "DESIGNORIGIN" ) )
  505. {
  506. DesignOrigin.Parse( aChildNode->GetChildren() );
  507. }
  508. else if( cNodeName == wxT( "DESIGNAREA" ) )
  509. {
  510. std::vector<POINT> pts = ParseAllChildPoints( aChildNode, true, 2 );
  511. DesignArea = std::make_pair( pts[0], pts[1] );
  512. }
  513. else if( cNodeName == wxT( "DESIGNREF" ) )
  514. {
  515. DesignOrigin.Parse( aChildNode->GetChildren() );
  516. }
  517. else if( cNodeName == wxT( "DESIGNLIMIT" ) )
  518. {
  519. DesignLimit.Parse( aChildNode->GetChildren() );
  520. }
  521. else
  522. {
  523. return false;
  524. }
  525. return true;
  526. }
  527. void CADSTAR_ARCHIVE_PARSER::SETTINGS::Parse( XNODE* aNode )
  528. {
  529. wxASSERT( aNode->GetName() == wxT( "SETTINGS" ) );
  530. XNODE* cNode = aNode->GetChildren();
  531. for( ; cNode; cNode = cNode->GetNext() )
  532. {
  533. wxString cNodeName = cNode->GetName();
  534. if( ParseSubNode( cNode ) )
  535. continue;
  536. else
  537. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "SETTINGS" ) );
  538. }
  539. }
  540. CADSTAR_ARCHIVE_PARSER::ALIGNMENT CADSTAR_ARCHIVE_PARSER::ParseAlignment( XNODE* aNode )
  541. {
  542. wxASSERT( aNode->GetName() == wxT( "ALIGN" ) );
  543. wxString alignmentStr = GetXmlAttributeIDString( aNode, 0 );
  544. if( alignmentStr == wxT( "BOTTOMCENTER" ) )
  545. return ALIGNMENT::BOTTOMCENTER;
  546. else if( alignmentStr == wxT( "BOTTOMLEFT" ) )
  547. return ALIGNMENT::BOTTOMLEFT;
  548. else if( alignmentStr == wxT( "BOTTOMRIGHT" ) )
  549. return ALIGNMENT::BOTTOMRIGHT;
  550. else if( alignmentStr == wxT( "CENTERCENTER" ) )
  551. return ALIGNMENT::CENTERCENTER;
  552. else if( alignmentStr == wxT( "CENTERLEFT" ) )
  553. return ALIGNMENT::CENTERLEFT;
  554. else if( alignmentStr == wxT( "CENTERRIGHT" ) )
  555. return ALIGNMENT::CENTERRIGHT;
  556. else if( alignmentStr == wxT( "TOPCENTER" ) )
  557. return ALIGNMENT::TOPCENTER;
  558. else if( alignmentStr == wxT( "TOPLEFT" ) )
  559. return ALIGNMENT::TOPLEFT;
  560. else if( alignmentStr == wxT( "TOPRIGHT" ) )
  561. return ALIGNMENT::TOPRIGHT;
  562. else
  563. THROW_UNKNOWN_PARAMETER_IO_ERROR( alignmentStr, wxT( "ALIGN" ) );
  564. //shouldn't be here but avoids compiler warning
  565. return ALIGNMENT::NO_ALIGNMENT;
  566. }
  567. CADSTAR_ARCHIVE_PARSER::JUSTIFICATION CADSTAR_ARCHIVE_PARSER::ParseJustification( XNODE* aNode )
  568. {
  569. wxASSERT( aNode->GetName() == wxT( "JUSTIFICATION" ) );
  570. wxString justificationStr = GetXmlAttributeIDString( aNode, 0 );
  571. if( justificationStr == wxT( "LEFT" ) )
  572. return JUSTIFICATION::LEFT;
  573. else if( justificationStr == wxT( "RIGHT" ) )
  574. return JUSTIFICATION::RIGHT;
  575. else if( justificationStr == wxT( "CENTER" ) )
  576. return JUSTIFICATION::CENTER;
  577. else
  578. THROW_UNKNOWN_PARAMETER_IO_ERROR( justificationStr, wxT( "JUSTIFICATION" ) );
  579. return JUSTIFICATION::LEFT;
  580. }
  581. CADSTAR_ARCHIVE_PARSER::READABILITY CADSTAR_ARCHIVE_PARSER::ParseReadability( XNODE* aNode )
  582. {
  583. wxASSERT( aNode->GetName() == wxT( "READABILITY" ) );
  584. wxString readabilityStr = GetXmlAttributeIDString( aNode, 0 );
  585. if( readabilityStr == wxT( "BOTTOM_TO_TOP" ) )
  586. return READABILITY::BOTTOM_TO_TOP;
  587. else if( readabilityStr == wxT( "TOP_TO_BOTTOM" ) )
  588. return READABILITY::TOP_TO_BOTTOM;
  589. else
  590. THROW_UNKNOWN_PARAMETER_IO_ERROR( readabilityStr, wxT( "READABILITY" ) );
  591. return READABILITY::BOTTOM_TO_TOP;
  592. }
  593. void CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION::ParseIdentifiers( XNODE* aNode )
  594. {
  595. TextCodeID = GetXmlAttributeIDString( aNode, 0 );
  596. LayerID = GetXmlAttributeIDString( aNode, 1 );
  597. }
  598. bool CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION::ParseSubNode( XNODE* aChildNode )
  599. {
  600. wxString cNodeName = aChildNode->GetName();
  601. if( cNodeName == wxT( "PT" ) )
  602. Position.Parse( aChildNode );
  603. else if( cNodeName == wxT( "ORIENT" ) )
  604. OrientAngle = GetXmlAttributeIDLong( aChildNode, 0 );
  605. else if( cNodeName == wxT( "MIRROR" ) )
  606. Mirror = true;
  607. else if( cNodeName == wxT( "FIX" ) )
  608. Fixed = true;
  609. else if( cNodeName == wxT( "ALIGN" ) )
  610. Alignment = ParseAlignment( aChildNode );
  611. else if( cNodeName == wxT( "JUSTIFICATION" ) )
  612. Justification = ParseJustification( aChildNode );
  613. else
  614. return false;
  615. return true;
  616. }
  617. void CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION::Parse( XNODE* aNode )
  618. {
  619. wxASSERT( aNode->GetName() == wxT( "ATTRLOC" ) );
  620. ParseIdentifiers( aNode );
  621. //Parse child nodes
  622. XNODE* cNode = aNode->GetChildren();
  623. for( ; cNode; cNode = cNode->GetNext() )
  624. {
  625. if( ParseSubNode( cNode ) )
  626. continue;
  627. else
  628. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "ATTRLOC" ) );
  629. }
  630. if( !Position.IsFullySpecified() )
  631. THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "ATTRLOC" ) );
  632. }
  633. void CADSTAR_ARCHIVE_PARSER::ATTRNAME::COLUMNORDER::Parse( XNODE* aNode )
  634. {
  635. wxASSERT( aNode->GetName() == wxT( "COLUMNORDER" ) );
  636. ID = GetXmlAttributeIDLong( aNode, 0 );
  637. Order = GetXmlAttributeIDLong( aNode, 1 );
  638. CheckNoChildNodes( aNode );
  639. }
  640. void CADSTAR_ARCHIVE_PARSER::ATTRNAME::COLUMNWIDTH::Parse( XNODE* aNode )
  641. {
  642. wxASSERT( aNode->GetName() == wxT( "COLUMNWIDTH" ) );
  643. ID = GetXmlAttributeIDLong( aNode, 0 );
  644. Width = GetXmlAttributeIDLong( aNode, 1 );
  645. CheckNoChildNodes( aNode );
  646. }
  647. void CADSTAR_ARCHIVE_PARSER::ATTRNAME::Parse( XNODE* aNode )
  648. {
  649. wxASSERT( aNode->GetName() == wxT( "ATTRNAME" ) );
  650. ID = GetXmlAttributeIDString( aNode, 0 );
  651. Name = GetXmlAttributeIDString( aNode, 1 );
  652. XNODE* cNode = aNode->GetChildren();
  653. wxString location = wxString::Format( "ATTRNAME -> %s", Name );
  654. for( ; cNode; cNode = cNode->GetNext() )
  655. {
  656. wxString cNodeName = cNode->GetName();
  657. if( cNodeName == wxT( "ATTROWNER" ) )
  658. {
  659. wxString attOwnerVal = GetXmlAttributeIDString( cNode, 0 );
  660. if( attOwnerVal == wxT( "ALL_ITEMS" ) )
  661. AttributeOwner = ATTROWNER::ALL_ITEMS;
  662. else if( attOwnerVal == wxT( "AREA" ) )
  663. AttributeOwner = ATTROWNER::AREA;
  664. else if( attOwnerVal == wxT( "BOARD" ) )
  665. AttributeOwner = ATTROWNER::BOARD;
  666. else if( attOwnerVal == wxT( "COMPONENT" ) )
  667. AttributeOwner = ATTROWNER::COMPONENT;
  668. else if( attOwnerVal == wxT( "CONNECTION" ) )
  669. AttributeOwner = ATTROWNER::CONNECTION;
  670. else if( attOwnerVal == wxT( "COPPER" ) )
  671. AttributeOwner = ATTROWNER::COPPER;
  672. else if( attOwnerVal == wxT( "DOCSYMBOL" ) )
  673. AttributeOwner = ATTROWNER::DOCSYMBOL;
  674. else if( attOwnerVal == wxT( "FIGURE" ) )
  675. AttributeOwner = ATTROWNER::FIGURE;
  676. else if( attOwnerVal == wxT( "NET" ) )
  677. AttributeOwner = ATTROWNER::NET;
  678. else if( attOwnerVal == wxT( "NETCLASS" ) )
  679. AttributeOwner = ATTROWNER::NETCLASS;
  680. else if( attOwnerVal == wxT( "PART" ) )
  681. AttributeOwner = ATTROWNER::PART;
  682. else if( attOwnerVal == wxT( "PART_DEFINITION" ) )
  683. AttributeOwner = ATTROWNER::PART_DEFINITION;
  684. else if( attOwnerVal == wxT( "PIN" ) )
  685. AttributeOwner = ATTROWNER::PIN;
  686. else if( attOwnerVal == wxT( "SYMBOL" ) )
  687. AttributeOwner = ATTROWNER::SYMBOL;
  688. else if( attOwnerVal == wxT( "SYMDEF" ) )
  689. AttributeOwner = ATTROWNER::SYMDEF;
  690. else if( attOwnerVal == wxT( "TEMPLATE" ) )
  691. AttributeOwner = ATTROWNER::TEMPLATE;
  692. else if( attOwnerVal == wxT( "TESTPOINT" ) )
  693. AttributeOwner = ATTROWNER::TESTPOINT;
  694. else
  695. THROW_UNKNOWN_PARAMETER_IO_ERROR( attOwnerVal, location );
  696. }
  697. else if( cNodeName == wxT( "ATTRUSAGE" ) )
  698. {
  699. wxString attUsageVal = GetXmlAttributeIDString( cNode, 0 );
  700. if( attUsageVal == wxT( "BOTH" ) )
  701. AttributeUsage = ATTRUSAGE::BOTH;
  702. else if( attUsageVal == wxT( "COMPONENT" ) )
  703. AttributeUsage = ATTRUSAGE::COMPONENT;
  704. else if( attUsageVal == wxT( "PART_DEFINITION" ) )
  705. AttributeUsage = ATTRUSAGE::PART_DEFINITION;
  706. else if( attUsageVal == wxT( "PART_LIBRARY" ) )
  707. AttributeUsage = ATTRUSAGE::PART_LIBRARY;
  708. else if( attUsageVal == wxT( "SYMBOL" ) )
  709. AttributeUsage = ATTRUSAGE::SYMBOL;
  710. else
  711. THROW_UNKNOWN_PARAMETER_IO_ERROR( attUsageVal, location );
  712. }
  713. else if( cNodeName == wxT( "NOTRANSFER" ) )
  714. {
  715. NoTransfer = true;
  716. }
  717. else if( cNodeName == wxT( "COLUMNORDER" ) )
  718. {
  719. COLUMNORDER cOrder;
  720. cOrder.Parse( cNode );
  721. ColumnOrders.push_back( cOrder );
  722. }
  723. else if( cNodeName == wxT( "COLUMNWIDTH" ) )
  724. {
  725. COLUMNWIDTH cWidth;
  726. cWidth.Parse( cNode );
  727. ColumnWidths.push_back( cWidth );
  728. }
  729. else if( cNodeName == wxT( "COLUMNINVISIBLE" ) )
  730. {
  731. ColumnInvisible = true;
  732. }
  733. else
  734. {
  735. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
  736. }
  737. }
  738. }
  739. void CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_VALUE::Parse( XNODE* aNode )
  740. {
  741. wxASSERT( aNode->GetName() == wxT( "ATTR" ) );
  742. AttributeID = GetXmlAttributeIDString( aNode, 0 );
  743. Value = GetXmlAttributeIDString( aNode, 1 );
  744. XNODE* cNode = aNode->GetChildren();
  745. for( ; cNode; cNode = cNode->GetNext() )
  746. {
  747. if( cNode->GetName() == wxT( "READONLY" ) )
  748. {
  749. ReadOnly = true;
  750. }
  751. else if( cNode->GetName() == wxT( "ATTRLOC" ) )
  752. {
  753. AttributeLocation.Parse( cNode );
  754. HasLocation = true;
  755. }
  756. else
  757. {
  758. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "ATTR" ) );
  759. }
  760. }
  761. }
  762. void CADSTAR_ARCHIVE_PARSER::TEXT_LOCATION::Parse( XNODE* aNode )
  763. {
  764. wxASSERT( aNode->GetName() == wxT( "TEXTLOC" ) );
  765. wxString attributeStr = GetXmlAttributeIDString( aNode, 0 );
  766. bool attributeIDisSet = false;
  767. if( attributeStr == wxT( "PART_NAME" ) )
  768. {
  769. AttributeID = PART_NAME_ATTRID;
  770. attributeIDisSet = true;
  771. }
  772. else if( attributeStr == wxT( "COMP_NAME" ) )
  773. {
  774. AttributeID = COMPONENT_NAME_ATTRID;
  775. attributeIDisSet = true;
  776. }
  777. else if( attributeStr == wxT( "COMP_NAME2" ) )
  778. {
  779. AttributeID = COMPONENT_NAME_2_ATTRID;
  780. attributeIDisSet = true;
  781. }
  782. else if( attributeStr == wxT( "SYMBOL_NAME" ) )
  783. {
  784. AttributeID = SYMBOL_NAME_ATTRID;
  785. attributeIDisSet = true;
  786. }
  787. else if( attributeStr == wxT( "LINK_ORIGIN" ) )
  788. {
  789. AttributeID = LINK_ORIGIN_ATTRID;
  790. attributeIDisSet = true;
  791. }
  792. else if( attributeStr == wxT( "SIGNALNAME_ORIGIN" ) )
  793. {
  794. AttributeID = SIGNALNAME_ORIGIN_ATTRID;
  795. attributeIDisSet = true;
  796. }
  797. else if( attributeStr == wxT( "ATTRREF" ) )
  798. {
  799. //We will initialise when we parse all child nodes
  800. attributeIDisSet = false;
  801. }
  802. else
  803. {
  804. THROW_UNKNOWN_PARAMETER_IO_ERROR( attributeStr, wxT( "TEXTLOC" ) );
  805. }
  806. TextCodeID = GetXmlAttributeIDString( aNode, 1 );
  807. LayerID = GetXmlAttributeIDString( aNode, 2, false );
  808. //Parse child nodes
  809. XNODE* cNode = aNode->GetChildren();
  810. for( ; cNode; cNode = cNode->GetNext() )
  811. {
  812. wxString cNodeName = cNode->GetName();
  813. if( ParseSubNode( cNode ) )
  814. {
  815. continue;
  816. }
  817. else if( !attributeIDisSet && cNodeName == wxT( "ATTRREF" ) )
  818. {
  819. AttributeID = GetXmlAttributeIDString( cNode, 0 );
  820. attributeIDisSet = true;
  821. }
  822. else if( cNodeName == wxT( "ORIENT" ) )
  823. {
  824. OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
  825. }
  826. else if( cNodeName == wxT( "MIRROR" ) )
  827. {
  828. Mirror = true;
  829. }
  830. else if( cNodeName == wxT( "FIX" ) )
  831. {
  832. Fixed = true;
  833. }
  834. else if( cNodeName == wxT( "ALIGN" ) )
  835. {
  836. Alignment = ParseAlignment( cNode );
  837. }
  838. else if( cNodeName == wxT( "JUSTIFICATION" ) )
  839. {
  840. Justification = ParseJustification( cNode );
  841. }
  842. else
  843. {
  844. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEXTLOC" ) );
  845. }
  846. }
  847. if( !Position.IsFullySpecified() )
  848. THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "TEXTLOC" ) );
  849. }
  850. void CADSTAR_ARCHIVE_PARSER::NETCLASS::Parse( XNODE* aNode )
  851. {
  852. wxASSERT( aNode->GetName() == wxT( "NETCLASS" ) );
  853. ID = GetXmlAttributeIDString( aNode, 0 );
  854. Name = GetXmlAttributeIDString( aNode, 1 );
  855. XNODE* cNode = aNode->GetChildren();
  856. wxString location = wxString::Format( "NETCLASS -> %s", Name );
  857. for( ; cNode; cNode = cNode->GetNext() )
  858. {
  859. wxString cNodeName = cNode->GetName();
  860. if( cNodeName == wxT( "ATTR" ) )
  861. {
  862. ATTRIBUTE_VALUE attribute_val;
  863. attribute_val.Parse( cNode );
  864. Attributes.push_back( attribute_val );
  865. }
  866. else
  867. {
  868. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
  869. }
  870. }
  871. }
  872. void CADSTAR_ARCHIVE_PARSER::SPCCLASSNAME::Parse( XNODE* aNode )
  873. {
  874. wxASSERT( aNode->GetName() == wxT( "SPCCLASSNAME" ) );
  875. ID = GetXmlAttributeIDString( aNode, 0 );
  876. Name = GetXmlAttributeIDString( aNode, 1 );
  877. }
  878. bool CADSTAR_ARCHIVE_PARSER::CODEDEFS::ParseSubNode( XNODE* aChildNode )
  879. {
  880. wxString nodeName = aChildNode->GetName();
  881. if( nodeName == wxT( "LINECODE" ) )
  882. {
  883. LINECODE linecode;
  884. linecode.Parse( aChildNode );
  885. LineCodes.insert( std::make_pair( linecode.ID, linecode ) );
  886. }
  887. else if( nodeName == wxT( "HATCHCODE" ) )
  888. {
  889. HATCHCODE hatchcode;
  890. hatchcode.Parse( aChildNode );
  891. HatchCodes.insert( std::make_pair( hatchcode.ID, hatchcode ) );
  892. }
  893. else if( nodeName == wxT( "TEXTCODE" ) )
  894. {
  895. TEXTCODE textcode;
  896. textcode.Parse( aChildNode );
  897. TextCodes.insert( std::make_pair( textcode.ID, textcode ) );
  898. }
  899. else if( nodeName == wxT( "ROUTECODE" ) )
  900. {
  901. ROUTECODE routecode;
  902. routecode.Parse( aChildNode );
  903. RouteCodes.insert( std::make_pair( routecode.ID, routecode ) );
  904. }
  905. else if( nodeName == wxT( "ATTRNAME" ) )
  906. {
  907. ATTRNAME attrname;
  908. attrname.Parse( aChildNode );
  909. AttributeNames.insert( std::make_pair( attrname.ID, attrname ) );
  910. }
  911. else if( nodeName == wxT( "NETCLASS" ) )
  912. {
  913. NETCLASS netclass;
  914. netclass.Parse( aChildNode );
  915. NetClasses.insert( std::make_pair( netclass.ID, netclass ) );
  916. }
  917. else if( nodeName == wxT( "SPCCLASSNAME" ) )
  918. {
  919. SPCCLASSNAME spcclassname;
  920. spcclassname.Parse( aChildNode );
  921. SpacingClassNames.insert( std::make_pair( spcclassname.ID, spcclassname ) );
  922. }
  923. else
  924. {
  925. return false;
  926. }
  927. return true;
  928. }
  929. CADSTAR_ARCHIVE_PARSER::SWAP_RULE CADSTAR_ARCHIVE_PARSER::ParseSwapRule( XNODE* aNode )
  930. {
  931. wxASSERT( aNode->GetName() == wxT( "SWAPRULE" ) );
  932. SWAP_RULE retval;
  933. wxString swapRuleStr = GetXmlAttributeIDString( aNode, 0 );
  934. if( swapRuleStr == wxT( "NO_SWAP" ) )
  935. retval = SWAP_RULE::NO_SWAP;
  936. else if( swapRuleStr == wxT( "USE_SWAP_LAYER" ) )
  937. retval = SWAP_RULE::USE_SWAP_LAYER;
  938. else
  939. THROW_UNKNOWN_PARAMETER_IO_ERROR( swapRuleStr, wxT( "SWAPRULE" ) );
  940. return retval;
  941. }
  942. void CADSTAR_ARCHIVE_PARSER::REUSEBLOCK::Parse( XNODE* aNode )
  943. {
  944. wxASSERT( aNode->GetName() == wxT( "REUSEBLOCK" ) );
  945. ID = GetXmlAttributeIDString( aNode, 0 );
  946. Name = GetXmlAttributeIDString( aNode, 1 );
  947. FileName = GetXmlAttributeIDString( aNode, 2 );
  948. XNODE* cNode = aNode->GetChildren();
  949. for( ; cNode; cNode = cNode->GetNext() )
  950. {
  951. wxString cNodeName = cNode->GetName();
  952. if( cNodeName == wxT( "MIRROR" ) )
  953. Mirror = true;
  954. else if( cNodeName == wxT( "ORIENT" ) )
  955. OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
  956. else
  957. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "REUSEBLOCK" ) );
  958. }
  959. }
  960. bool CADSTAR_ARCHIVE_PARSER::REUSEBLOCKREF::IsEmpty()
  961. {
  962. return ReuseBlockID == wxEmptyString && ItemReference == wxEmptyString;
  963. }
  964. void CADSTAR_ARCHIVE_PARSER::REUSEBLOCKREF::Parse( XNODE* aNode )
  965. {
  966. wxASSERT( aNode->GetName() == wxT( "REUSEBLOCKREF" ) );
  967. ReuseBlockID = GetXmlAttributeIDString( aNode, 0 );
  968. ItemReference = GetXmlAttributeIDString( aNode, 1 );
  969. CheckNoChildNodes( aNode );
  970. }
  971. void CADSTAR_ARCHIVE_PARSER::GROUP::Parse( XNODE* aNode )
  972. {
  973. wxASSERT( aNode->GetName() == wxT( "GROUP" ) );
  974. ID = GetXmlAttributeIDString( aNode, 0 );
  975. Name = GetXmlAttributeIDString( aNode, 1 );
  976. XNODE* cNode = aNode->GetChildren();
  977. for( ; cNode; cNode = cNode->GetNext() )
  978. {
  979. wxString cNodeName = cNode->GetName();
  980. if( cNodeName == wxT( "FIX" ) )
  981. Fixed = true;
  982. else if( cNodeName == wxT( "TRANSFER" ) )
  983. Transfer = true;
  984. else if( cNodeName == wxT( "GROUPREF" ) )
  985. GroupID = GetXmlAttributeIDString( cNode, 0 );
  986. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  987. ReuseBlockRef.Parse( cNode );
  988. else
  989. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "GROUP" ) );
  990. }
  991. }
  992. void CADSTAR_ARCHIVE_PARSER::FIGURE::Parse( XNODE* aNode )
  993. {
  994. wxASSERT( aNode->GetName() == wxT( "FIGURE" ) );
  995. ID = GetXmlAttributeIDString( aNode, 0 );
  996. LineCodeID = GetXmlAttributeIDString( aNode, 1 );
  997. LayerID = GetXmlAttributeIDString( aNode, 2 );
  998. XNODE* cNode = aNode->GetChildren();
  999. bool shapeIsInitialised = false; // Stop more than one Shape Object
  1000. wxString location = wxString::Format( "Figure %s", ID );
  1001. if( !cNode )
  1002. THROW_MISSING_NODE_IO_ERROR( wxT( "Shape" ), location );
  1003. for( ; cNode; cNode = cNode->GetNext() )
  1004. {
  1005. wxString cNodeName = cNode->GetName();
  1006. if( !shapeIsInitialised && Shape.IsShape( cNode ) )
  1007. {
  1008. Shape.Parse( cNode );
  1009. shapeIsInitialised = true;
  1010. }
  1011. else if( cNodeName == wxT( "SWAPRULE" ) )
  1012. {
  1013. SwapRule = ParseSwapRule( cNode );
  1014. }
  1015. else if( cNodeName == wxT( "FIX" ) )
  1016. {
  1017. Fixed = true;
  1018. }
  1019. else if( cNodeName == wxT( "GROUPREF" ) )
  1020. {
  1021. GroupID = GetXmlAttributeIDString( cNode, 0 );
  1022. }
  1023. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  1024. {
  1025. ReuseBlockRef.Parse( cNode );
  1026. }
  1027. else if( cNodeName == wxT( "ATTR" ) )
  1028. {
  1029. ATTRIBUTE_VALUE attr;
  1030. attr.Parse( cNode );
  1031. AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
  1032. }
  1033. else
  1034. {
  1035. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
  1036. }
  1037. }
  1038. }
  1039. void CADSTAR_ARCHIVE_PARSER::TEXT::Parse( XNODE* aNode )
  1040. {
  1041. wxASSERT( aNode->GetName() == wxT( "TEXT" ) );
  1042. ID = GetXmlAttributeIDString( aNode, 0 );
  1043. //TODO: Need to lex/parse "Text" to identify design fields (e.g "<@DESIGN_TITLE@>") and
  1044. // hyperlinks (e.g. "<@HYPERLINK\"[link]\"[link text]@>")
  1045. Text = GetXmlAttributeIDString( aNode, 1 );
  1046. TextCodeID = GetXmlAttributeIDString( aNode, 2 );
  1047. LayerID = GetXmlAttributeIDString( aNode, 3 );
  1048. XNODE* cNode = aNode->GetChildren();
  1049. if( !cNode )
  1050. THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), wxT( "TEXT" ) );
  1051. for( ; cNode; cNode = cNode->GetNext() )
  1052. {
  1053. wxString cNodeName = cNode->GetName();
  1054. if( cNodeName == wxT( "PT" ) )
  1055. Position.Parse( cNode );
  1056. else if( cNodeName == wxT( "ORIENT" ) )
  1057. OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
  1058. else if( cNodeName == wxT( "MIRROR" ) )
  1059. Mirror = true;
  1060. else if( cNodeName == wxT( "FIX" ) )
  1061. Fixed = true;
  1062. else if( cNodeName == wxT( "SWAPRULE" ) )
  1063. SwapRule = ParseSwapRule( cNode );
  1064. else if( cNodeName == wxT( "ALIGN" ) )
  1065. Alignment = ParseAlignment( cNode );
  1066. else if( cNodeName == wxT( "JUSTIFICATION" ) )
  1067. Justification = ParseJustification( cNode );
  1068. else if( cNodeName == wxT( "GROUPREF" ) )
  1069. GroupID = GetXmlAttributeIDString( cNode, 0 );
  1070. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  1071. ReuseBlockRef.Parse( cNode );
  1072. else
  1073. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "TEXT" ) );
  1074. }
  1075. }
  1076. void CADSTAR_ARCHIVE_PARSER::SYMDEF::ParseIdentifiers( XNODE* aNode )
  1077. {
  1078. wxASSERT( aNode->GetName() == wxT( "SYMDEF" ) );
  1079. ID = GetXmlAttributeIDString( aNode, 0 );
  1080. ReferenceName = GetXmlAttributeIDString( aNode, 1 );
  1081. Alternate = GetXmlAttributeIDString( aNode, 2 );
  1082. }
  1083. bool CADSTAR_ARCHIVE_PARSER::SYMDEF::ParseSubNode( XNODE* aChildNode )
  1084. {
  1085. wxString cNodeName = aChildNode->GetName();
  1086. if( cNodeName == wxT( "PT" ) )
  1087. {
  1088. Origin.Parse( aChildNode );
  1089. }
  1090. else if( cNodeName == wxT( "STUB" ) )
  1091. {
  1092. Stub = true;
  1093. }
  1094. else if( cNodeName == wxT( "VERSION" ) )
  1095. {
  1096. Version = GetXmlAttributeIDLong( aChildNode, 0 );
  1097. }
  1098. else if( cNodeName == wxT( "FIGURE" ) )
  1099. {
  1100. FIGURE figure;
  1101. figure.Parse( aChildNode );
  1102. Figures.insert( std::make_pair( figure.ID, figure ) );
  1103. }
  1104. else if( cNodeName == wxT( "TEXT" ) )
  1105. {
  1106. TEXT txt;
  1107. txt.Parse( aChildNode );
  1108. Texts.insert( std::make_pair( txt.ID, txt ) );
  1109. }
  1110. else if( cNodeName == wxT( "TEXTLOC" ) )
  1111. {
  1112. TEXT_LOCATION textloc;
  1113. textloc.Parse( aChildNode );
  1114. TextLocations.insert( std::make_pair( textloc.AttributeID, textloc ) );
  1115. }
  1116. else if( cNodeName == wxT( "ATTR" ) )
  1117. {
  1118. ATTRIBUTE_VALUE attrVal;
  1119. attrVal.Parse( aChildNode );
  1120. AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
  1121. }
  1122. else
  1123. {
  1124. return false;
  1125. }
  1126. return true;
  1127. }
  1128. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::GATE::Parse( XNODE* aNode )
  1129. {
  1130. wxASSERT( aNode->GetName() == wxT( "GATEDEFINITION" ) );
  1131. ID = GetXmlAttributeIDString( aNode, 0 );
  1132. Name = GetXmlAttributeIDString( aNode, 1 );
  1133. Alternate = GetXmlAttributeIDString( aNode, 2 );
  1134. PinCount = GetXmlAttributeIDLong( aNode, 3 );
  1135. CheckNoChildNodes( aNode );
  1136. }
  1137. CADSTAR_ARCHIVE_PARSER::PART::PIN_TYPE CADSTAR_ARCHIVE_PARSER::PART::GetPinType( XNODE* aNode )
  1138. {
  1139. wxASSERT( aNode->GetName() == wxT( "PINTYPE" ) );
  1140. wxString pinTypeStr = GetXmlAttributeIDString( aNode, 0 );
  1141. std::map<wxString, PIN_TYPE> pinTypeMap = { { wxT( "INPUT" ), PIN_TYPE::INPUT },
  1142. { wxT( "OUTPUT_OR" ), PIN_TYPE::OUTPUT_OR },
  1143. { wxT( "OUTPUT_NOT_OR" ), PIN_TYPE::OUTPUT_NOT_OR },
  1144. { wxT( "OUTPUT_NOT_NORM_OR" ), PIN_TYPE::OUTPUT_NOT_NORM_OR },
  1145. { wxT( "POWER" ), PIN_TYPE::POWER }, { wxT( "GROUND" ), PIN_TYPE::GROUND },
  1146. { wxT( "TRISTATE_BIDIR" ), PIN_TYPE::TRISTATE_BIDIR },
  1147. { wxT( "TRISTATE_INPUT" ), PIN_TYPE::TRISTATE_INPUT },
  1148. { wxT( "TRISTATE_DRIVER" ), PIN_TYPE::TRISTATE_DRIVER } };
  1149. if( pinTypeMap.find( pinTypeStr ) == pinTypeMap.end() )
  1150. THROW_UNKNOWN_PARAMETER_IO_ERROR( pinTypeStr, aNode->GetName() );
  1151. return pinTypeMap[pinTypeStr];
  1152. }
  1153. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::PIN::Parse( XNODE* aNode )
  1154. {
  1155. wxASSERT( aNode->GetName() == wxT( "PARTDEFINITIONPIN" ) );
  1156. ID = GetXmlAttributeIDLong( aNode, 0 );
  1157. XNODE* cNode = aNode->GetChildren();
  1158. for( ; cNode; cNode = cNode->GetNext() )
  1159. {
  1160. wxString cNodeName = cNode->GetName();
  1161. if( cNodeName == wxT( "PINNAME" ) )
  1162. {
  1163. Name = GetXmlAttributeIDString( cNode, 0 );
  1164. }
  1165. else if( cNodeName == wxT( "PINLABEL" ) )
  1166. {
  1167. Label = GetXmlAttributeIDString( cNode, 0 );
  1168. }
  1169. else if( cNodeName == wxT( "PINSIGNAL" ) )
  1170. {
  1171. Signal = GetXmlAttributeIDString( cNode, 0 );
  1172. }
  1173. else if( cNodeName == wxT( "PINTERM" ) )
  1174. {
  1175. TerminalGate = GetXmlAttributeIDString( cNode, 0 );
  1176. TerminalPin = GetXmlAttributeIDLong( cNode, 1 );
  1177. }
  1178. else if( cNodeName == wxT( "PINTYPE" ) )
  1179. {
  1180. Type = GetPinType( cNode );
  1181. }
  1182. else if( cNodeName == wxT( "PINLOAD" ) )
  1183. {
  1184. Load = GetXmlAttributeIDLong( cNode, 0 );
  1185. }
  1186. else if( cNodeName == wxT( "PINPOSITION" ) )
  1187. {
  1188. Position = (POSITION) GetXmlAttributeIDLong( cNode, 0 );
  1189. }
  1190. else if( cNodeName == wxT( "PINIDENTIFIER" ) )
  1191. {
  1192. Identifier = GetXmlAttributeIDString( cNode, 0 );
  1193. }
  1194. else
  1195. {
  1196. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1197. }
  1198. }
  1199. }
  1200. void CADSTAR_ARCHIVE_PARSER::PART::PART_PIN::Parse( XNODE* aNode )
  1201. {
  1202. wxASSERT( aNode->GetName() == wxT( "PARTPIN" ) );
  1203. ID = GetXmlAttributeIDLong( aNode, 0 );
  1204. XNODE* cNode = aNode->GetChildren();
  1205. for( ; cNode; cNode = cNode->GetNext() )
  1206. {
  1207. wxString cNodeName = cNode->GetName();
  1208. if( cNodeName == wxT( "PINNAME" ) )
  1209. Name = GetXmlAttributeIDString( cNode, 0 );
  1210. else if( cNodeName == wxT( "PINTYPE" ) )
  1211. Type = GetPinType( cNode );
  1212. else if( cNodeName == wxT( "PINIDENTIFIER" ) )
  1213. Identifier = GetXmlAttributeIDString( cNode, 0 );
  1214. else
  1215. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1216. }
  1217. }
  1218. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::PIN_EQUIVALENCE::Parse( XNODE* aNode )
  1219. {
  1220. wxASSERT( aNode->GetName() == wxT( "PINEQUIVALENCE" ) );
  1221. wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
  1222. for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
  1223. {
  1224. if( !IsValidAttribute( xmlAttribute ) )
  1225. continue;
  1226. long pinId;
  1227. if( !xmlAttribute->GetValue().ToLong( &pinId ) )
  1228. THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), aNode->GetName() );
  1229. PinIDs.push_back( (PART_DEFINITION_PIN_ID) pinId );
  1230. }
  1231. CheckNoChildNodes( aNode );
  1232. }
  1233. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::SWAP_GATE::Parse( XNODE* aNode )
  1234. {
  1235. wxASSERT( aNode->GetName() == wxT( "SWAPGATE" ) );
  1236. wxXmlAttribute* xmlAttribute = aNode->GetAttributes();
  1237. for( ; xmlAttribute; xmlAttribute = xmlAttribute->GetNext() )
  1238. {
  1239. if( !IsValidAttribute( xmlAttribute ) )
  1240. continue;
  1241. long pinId;
  1242. if( !xmlAttribute->GetValue().ToLong( &pinId ) )
  1243. THROW_UNKNOWN_PARAMETER_IO_ERROR( xmlAttribute->GetValue(), aNode->GetName() );
  1244. PinIDs.push_back( (PART_DEFINITION_PIN_ID) pinId );
  1245. }
  1246. CheckNoChildNodes( aNode );
  1247. }
  1248. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::SWAP_GROUP::Parse( XNODE* aNode )
  1249. {
  1250. wxASSERT( aNode->GetName() == wxT( "SWAPGROUP" ) );
  1251. GateName = GetXmlAttributeIDString( aNode, 0 );
  1252. XNODE* cNode = aNode->GetChildren();
  1253. for( ; cNode; cNode = cNode->GetNext() )
  1254. {
  1255. wxString cNodeName = cNode->GetName();
  1256. if( cNodeName == wxT( "EXTERNAL" ) )
  1257. {
  1258. External = true;
  1259. }
  1260. else if( cNodeName == wxT( "SWAPGATE" ) )
  1261. {
  1262. SWAP_GATE swapGate;
  1263. swapGate.Parse( cNode );
  1264. SwapGates.push_back( swapGate );
  1265. }
  1266. else
  1267. {
  1268. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1269. }
  1270. }
  1271. }
  1272. void CADSTAR_ARCHIVE_PARSER::PART::DEFINITION::Parse( XNODE* aNode )
  1273. {
  1274. wxASSERT( aNode->GetName() == wxT( "PARTDEFINITION" ) );
  1275. Name = GetXmlAttributeIDString( aNode, 0 );
  1276. XNODE* cNode = aNode->GetChildren();
  1277. for( ; cNode; cNode = cNode->GetNext() )
  1278. {
  1279. wxString cNodeName = cNode->GetName();
  1280. if( cNodeName == wxT( "HIDEPINNAMES" ) )
  1281. {
  1282. HidePinNames = true;
  1283. }
  1284. else if( cNodeName == wxT( "MAXPIN" ) )
  1285. {
  1286. MaxPinCount = GetXmlAttributeIDLong( cNode, 0 );
  1287. }
  1288. else if( cNodeName == wxT( "GATEDEFINITION" ) )
  1289. {
  1290. GATE gate;
  1291. gate.Parse( cNode );
  1292. GateSymbols.insert( std::make_pair( gate.ID, gate ) );
  1293. }
  1294. else if( cNodeName == wxT( "PARTDEFINITIONPIN" ) )
  1295. {
  1296. PIN pin;
  1297. pin.Parse( cNode );
  1298. Pins.insert( std::make_pair( pin.ID, pin ) );
  1299. }
  1300. else if( cNodeName == wxT( "ATTR" ) )
  1301. {
  1302. ATTRIBUTE_VALUE attr;
  1303. attr.Parse( cNode );
  1304. AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
  1305. }
  1306. else if( cNodeName == wxT( "PINEQUIVALENCE" ) )
  1307. {
  1308. PIN_EQUIVALENCE pinEq;
  1309. pinEq.Parse( cNode );
  1310. PinEquivalences.push_back( pinEq );
  1311. }
  1312. else if( cNodeName == wxT( "SWAPGROUP" ) )
  1313. {
  1314. SWAP_GROUP swapGroup;
  1315. swapGroup.Parse( cNode );
  1316. SwapGroups.push_back( swapGroup );
  1317. }
  1318. else
  1319. {
  1320. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1321. }
  1322. }
  1323. }
  1324. void CADSTAR_ARCHIVE_PARSER::PART::Parse( XNODE* aNode )
  1325. {
  1326. wxASSERT( aNode->GetName() == wxT( "PART" ) );
  1327. ID = GetXmlAttributeIDString( aNode, 0 );
  1328. Name = GetXmlAttributeIDString( aNode, 1 );
  1329. XNODE* cNode = aNode->GetChildren();
  1330. for( ; cNode; cNode = cNode->GetNext() )
  1331. {
  1332. wxString cNodeName = cNode->GetName();
  1333. if( cNodeName == wxT( "VERSION" ) )
  1334. {
  1335. Version = GetXmlAttributeIDLong( cNode, 0 );
  1336. }
  1337. else if( cNodeName == wxT( "HIDEPINNAMES" ) )
  1338. {
  1339. HidePinNames = true;
  1340. }
  1341. else if( cNodeName == wxT( "PARTDEFINITION" ) )
  1342. {
  1343. Definition.Parse( cNode );
  1344. }
  1345. else if( cNodeName == wxT( "PARTPIN" ) )
  1346. {
  1347. PART_PIN pin;
  1348. pin.Parse( cNode );
  1349. PartPins.insert( std::make_pair( pin.ID, pin ) );
  1350. }
  1351. else if( cNodeName == wxT( "ATTR" ) )
  1352. {
  1353. ATTRIBUTE_VALUE attr;
  1354. attr.Parse( cNode );
  1355. AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
  1356. }
  1357. else
  1358. {
  1359. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1360. }
  1361. }
  1362. }
  1363. void CADSTAR_ARCHIVE_PARSER::PARTS::Parse( XNODE* aNode )
  1364. {
  1365. wxASSERT( aNode->GetName() == wxT( "PARTS" ) );
  1366. XNODE* cNode = aNode->GetChildren();
  1367. for( ; cNode; cNode = cNode->GetNext() )
  1368. {
  1369. wxString cNodeName = cNode->GetName();
  1370. if( cNodeName == wxT( "PART" ) )
  1371. {
  1372. PART part;
  1373. part.Parse( cNode );
  1374. PartDefinitions.insert( std::make_pair( part.ID, part ) );
  1375. }
  1376. else
  1377. {
  1378. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1379. }
  1380. }
  1381. }
  1382. void CADSTAR_ARCHIVE_PARSER::NET::JUNCTION::Parse( XNODE* aNode )
  1383. {
  1384. wxASSERT( aNode->GetName() == wxT( "JPT" ) );
  1385. ID = GetXmlAttributeIDString( aNode, 0 );
  1386. LayerID = GetXmlAttributeIDString( aNode, 1 );
  1387. XNODE* cNode = aNode->GetChildren();
  1388. for( ; cNode; cNode = cNode->GetNext() )
  1389. {
  1390. wxString cNodeName = cNode->GetName();
  1391. if( cNodeName == wxT( "PT" ) )
  1392. Location.Parse( cNode );
  1393. else if( cNodeName == wxT( "FIX" ) )
  1394. Fixed = true;
  1395. else if( cNodeName == wxT( "GROUPREF" ) )
  1396. GroupID = GetXmlAttributeIDString( cNode, 0 );
  1397. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  1398. ReuseBlockRef.Parse( cNode );
  1399. else
  1400. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1401. }
  1402. }
  1403. void CADSTAR_ARCHIVE_PARSER::NET::CONNECTION::ParseIdentifiers( XNODE* aNode )
  1404. {
  1405. wxASSERT( aNode->GetName() == wxT( "CONN" ) );
  1406. StartNode = GetXmlAttributeIDString( aNode, 0 );
  1407. EndNode = GetXmlAttributeIDString( aNode, 1 );
  1408. RouteCodeID = GetXmlAttributeIDString( aNode, 2 );
  1409. }
  1410. bool CADSTAR_ARCHIVE_PARSER::NET::CONNECTION::ParseSubNode( XNODE* aChildNode )
  1411. {
  1412. wxString cNodeName = aChildNode->GetName();
  1413. if( cNodeName == wxT( "FIX" ) )
  1414. {
  1415. Fixed = true;
  1416. }
  1417. else if( cNodeName == wxT( "HIDDEN" ) )
  1418. {
  1419. Hidden = true;
  1420. }
  1421. else if( cNodeName == wxT( "GROUPREF" ) )
  1422. {
  1423. GroupID = GetXmlAttributeIDString( aChildNode, 0 );
  1424. }
  1425. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  1426. {
  1427. ReuseBlockRef.Parse( aChildNode );
  1428. }
  1429. else if( cNodeName == wxT( "ATTR" ) )
  1430. {
  1431. ATTRIBUTE_VALUE attrVal;
  1432. attrVal.Parse( aChildNode );
  1433. AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
  1434. }
  1435. else
  1436. {
  1437. return false;
  1438. }
  1439. return true;
  1440. }
  1441. void CADSTAR_ARCHIVE_PARSER::NET::ParseIdentifiers( XNODE* aNode )
  1442. {
  1443. wxASSERT( aNode->GetName() == wxT( "NET" ) );
  1444. ID = GetXmlAttributeIDString( aNode, 0 );
  1445. }
  1446. bool CADSTAR_ARCHIVE_PARSER::NET::ParseSubNode( XNODE* aChildNode )
  1447. {
  1448. wxString cNodeName = aChildNode->GetName();
  1449. if( cNodeName == wxT( "NETCODE" ) )
  1450. {
  1451. RouteCodeID = GetXmlAttributeIDString( aChildNode, 0 );
  1452. }
  1453. else if( cNodeName == wxT( "SIGNAME" ) )
  1454. {
  1455. Name = GetXmlAttributeIDString( aChildNode, 0 );
  1456. }
  1457. else if( cNodeName == wxT( "SIGNUM" ) )
  1458. {
  1459. SignalNum = GetXmlAttributeIDLong( aChildNode, 0 );
  1460. }
  1461. else if( cNodeName == wxT( "HIGHLIT" ) )
  1462. {
  1463. Highlight = true;
  1464. }
  1465. else if( cNodeName == wxT( "JPT" ) )
  1466. {
  1467. JUNCTION jpt;
  1468. jpt.Parse( aChildNode );
  1469. Junctions.insert( std::make_pair( jpt.ID, jpt ) );
  1470. }
  1471. else if( cNodeName == wxT( "NETCLASSREF" ) )
  1472. {
  1473. NetClassID = GetXmlAttributeIDString( aChildNode, 0 );
  1474. }
  1475. else if( cNodeName == wxT( "SPACINGCLASS" ) )
  1476. {
  1477. SpacingClassID = GetXmlAttributeIDString( aChildNode, 0 );
  1478. }
  1479. else if( cNodeName == wxT( "ATTR" ) )
  1480. {
  1481. ATTRIBUTE_VALUE attrVal;
  1482. attrVal.Parse( aChildNode );
  1483. AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
  1484. }
  1485. else
  1486. {
  1487. return false;
  1488. }
  1489. return true;
  1490. }
  1491. void CADSTAR_ARCHIVE_PARSER::DOCUMENTATION_SYMBOL::Parse( XNODE* aNode )
  1492. {
  1493. wxASSERT( aNode->GetName() == wxT( "DOCSYMBOL" ) );
  1494. ID = GetXmlAttributeIDString( aNode, 0 );
  1495. SymdefID = GetXmlAttributeIDString( aNode, 1 );
  1496. LayerID = GetXmlAttributeIDString( aNode, 2 );
  1497. XNODE* cNode = aNode->GetChildren();
  1498. bool originParsed = false;
  1499. for( ; cNode; cNode = cNode->GetNext() )
  1500. {
  1501. wxString cNodeName = cNode->GetName();
  1502. if( !originParsed && cNodeName == wxT( "PT" ) )
  1503. {
  1504. Origin.Parse( cNode );
  1505. originParsed = true;
  1506. }
  1507. else if( cNodeName == wxT( "GROUPREF" ) )
  1508. {
  1509. GroupID = GetXmlAttributeIDString( cNode, 0 );
  1510. }
  1511. else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
  1512. {
  1513. ReuseBlockRef.Parse( cNode );
  1514. }
  1515. else if( cNodeName == wxT( "FIX" ) )
  1516. {
  1517. Fixed = true;
  1518. }
  1519. else if( cNodeName == wxT( "MIRROR" ) )
  1520. {
  1521. Mirror = true;
  1522. }
  1523. else if( cNodeName == wxT( "READABILITY" ) )
  1524. {
  1525. Readability = ParseReadability( cNode );
  1526. }
  1527. else if( cNodeName == wxT( "ORIENT" ) )
  1528. {
  1529. OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
  1530. }
  1531. else if( cNodeName == wxT( "ATTR" ) )
  1532. {
  1533. ATTRIBUTE_VALUE attr;
  1534. attr.Parse( cNode );
  1535. AttributeValues.insert( std::make_pair( attr.AttributeID, attr ) );
  1536. }
  1537. else if( cNodeName == wxT( "SCALE" ) )
  1538. {
  1539. ScaleRatioNumerator = GetXmlAttributeIDLong( cNode, 0 );
  1540. ScaleRatioDenominator = GetXmlAttributeIDLong( cNode, 1 );
  1541. }
  1542. else
  1543. {
  1544. THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
  1545. }
  1546. }
  1547. if( !originParsed )
  1548. THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
  1549. }
  1550. void CADSTAR_ARCHIVE_PARSER::InsertAttributeAtEnd( XNODE* aNode, wxString aValue )
  1551. {
  1552. wxString result;
  1553. int numAttributes = 0;
  1554. if( aNode->GetAttribute( wxT( "numAttributes" ), &result ) )
  1555. {
  1556. numAttributes = wxAtoi( result );
  1557. aNode->DeleteAttribute( wxT( "numAttributes" ) );
  1558. ++numAttributes;
  1559. }
  1560. aNode->AddAttribute( wxT( "numAttributes" ), wxString::Format( wxT( "%i" ), numAttributes ) );
  1561. wxString paramName = wxT( "attr" );
  1562. paramName << numAttributes;
  1563. aNode->AddAttribute( paramName, aValue );
  1564. }
  1565. XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile(
  1566. const wxString& aFileName, const wxString& aFileTypeIdentifier )
  1567. {
  1568. KEYWORD emptyKeywords[1] = {};
  1569. XNODE * iNode = NULL, *cNode = NULL;
  1570. int tok;
  1571. bool cadstarFileCheckDone = false;
  1572. wxString str;
  1573. wxCSConv win1252( wxT( "windows-1252" ) );
  1574. wxMBConv* conv = &win1252; // Initial testing suggests file encoding to be Windows-1252
  1575. // More samples required.
  1576. FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
  1577. if( !fp )
  1578. THROW_IO_ERROR( wxString::Format( _( "Cannot open file '%s'" ), aFileName ) );
  1579. DSNLEXER lexer( emptyKeywords, 0, fp, aFileName );
  1580. while( ( tok = lexer.NextTok() ) != DSN_EOF )
  1581. {
  1582. if( tok == DSN_RIGHT )
  1583. {
  1584. cNode = iNode;
  1585. if( cNode )
  1586. {
  1587. iNode = cNode->GetParent();
  1588. }
  1589. else
  1590. {
  1591. //too many closing brackets
  1592. THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
  1593. }
  1594. }
  1595. else if( tok == DSN_LEFT )
  1596. {
  1597. tok = lexer.NextTok();
  1598. str = wxString( lexer.CurText(), *conv );
  1599. cNode = new XNODE( wxXML_ELEMENT_NODE, str );
  1600. if( iNode )
  1601. {
  1602. //we will add it as attribute as well as child node
  1603. InsertAttributeAtEnd( iNode, str );
  1604. iNode->AddChild( cNode );
  1605. }
  1606. else if( !cadstarFileCheckDone )
  1607. {
  1608. if( cNode->GetName() != aFileTypeIdentifier )
  1609. THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
  1610. cadstarFileCheckDone = true;
  1611. }
  1612. iNode = cNode;
  1613. }
  1614. else if( iNode )
  1615. {
  1616. str = wxString( lexer.CurText(), *conv );
  1617. //Insert even if string is empty
  1618. InsertAttributeAtEnd( iNode, str );
  1619. }
  1620. else
  1621. {
  1622. //not enough closing brackets
  1623. THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
  1624. }
  1625. }
  1626. // Not enough closing brackets
  1627. if( iNode != NULL )
  1628. THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
  1629. // Throw if no data was parsed
  1630. if( cNode )
  1631. return cNode;
  1632. else
  1633. THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
  1634. return NULL;
  1635. }
  1636. bool CADSTAR_ARCHIVE_PARSER::IsValidAttribute( wxXmlAttribute* aAttribute )
  1637. {
  1638. return aAttribute->GetName() != wxT( "numAttributes" );
  1639. }
  1640. wxString CADSTAR_ARCHIVE_PARSER::GetXmlAttributeIDString(
  1641. XNODE* aNode, unsigned int aID, bool aIsRequired )
  1642. {
  1643. wxString attrName, retVal;
  1644. attrName = "attr";
  1645. attrName << aID;
  1646. if( !aNode->GetAttribute( attrName, &retVal ) )
  1647. {
  1648. if( aIsRequired )
  1649. THROW_MISSING_PARAMETER_IO_ERROR( std::to_string( aID ), aNode->GetName() );
  1650. else
  1651. return wxEmptyString;
  1652. }
  1653. return retVal;
  1654. }
  1655. long CADSTAR_ARCHIVE_PARSER::GetXmlAttributeIDLong(
  1656. XNODE* aNode, unsigned int aID, bool aIsRequired )
  1657. {
  1658. long retVal;
  1659. bool success = GetXmlAttributeIDString( aNode, aID, aIsRequired ).ToLong( &retVal );
  1660. if( !success )
  1661. {
  1662. if( aIsRequired )
  1663. THROW_PARSING_IO_ERROR( std::to_string( aID ), aNode->GetName() );
  1664. else
  1665. return UNDEFINED_VALUE;
  1666. }
  1667. return retVal;
  1668. }
  1669. void CADSTAR_ARCHIVE_PARSER::CheckNoChildNodes( XNODE* aNode )
  1670. {
  1671. if( aNode && aNode->GetChildren() )
  1672. THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
  1673. }
  1674. void CADSTAR_ARCHIVE_PARSER::CheckNoNextNodes( XNODE* aNode )
  1675. {
  1676. if( aNode && aNode->GetNext() )
  1677. THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetNext()->GetName(), aNode->GetParent()->GetName() );
  1678. }
  1679. void CADSTAR_ARCHIVE_PARSER::ParseChildEValue( XNODE* aNode, EVALUE& aValueToParse )
  1680. {
  1681. if( aNode->GetChildren()->GetName() == wxT( "E" ) )
  1682. aValueToParse.Parse( aNode->GetChildren() );
  1683. else
  1684. THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
  1685. }
  1686. std::vector<CADSTAR_ARCHIVE_PARSER::POINT> CADSTAR_ARCHIVE_PARSER::ParseAllChildPoints(
  1687. XNODE* aNode, bool aTestAllChildNodes, int aExpectedNumPoints )
  1688. {
  1689. std::vector<POINT> retVal;
  1690. XNODE* cNode = aNode->GetChildren();
  1691. for( ; cNode; cNode = cNode->GetNext() )
  1692. {
  1693. if( cNode->GetName() == wxT( "PT" ) )
  1694. {
  1695. POINT pt;
  1696. //TODO try.. catch + throw again with more detailed error information
  1697. pt.Parse( cNode );
  1698. retVal.push_back( pt );
  1699. }
  1700. else if( aTestAllChildNodes )
  1701. {
  1702. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
  1703. }
  1704. }
  1705. if( aExpectedNumPoints != UNDEFINED_VALUE
  1706. && retVal.size() != static_cast<size_t>( aExpectedNumPoints ) )
  1707. {
  1708. THROW_IO_ERROR( wxString::Format(
  1709. _( "Unexpected number of points in '%s'. Found %d but expected %d." ),
  1710. aNode->GetName(), retVal.size(), aExpectedNumPoints ) );
  1711. }
  1712. return retVal;
  1713. }
  1714. std::vector<CADSTAR_ARCHIVE_PARSER::VERTEX> CADSTAR_ARCHIVE_PARSER::ParseAllChildVertices(
  1715. XNODE* aNode, bool aTestAllChildNodes )
  1716. {
  1717. std::vector<VERTEX> retVal;
  1718. XNODE* cNode = aNode->GetChildren();
  1719. for( ; cNode; cNode = cNode->GetNext() )
  1720. {
  1721. if( VERTEX::IsVertex( cNode ) )
  1722. {
  1723. VERTEX vertex;
  1724. //TODO try.. catch + throw again with more detailed error information
  1725. vertex.Parse( cNode );
  1726. retVal.push_back( vertex );
  1727. }
  1728. else if( aTestAllChildNodes )
  1729. {
  1730. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
  1731. }
  1732. }
  1733. return retVal;
  1734. }
  1735. std::vector<CADSTAR_ARCHIVE_PARSER::CUTOUT> CADSTAR_ARCHIVE_PARSER::ParseAllChildCutouts(
  1736. XNODE* aNode, bool aTestAllChildNodes )
  1737. {
  1738. std::vector<CUTOUT> retVal;
  1739. XNODE* cNode = aNode->GetChildren();
  1740. for( ; cNode; cNode = cNode->GetNext() )
  1741. {
  1742. if( cNode->GetName() == wxT( "CUTOUT" ) )
  1743. {
  1744. CUTOUT cutout;
  1745. //TODO try.. catch + throw again with more detailed error information
  1746. cutout.Parse( cNode );
  1747. retVal.push_back( cutout );
  1748. }
  1749. else if( aTestAllChildNodes )
  1750. {
  1751. THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
  1752. }
  1753. }
  1754. return retVal;
  1755. }