diff options
Diffstat (limited to 'new/sch_lib.h')
-rw-r--r-- | new/sch_lib.h | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/new/sch_lib.h b/new/sch_lib.h new file mode 100644 index 0000000..9a383c3 --- /dev/null +++ b/new/sch_lib.h @@ -0,0 +1,365 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> + * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef SCH_LIB_H_ +#define SCH_LIB_H_ + +#include <utf8.h> +#include <richio.h> +#include <import_export.h> + + +namespace SCH { + +class LPID; +class PART; +class LIB_TABLE; + +/** + * Class LIB_SOURCE + * is an abstract class from which implementation specific LIB_SOURCEs + * may be derived, one for each kind of library type allowed in the library table. + * The class name stems from the fact that this interface only provides READ ONLY + * functions. + * + * @author Dick Hollenbeck + */ +class LIB_SOURCE +{ + friend class LIB; ///< the LIB uses these functions. + +protected: ///< derived classes must implement + + /** + * Function GetSourceType + * returns the library table entry's type for this library source. + */ + const STRING& GetSourceType() { return sourceType; } + + /** + * Function GetSourceURI + * returns absolute location of the library source. + */ + const STRING& GetSourceURI() { return sourceURI; } + + //-----<abstract for implementors>--------------------------------------- + + /** + * Function ReadPart + * fetches @a aPartName's s-expression into @a aResult after clear()ing aResult. + */ + virtual void ReadPart( STR_UTF* aResult, const STRING& aPartName, const STRING& aRev = "" ) + throw( IO_ERROR ) = 0; + + /** + * Function ReadParts + * fetches the s-expressions for each part given in @a aPartNames, into @a aResults, + * honoring the array indices respectfully. + * @param aPartNames is a list of part names, one name per list element. If a part name + * does not have a version string, then the most recent version is fetched. + * @param aResults receives the s-expressions + */ + virtual void ReadParts( STR_UTFS* aResults, const STRINGS& aPartNames ) + throw( IO_ERROR ) = 0; + + /** + * Function GetCategories + * fetches all categories present in the library source into @a aResults + */ + virtual void GetCategories( STRINGS* aResults ) + throw( IO_ERROR ) = 0; + + /** + * Function GetCategoricalPartNames + * fetches all the part names for @a aCategory, which was returned by GetCategories(). + * + * @param aCategory is a subdividing navigator within the library source, + * but may default to empty which will be taken to mean all categories. + * + * @param aResults is a place to put the fetched result, one category per STRING. + */ + virtual void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory="" ) + throw( IO_ERROR ) = 0; + + /** + * Function GetRevisions + * fetches all revisions for @a aPartName into @a aResults. Revisions are strings + * like "rev12", "rev279", and are library source agnostic. These do not have to be + * in a contiguous order, but the first 3 characters must be "rev" and subsequent + * characters must consist of at least one decimal digit. If the LIB_SOURCE + * does not support revisions, it is allowed to return a single "" string as + * the only result. This means aPartName is present in the libsource, only once + * without a revision. This is a special case. + */ + virtual void GetRevisions( STRINGS* aResults, const STRING& aPartName ) + throw( IO_ERROR ) = 0; + + /** + * Function FindParts + * fetches part names for all parts matching the criteria given in @a + * aQuery, into @a aResults. The query string is designed to be easily marshalled, + * i.e. serialized, so that long distance queries can be made with minimal overhead. + * The library source needs to have an intelligent friend on the other end if + * the actual library data is remotely located, otherwise it will be too slow + * to honor this portion of the API contract. + * + * @param aQuery is a string holding a domain specific query language expression. + * One candidate here is an s-expression that uses (and ..) and (or ..) operators + * and uses them as RPN. For example "(and (footprint 0805)(value 33ohm)(category passives))". + * The UI can shield the user from this if it wants. + * + * @param aResults is a place to put the fetched part names, one part per STRING. + */ + virtual void FindParts( STRINGS* aResults, const STRING& aQuery ) + throw( IO_ERROR ) = 0; + + //-----</abstract for implementors>-------------------------------------- + + +protected: + STRING sourceType; + STRING sourceURI; +}; + + +/** + * Class LIB_SINK + * is an abstract class from which implementation specific LIB_SINKs + * may be derived, one for each kind of library type in the library table that + * supports writing. The class name stems from the fact that this interface + * only provides WRITE functions. + * + * @author Dick Hollenbeck + */ +class LIB_SINK +{ + friend class LIB; ///< only the LIB uses these functions. + +protected: ///< derived classes must implement + + /** + * Function GetSinkType + * returns the library table entry's type for this library sink. + */ + const STRING& GetSinkType() { return sinkType; } + + /** + * Function GetSinkURI + * returns absolute location of the library sink. + */ + const STRING& GetSinkURI() { return sinkURI; } + + /** + * Function WritePart + * saves the part to non-volatile storage. @a aPartName may have the revision + * portion present. If it is not present, and a overwrite of an existhing + * part is done, then LIB::ReloadPart() must be called on this same part + * and all parts that inherit it must be reparsed. + * @return STRING - if the LIB_SINK support revision numbering, then return a + * revision name that was next in the sequence, e.g. "rev22", else "". + */ + virtual STRING WritePart( const STRING& aPartName, const STRING& aSExpression ) + throw( IO_ERROR ) = 0; + +protected: + STRING sinkType; + STRING sinkURI; +}; + + +class PARTS; + + +/** + * Class LIB + * is a cache of parts, and because the LIB_SOURCE is abstracted, there + * should be no need to extend from this class in any case except for the + * PARTS_LIST. + * + * @author Dick Hollenbeck + */ +class MY_API LIB +{ + friend class LIB_TABLE; ///< protected constructor, LIB_TABLE may construct + +protected: // constructor is not public, called from LIB_TABLE only. + + /** + * Constructor LIB + * is not public and is only called from class LIB_TABLE + * + * @param aLogicalLibrary is the name of a well known logical library, and is + * known because it already exists in the library table. + * + * @param aSource is an open LIB_SOURCE whose ownership is + * given over to this LIB. + * + * @param aSink is an open LIB_SINK whose ownership is given over + * to this LIB, and it is normally NULL. + */ + LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink = NULL ); + +public: + + ~LIB(); + + /** + * Function HasSink + * returns true if this library has write/save capability. Most LIBs + * are read only. + */ + bool HasSink() { return sink != NULL; } + + /** + * Function LogicalName + * returns the logical name of this LIB. + */ + STRING LogicalName(); + + //-----<use delegates: source and sink>--------------------------------- + + /** + * Function LookupPart + * returns a PART given @a aPartName, such as "passives/R". No ownership + * is given to the PART, it stays in the cache that is this LIB. + * + * @param aLPID is the part to lookup. The logicalLibName can be empty in it + * since yes, we know which LIB is in play. + * + * @param aLibTable is the LIB_TABLE view that is in effect for inheritance, + * and comes from the big containing SCHEMATIC object. + * + * @return PART* - The desired PART and will never be NULL. No ownership is + * given to caller. PARTs always reside in the cache that is a LIB. + * + * @throw IO_ERROR if the part cannot be found or loaded. + */ + PART* LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) + throw( IO_ERROR ); + + /** + * Function ReloadPart + * will reload the part assuming the library source has a changed content + * for it. + */ + void ReloadPart( PART* aPart ) throw( IO_ERROR ); + + /** + * Function GetCategories + * returns all categories of parts within this LIB into @a aResults. + */ + STRINGS GetCategories() throw( IO_ERROR ); + + /** + * Function GetCategoricalPartNames + * returns the part names for @a aCategory, and at the same time + * creates cache entries for the very same parts if they do not already exist + * in this LIB (i.e. cache). + */ + STRINGS GetCategoricalPartNames( const STRING& aCategory = "" ) throw( IO_ERROR ); + + + //-----<.use delegates: source and sink>-------------------------------- + + /** + * Function WritePart + * saves the part to non-volatile storage and returns the next new revision + * name in the sequence established by the LIB_SINK. + */ + STRING WritePart( PART* aPart ) throw( IO_ERROR ); + + void SetPartBody( PART* aPart, const STRING& aSExpression ) throw( IO_ERROR ); + + /** + * Function GetRevisions + * returns the revisions of @a aPartName that are present in this LIB. + * The returned STRINGS will look like "rev1", "rev2", etc. + */ + STRINGS GetRevisions( const STRING& aPartName ) throw( IO_ERROR ); + + /** + * Function FindParts + * returns part names for all parts matching the criteria given in @a + * aQuery, into @a aResults. The query string is designed to be easily marshalled, + * i.e. serialized, so that long distance queries can be made with minimal overhead. + * The library source needs to have an intelligent friend on the other end if + * the actual library data is remotely located, otherwise it will be too slow + * to honor this portion of the API contract. + * + * @param aQuery is a string holding a domain specific language expression. One candidate + * here is an RPN s-expression that uses (and ..) and (or ..) operators. For example + * "(and (footprint 0805)(value 33ohm)(category passives))" + */ + STRINGS FindParts( const STRING& aQuery ) throw( IO_ERROR ) + { + // run the query on the cached data first for any PARTS which are fully + // parsed (i.e. cached), then on the LIB_SOURCE to find any that + // are not fully parsed, then unify the results. + + return STRINGS(); + } + +#if defined(DEBUG) + static void Test( int argc, char** argv ) throw( IO_ERROR ); +#endif + +protected: + + STR_UTF fetch; // scratch, used to fetch things, grows to worst case size. + STR_UTFS vfetch; // scratch, used to fetch things. + + STRING logicalName; + LIB_SOURCE* source; + LIB_SINK* sink; + + STRINGS categories; + bool cachedCategories; /// < is true only after reading categories + + + /** parts are in various states of readiness: + * 1) not even loaded (if cachedParts is false) + * 2) present, but without member 'body' having been read() yet. + * 3) body has been read, but not parsed yet. + * 4) parsed and inheritance if any has been applied. + */ + PARTS* parts; + + /** + * Function lookupPart + * looks up a PART, returns NULL if cannot find in source. Does not parse + * the part. Does not even load the part's Sweet string. No ownership + * is given to the PART, it stays in the cache that is this LIB. + * + * @throw IO_ERROR if there is some kind of communications error reading + * the original list of parts. + * + * @return PART* - the cached PART, or NULL if not found. No ownership transferred. + */ + const PART* lookupPart( const LPID& aLPID ) throw( IO_ERROR ); +}; + + +} // namespace SCH + +#endif // SCH_LIB_H_ |