41#include <wx/xml/xml.h>
126constexpr uint32_t BITFIELD( uint32_t aWidth, uint32_t aFirst, uint32_t aLast )
128 return ( aWidth << 16 ) | ( aFirst << 8 ) | aLast;
143 const char* treeName;
156 unsigned cmd, cmdMask;
169 0, 0, SS_DIRECT, nullptr \
173 nullptr, T_INT, 0, 0 \
177const SCRIPT_ROW g_script[] = {
182 { { 4, 4, SS_RECURSIVE_MINUS_1,
nullptr },
TERM_S },
183 { {
"subsecs", T_INT, 2, 2 },
184 {
"numsecs", T_INT, 4, 4 },
185 {
"subsecsMSB", T_INT, 3, 1 },
186 {
"subsecsLSB", T_INT, 2, 1 },
187 {
"numsecsMSB2", T_INT, 7, 1 },
188 {
"numsecsMSB1", T_INT, 6, 1 },
189 {
"numsecsMSB0", T_INT, 5, 1 },
190 {
"numsecsLSB", T_INT, 4, 1 },
191 {
"v1", T_INT, 8, 1 },
192 {
"v2", T_INT, 9, 1 },
200 { {
"display", T_BMB, 2, 0x01 },
201 {
"visible", T_BMB, 2, 0x02 },
202 {
"unit", T_UBF, 3, BITFIELD( 1, 0, 3 ) },
203 {
"altunit", T_UBF, 3, BITFIELD( 1, 4, 7 ) },
204 {
"multiple", T_INT, 4, 3 },
205 {
"size", T_DBL, 8, 8 },
206 {
"altsize", T_DBL, 16, 8 },
213 { {
"side", T_BMB, 2, 0x10 },
214 {
"visible", T_UBF, 2, BITFIELD( 1, 2, 3 ) },
215 {
"active", T_BMB, 2, 0x02 },
216 {
"number", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
217 {
"other", T_INT, 4, 1 },
218 {
"fill", T_UBF, 5, BITFIELD( 1, 0, 3 ) },
219 {
"color", T_UBF, 6, BITFIELD( 1, 0, 5 ) },
220 {
"name", T_STR, 15, 9 },
226 { { 4, 4, SS_DIRECT,
nullptr },
TERM_S },
227 { {
"shtsubsecs", T_INT, 8, 4 }, {
"atrsubsecs", T_INT, 12, 4 }, {
"xref_format", T_STR, 19, 5 },
TERM_A } },
232 { { 4, 4, SS_RECURSIVE,
nullptr }, { 8, 4, SS_RECURSIVE,
nullptr }, { 12, 4, SS_RECURSIVE,
nullptr },
TERM_S },
233 { {
"devsubsecs", T_INT, 4, 4 },
234 {
"symsubsecs", T_INT, 8, 4 },
235 {
"pacsubsecs", T_INT, 12, 4 },
236 {
"children", T_INT, 8, 4 },
237 {
"name", T_STR, 16, 8 },
243 { { 4, 4, SS_DIRECT,
nullptr },
TERM_S },
244 { {
"children", T_INT, 8, 4 }, {
"library", T_STR, 16, 8 },
TERM_A } },
249 { { 4, 4, SS_RECURSIVE,
nullptr },
TERM_S },
250 { {
"children", T_INT, 8, 4 }, {
"library", T_STR, 16, 8 },
TERM_A } },
255 { { 4, 4, SS_RECURSIVE,
nullptr },
TERM_S },
256 { {
"subsects", T_INT, 4, 4 },
257 {
"children", T_INT, 8, 2 },
258 {
"desc", T_STR, 10, 6 },
259 {
"library", T_STR, 16, 8 },
265 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
266 { {
"minx", T_INT, 4, 2 },
267 {
"miny", T_INT, 6, 2 },
268 {
"maxx", T_INT, 8, 2 },
269 {
"maxy", T_INT, 10, 2 },
270 {
"partsubsecs", T_INT, 12, 4 },
271 {
"bussubsecs", T_INT, 16, 4 },
272 {
"netsubsecs", T_INT, 20, 4 },
278 { { 12, 4, SS_RECURSIVE,
"libraries" },
279 { 2, 2, SS_DIRECT,
"plain" },
280 { 16, 4, SS_RECURSIVE,
"elements" },
281 { 20, 4, SS_RECURSIVE,
"signals" },
283 { {
"minx", T_INT, 4, 2 },
284 {
"miny", T_INT, 6, 2 },
285 {
"maxx", T_INT, 8, 2 },
286 {
"maxy", T_INT, 10, 2 },
287 {
"defsubsecs", T_INT, 12, 4 },
288 {
"pacsubsecs", T_INT, 16, 4 },
289 {
"netsubsecs", T_INT, 20, 4 },
295 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
296 { {
"minx", T_INT, 4, 2 },
297 {
"miny", T_INT, 6, 2 },
298 {
"maxx", T_INT, 8, 2 },
299 {
"maxy", T_INT, 10, 2 },
300 {
"airwires", T_BMB, 12, 0x02 },
301 {
"netclass", T_UBF, 13, BITFIELD( 1, 0, 3 ) },
302 {
"name", T_STR, 16, 8 },
308 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
309 { {
"minx", T_INT, 4, 2 },
310 {
"miny", T_INT, 6, 2 },
311 {
"maxx", T_INT, 8, 2 },
312 {
"maxy", T_INT, 10, 2 },
313 {
"name", T_STR, 16, 8 },
319 { { 2, 2, SS_RECURSIVE,
nullptr },
TERM_S },
320 { {
"minx", T_INT, 4, 2 },
321 {
"miny", T_INT, 6, 2 },
322 {
"maxx", T_INT, 8, 2 },
323 {
"maxy", T_INT, 10, 2 },
324 {
"desc", T_STR, 13, 5 },
325 {
"name", T_STR, 18, 6 },
331 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
332 { {
"minx", T_INT, 4, 2 },
333 {
"miny", T_INT, 6, 2 },
334 {
"maxx", T_INT, 8, 2 },
335 {
"maxy", T_INT, 10, 2 },
336 {
"netclass", T_UBF, 13, BITFIELD( 1, 0, 3 ) },
337 {
"name", T_STR, 18, 6 },
343 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
344 { {
"minx", T_INT, 4, 2 }, {
"miny", T_INT, 6, 2 }, {
"maxx", T_INT, 8, 2 }, {
"maxy", T_INT, 10, 2 },
TERM_A } },
349 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
350 { {
"minx", T_INT, 4, 2 },
351 {
"miny", T_INT, 6, 2 },
352 {
"maxx", T_INT, 8, 2 },
353 {
"maxy", T_INT, 10, 2 },
354 {
"width", T_INT, 12, 2 },
355 {
"spacing", T_INT, 14, 2 },
356 {
"isolate", T_INT, 16, 2 },
357 {
"layer", T_UBF, 18, BITFIELD( 1, 0, 7 ) },
358 {
"pour", T_BMB, 19, 0x01 },
359 {
"rank", T_BMB, 19, BITFIELD( 1, 1, 3 ) },
360 {
"thermals", T_BMB, 19, 0x80 },
361 {
"orphans", T_BMB, 19, 0x40 },
368 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
369 {
"half_width", T_INT, 20, 2 },
370 {
"stflags", T_BMB, 22, 0x33 },
371 {
"clockwise", T_BMB, 22, 0x20 },
372 {
"linetype", T_UBF, 23, BITFIELD( 1, 0, 7 ) },
373 {
"linetype_0_x1", T_INT, 4, 4 },
374 {
"linetype_0_y1", T_INT, 8, 4 },
375 {
"linetype_0_x2", T_INT, 12, 4 },
376 {
"linetype_0_y2", T_INT, 16, 4 },
377 {
"arc_negflags", T_UBF, 19, BITFIELD( 1, 0, 4 ) },
378 {
"arc_c1", T_INT, 7, 1 },
379 {
"arc_c2", T_INT, 11, 1 },
380 {
"arc_c3", T_INT, 15, 1 },
381 {
"arc_x1", T_INT, 4, 3 },
382 {
"arc_y1", T_INT, 8, 3 },
383 {
"arc_x2", T_INT, 12, 3 },
384 {
"arc_y2", T_INT, 16, 3 },
391 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
392 {
"half_width", T_INT, 20, 2 },
393 {
"clockwise", T_BMB, 22, 0x20 },
394 {
"arctype", T_UBF, 23, BITFIELD( 1, 0, 7 ) },
395 {
"arc_negflags", T_UBF, 19, BITFIELD( 1, 0, 7 ) },
396 {
"arc_c1", T_INT, 7, 1 },
397 {
"arc_c2", T_INT, 11, 1 },
398 {
"arc_c3", T_INT, 15, 1 },
399 {
"arc_x1", T_INT, 4, 3 },
400 {
"arc_y1", T_INT, 8, 3 },
401 {
"arc_x2", T_INT, 12, 3 },
402 {
"arc_y2", T_INT, 16, 3 },
403 {
"arctype_other_x1", T_INT, 4, 4 },
404 {
"arctype_other_y1", T_INT, 8, 4 },
405 {
"arctype_other_x2", T_INT, 12, 4 },
406 {
"arctype_other_y2", T_INT, 16, 4 },
413 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
414 {
"x", T_INT, 4, 4 },
415 {
"y", T_INT, 8, 4 },
416 {
"radius", T_INT, 12, 4 },
417 {
"half_width", T_INT, 20, 4 },
424 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
425 {
"x1", T_INT, 4, 4 },
426 {
"y1", T_INT, 8, 4 },
427 {
"x2", T_INT, 12, 4 },
428 {
"y2", T_INT, 16, 4 },
429 {
"bin_rot", T_INT, 20, 2 },
436 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
437 {
"x", T_INT, 4, 4 },
438 {
"y", T_INT, 8, 4 },
439 {
"width_2", T_INT, 12, 2 },
446 { {
"x", T_INT, 4, 4 },
447 {
"y", T_INT, 8, 4 },
448 {
"half_diameter", T_UBF, 12, BITFIELD( 2, 0, 15 ) },
449 {
"half_drill", T_UBF, 12, BITFIELD( 2, 0, 15 ) },
456 { {
"shape", T_INT, 2, 1 },
457 {
"x", T_INT, 4, 4 },
458 {
"y", T_INT, 8, 4 },
459 {
"half_drill", T_UBF, 12, BITFIELD( 2, 0, 15 ) },
460 {
"half_diameter", T_UBF, 14, BITFIELD( 2, 0, 15 ) },
461 {
"layers", T_UBF, 16, BITFIELD( 1, 0, 7 ) },
462 {
"stop", T_BMB, 17, 0x01 },
469 { {
"shape", T_INT, 2, 1 },
470 {
"x", T_INT, 4, 4 },
471 {
"y", T_INT, 8, 4 },
472 {
"half_drill", T_UBF, 12, BITFIELD( 2, 0, 15 ) },
473 {
"half_diameter", T_UBF, 14, BITFIELD( 2, 0, 15 ) },
474 {
"bin_rot", T_INT, 16, 2 },
475 {
"stop", T_BMB, 18, 0x01 },
476 {
"thermals", T_BMB, 18, 0x04 },
477 {
"first", T_BMB, 18, 0x08 },
478 {
"name", T_STR, 19, 5 },
485 { {
"roundness", T_INT, 2, 1 },
486 {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
487 {
"x", T_INT, 4, 4 },
488 {
"y", T_INT, 8, 4 },
489 {
"half_dx", T_UBF, 12, BITFIELD( 2, 0, 15 ) },
490 {
"half_dy", T_UBF, 14, BITFIELD( 2, 0, 15 ) },
491 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
492 {
"stop", T_BMB, 18, 0x01 },
493 {
"cream", T_BMB, 18, 0x02 },
494 {
"thermals", T_BMB, 18, 0x04 },
495 {
"first", T_BMB, 18, 0x08 },
496 {
"name", T_STR, 19, 5 },
503 { {
"function", T_UBF, 2, BITFIELD( 1, 0, 1 ) },
504 {
"visible", T_UBF, 2, BITFIELD( 1, 6, 7 ) },
505 {
"x", T_INT, 4, 4 },
506 {
"y", T_INT, 8, 4 },
507 {
"direction", T_UBF, 12, BITFIELD( 1, 0, 3 ) },
508 {
"length", T_UBF, 12, BITFIELD( 1, 4, 5 ) },
509 {
"bin_rot", T_UBF, 12, BITFIELD( 1, 6, 7 ) },
510 {
"swaplevel", T_INT, 13, 1 },
511 {
"name", T_STR, 14, 10 },
518 { {
"x", T_INT, 4, 4 },
519 {
"y", T_INT, 8, 4 },
520 {
"addlevel", T_INT, 12, 1 },
521 {
"swap", T_INT, 13, 1 },
522 {
"symno", T_INT, 14, 2 },
523 {
"name", T_STR, 16, 8 },
533 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
534 { {
"x", T_INT, 4, 4 },
535 {
"y", T_INT, 8, 4 },
536 {
"library", T_INT, 12, 2 },
537 {
"package", T_INT, 14, 2 },
538 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
539 {
"mirrored", T_BMB, 17, 0x10 },
540 {
"spin", T_BMB, 17, 0x40 },
547 { {
"name", T_STR, 2, 8 }, {
"value", T_STR, 10, 14 },
TERM_A } },
552 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
553 { {
"x", T_INT, 4, 4 },
554 {
"y", T_INT, 8, 4 },
555 {
"placed", T_INT, 12, 2 },
556 {
"gateno", T_INT, 14, 2 },
557 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 10, 11 ) },
558 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
559 {
"smashed", T_BMB, 18, 0x01 },
566 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
567 {
"x", T_INT, 4, 4 },
568 {
"y", T_INT, 8, 4 },
569 {
"half_size", T_INT, 12, 2 },
570 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
571 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
572 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
573 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
574 {
"textfield", T_STR, 18, 5 },
581 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
582 {
"x", T_INT, 4, 4 },
583 {
"y", T_INT, 8, 4 },
584 {
"size", T_INT, 12, 2 },
585 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
586 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
587 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
588 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
589 {
"textfield", T_STR, 18, 5 },
596 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
597 {
"x", T_INT, 4, 4 },
598 {
"y", T_INT, 8, 4 },
599 {
"size", T_INT, 12, 2 },
600 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
601 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
602 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
603 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
604 {
"textfield", T_STR, 18, 5 },
611 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
612 {
"x", T_INT, 4, 4 },
613 {
"y", T_INT, 8, 4 },
614 {
"size", T_INT, 12, 2 },
615 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
616 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
617 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
618 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
619 {
"textfield", T_STR, 18, 5 },
625 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
626 { {
"package", T_INT, 4, 2 }, {
"table", T_STR, 6, 13 }, {
"name", T_STR, 19, 5 },
TERM_A } },
631 { { 2, 2, SS_RECURSIVE,
"gates" }, { 4, 2, SS_RECURSIVE,
"variants" },
TERM_S },
632 { {
"gates", T_INT, 2, 2 },
633 {
"variants", T_INT, 4, 2 },
634 {
"prefix", T_STR, 8, 5 },
635 {
"desc", T_STR, 13, 5 },
636 {
"name", T_STR, 18, 5 },
642 { { 2, 2, SS_DIRECT,
nullptr },
TERM_S },
643 { {
"lib", T_INT, 4, 2 },
644 {
"device", T_INT, 6, 2 },
645 {
"variant", T_INT, 8, 1 },
646 {
"technology", T_INT, 9, 2 },
647 {
"name", T_STR, 11, 5 },
648 {
"value", T_STR, 16, 8 },
658 { {
"partnumber", T_INT, 4, 2 }, {
"pin", T_INT, 6, 2 },
TERM_A } },
664 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
665 {
"x", T_INT, 4, 4 },
666 {
"y", T_INT, 8, 4 },
667 {
"size", T_INT, 12, 2 },
668 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
669 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
670 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
671 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
672 {
"textfield", T_STR, 18, 5 },
679 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
680 {
"x", T_INT, 4, 4 },
681 {
"y", T_INT, 8, 4 },
682 {
"size", T_INT, 12, 2 },
683 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
684 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
685 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
686 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
687 {
"textfield", T_STR, 18, 5 },
694 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
695 {
"x", T_INT, 4, 4 },
696 {
"y", T_INT, 8, 4 },
697 {
"size", T_INT, 12, 2 },
698 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
699 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
700 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
701 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
702 {
"textfield", T_STR, 18, 5 },
709 { {
"symbol", T_STR, 2, 5 }, {
"attribute", T_STR, 7, 17 },
TERM_A } },
715 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
716 {
"x1", T_INT, 4, 4 },
717 {
"y1", T_INT, 8, 4 },
718 {
"x2", T_INT, 12, 4 },
719 {
"y2", T_INT, 16, 4 },
720 {
"cols", T_INT, 20, 1 },
721 {
"rows", T_INT, 21, 1 },
722 {
"borders", T_INT, 22, 1 },
729 { {
"layer", T_UBF, 3, BITFIELD( 1, 0, 7 ) },
730 {
"x", T_INT, 4, 4 },
731 {
"y", T_INT, 8, 4 },
732 {
"size", T_INT, 12, 2 },
733 {
"ratio", T_UBF, 14, BITFIELD( 2, 2, 6 ) },
734 {
"bin_rot", T_UBF, 16, BITFIELD( 2, 0, 11 ) },
735 {
"mirrored", T_UBF, 16, BITFIELD( 2, 12, 12 ) },
736 {
"spin", T_UBF, 16, BITFIELD( 2, 14, 14 ) },
737 {
"textfield", T_STR, 18, 5 },
750 auto child = std::make_unique<EGB_NODE>();
753 child->parent =
this;
754 children.push_back( std::move( child ) );
762 auto it =
props.find( aKey );
763 return it ==
props.end() ? wxString() : it->second;
770 Prop( aKey ).ToLong( &val );
778 wxLongLong_t val = 0;
779 Prop( aKey ).ToLongLong( &val );
781 return wxString::Format( wxS(
"%lld" ), val * 2 );
789 if( child->id == aId )
801 if( child->name == aName )
815 uint8_t buf[2] = { 0, 0 };
817 if( !aStream.IsOk() )
820 aStream.Read( buf, 2 );
822 if( aStream.LastRead() != 2 )
825 if( buf[0] == 0x10 && ( buf[1] == 0x00 || buf[1] == 0x80 ) )
834 if(
m_buf ==
nullptr || aOffs >
m_buf->size() || aLen >
m_buf->size() - aOffs )
835 THROW_IO_ERROR(
_(
"Short read in Eagle binary file (field out of bounds)." ) );
845 for(
unsigned n = 0; n < aLen; n++ )
848 l |= ( *m_buf )[aOffs + aLen - n - 1];
861 if( ( *
m_buf )[aOffs + aLen - 1] & 0x80 )
864 for(
unsigned n = 0; n < aLen; n++ )
867 l |= ( *m_buf )[aOffs + aLen - n - 1];
870 return static_cast<int32_t
>( l );
878 return ( ( *
m_buf )[aOffs] & aMask ) != 0;
884 unsigned first = ( aField >> 8 ) & 0xff;
885 unsigned last = aField & 0xff;
886 uint32_t mask = ( 1u << ( last - first + 1 ) ) - 1;
890 uint32_t val =
loadU32( aOffs, ( aField >> 16 ) & 0xff ) >> first;
900 const char* start =
reinterpret_cast<const char*
>(
m_buf->data() + aOffs );
906 while( n < aLen && start[n] !=
'\0' )
909 return wxString::FromUTF8( start, n );
915 static_assert(
sizeof( double ) == 8,
"Eagle binary doubles are 8-byte IEEE-754" );
924 for(
unsigned n = 0; n <
sizeof( double ); n++ )
925 bits |=
static_cast<uint64_t
>( ( *
m_buf )[aOffs + n] ) << ( 8 * n );
928 memcpy( &d, &bits,
sizeof( d ) );
937 THROW_IO_ERROR(
_(
"Short read in Eagle binary file (truncated block)." ) );
939 size_t blockStart =
m_pos;
945 if( aNumBlocks < 0 && ( *
m_buf )[blockStart] == 0x10 )
946 aNumBlocks =
loadS32( blockStart + 4, 4 );
948 const SCRIPT_ROW* sc =
nullptr;
950 for(
const SCRIPT_ROW* row = g_script; row->cmd != 0; row++ )
952 unsigned cmdh = ( row->cmd >> 8 ) & 0xFF;
953 unsigned cmdl = row->cmd & 0xFF;
954 unsigned mskh = ( row->cmdMask >> 8 ) & 0xFF;
955 unsigned mskl = row->cmdMask & 0xFF;
957 if( ( cmdh != ( ( *
m_buf )[blockStart] & mskh ) ) || ( cmdl != ( ( *
m_buf )[blockStart + 1] & mskl ) ) )
964 for(
const FMATCH* fm = row->fmatch; fm->offs != 0; fm++ )
966 if(
loadS32( blockStart + fm->offs, fm->len ) != fm->val )
982 THROW_IO_ERROR( wxString::Format(
_(
"Unknown Eagle binary block id 0x%02x%02x at offset %zu." ),
983 (
unsigned) ( *
m_buf )[blockStart], (
unsigned) ( *
m_buf )[blockStart + 1],
988 aParent->
AddChild(
static_cast<int>( sc->cmd ),
989 sc->name ? wxString::FromUTF8( sc->name ) : wxString( wxS(
"UNKNOWN" ) ) );
991 for(
const ATTR* at = sc->attrs; at->name !=
nullptr; at++ )
999 case T_BMB: val =
loadBmb( blockStart + at->offs, at->len ) ? wxS(
"yes" ) : wxS(
"no" );
break;
1000 case T_UBF: val = wxString::Format( wxS(
"%u" ),
loadUbf( blockStart + at->offs, at->len ) );
break;
1001 case T_INT: val = wxString::Format( wxS(
"%d" ),
loadS32( blockStart + at->offs, at->len ) );
break;
1002 case T_DBL: val = wxString::FromCDouble(
loadDouble( blockStart + at->offs ) );
break;
1003 case T_STR: val =
loadStr( blockStart + at->offs, at->len );
break;
1006 node->
props[wxString::FromUTF8( at->name )] = val;
1011 for(
const SUBSECT* ss = sc->subs; ss->offs != 0; ss++ )
1013 uint32_t numch =
loadU32( blockStart + ss->offs, ss->len );
1016 if( ss->treeName !=
nullptr )
1017 lpar = node->
AddChild( 0, wxString::FromUTF8( ss->treeName ) );
1019 if( ss->ssType == SS_DIRECT )
1021 for( uint32_t n = 0; n < numch && aNumBlocks > 0; n++ )
1029 if( ss->ssType == SS_RECURSIVE_MINUS_1 && numch > 0 )
1034 for( uint32_t n = 0; n < numch && rem > 0; n++ )
1066 size_t total =
static_cast<size_t>( textLen ) + 4;
1075 while( cur <
end && ( *
m_buf )[cur] !=
'\0' )
1079 while( cur <
end && ( *
m_buf )[cur] !=
'\0' )
1082 m_freeText.push_back( wxString::FromUTF8(
reinterpret_cast<const char*
>(
m_buf->data() + s ), cur - s ) );
1095 wxLogTrace(
traceEagleIo, wxS(
"Eagle bin: free-text reference out of strings" ) );
1127 uint8_t c = ( *m_buf )[
m_pos++];
1144 const size_t kDrcLen = 244;
1151 auto mil = [&](
size_t aOffs ) ->
long
1153 return static_cast<long>(
loadS32( b + aOffs, 4 ) / 2.54 / 100 );
1169 auto it = aNode->
props.find( aField );
1171 if( it == aNode->
props.end() || it->second.IsEmpty() )
1175 if(
static_cast<unsigned char>( it->second[0] ) == 0x7F )
1182 auto fixThreeByte = [](
long num,
bool neg ) ->
long
1184 if( num < 0 && neg )
1186 else if( num > 0 && neg )
1187 return num - 0x800000;
1188 else if( num < 0 && !neg )
1189 return num + 0x800000;
1194 auto fixOneByte = [](
long num ) ->
long
1196 return num < 0 ? num + 0x80 : num;
1199 auto setLong = [&](
const wxString& aKey,
long aVal )
1201 aElem->
props[aKey] = wxString::Format( wxS(
"%ld" ), aVal );
1207 auto interpolate = []( int64_t aNumerator, int64_t aSpan, int64_t aDivisor, int64_t aOffset ) ->
long
1209 return static_cast<long>( aNumerator * aSpan / aDivisor + aOffset );
1212 if( aLineType == 129 || aArcType == 0 )
1214 long arcFlags = aElem->
PropLong( wxS(
"arc_negflags" ) );
1215 long x1 = fixThreeByte( aElem->
PropLong( wxS(
"arc_x1" ) ), arcFlags & 0x02 );
1216 long y1 = fixThreeByte( aElem->
PropLong( wxS(
"arc_y1" ) ), arcFlags & 0x04 );
1217 long x2 = fixThreeByte( aElem->
PropLong( wxS(
"arc_x2" ) ), arcFlags & 0x08 );
1218 long y2 = fixThreeByte( aElem->
PropLong( wxS(
"arc_y2" ) ), arcFlags & 0x10 );
1220 long c = fixOneByte( aElem->
PropLong( wxS(
"arc_c1" ) ) )
1221 + 256 * fixOneByte( aElem->
PropLong( wxS(
"arc_c2" ) ) )
1222 + 256L * 256 * fixOneByte( aElem->
PropLong( wxS(
"arc_c3" ) ) );
1223 c = fixThreeByte( c, arcFlags & 0x01 );
1225 setLong( wxS(
"x1" ), x1 );
1226 setLong( wxS(
"y1" ), y1 );
1227 setLong( wxS(
"x2" ), x2 );
1228 setLong( wxS(
"y2" ), y2 );
1230 long x3 = ( x1 + x2 ) / 2;
1231 long y3 = ( y1 + y2 ) / 2;
1232 long cx = 0, cy = 0;
1234 if( x1 == x2 && y1 == y2 )
1244 cy = interpolate( x3 - cx, x2 - x1, y2 - y1, y3 );
1249 cx = interpolate( y3 - cy, y2 - y1, x2 - x1, x3 );
1252 long radius =
static_cast<long>( std::hypot( cx - x2, cy - y2 ) );
1253 setLong( wxS(
"radius" ),
radius );
1254 setLong( wxS(
"x" ), cx );
1255 setLong( wxS(
"y" ), cy );
1257 if( cx == x2 && cy == y1 && x2 < x1 && y2 > y1 )
1259 aElem->
props[wxS(
"StartAngle" )] = wxS(
"90" );
1260 aElem->
props[wxS(
"Delta" )] = wxS(
"90" );
1262 else if( cx == x1 && cy == y2 && x2 < x1 && y1 > y2 )
1264 aElem->
props[wxS(
"StartAngle" )] = wxS(
"0" );
1265 aElem->
props[wxS(
"Delta" )] = wxS(
"90" );
1267 else if( cx == x2 && cy == y1 && x2 > x1 && y1 > y2 )
1269 aElem->
props[wxS(
"StartAngle" )] = wxS(
"270" );
1270 aElem->
props[wxS(
"Delta" )] = wxS(
"90" );
1272 else if( cx == x1 && cy == y2 && x2 > x1 && y2 > y1 )
1274 aElem->
props[wxS(
"StartAngle" )] = wxS(
"180" );
1275 aElem->
props[wxS(
"Delta" )] = wxS(
"90" );
1279 double theta1 = 180.0 - 180.0 /
M_PI * atan2( cy - y1, x1 - cx );
1280 double theta2 = 180.0 - 180.0 /
M_PI * atan2( cy - y2, x2 - cx );
1281 double deltaTheta = theta2 - theta1;
1283 while( theta1 > 360 )
1286 while( deltaTheta < -180 )
1289 while( deltaTheta > 180 )
1292 setLong( wxS(
"StartAngle" ),
static_cast<long>( theta1 ) );
1293 setLong( wxS(
"Delta" ),
static_cast<long>( deltaTheta ) );
1296 else if( ( aLineType > 0 && aLineType < 129 ) || aArcType > 0 )
1298 long x1 = 0, y1 = 0, x2 = 0, y2 = 0, cx = 0, cy = 0;
1300 if( aElem->
HasProp( wxS(
"arctype_other_x1" ) ) )
1302 x1 = aElem->
PropLong( wxS(
"arctype_other_x1" ) );
1303 y1 = aElem->
PropLong( wxS(
"arctype_other_y1" ) );
1304 x2 = aElem->
PropLong( wxS(
"arctype_other_x2" ) );
1305 y2 = aElem->
PropLong( wxS(
"arctype_other_y2" ) );
1309 x1 = aElem->
PropLong( wxS(
"linetype_0_x1" ) );
1310 y1 = aElem->
PropLong( wxS(
"linetype_0_y1" ) );
1311 x2 = aElem->
PropLong( wxS(
"linetype_0_x2" ) );
1312 y2 = aElem->
PropLong( wxS(
"linetype_0_y2" ) );
1316 auto setAngles = [&](
const char* aStart,
const char* aDelta )
1318 aElem->
props[wxS(
"StartAngle" )] = wxString::FromUTF8( aStart );
1319 aElem->
props[wxS(
"Delta" )] = wxString::FromUTF8( aDelta );
1322 if( aLineType == 0x78 || aArcType == 0x01 )
1324 cx = std::min( x1, x2 );
1325 cy = std::min( y1, y2 );
1326 setAngles(
"180",
"90" );
1328 else if( aLineType == 0x79 || aArcType == 0x02 )
1330 cx = std::max( x1, x2 );
1331 cy = std::min( y1, y2 );
1332 setAngles(
"270",
"90" );
1334 else if( aLineType == 0x7a || aArcType == 0x03 )
1336 cx = std::max( x1, x2 );
1337 cy = std::max( y1, y2 );
1338 setAngles(
"0",
"90" );
1340 else if( aLineType == 0x7b || aArcType == 0x04 )
1342 cx = std::min( x1, x2 );
1343 cy = std::max( y1, y2 );
1344 setAngles(
"90",
"90" );
1346 else if( aLineType == 0x7c || aArcType == 0x05 )
1348 cx = ( x1 + x2 ) / 2;
1349 cy = ( y1 + y2 ) / 2;
1350 setAngles(
"90",
"180" );
1352 else if( aLineType == 0x7d || aArcType == 0x06 )
1354 cx = ( x1 + x2 ) / 2;
1355 cy = ( y1 + y2 ) / 2;
1356 setAngles(
"270",
"180" );
1358 else if( aLineType == 0x7e || aArcType == 0x07 )
1360 cx = ( x1 + x2 ) / 2;
1361 cy = ( y1 + y2 ) / 2;
1362 setAngles(
"180",
"180" );
1364 else if( aLineType == 0x7f || aArcType == 0x08 )
1366 cx = ( x1 + x2 ) / 2;
1367 cy = ( y1 + y2 ) / 2;
1368 setAngles(
"0",
"180" );
1378 long radius =
static_cast<long>( std::hypot( cx - x2, cy - y2 ) );
1379 setLong( wxS(
"radius" ),
radius );
1380 setLong( wxS(
"x" ), cx );
1381 setLong( wxS(
"y" ), cy );
1390 int lineType = aRoot->
HasProp( wxS(
"linetype" ) ) ? (int) aRoot->
PropLong( wxS(
"linetype" ) ) : -1;
1396 aRoot->
props[wxS(
"x1" )] = aRoot->
Prop( wxS(
"linetype_0_x1" ) );
1397 aRoot->
props[wxS(
"y1" )] = aRoot->
Prop( wxS(
"linetype_0_y1" ) );
1398 aRoot->
props[wxS(
"x2" )] = aRoot->
Prop( wxS(
"linetype_0_x2" ) );
1399 aRoot->
props[wxS(
"y2" )] = aRoot->
Prop( wxS(
"linetype_0_y2" ) );
1409 if( aRoot->
HasProp( wxS(
"Delta" ) ) )
1410 aRoot->
props[wxS(
"curve" )] = aRoot->
Prop( wxS(
"Delta" ) );
1414 for(
const auto& child : aRoot->
children )
1423 int arcType = aRoot->
HasProp( wxS(
"arctype" ) ) ? (int) aRoot->
PropLong( wxS(
"arctype" ) ) : -1;
1427 aRoot->
props[wxS(
"x1" )] = aRoot->
Prop( wxS(
"arc_x1" ) );
1428 aRoot->
props[wxS(
"y1" )] = aRoot->
Prop( wxS(
"arc_y1" ) );
1429 aRoot->
props[wxS(
"x2" )] = aRoot->
Prop( wxS(
"arc_x2" ) );
1430 aRoot->
props[wxS(
"y2" )] = aRoot->
Prop( wxS(
"arc_y2" ) );
1432 else if( arcType > 0 )
1434 aRoot->
props[wxS(
"x1" )] = aRoot->
Prop( wxS(
"arctype_other_x1" ) );
1435 aRoot->
props[wxS(
"y1" )] = aRoot->
Prop( wxS(
"arctype_other_y1" ) );
1436 aRoot->
props[wxS(
"x2" )] = aRoot->
Prop( wxS(
"arctype_other_x2" ) );
1437 aRoot->
props[wxS(
"y2" )] = aRoot->
Prop( wxS(
"arctype_other_y2" ) );
1445 if( aRoot->
HasProp( wxS(
"Delta" ) ) )
1446 aRoot->
props[wxS(
"curve" )] = aRoot->
Prop( wxS(
"Delta" ) );
1449 for(
const auto& child : aRoot->
children )
1461 aRoot->
props[wxS(
"extent" )] = wxS(
"1-16" );
1464 for(
const auto& child : aRoot->
children )
1475 static const wxString dimAttrs[] = { wxS(
"x" ), wxS(
"y" ), wxS(
"x1" ), wxS(
"y1" ),
1476 wxS(
"x2" ), wxS(
"y2" ), wxS(
"x3" ), wxS(
"y3" ),
1477 wxS(
"width" ), wxS(
"drill" ), wxS(
"diameter" ), wxS(
"radius" ),
1478 wxS(
"size" ), wxS(
"dx" ), wxS(
"dy" ), wxS(
"spacing" ),
1481 for(
const wxString& key : dimAttrs )
1483 auto it = aRoot->
props.find( key );
1485 if( it == aRoot->
props.end() )
1490 if( it->second.ToCDouble( &du ) )
1491 it->second = wxString::FromCDouble( du * 0.0001, 4 );
1494 for(
const auto& child : aRoot->
children )
1506 for(
const auto& child : aRoot->
children )
1515 if( aRoot->
HasProp( wxS(
"half_dx" ) ) )
1520 if( aRoot->
HasProp( wxS(
"half_dy" ) ) )
1526 for(
const auto& child : aRoot->
children )
1536 if( aRoot->
HasProp( wxS(
"half_drill" ) ) )
1541 if( aRoot->
HasProp( wxS(
"half_diameter" ) ) )
1543 aRoot->
props[wxS(
"diameter" )] = aRoot->
PropDoubled( wxS(
"half_diameter" ) );
1546 if( aRoot->
HasProp( wxS(
"half_size" ) ) )
1552 for(
const auto& child : aRoot->
children )
1575 default:
return false;
1587 auto flagSet = [&](
const wxString& aKey )
1592 const wxString v = aRoot->
Prop( aKey );
1593 return v != wxS(
"no" ) && v != wxS(
"0" );
1596 bool mirrored = flagSet( wxS(
"mirrored" ) );
1597 bool spin = flagSet( wxS(
"spin" ) );
1599 long deg = aRoot->
PropLong( wxS(
"bin_rot" ) );
1611 rot << wxString::Format( wxS(
"%ld" ), ( 360 * deg ) / 4096 );
1613 rot << wxString::Format( wxS(
"%ld" ), ( deg & 0x00f0 ) * 90 );
1617 aRoot->
props[wxS(
"rot" )] = rot;
1620 for(
const auto& child : aRoot->
children )
1688 for(
const auto& child : aRoot->
children )
1697 std::vector<std::unique_ptr<EGB_NODE>> kept;
1699 for(
auto& child : aDrawing->
children )
1705 if( child->HasProp( wxS(
"visible" ) ) )
1707 child->props[wxS(
"visible" )] = child->PropLong( wxS(
"visible" ) ) != 0 ? wxS(
"yes" ) : wxS(
"no" );
1710 child->parent = aLayers;
1711 aLayers->
children.push_back( std::move( child ) );
1715 kept.push_back( std::move( child ) );
1719 aDrawing->
children = std::move( kept );
1725 auto addParam = [&](
const wxString& aName,
const wxString& aValue )
1728 p->
props[wxS(
"name" )] = aName;
1729 p->
props[wxS(
"value" )] = aValue;
1732 addParam( wxS(
"mdWireWire" ), wxString::Format( wxS(
"%ldmil" ), aDrc.
mdWireWire ) );
1733 addParam( wxS(
"msWidth" ), wxString::Format( wxS(
"%ldmil" ), aDrc.
msWidth ) );
1734 addParam( wxS(
"rvPadTop" ), wxString::FromCDouble( aDrc.
rvPadTop ) );
1735 addParam( wxS(
"rvPadInner" ), wxString::FromCDouble( aDrc.
rvPadInner ) );
1736 addParam( wxS(
"rvPadBottom" ), wxString::FromCDouble( aDrc.
rvPadBottom ) );
1745 if( aLibraries ==
nullptr )
1751 std::vector<std::unique_ptr<EGB_NODE>> wrapped;
1753 for(
auto& child : aLibraries->
children )
1758 auto lib = std::make_unique<EGB_NODE>();
1760 lib->name = wxS(
"library" );
1761 lib->parent = aLibraries;
1762 child->
parent = lib.get();
1763 lib->
children.push_back( std::move( child ) );
1764 wrapped.push_back( std::move( lib ) );
1767 if( !wrapped.empty() )
1768 aLibraries->
children = std::move( wrapped );
1774 if( aElements ==
nullptr )
1779 for(
auto& el : aElements->
children )
1784 for(
auto& el2 : el->children )
1789 for(
const auto& [key, value] : el2->props )
1791 if( key == wxS(
"name" ) )
1793 if( value == wxS(
"-" ) )
1794 el->props[wxS(
"name" )] = wxS(
"HYPHEN" );
1796 el->props[wxS(
"name" )] = value;
1798 else if( key == wxS(
"value" ) )
1800 el->props[wxS(
"value" )] = value;
1810 if( aLibraries ==
nullptr )
1818 for(
size_t li = 0; li < aLibraries->
children.size(); li++ )
1829 wxString libName = pkgs ? pkgs->
Prop( wxS(
"library" ) ) : wxString();
1831 if( libName.IsEmpty() )
1832 libName = wxString::Format( wxS(
"lib%zu" ), li + 1 );
1834 lib->
props[wxS(
"name" )] = libName;
1836 if( pkgs ==
nullptr )
1839 std::map<wxString, int> seen;
1841 for(
size_t pi = 0; pi < pkgs->
children.size(); pi++ )
1844 wxString
name = pkg->
Prop( wxS(
"name" ) );
1846 if(
name.IsEmpty() )
1847 name = wxString::Format( wxS(
"pkg%zu" ), pi + 1 );
1851 if(
int& count = seen[
name]; count++ > 0 )
1852 name = wxString::Format( wxS(
"%s_%d" ),
name, count );
1858 if( aElements ==
nullptr )
1861 auto nameByIdx = [&](
EGB_NODE* aParent,
long aIdx ) -> wxString
1863 if( aParent ==
nullptr || aIdx < 1 || aIdx > (
long) aParent->
children.size() )
1866 return aParent->
children[aIdx - 1]->Prop( wxS(
"name" ) );
1869 for(
auto& el : aElements->
children )
1874 long libIdx = el->PropLong( wxS(
"library" ) );
1875 EGB_NODE* lib = ( libIdx >= 1 && libIdx <= (long) aLibraries->
children.size() )
1876 ? aLibraries->
children[libIdx - 1].get()
1879 if( lib ==
nullptr )
1882 el->props[wxS(
"library" )] = lib->
Prop( wxS(
"name" ) );
1885 wxString pkgName = nameByIdx( pkgs, el->
PropLong( wxS(
"package" ) ) );
1887 if( !pkgName.IsEmpty() )
1888 el->props[wxS(
"package" )] = pkgName;
1895 if( aSignals ==
nullptr )
1903 for(
size_t i = 0; i < aSignals->
children.size(); i++ )
1910 std::vector<std::unique_ptr<EGB_NODE>> kept;
1911 std::vector<std::unique_ptr<EGB_NODE>> promoted;
1917 inner->parent = aSignals;
1918 promoted.push_back( std::move( inner ) );
1922 kept.push_back( std::move( inner ) );
1930 for(
auto& p : promoted )
1931 aSignals->
children.push_back( std::move( p ) );
1938 if( aSignals ==
nullptr || aElements ==
nullptr || aLibraries ==
nullptr )
1941 auto elemByIdx = [&](
long aIdx ) ->
EGB_NODE*
1943 if( aIdx < 1 || aIdx > (
long) aElements->
children.size() )
1946 return aElements->
children[aIdx - 1].get();
1949 auto libByIdx = [&](
long aIdx ) ->
EGB_NODE*
1951 if( aIdx < 1 || aIdx > (
long) aLibraries->
children.size() )
1954 return aLibraries->
children[aIdx - 1].get();
1959 if( aLib ==
nullptr )
1964 if( pkgs ==
nullptr || aIdx < 1 || aIdx > (
long) pkgs->
children.size() )
1967 return pkgs->
children[aIdx - 1].get();
1970 for(
auto& sig : aSignals->
children )
1974 for(
auto& cr : sig->children )
1979 long partNum = cr->PropLong( wxS(
"partnumber" ) );
1980 EGB_NODE* elem = elemByIdx( partNum );
1982 if( elem ==
nullptr )
1985 cr->props[wxS(
"element" )] = elem->
Prop( wxS(
"name" ) );
1991 if( pkg ==
nullptr )
1993 cr->props[wxS(
"pad" )] = wxS(
"PIN_NOT_FOUND" );
1997 long pinNum = cr->PropLong( wxS(
"pin" ) );
2000 for(
const auto& child : pkg->
children )
2002 int kind = child->id & 0xFF00;
2008 found = child.get();
2014 if( found ==
nullptr )
2015 cr->
props[wxS(
"pad" )] = wxS(
"PIN_NOT_FOUND" );
2016 else if( found->
HasProp( wxS(
"name" ) ) )
2017 cr->props[wxS(
"pad" )] = found->
Prop( wxS(
"name" ) );
2019 cr->props[wxS(
"pad" )] = cr->Prop( wxS(
"pin" ) );
2029 if( drawing ==
nullptr )
2042 if( board !=
nullptr )
2047 if( libraries ==
nullptr )
2048 THROW_IO_ERROR(
_(
"Eagle binary layout is missing a board/libraries node." ) );
2056 if( drcNode !=
nullptr )
2089 wxXmlNode* xml =
new wxXmlNode( wxXML_ELEMENT_NODE, aNode->
name );
2091 for(
const auto& [key, value] : aNode->
props )
2092 xml->AddAttribute( key, value );
2096 for(
const auto& child : aNode->
children )
2097 xml->AddChild(
toXml( child.get() ) );
2108 if( aBytes.size() < 24 )
2109 THROW_IO_ERROR(
_(
"File is too small to be an Eagle binary board." ) );
2111 m_root = std::make_unique<EGB_NODE>();
2113 m_root->name = wxS(
"eagle" );
2115 long numBlocks = -1;
2127 auto doc = std::make_unique<wxXmlDocument>();
wxXmlNode * toXml(const EGB_NODE *aNode) const
void postprocSignals(EGB_NODE *aSignals)
std::unique_ptr< wxXmlDocument > Parse(const std::vector< uint8_t > &aBytes)
Parse a binary Eagle board into an XML DOM compatible with the XML walker.
void requireBytes(size_t aOffs, size_t aLen) const
uint32_t loadUbf(size_t aOffs, uint32_t aField) const
void postprocCircles(EGB_NODE *aRoot)
bool readDrc(DRC_CTX &aDrc)
void postprocFreeText(EGB_NODE *aRoot)
bool isRotatable(int aId) const
void postprocLibs(EGB_NODE *aLibraries)
const wxString & nextLongText()
uint32_t loadU32(size_t aOffs, unsigned aLen) const
size_t m_pos
current read cursor
void postprocUnits(EGB_NODE *aRoot)
void postprocArcs(EGB_NODE *aRoot)
wxString loadStr(size_t aOffs, unsigned aLen) const
void fixLongText(EGB_NODE *aNode, const wxString &aField)
void postProcess(EGB_NODE *aRoot, const DRC_CTX &aDrc)
int readBlock(long &aNumBlocks, EGB_NODE *aParent)
void postprocSmd(EGB_NODE *aRoot)
const std::vector< uint8_t > * m_buf
file contents, not owned
void postprocContactRefs(EGB_NODE *aSignals, EGB_NODE *aElements, EGB_NODE *aLibraries)
void postprocWires(EGB_NODE *aRoot)
std::vector< wxString > m_freeText
NUL-delimited notes strings.
void postprocLayers(EGB_NODE *aDrawing, EGB_NODE *aLayers)
bool loadBmb(size_t aOffs, uint32_t aMask) const
void postprocRotation(EGB_NODE *aRoot)
void arcDecode(EGB_NODE *aElem, int aArcType, int aLineType)
double loadDouble(size_t aOffs) const
static bool IsBinaryEagle(wxInputStream &aStream)
Probe the first two bytes for the binary magic.
void postprocDimensions(EGB_NODE *aRoot)
std::unique_ptr< EGB_NODE > m_root
wxString m_invalidText
returned when out of strings
void postprocDrc(EGB_NODE *aDrcNode, const DRC_CTX &aDrc)
void postprocVias(EGB_NODE *aRoot)
void postprocNames(EGB_NODE *aLibraries, EGB_NODE *aElements)
void postprocElements(EGB_NODE *aElements)
int32_t loadS32(size_t aOffs, unsigned aLen) const
@ EGKW_SECT_PACKAGEVARIANT
@ EGKW_SECT_SCHEMACONNECTION
@ EGKW_SECT_VARIANTCONNECTIONS
@ EGKW_SECT_ATTRIBUTEVALUE
const wxChar *const traceEagleIo
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
This file contains miscellaneous commonly used macros and functions.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
DRC values pulled from the trailing 244-byte block (or sane defaults).
Lightweight mutable tree node for the intermediate Eagle binary tree.
std::map< wxString, wxString > props
long PropLong(const wxString &aKey) const
std::vector< std::unique_ptr< EGB_NODE > > children
EGB_NODE * FindChildById(int aId) const
bool HasProp(const wxString &aKey) const
EGB_NODE * AddChild(int aId, const wxString &aName)
wxString PropDoubled(const wxString &aKey) const
Format a property doubled in 64-bit so the half-to-full widening cannot overflow a 32-bit long.
wxString Prop(const wxString &aKey) const
EGB_NODE * FindChildByName(const wxString &aName) const
wxLogTrace helper definitions.