summaryrefslogtreecommitdiff
path: root/new/sch_dir_lib_source.h
blob: 9d39352f9eb676e839e714aac6f5486145a44e80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
 * 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 DIR_LIB_SOURCE_H_
#define DIR_LIB_SOURCE_H_


#include <set>
#include <vector>

#include <sch_lib.h>


/// This file extension is an implementation detail specific to this LIB_SOURCE
/// and to a corresponding LIB_SINK.
/// Core EESCHEMA should never have to see this.
#define SWEET_EXT       ".part"
#define SWEET_EXTZ      (sizeof(SWEET_EXT)-1)


/**
 * struct BY_REV
 * is here to provide a custom way to compare STRINGs.  Namely, the revN[N..]
 * string if present, is collated according to a 'higher revision first', but
 * any part string without a revision, is even 'before' that.
 */
struct BY_REV
{
    bool operator() ( const STRING& s1, const STRING& s2 ) const;
};


/**
 * Type PART_CACHE
 * holds a set of part names in sorted order, according to the sort
 * order given by struct BY_REV.
 */
typedef std::set< STRING, BY_REV >  PART_CACHE;


/**
 * Type NAME_CACHE
 * holds a set of categories in sorted order.
 */
typedef std::set< STRING >          NAME_CACHE;


namespace SCH {

/**
 * Class DIR_LIB_SOURCE
 * implements a LIB_SOURCE in a file system directory.
 *
 * @author Dick Hollenbeck
 */
class DIR_LIB_SOURCE : public LIB_SOURCE
{
    friend class LIB_TABLE;     ///< constructor is protected, LIB_TABLE can construct

    bool                useVersioning;  ///< use files with extension ".revNNN..", else not

    /// normal partnames, some of which may be prefixed with a category,
    /// and some of which may have legal "revN[N..]" type strings.
    PART_CACHE          partnames;

    typedef PART_CACHE::const_iterator PN_ITER;

    /// categories which we expect to find in the set of @a partnames
    NAME_CACHE          categories;

    std::vector<char>   readBuffer;     ///< used by readString()

    /**
     * Function cache
     * [re-]loads the directory cache(s).
     */
    void cache() throw( IO_ERROR );

    /**
     * Function isCategoryName
     * returns true iff aName is a valid category name.
     */
    bool isCategoryName( const char* aName )
    {
        return true;
    }

    /**
     * Function makePartName
     * returns true iff aEntry holds a valid part filename, in the form of
     * "someroot.part[.revNNNN]"  where NNN are number characters [0-9]
     * @param aEntry is the raw directory entry without path information.
     * @param aCategory is the last portion of the directory path.
     * @param aPartName is where to put a part name, assuming @a aEntry is legal.
     * @return bool - true only if aEntry is a legal part file name.
     */
    bool makePartName( STRING* aPartName, const char* aEntry, const STRING& aCategory );

    /**
     * Function readString
     * reads a Sweet string into aResult.  Candidate for virtual function later.
     */
    void readString( STRING* aResult, const STRING& aFileName ) throw( IO_ERROR );

    /**
     * Function cacheOneDir
     * loads part names [and categories] from a directory given by
     * "sourceURI + '/' + category"
     * Categories are only loaded if processing the top most directory because
     * only one level of categories is supported.  We know we are in the
     * top most directory if aCategory is empty.
     */
    void cacheOneDir( const STRING& aCategory ) throw( IO_ERROR );

    /**
     * Function makeFileName
     * converts a part name into a filename and returns it.
     */
    STRING makeFileName( const STRING& aPartName );

protected:

    /**
     * Constructor DIR_LIB_SOURCE( const STRING& aDirectoryPath )
     * sets up a LIB_SOURCE using aDirectoryPath in a file system.
     * @see LIB_TABLE::LookupPart().
     *
     * @param aDirectoryPath is a full file pathname of a directory which contains
     *  the library source of part files.  Examples might be "C:\kicad_data\mylib" or
     *  "/home/designer/mylibdir".  This is not a URI, but an OS specific path that
     *  can be given to opendir().
     *
     * @param aOptions is the options string from the library table, currently
     *  the only supported option, that this LIB_SOURCE knows about is
     *  "useVersioning".  If present means support versioning in the directory
     *  tree, otherwise only a single version of each part is recognized, namely the
     *  one without the ".revN[N..]" trailer.
     */
    DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = "" ) throw( IO_ERROR );

    ~DIR_LIB_SOURCE();

    //-----<LIB_SOURCE implementation functions >------------------------------

    void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = "" )
        throw( IO_ERROR );

    void ReadParts( STRINGS* aResults, const STRINGS& aPartNames )
        throw( IO_ERROR );

    void GetCategories( STRINGS* aResults ) throw( IO_ERROR );

    void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory = "" )
        throw( IO_ERROR );

    void GetRevisions( STRINGS* aResults, const STRING& aPartName )
        throw( IO_ERROR );

    void FindParts( STRINGS* aResults, const STRING& aQuery ) throw( IO_ERROR )
    {
        // @todo
    }

    //-----</LIB_SOURCE implementation functions >------------------------------

#if defined(DEBUG)
    /**
     * Function Show
     * will output a debug dump of contents.
     */
    void Show();

public:
    static void Test( int argc, char** argv );

#endif
};

}       // namespace SCH

#endif  // DIR_LIB_SOURCE_H_