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

Last change on this file since 205 was 205, checked in by dkearney, 19 years ago

added isvalid function, but it doesnt work yet.
tested copying from one library to another
changed package name to RapptureLibrary?
adjusted related make and configure files

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