source: trunk/include/core/RpLibrary.h @ 77

Last change on this file since 77 was 77, checked in by dkearney, 15 years ago
  1. initial checkin of RpLibrary? code, includes c++/c/fortran bindings
  2. minor modifications to makefiles to accommodate new code
  3. updated README in src to tell how to compile code in src and test
File size: 12.0 KB
Line 
1
2#include "scew.h"
3#include "scew_extras.h"
4#include <iostream>
5#include <string>
6#include <sstream>
7#include <stdlib.h>
8#include <errno.h>
9
10/* indentation size (in whitespaces) */
11#define INDENT_SIZE 4
12
13#ifndef _RpLIBRARY_H
14#define _RpLIBRARY_H
15
16class RpLibrary
17{
18    public:
19       
20        // users member fxns
21
22        RpLibrary* element (std::string path = "", std::string as = "object");
23        // should return RpObject& but for simplicity right now it doesnt
24        // RpObject will either be an Array, RpString, RpNumber ...
25        /*
26        RpLibrary** children (  std::string path = "",
27                                std::string as = "object",
28                                std::string type = ""   );
29        */
30
31        RpLibrary*  children (  std::string path = "",
32                                RpLibrary* rpChildNode = NULL,
33                                std::string type = "",
34                                int* childCount = NULL  );
35
36        RpLibrary*  get (std::string path = "");
37        std::string getString (std::string path = "");
38        double      getDouble (std::string path = "");
39
40        RpLibrary& put (    std::string path,
41                            std::string value,
42                            std::string id = "",
43                            int append = 0  );
44       
45        RpLibrary& put (    std::string path,
46                            double value,
47                            std::string id = "",
48                            int append = 0  );
49
50        RpLibrary& remove (std::string path = "");
51
52        std::string xml();
53
54        std::string nodeType();
55        std::string nodeId();
56        std::string nodeComp();
57       
58        const char* nodeTypeC();
59        const char* nodeIdC();
60        const char* nodeCompC();
61
62        // no arg constructor
63        // used when we dont want to read an xml file to populate the xml tree
64        // we are building a new xml structure
65        RpLibrary ()
66            :   parser      (NULL),
67                tree        (NULL),
68                root        (NULL)
69                   
70        {
71            tree = scew_tree_create();
72            freeTree = 1;
73            root = scew_tree_add_root(tree, "run");
74        }
75
76        RpLibrary (
77                    std::string filePath
78                )
79            :   parser      (NULL),
80                tree        (NULL),
81                root        (NULL)
82        {
83           
84            if (filePath.length() != 0) {
85                // file path should not be null or empty string unless we are
86                // creating a new xml file
87
88                parser = scew_parser_create();
89
90                scew_parser_ignore_whitespaces(parser, 1);
91
92                /* Loads an XML file */
93                if (!scew_parser_load_file(parser, filePath.c_str()))
94                {
95                    scew_error code = scew_error_code();
96                    printf("Unable to load file (error #%d: %s)\n", code,
97                           scew_error_string(code));
98
99                    /*
100                    std::cout << "Unable to load file (error #" \
101                              << code << ": " << scew_error_string(code) \
102                              << ")\n" << std::endl;
103                    */
104
105                    if (code == scew_error_expat)
106                    {
107                        enum XML_Error expat_code =
108                            scew_error_expat_code(parser);
109                        printf("Expat error #%d (line %d, column %d): %s\n",
110                               expat_code,
111                               scew_error_expat_line(parser),
112                               scew_error_expat_column(parser),
113                               scew_error_expat_string(expat_code));
114                    }
115                    // should probably exit program or something
116                    // return EXIT_FAILURE;
117                   
118                }
119
120                tree = scew_parser_tree(parser);
121                freeTree = 0;
122                root = scew_tree_root(tree);
123            }
124            else {
125                // create a new xml (from an empty file)
126            }
127        }
128
129       
130        // copy constructor
131        // for some reason making this a const gives me problems when calling xml()
132        // need help looking into this
133        // RpLibrary ( const RpLibrary& other )
134        RpLibrary ( RpLibrary& other )
135            : parser    (NULL),
136              tree      (NULL),
137              root      (NULL)
138        {
139            std::string buffer;
140            int buffLen;
141
142            // fill in the current RpLibrary's data with other's data
143            parser = scew_parser_create();
144            scew_parser_ignore_whitespaces(parser, 1);
145
146            // Loads the XML from other
147            // the length cannot be 0 because xml() should not be returning
148            // empty strings
149            buffer = other.xml();
150            buffLen = buffer.length();
151           
152            if (buffLen > 0) {
153                if (!scew_parser_load_buffer(parser,buffer.c_str(),buffLen))
154                {
155                    // there was an error loading the buffer
156                    // how do you tell the user, you couldn't make a copy?
157                    scew_error code = scew_error_code();
158                    printf("Unable to load buffer (error #%d: %s)\n", code,
159                           scew_error_string(code));
160
161                    if (code == scew_error_expat)
162                    {
163                        enum XML_Error expat_code =
164                            scew_error_expat_code(parser);
165                        printf("Expat error #%d (line %d, column %d): %s\n",
166                               expat_code,
167                               scew_error_expat_line(parser),
168                               scew_error_expat_column(parser),
169                               scew_error_expat_string(expat_code));
170                    }
171
172                    // return an empty RpLibrary?
173                    // return EXIT_FAILURE;
174                   
175                    parser = NULL;
176                }
177                else {
178
179                    // parsing the buffer was successful
180                    // populate the new data members.
181
182                    tree = scew_parser_tree(parser);
183                    freeTree = 0;
184                    root = scew_tree_root(tree);
185
186                }
187
188            } // end if (buffer.length() != 0) {
189        }// end copy constructor
190
191        // for some reason making this a const gives me problems when calling xml()
192        // need help looking into this
193        // RpLibrary& operator= (const RpLibrary& other) {
194        RpLibrary& operator= (RpLibrary& other) {
195
196            std::string buffer;
197            int buffLen;
198
199            scew_parser* tmp_parser;
200            scew_tree* tmp_tree;
201            scew_element* tmp_root;
202            int tmp_freeTree;
203
204            if (this != &other) {
205
206                tmp_parser   = parser;
207                tmp_tree     = tree;
208                tmp_root     = root;
209                tmp_freeTree = freeTree;
210
211                // fill in the current RpLibrary's data with other's data
212                parser = scew_parser_create();
213                scew_parser_ignore_whitespaces(parser, 1);
214
215                // Loads the XML from other
216                // the length cannot be 0 because xml() should not be returning
217                // empty strings
218                buffer = other.xml();
219                buffLen = buffer.length();
220               
221                if (buffLen > 0) {
222                    if (!scew_parser_load_buffer(parser,buffer.c_str(),buffLen))
223                    {
224                        // there was an error loading the buffer
225                        // how do you tell the user, you couldn't make a copy?
226                        scew_error code = scew_error_code();
227                        printf("Unable to load buffer (error #%d: %s)\n", code,
228                               scew_error_string(code));
229
230                        if (code == scew_error_expat)
231                        {
232                            enum XML_Error expat_code =
233                                scew_error_expat_code(parser);
234                            printf("Expat error #%d (line %d, column %d): %s\n",
235                                   expat_code,
236                                   scew_error_expat_line(parser),
237                                   scew_error_expat_column(parser),
238                                   scew_error_expat_string(expat_code));
239                        }
240
241                        // return things back to the way they used to be
242                        // or maybe return an empty RpLibrary?
243                        // return EXIT_FAILURE;
244                       
245                        // return this object to its previous state.
246                        parser = tmp_parser;
247                    }
248                    else {
249
250                        // parsing the buffer was successful
251                        // populate the new data members.
252
253                        tree = scew_parser_tree(parser);
254                        freeTree = 0;
255                        root = scew_tree_root(tree);
256
257                        // free the current RpLibrary's data
258                        // we do the free so far down so we can see if
259                        // parsing the other object's xml fails.
260                        // if the parsing fails, we can still return this
261                        // object to its previous state.
262                        if (tmp_tree && tmp_freeTree) {
263                            scew_tree_free(tmp_tree);
264                            tmp_tree = NULL;
265                        }
266                        if (tmp_parser) {
267                            scew_parser_free(tmp_parser);
268                            tmp_parser = NULL;
269                        }
270                        if (tmp_root) {
271                            tmp_root = NULL;
272                        }
273                    }
274
275                } // end if (buffer.length() != 0) {
276            } // end if (this != &other)
277
278            return *this;
279        } // end operator=
280               
281
282        // default destructor
283        virtual ~RpLibrary ()
284        {
285            // clean up dynamic memory
286
287            if (tree && freeTree) {
288                scew_tree_free(tree);
289                tree = NULL;
290            }
291            if (parser) {
292                scew_parser_free(parser);
293                parser = NULL;
294            }
295            if (root) {
296                // scew_element_free(root);
297                root = NULL;
298            }
299        }
300
301    private:
302
303        scew_parser* parser;
304        scew_tree* tree;
305        scew_element* root;
306       
307        // flag to tell if we are responsible for calling scew_tree_free
308        // on the tree structure. if we get our tree by using the scew_tree_create
309        // fxn, we need to free it. if we get our tree using the scew_parser_tree
310        // fxn, then it will be free'd when the parser is free'd.
311        int freeTree;
312
313
314        RpLibrary ( scew_element* node)
315            :   parser      (NULL),
316                tree        (NULL),
317                root        (node)
318                   
319        {}
320
321
322        std::string _get_attribute(scew_element* element, std::string attributeName);
323        int _path2list (std::string& path, std::string** list, int listLen);
324        std::string _node2name (scew_element* node);
325        std::string _node2comp (scew_element* node);
326        int _splitPath (std::string& path,
327                        std::string& tagName,
328                        int* idx,
329                        std::string& id );
330        scew_element* _find (std::string path, int create);
331        void print_indent (unsigned int indent, std::stringstream& outString);
332        void print_attributes (scew_element* element, std::stringstream& outString);
333        void print_element( scew_element* element,
334                            unsigned int indent,
335                            std::stringstream& outString    );
336
337
338};
339
340/*--------------------------------------------------------------------------*/
341/*--------------------------------------------------------------------------*/
342
343#endif
Note: See TracBrowser for help on using the repository browser.