source: trunk/src/core/RpLibrary.h @ 597

Last change on this file since 597 was 597, checked in by dkearney, 14 years ago

adjusted core makefile to not remove setup.py when doing a make clean
adjusted putFile and putData commands and flags in matlab, octave,fortran,perl
changed the RPLIB_[TEXT,BINARY] flags to RPLIB_COMPRESS and RPLIB_NO_COMPRESS flags
adjusted the c-example for compress to incorporate newly named flags.
adjusted rappture library header to find rappture buffer header files in rappture2 directory.

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