source: trunk/src/objects/RpObject.cc @ 1581

Last change on this file since 1581 was 1581, checked in by dkearney, 11 years ago

updates for the rappture objects, object examples, and object apis. small fix for rpunits c interface to check string length. there should probably be more of these checks in the c interface, but units should also be rewritten. added folders to separate out octave2 and octave3 app-fermi examples

File size: 10.4 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  RpObject.cc
4 *
5 *   Rappture 2.0 Object member functions
6 *
7 * ======================================================================
8 *  AUTHOR:  Derrick Kearney, Purdue University
9 *  Copyright (c) 2005-2009  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15
16#include "RpObject.h"
17#include "RpHashHelper.h"
18#include <cstring>
19
20using namespace Rappture;
21
22Object::Object()
23{
24    __init();
25}
26
27Object::Object (
28    const char *name,
29    const char *path,
30    const char *label,
31    const char *desc,
32    const char *hints,
33    const char *color   )
34{
35    this->name(name);
36    this->path(path);
37    this->label(label);
38    this->desc(desc);
39    this->hints(hints);
40    this->color(color);
41}
42
43Object::Object(const Object& o)
44{
45    name(o.name());
46    path(o.path());
47    label(o.label());
48    desc(o.desc());
49    hints(o.hints());
50    color(o.color());
51    // icon(o.icon());
52
53    if (o._h != NULL) {
54        Rp_HashCopy(_h,o._h,charCpyFxn);
55    }
56}
57
58Object::~Object()
59{
60    __clear();
61}
62
63const char*
64Object::name() const
65{
66    return propstr("name");
67}
68
69void
70Object::name(const char *p)
71{
72    propstr("name",p);
73}
74
75const char*
76Object::path() const
77{
78    return propstr("path");
79}
80
81void
82Object::path(const char *p)
83{
84    propstr("path",p);
85}
86
87const char*
88Object::label() const
89{
90    return propstr("label");
91}
92
93void
94Object::label(
95    const char *p)
96{
97    propstr("label",p);
98}
99
100const char*
101Object::desc() const
102{
103    return propstr("desc");
104}
105
106void
107Object::desc(const char *p)
108{
109    propstr("desc",p);
110}
111
112const char*
113Object::hints() const
114{
115    return propstr("hints");
116}
117
118void
119Object::hints(const char *p)
120{
121    propstr("hints",p);
122}
123
124const char*
125Object::color() const
126{
127    return propstr("color");
128}
129
130void
131Object::color(const char *p)
132{
133    propstr("color",p);
134}
135
136// get a general property
137const void *
138Object::property(const char *key) const
139{
140    if (key == NULL) {
141        // no key to search for
142        return NULL;
143    }
144
145    if (_h == NULL) {
146        // hash table does not exist, value is not in table
147        return NULL;
148    }
149
150    // get the value
151    return Rp_HashSearchNode(_h,key);
152}
153
154// set a general property
155void
156Object::property(const char *key, const void *val, size_t nbytes)
157{
158    if (key == NULL) {
159        // no key for value
160        return;
161    }
162
163    if (_h == NULL) {
164        // hash table does not exist, create it
165        _h = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
166        Rp_InitHashTable(_h,RP_STRING_KEYS);
167    }
168
169    // FIXME: this is suspect,
170    // want to use void's and void*'s but c++ wont let me
171    // g++ says there is no delete[] for void*
172    void *tmp = new char[nbytes];
173    memcpy(tmp,val,nbytes);
174
175    // set the value
176    char *old = (char *) Rp_HashRemoveNode(_h,key);
177    delete[] old;
178    old = NULL;
179    Rp_HashAddNode(_h,key,tmp);
180
181    return;
182}
183
184// get a const char* property
185const char *
186Object::propstr(const char *key) const
187{
188    if (key == NULL) {
189        // no key for value
190        return NULL;
191    }
192
193    if (_h == NULL) {
194        // hash table does not exist, value does not exist in table
195        return NULL;
196    }
197
198    // get the value
199    return (const char *) Rp_HashSearchNode(_h,key);
200}
201
202// set a const char* property
203void
204Object::propstr(const char *key, const char *val)
205{
206    char *str = NULL;
207
208    if (key == NULL) {
209        // no key for value
210        return;
211    }
212
213    if (_h == NULL) {
214        // hash table does not exist, create it
215        _h = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
216        Rp_InitHashTable(_h,RP_STRING_KEYS);
217    }
218
219    if (val == NULL) {
220        // no value provided, no value stored.
221        // FIXME: raise error.
222        return;
223    }
224
225    // set the value
226    // FIXME: this is suspect,
227    // want to use void's and void*'s but c++ wont let me
228    // g++ says there is no delete[] for void*
229    // FIXME: can probably just get the length and use property() fxn
230    size_t l = strlen(val);
231    str = new char[l+1];
232    strcpy(str,val);
233
234    char *old = (char *) Rp_HashRemoveNode(_h,key);
235    delete[] old;
236    old = NULL;
237    Rp_HashAddNode(_h,key,str);
238
239    return;
240}
241
242// remove a property from the hash table
243void
244Object::propremove(const char *key)
245{
246    if ((key == NULL) || (_h == NULL)) {
247        // key or hash table does not exist
248        return;
249    }
250
251    char *tmp = (char *) Rp_HashRemoveNode(_h,key);
252    delete[] tmp;
253    tmp = NULL;
254    return;
255}
256
257void
258Object::__hintParser(
259    char *hint,
260    const char **hintKey,
261    const char **hintVal) const
262{
263
264    // hints are null terminated strings with a hint key
265    // and hint value separated by an equal sign.
266    // they take the following form:
267    // hintKey=hintVal
268    // this function does change the original hint string.
269
270    char *v = NULL;
271
272    if (hint == NULL) {
273        return;
274    }
275
276    v = strchrnul(hint,'=');
277    *hintKey = hint;
278    if ((*v == '\0') || (*(v+1) == '\0')) {
279        // incomplete hint string
280        *hintVal = NULL;
281    } else {
282        *v = '\0';
283        *hintVal = v+1;
284    }
285
286    return;
287}
288
289void
290Object::vvalue(void *storage, size_t numHints, va_list arg) const
291{
292    // bland objects take no hints
293    char buf[1024];
294    char *hintCopy = NULL;
295    size_t hintLen = 0;
296
297    char *hint = NULL;
298    const char *hintKey = NULL;
299    const char *hintVal = NULL;
300
301    while (numHints > 0) {
302        numHints--;
303        hint = va_arg(arg, char *);
304        hintLen = strlen(hint);
305        if (hintLen < 1024) {
306            hintCopy = buf;
307        } else {
308            hintCopy = new char[hintLen+1];
309        }
310        strcpy(hintCopy,hint);
311        __hintParser(hintCopy,&hintKey,&hintVal);
312        if (hintCopy != buf) {
313            delete hintCopy;
314        }
315    }
316    return;
317}
318
319void
320Object::__init()
321{
322    _h = NULL;
323    label("");
324    desc("");
325    hints("");
326    color("");
327    // icon(NULL);
328    path("");
329
330    _tmpBuf.clear();
331
332    _h = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
333    Rp_InitHashTable(_h,RP_STRING_KEYS);
334}
335
336void
337Object::__clear()
338{
339    _tmpBuf.clear();
340
341    // traverse the hash table to delete values, then delete hash table
342    if (_h != NULL) {
343        Rp_HashEntry *hEntry = NULL;
344        Rp_HashSearch hSearch;
345
346        hEntry = Rp_FirstHashEntry(_h,&hSearch);
347        while (hEntry != NULL) {
348            // FIXME: this is suspect,
349            // want to use void's and void*'s but c++ wont let me
350            // g++ says there is no delete[] for void*
351            char *v = (char *) Rp_GetHashValue(hEntry);
352            delete[] v;
353            v = NULL;
354            hEntry = Rp_NextHashEntry(&hSearch);
355        }
356
357        Rp_DeleteHashTable(_h);
358        _h = NULL;
359    }
360}
361
362/*
363const char *
364Object::xml(size_t indent, size_t tabstop) const
365{
366    return NULL;
367}
368*/
369
370/*
371void
372Object::xml(const char *xmltext)
373{
374    return;
375}
376*/
377
378/**********************************************************************/
379// METHOD: configure(ClientData c)
380/// construct an object from the provided tree
381/**
382 * construct an object from the provided tree
383 */
384
385void
386Object::configure(size_t as, ClientData c)
387{
388    if (as == RPCONFIG_XML) {
389        __configureFromXml(c);
390    } else if (as == RPCONFIG_TREE) {
391        __configureFromTree(c);
392    }
393}
394
395/**********************************************************************/
396// METHOD: configureFromXml(const char *xmltext)
397/// configure the object based on Rappture1.1 xmltext
398/**
399 * Configure the object based on the provided xml
400 */
401
402void
403Object::__configureFromXml(ClientData c)
404{
405    const char *xmltext = (const char *)c;
406    if (xmltext == NULL) {
407        // FIXME: setup error
408        return;
409    }
410
411    Rp_ParserXml *p = Rp_ParserXmlCreate();
412    Rp_ParserXmlParse(p, xmltext);
413    __configureFromTree(p);
414
415    return;
416}
417
418void
419Object::__configureFromTree(ClientData c)
420{
421    Rp_ParserXml *p = (Rp_ParserXml *)c;
422    if (p == NULL) {
423        // FIXME: setup error
424        return;
425    }
426
427    Rp_TreeNode node = Rp_ParserXmlElement(p,NULL);
428
429    Rappture::Path pathObj(Rp_ParserXmlNodePath(p,node));
430
431    path(pathObj.parent());
432    name(Rp_ParserXmlNodeId(p,node));
433
434    pathObj.clear();
435    pathObj.add("about");
436    pathObj.add("label");
437    label(Rp_ParserXmlGet(p,pathObj.path()));
438    pathObj.type("description");
439    desc(Rp_ParserXmlGet(p,pathObj.path()));
440    pathObj.type("hints");
441    hints(Rp_ParserXmlGet(p,pathObj.path()));
442    pathObj.type("color");
443    color(Rp_ParserXmlGet(p,pathObj.path()));
444
445    return;
446}
447
448/**********************************************************************/
449// METHOD: dump(size_t as, void *p)
450/// construct a number object from the provided tree
451/**
452 * construct a number object from the provided tree
453 */
454
455void
456Object::dump(size_t as, ClientData p)
457{
458    if (as == RPCONFIG_XML) {
459        __dumpToXml(p);
460    } else if (as == RPCONFIG_TREE) {
461        __dumpToTree(p);
462    }
463}
464
465/**********************************************************************/
466// METHOD: dumpToXml(ClientData p)
467/// configure the object based on Rappture1.1 xmltext
468/**
469 * Configure the object based on the provided xml
470 */
471
472void
473Object::__dumpToXml(ClientData c)
474{
475    if (c == NULL) {
476        // FIXME: setup error
477        return;
478    }
479
480    ClientDataXml *d = (ClientDataXml *)c;
481    Rp_ParserXml *parser = Rp_ParserXmlCreate();
482    __dumpToTree(parser);
483    _tmpBuf.appendf("%s",Rp_ParserXmlXml(parser));
484    d->retStr = _tmpBuf.bytes();
485    Rp_ParserXmlDestroy(&parser);
486}
487
488/**********************************************************************/
489// METHOD: dumpToTree(ClientData p)
490/// dump the object to a Rappture1.1 based tree
491/**
492 * Dump the object to a Rappture1.1 based tree
493 */
494
495void
496Object::__dumpToTree(ClientData c)
497{
498    if (c == NULL) {
499        // FIXME: setup error
500        return;
501    }
502
503    Rp_ParserXml *parser = (Rp_ParserXml *)c;
504
505    Path p;
506
507    p.parent(path());
508    p.last();
509
510    p.add("object");
511    p.id(name());
512
513    p.add("about");
514
515    p.add("label");
516    Rp_ParserXmlPutF(parser,p.path(),"%s",label());
517
518    p.type("description");
519    Rp_ParserXmlPutF(parser,p.path(),"%s",desc());
520
521    p.type("hints");
522    Rp_ParserXmlPutF(parser,p.path(),"%s", hints());
523
524    p.type("color");
525    Rp_ParserXmlPutF(parser,p.path(),"%s", color());
526
527    return;
528}
529
530Outcome &
531Object::outcome() const
532{
533    return _status;
534}
535
536const int
537Object::is() const
538{
539    // return "var" in hex
540    return 0x766172;
541}
542
543// -------------------------------------------------------------------- //
544
Note: See TracBrowser for help on using the repository browser.