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

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

fixes for tcl bindings.

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