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

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

Added putFile capability to octave, matlab, fortran, perl bindings
Adjusted the core putFile function and all put functions to accept unsigned ints
added enum flags for binary and text file for the putFile function in c/c++

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_TEXT          = 0,
23    RPLIB_BINARY        = 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 "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 fileType = RPLIB_BINARY,
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.