1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014-2017  Cirilo Bernardo
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 /*
26  * NOTE:
27  *
28  *  Rules to ensure friendly use within a DLL:
29  *
30  *  1. all functions which throw exceptions must not be publicly available;
31  *  they must become FRIEND functions instead.
32  *
33  *  2. All objects with PRIVATE functions which throw exceptions when
34  *  invoked by a PUBLIC function must indicate success or failure
35  *  and make the exception information available via a GetError()
36  *  routine.
37  *
38  *  General notes:
39  *
40  *  1. Due to the complexity of objects and the risk of accumulated
41  *  position errors, CAD packages should only delete or add complete
42  *  components. If a component being added already exists, it is
43  *  replaced by the new component IF and only if the CAD type is
44  *  permitted to make such changes.
45  *
46  *  2. Internally all units shall be in mm and by default we shall
47  *  write files with mm units. The internal flags mm/thou shall only
48  *  be used to translate data being read from or written to files.
49  *  This avoids the painful management of a mixture of mm and thou.
50  *  The API shall require all dimensions in mm; for people using any
51  *  other unit, it is their responsibility to perform the conversion
52  *  to mm. Conversion back to thou may incur small rounding errors.
53  */
54 
55 
56 #ifndef IDF_PARSER_H
57 #define IDF_PARSER_H
58 
59 #include <idf_outlines.h>
60 
61 class IDF3_COMPONENT;
62 
63 class IDF3_COMP_OUTLINE_DATA
64 {
65 public:
66     /**
67      * Create an object with default settings and no parent or associated outline.
68      */
69     IDF3_COMP_OUTLINE_DATA();
70 
71     /**
72      * Create an object with default settings and the specified parent and associated outline.
73      *
74      * @param aParent is the owning IDF3_COMPONENT object.
75      * @param aOutline is the outline for this placed component.
76      */
77     IDF3_COMP_OUTLINE_DATA( IDF3_COMPONENT* aParent, IDF3_COMP_OUTLINE* aOutline );
78 
79     /**
80      * Create an object the specified parent and associated outline and the specified data.
81      *
82      * @param aParent is the owning IDF3_COMPONENT object.
83      * @param aOutline is the outline for this placed component.
84      * @param aXoff is the X offset of this outline in relation to its parent.
85      * @param aYoff is the Y offset of this outline in relation to its parent.
86      * @param aZoff is the board offset of this outline as per IDFv3 specification.
87      * @param aAoff is the rotational offset of this outline in relation to its parent.
88      */
89     IDF3_COMP_OUTLINE_DATA( IDF3_COMPONENT* aParent, IDF3_COMP_OUTLINE* aOutline,
90                             double aXoff, double aYoff, double aZoff, double aAngleOff );
91 
92     ~IDF3_COMP_OUTLINE_DATA();
93 
94     /**
95      * Set the position and orientation of this outline item in relation to its parent.
96      *
97      * @param aXoff is the X offset of this outline in relation to its parent.
98      * @param aYoff is the Y offset of this outline in relation to its parent.
99      * @param aZoff is the board offset of this outline as per IDFv3 specification.
100      * @param aAoff is the rotational offset of this outline in relation to its parent.
101      *
102      * @return true if the operation succeeded, false if an ownership violation occurred.
103      */
104     bool SetOffsets( double aXoff, double aYoff, double aZoff, double aAngleOff );
105 
106     /**
107      * Retrieve the position and orientation of this outline item in relation to its parent.
108      *
109      * @param aXoff is the X offset of this outline in relation to its parent.
110      * @param aYoff is the Y offset of this outline in relation to its parent.
111      * @param aZoff is the board offset of this outline as per IDFv3 specification.
112      * @param aAoff is the rotational offset of this outline in relation to its parent.
113      */
114     void GetOffsets( double& aXoff, double& aYoff, double& aZoff, double& aAngleOff );
115 
116     /**
117      * Set the parent object.
118      *
119      * @param aParent is the owning IDF3_COMPONENT object.
120      */
121     void SetParent( IDF3_COMPONENT* aParent );
122 
123     /**
124      * Set the outline whose position is managed by this object.
125      *
126      * @param aOutline is the outline for this component.
127      * @return true if the operation succeeded, false if an ownership violation occurred.
128      */
129     bool SetOutline( IDF3_COMP_OUTLINE* aOutline );
130 
131     /**
132      * Retrieve the outline whose position is managed by this object.
133      *
134      * @return the outline for this component.
135      */
GetOutline(void)136     IDF3_COMP_OUTLINE* GetOutline( void )
137     {
138         return outline;
139     }
140 
GetError(void)141     const std::string& GetError( void )
142     {
143         return errormsg;
144     }
145 
146 private:
147 
148 #ifndef DISABLE_IDF_OWNERSHIP
149     bool checkOwnership( int aSourceLine, const char* aSourceFunc );
150 #endif
151 
152     /**
153      * Read placement data from an open IDFv3 file.
154      *
155      * @param aBoardFile is the open IDFv3 file
156      * @param aBoardState is the internal status flag of the IDF parser
157      * @param aIdfVersion is the version of the file currently being parsed
158      * @param aBoard is the IDF3_BOARD object which will store the data
159      *
160      * @return true if placement data was successfully read. false if
161      * no placement data was read; this may happen if the end of the placement
162      * data was encountered or an error occurred. if an error occurred then
163      * an exception is thrown.
164      */
165     bool readPlaceData( std::istream &aBoardFile, IDF3::FILE_STATE& aBoardState,
166                         IDF3_BOARD *aBoard, IDF3::IDF_VERSION aIdfVersion,
167                         bool aNoSubstituteOutlines );
168 
169     /**
170      * Write RECORD 2 and RECORD 3 of a PLACEMENT section as per IDFv3 specification.
171      *
172      * @param aBoardFile is the open IDFv3 file.
173      * @param aXpos is the X location of the parent component.
174      * @param aYpos is the Y location of the parent component.
175      * @param aAngle is the rotation of the parent component.
176      * @param aRefDes is the reference designator of the parent component.
177      * @param aPlacement is the IDF Placement Status of the parent component.
178      * @param aSide is the IDF Layer Designator (TOP or BOTTOM).
179      * @return true if data was successfully written, otherwise false.
180      */
181     void writePlaceData( std::ostream& aBoardFile, double aXpos, double aYpos, double aAngle,
182                          const std::string& aRefDes, IDF3::IDF_PLACEMENT aPlacement,
183                          IDF3::IDF_LAYER aSide );
184 
185     friend class IDF3_BOARD;
186     friend class IDF3_COMPONENT;
187 
188     double xoff;    // X offset from KiCad or X placement from IDF file
189     double yoff;    // Y offset from KiCad or Y placement from IDF file
190     double zoff;    // height offset (specified in IDFv3 spec, corresponds to KiCad Z offset)
191     double aoff;    // angular offset from KiCad or Rotation Angle from IDF file
192     std::string errormsg;
193 
194     IDF3_COMP_OUTLINE* outline; // component outline to use
195     IDF3_COMPONENT* parent;     // associated component
196 };
197 
198 
199 class IDF3_COMPONENT
200 {
201 public:
202     /**
203      * Set the parent object and initializes other internal parameters to default values.
204      *
205      * @param aParent is the owning IDF3_BOARD object.
206      */
207     IDF3_COMPONENT( IDF3_BOARD* aParent );
208 
209     ~IDF3_COMPONENT();
210 
211     /**
212      * Set the parent object.
213      *
214      * @param aParent is the owning IDF3_BOARD object.
215      */
216     void SetParent( IDF3_BOARD* aParent );
217 
218     /**
219      * @return the type of CAD (IDF3::CAD_ELEC, IDF3::CAD_MECH) which instantiated this object.
220      */
221     IDF3::CAD_TYPE GetCadType( void );
222 
223     /**
224      * @return the IDF UNIT type of the parent object or IDF3::UNIT_INVALID if the parent was
225      *         not set.
226      */
227     IDF3::IDF_UNIT GetUnit( void );
228 
229     /**
230      * Set the Reference Designator (RefDes) of this component.
231      *
232      * The RefDes is shared by all outlines associated with this component.
233      *
234      * @return true if the RefDes was accepted, otherwise false. Prohibited values include empty
235      *         strings and the word PANEL.
236      */
237     bool SetRefDes( const std::string& aRefDes );
238 
239     /**
240      * Retrieve the Reference Designator (RefDes) of this component.
241      *
242      * @return the Reference Designator.
243      */
244     const std::string& GetRefDes( void );
245 
246     /**
247      * Add a drill entry to the component and returns its pointer.
248      *
249      * @param aDia diameter of the drill (mm).
250      * @param aXpos X position of the drill (mm).
251      * @param aYpos Y position of the drill (mm).
252      * @param aPlating plating type (PTH, NPTH).
253      * @param aHoleType hole class (PIN, VIA, MTG, TOOL, etc).
254      * @param aOwner owning CAD system (ECAD, MCAD, UNOWNED).
255      * @return the newly created drill entry or NULL.
256      */
257     IDF_DRILL_DATA* AddDrill( double aDia, double aXpos, double aYpos,
258                               IDF3::KEY_PLATING aPlating,
259                               const std::string& aHoleType,
260                               IDF3::KEY_OWNER aOwner );
261 
262     /**
263      * Add the given drill entry to the component and returns the pointer to indicate success.
264      *
265      * A return value of NULL indicates that the item was not added and it is the user's
266      * responsibility to delete the object if necessary.
267      *
268      * @param aDrilledHole pointer to a drill entry.
269      * @return aDrilledHole if the function succeeds, otherwise NULL.
270      */
271     IDF_DRILL_DATA* AddDrill( IDF_DRILL_DATA* aDrilledHole );
272 
273     /**
274      * Delete a drill entry based on its size and location.
275      *
276      * This operation is subject to IDF ownership rules.
277      *
278      * @param aDia diameter (mm) of the drilled hole to be deleted.
279      * @param aXpos X position (mm) of the hole to be deleted.
280      * @param aYpos X position (mm) of the hole to be deleted.
281      * @return true if a drill was found and deleted, otherwise false.
282      * @throw if an ownership violation occurs.
283      */
284     bool DelDrill( double aDia, double aXpos, double aYpos );
285 
286     /**
287      * Delete a drill entry based on pointer.
288      *
289      * This operation is subject to IDF ownership rules.
290      *
291      * @param aDrill the pointer associated with the drill entry to be deleted.
292      * @return true if a drill was found and deleted, otherwise false.
293      * @throw if an ownership violation occurs.
294      */
295     bool DelDrill( IDF_DRILL_DATA* aDrill );
296 
297     /**
298      * Return the internal list of drills.
299      *
300      * To avoid IDF violations, the user should not alter these entries.
301      */
302     const std::list< IDF_DRILL_DATA* >* const GetDrills( void );
303 
304     /**
305      * Add the given component outline data to this component.
306      *
307      * @param aComponentOutline is a pointer to the outline data to be added.
308      * @return true if the operation succeeds, otherwise false.
309      */
310     bool AddOutlineData( IDF3_COMP_OUTLINE_DATA* aComponentOutline );
311 
312     /**
313      * Remove outline data based on the pointer provided.
314      *
315      * @param aComponentOutline is a pointer to be deleted from the internal list.
316      * @return true if the data was found and deleted, otherwise false.
317      */
318     bool DeleteOutlineData( IDF3_COMP_OUTLINE_DATA* aComponentOutline );
319 
320     /**
321      * Remove outline data based on the provided index.
322      *
323      * @param aIndex is an index to the internal outline list.
324      * @return true if the data was deleted, false if the index was out of bounds.
325      */
326     bool DeleteOutlineData( size_t aIndex );
327 
328     /**
329      * @return the number of outlines in the internal list.
330      */
331     size_t GetOutlinesSize( void );
332 
333 
334     /**
335      * @return the internal list of outline data.
336      */
337     const std::list< IDF3_COMP_OUTLINE_DATA* >*const GetOutlinesData( void );
338 
339     /**
340      * Retrieve the internal position parameters and returns true if the
341      * position was previously set, otherwise false.
342      */
343     bool GetPosition( double& aXpos, double& aYpos, double& aAngle, IDF3::IDF_LAYER& aLayer );
344 
345     // NOTE: it may be possible to extend this so that internal drills and outlines
346     // are moved when the component is moved. However there is always a danger of
347     // position creep due to the relative position updates.
348     /**
349      * Set the internal position parameters and returns true if the position was set, false if
350      * the position was previously set.
351      *
352      * This object does not allow modification of the position once it is set since this may
353      * adversely affect the relationship with its internal objects.
354      *
355      * @param aXpos is the X position (mm) of the component.
356      * @param aYpos is the Y position (mm) of the component.
357      * @param aAngle is the rotation of the component (degrees).
358      * @param aLayer is the layer on which the component is places (TOP, BOTTOM).
359      * @return true if the position was set, otherwise false.
360      */
361     bool SetPosition( double aXpos, double aYpos, double aAngle, IDF3::IDF_LAYER aLayer );
362 
363     /**
364      * @return the IDF placement value of this component (UNPLACED, PLACED, ECAD, MCAD).
365      */
366     IDF3::IDF_PLACEMENT GetPlacement( void );
367 
368     /**
369      * Set the placement value of the component subject to ownership rules.
370      *
371      * An exception is thrown if aPlacementValue is invalid or an ownership
372      * violation occurs.
373      *
374      * @return true if the operation succeeded, otherwise false and the error message is set.
375      */
376     bool SetPlacement( IDF3::IDF_PLACEMENT aPlacementValue );
377 
GetError(void)378     const std::string& GetError( void )
379     {
380         return errormsg;
381     }
382 
383 private:
384     friend class IDF3_BOARD;
385 
386     /**
387      * Write the internal drill data to an IDFv3 .DRILLED_HOLES section.
388      *
389      * @param aBoardFile is an IDFv3 file opened for writing.
390      * @return true if the operation succeeded, otherwise false.
391      */
392     bool writeDrillData( std::ostream& aBoardFile );
393 
394     /**
395      * Write the component placement data to an IDFv3 .PLACEMENT section.
396      *
397      * @param aBoardFile is an IDFv3 file opened for writing.
398      * @return true if the operation succeeded, otherwise false.
399      */
400     bool writePlaceData( std::ostream& aBoardFile );
401 
402 #ifndef DISABLE_IDF_OWNERSHIP
403     bool checkOwnership( int aSourceLine, const char* aSourceFunc );
404 #endif
405 
406     std::list< IDF3_COMP_OUTLINE_DATA* > components;
407     std::list< IDF_DRILL_DATA* > drills;
408 
409     double xpos;
410     double ypos;
411     double angle;
412     IDF3::IDF_PLACEMENT placement;
413     IDF3::IDF_LAYER     layer;          // [TOP/BOTTOM ONLY as per IDF spec]
414     bool                hasPosition;    ///< True after SetPosition is called once
415     std::string         refdes;         ///< Reference Description (MUST BE UNIQUE)
416     IDF3_BOARD*         parent;
417     std::string         errormsg;
418 };
419 
420 
421 class IDF3_BOARD
422 {
423 public:
424     IDF3_BOARD( IDF3::CAD_TYPE aCadType );
425     virtual ~IDF3_BOARD();
426 
427     IDF3::CAD_TYPE GetCadType( void );
428 
429     // retrieve the nominal unit used in reading/writing
430     // data. This is primarily for use by owned objects
431     // and is only of informational use for the end user.
432     // Internally all data is represented in mm and the
433     // end user must use only mm in the API.
434     IDF3::IDF_UNIT GetUnit( void );
435 
436     const std::string& GetNewRefDes( void );
437 
438     void SetBoardName( const std::string& aBoardName );
439     const std::string& GetBoardName( void );
440 
441     bool SetBoardThickness( double aBoardThickness );
442     double GetBoardThickness( void );
443 
444     bool ReadFile( const wxString& aFullFileName, bool aNoSubstituteOutlines = false );
445     bool WriteFile( const wxString& aFullFileName, bool aUnitMM = true,
446                     bool aForceUnitFlag = false );
447 
448     const std::string& GetIDFSource( void );
449     void  SetIDFSource( const std::string& aIDFSource);
450     const std::string& GetBoardSource( void );
451     const std::string& GetLibrarySource( void );
452     const std::string& GetBoardDate( void );
453     const std::string& GetLibraryDate( void );
454     int   GetBoardVersion( void );
455     bool  SetBoardVersion( int aVersion );
456     int   GetLibraryVersion( void );
457     bool  SetLibraryVersion( int aVersion );
458 
459     double GetUserScale( void );
460     bool SetUserScale( double aScaleFactor );
461 
462     int GetUserPrecision( void );
463     bool SetUserPrecision( int aPrecision );
464 
465     void GetUserOffset( double& aXoff, double& aYoff );
466     void SetUserOffset( double aXoff, double aYoff );
467 
468     bool AddBoardOutline( IDF_OUTLINE* aOutline );
469     bool DelBoardOutline( IDF_OUTLINE* aOutline );
470     bool DelBoardOutline( size_t aIndex );
471     size_t GetBoardOutlinesSize( void );
472     BOARD_OUTLINE* GetBoardOutline( void );
473     const std::list< IDF_OUTLINE* >*const GetBoardOutlines( void );
474 
475     // Operations for OTHER OUTLINES
476     const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines( void );
477 
478     /// XXX - TO BE IMPLEMENTED
479     //
480     // SetBoardOutlineOwner()
481     //
482     // AddDrillComment
483     // AddPlacementComment
484     // GetDrillComments()
485     // GetPlacementComments()
486     // ClearDrillComments()
487     // ClearPlacementComments()
488     // AddNoteComment
489     // GetNoteComments
490     // AddNote
491     //
492     // [IMPLEMENTED] const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines( void )
493     // size_t GetOtherOutlinesSize()
494     // OTHER_OUTLINE* AddOtherOutline( OTHER_OUTLINE* aOtherOutline )
495     // bool DelOtherOutline( int aIndex )
496     // bool DelOtherOutline( OTHER_OUTLINE* aOtherOutline )
497     //
498     // const std::list<ROUTE_OUTLINE*>*const GetRouteOutlines()
499     // size_t GetRouteOutlinesSize()
500     // ROUTE_OUTLINE* AddRouteOutline( ROUTE_OUTLINE* aRouteOutline )
501     // bool DelRouteOutline( int aIndex )
502     // bool DelRouteOutline( ROUTE_OUTLINE* aRouteOutline )
503     //
504     // const std::list<PLACE_OUTLINE*>*const GetPlacementOutlines()
505     // size_t GetPlacementOutlinesSize()
506     // PLACE_OUTLINE* AddPlacementOutline( PLACE_OUTLINE* aPlaceOutline )
507     // bool DelPlacementOutline( int aIndex )
508     // bool DelPlacementOutline( PLACE_OUTLINE* aPlaceOutline )
509     //
510     // const std::list<ROUTE_KO_OUTLINE*>*const GetRouteKeepOutOutlines()
511     // size_t GetRouteKeepOutOutlinesSize()
512     // ROUTE_KO_OUTLINE* AddRouteKeepoutOutline( ROUTE_KO_OUTLINE* aRouteKeepOut )
513     // bool DelRouteKeepOutOutline( int aIndex )
514     // bool DelRouteKeepOutOutline( ROUTE_KO_OUTLINE* aRouteKeepOut )
515     //
516     // const std::list<VIA_KO_OUTLINE*>*const GetViaKeepOutOutlines()
517     // size_t GetViaKeepOutOutlinesSize()
518     // VIA_KO_OUTLINE* AddViaKeepoutOutline( VIA_KO_OUTLINE* aViaKeepOut )
519     // bool DelViaKeepOutOutline( int aIndex )
520     // bool DelViaKeepOutOutline( VIA_KO_OUTLINE* aViaKeepOut )
521     //
522     // const std::list<PLACE_KO_OUTLINE*>*const GetPlacementKeepOutOutlines()
523     // size_t GetPlacementKeepOutOutlinesSize()
524     // PLACE_KO_OUTLINE* AddPlacementKeepoutOutline( PLACE_KO_OUTLINE* aPlaceKeepOut )
525     // bool DelPlacementKeepOutOutline( int aIndex )
526     // bool DelPlacementKeepOutOutline( PLACE_KO_OUTLINE* aPlaceKeepOut )
527     //
528     // const std::multimap<std::string, GROUP_OUTLINE*>*const GetGroupOutlines()
529     // size_t GetGroupOutlinesSize()
530     // GROUP_OUTLINE* AddGroupOutline( GROUP_OUTLINE* aGroupOutline )
531     // bool DelGroupOutline( int aIndex )
532     // bool DelGroupOutline( GROUP_OUTLINE* aGroupOutline )
533 
GetBoardDrills(void)534     std::list<IDF_DRILL_DATA*>& GetBoardDrills( void )
535     {
536         return board_drills;
537     }
538 
539     IDF_DRILL_DATA* AddBoardDrill( double aDia, double aXpos, double aYpos,
540                                    IDF3::KEY_PLATING aPlating,
541                                    const std::string& aHoleType,
542                                    IDF3::KEY_OWNER aOwner );
543 
544     IDF_DRILL_DATA* AddDrill( IDF_DRILL_DATA* aDrilledHole );
545 
546     bool DelBoardDrill( double aDia, double aXpos, double aYpos );
547 
548     // a slot is a deficient representation of a kicad slotted hole;
549     // it is usually associated with a component but IDFv3 does not
550     // provide for such an association.
551     bool AddSlot( double aWidth, double aLength, double aOrientation, double aX, double aY );
552 
553     bool AddComponent( IDF3_COMPONENT* aComponent );
554     bool DelComponent( IDF3_COMPONENT* aComponent );
555     bool DelComponent( size_t aIndex );
556     size_t GetComponentsSize( void );
557     std::map< std::string, IDF3_COMPONENT* >*const GetComponents( void );
558     IDF3_COMPONENT* FindComponent( const std::string& aRefDes );
559 
560     // Return a pointer to a component outline object or NULL if the object doesn't exist.
561     IDF3_COMP_OUTLINE* GetComponentOutline( const wxString& aFullFileName );
562 
563     // returns a pointer to the component outline object with the
564     // unique ID aComponentID
565     IDF3_COMP_OUTLINE* GetComponentOutline( const std::string& aComponentID );
566 
567     // returns a pointer to the outline "NOGEOM NOPART" which is substituted
568     // whenever a true outline cannot be found or is defective
569     IDF3_COMP_OUTLINE* GetInvalidOutline( const std::string& aGeomName,
570                                           const std::string& aPartName );
571 
572     // clears all data
573     void Clear( void );
574 
575     // return error string
GetError(void)576     const std::string& GetError( void )
577     {
578         return errormsg;
579     }
580 
581 private:
582     // Set the unit; this can only be done internally upon reading a file or saving.
583     bool setUnit( IDF3::IDF_UNIT aUnit, bool convert = false );
584 
585     IDF_DRILL_DATA* addCompDrill( double aDia, double aXpos, double aYpos,
586                                   IDF3::KEY_PLATING aPlating,
587                                   const std::string& aHoleType,
588                                   IDF3::KEY_OWNER aOwner,
589                                   const std::string& aRefDes );
590 
591     IDF_DRILL_DATA* addCompDrill( IDF_DRILL_DATA* aDrilledHole );
592 
593     bool delCompDrill( double aDia, double aXpos, double aYpos, const std::string& aRefDes );
594 
595     // read the DRILLED HOLES section
596     void readBrdDrills( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState );
597 
598     // read the NOTES section
599     void readBrdNotes( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState );
600 
601     // read the component placement section
602     void readBrdPlacement( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState,
603                            bool aNoSubstituteOutlines );
604 
605     // read the board HEADER
606     void readBrdHeader( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState );
607 
608     // read individual board sections; pay attention to IDFv3 section specifications
609     // exception thrown on unrecoverable errors. state flag set to FILE_PLACEMENT
610     // upon reading the PLACEMENT file; according to IDFv3 this is the final section
611     void readBrdSection( std::istream& aBoardFile, IDF3::FILE_STATE& aBoardState,
612                          bool aNoSubstituteOutlines );
613     // read the board file data
614     void readBoardFile( const std::string& aFileName, bool aNoSubstituteOutlines );
615 
616     // write the board file data
617     void writeBoardFile( const std::string& aFileName );
618 
619     // read the library sections (outlines)
620     void readLibSection( std::istream& aLibFile, IDF3::FILE_STATE& aLibState, IDF3_BOARD* aBoard );
621 
622     // read the library HEADER
623     void readLibHeader( std::istream& aLibFile, IDF3::FILE_STATE& aLibState );
624 
625     // read the library file data
626     void readLibFile( const std::string& aFileName );
627 
628     // write the library file data
629     bool writeLibFile( const std::string& aFileName );
630 
631 #ifndef DISABLE_IDF_OWNERSHIP
632     bool checkComponentOwnership( int aSourceLine, const char* aSourceFunc,
633                                   IDF3_COMPONENT* aComponent );
634 #endif
635 
636     std::map< std::string, std::string > uidFileList;     // map of files opened and UIDs
637     std::list< std::string > uidLibList;                  // list of UIDs read from a library file
638 
639     // string for passing error messages to user
640     std::string errormsg;
641     std::list< IDF_NOTE* >     notes;                     // IDF notes
642     std::list< std::string >   noteComments;              // comment list for NOTES section
643     std::list< std::string >   drillComments;             // comment list for DRILL section
644     std::list< std::string >   placeComments;             // comment list for PLACEMENT section
645     std::list<IDF_DRILL_DATA*> board_drills;
646     std::map< std::string, IDF3_COMPONENT*> components;   // drill and placement data for components
647 
648     // component outlines (data for library file).
649     std::map< std::string, IDF3_COMP_OUTLINE*> compOutlines;
650     std::string boardName;
651     IDF3::CAD_TYPE   cadType;
652     IDF3::IDF_UNIT   unit;
653     IDF3::IDF_VERSION   idfVer;                           // IDF version of Board or Library
654 
655     // counter for automatically numbered NOREFDES items
656     int iRefDes;
657     std::string sRefDes;
658 
659     std::string idfSource;  // SOURCE string to use when writing BOARD and LIBRARY headers
660     std::string brdSource;  // SOURCE string as retrieved from a BOARD file
661     std::string libSource;  // SOURCE string as retrieved from a LIBRARY file
662     std::string brdDate;    // DATE string from BOARD file
663     std::string libDate;    // DATE string from LIBRARY file
664     int brdFileVersion;     // File Version from BOARD file
665     int libFileVersion;     // File Version from LIBRARY file
666 
667     int    userPrec;        // user may store any integer here
668     double userScale;       // user may store a scale for translating to arbitrary units
669     double userXoff;        // user may specify an arbitrary X/Y offset
670     double userYoff;
671 
672     // main board outline and cutouts
673     BOARD_OUTLINE olnBoard;
674 
675     // OTHER outlines
676     std::map<std::string, OTHER_OUTLINE*> olnOther;
677 
678     // ROUTE outlines
679     std::list<ROUTE_OUTLINE*> olnRoute;
680 
681     // PLACEMENT outlines
682     std::list<PLACE_OUTLINE*> olnPlace;
683 
684     // ROUTE KEEPOUT outlines
685     std::list<ROUTE_KO_OUTLINE*> olnRouteKeepout;
686 
687     // VIA KEEPOUT outlines
688     std::list<VIA_KO_OUTLINE*> olnViaKeepout;
689 
690     // PLACE KEEPOUT outlines
691     std::list<PLACE_KO_OUTLINE*> olnPlaceKeepout;
692 
693     // PLACEMENT GROUP outlines
694     std::multimap<std::string, GROUP_OUTLINE*> olnGroup;
695 };
696 
697 #endif // IDF_PARSER_H
698