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

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

updating potential apis for c cpp and python. adding random() and diff()
functions to the rappture objects. objects should be able to generate a random
value for itself based on how it was configured. objects should be able to
compare itself with another object and tell us what the differences are.

File size: 10.6 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::random()
321{
322    // bland objects cannot make random values
323    return;
324}
325
326Rp_Chain *
327Object::diff(const Object &o)
328{
329    return NULL;
330}
331
332void
333Object::__init()
334{
335    _h = NULL;
336    label("");
337    desc("");
338    hints("");
339    color("");
340    // icon(NULL);
341    path("");
342
343    _tmpBuf.clear();
344
345    _h = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
346    Rp_InitHashTable(_h,RP_STRING_KEYS);
347}
348
349void
350Object::__clear()
351{
352    _tmpBuf.clear();
353
354    // traverse the hash table to delete values, then delete hash table
355    if (_h != NULL) {
356        Rp_HashEntry *hEntry = NULL;
357        Rp_HashSearch hSearch;
358
359        hEntry = Rp_FirstHashEntry(_h,&hSearch);
360        while (hEntry != NULL) {
361            // FIXME: this is suspect,
362            // want to use void's and void*'s but c++ wont let me
363            // g++ says there is no delete[] for void*
364            char *v = (char *) Rp_GetHashValue(hEntry);
365            delete[] v;
366            v = NULL;
367            hEntry = Rp_NextHashEntry(&hSearch);
368        }
369
370        Rp_DeleteHashTable(_h);
371        _h = NULL;
372    }
373}
374
375/*
376const char *
377Object::xml(size_t indent, size_t tabstop) const
378{
379    return NULL;
380}
381*/
382
383/*
384void
385Object::xml(const char *xmltext)
386{
387    return;
388}
389*/
390
391/**********************************************************************/
392// METHOD: configure(ClientData c)
393/// construct an object from the provided tree
394/**
395 * construct an object from the provided tree
396 */
397
398void
399Object::configure(size_t as, ClientData c)
400{
401    if (as == RPCONFIG_XML) {
402        __configureFromXml(c);
403    } else if (as == RPCONFIG_TREE) {
404        __configureFromTree(c);
405    }
406}
407
408/**********************************************************************/
409// METHOD: configureFromXml(const char *xmltext)
410/// configure the object based on Rappture1.1 xmltext
411/**
412 * Configure the object based on the provided xml
413 */
414
415void
416Object::__configureFromXml(ClientData c)
417{
418    const char *xmltext = (const char *)c;
419    if (xmltext == NULL) {
420        // FIXME: setup error
421        return;
422    }
423
424    Rp_ParserXml *p = Rp_ParserXmlCreate();
425    Rp_ParserXmlParse(p, xmltext);
426    __configureFromTree(p);
427
428    return;
429}
430
431void
432Object::__configureFromTree(ClientData c)
433{
434    Rp_ParserXml *p = (Rp_ParserXml *)c;
435    if (p == NULL) {
436        // FIXME: setup error
437        return;
438    }
439
440    Rp_TreeNode node = Rp_ParserXmlElement(p,NULL);
441
442    Rappture::Path pathObj(Rp_ParserXmlNodePath(p,node));
443
444    path(pathObj.parent());
445    name(Rp_ParserXmlNodeId(p,node));
446
447    pathObj.clear();
448    pathObj.add("about");
449    pathObj.add("label");
450    label(Rp_ParserXmlGet(p,pathObj.path()));
451    pathObj.type("description");
452    desc(Rp_ParserXmlGet(p,pathObj.path()));
453    pathObj.type("hints");
454    hints(Rp_ParserXmlGet(p,pathObj.path()));
455    pathObj.type("color");
456    color(Rp_ParserXmlGet(p,pathObj.path()));
457
458    return;
459}
460
461/**********************************************************************/
462// METHOD: dump(size_t as, void *p)
463/// construct a number object from the provided tree
464/**
465 * construct a number object from the provided tree
466 */
467
468void
469Object::dump(size_t as, ClientData p)
470{
471    if (as == RPCONFIG_XML) {
472        __dumpToXml(p);
473    } else if (as == RPCONFIG_TREE) {
474        __dumpToTree(p);
475    }
476}
477
478/**********************************************************************/
479// METHOD: dumpToXml(ClientData p)
480/// configure the object based on Rappture1.1 xmltext
481/**
482 * Configure the object based on the provided xml
483 */
484
485void
486Object::__dumpToXml(ClientData c)
487{
488    if (c == NULL) {
489        // FIXME: setup error
490        return;
491    }
492
493    ClientDataXml *d = (ClientDataXml *)c;
494    Rp_ParserXml *parser = Rp_ParserXmlCreate();
495    __dumpToTree(parser);
496    _tmpBuf.appendf("%s",Rp_ParserXmlXml(parser));
497    d->retStr = _tmpBuf.bytes();
498    Rp_ParserXmlDestroy(&parser);
499}
500
501/**********************************************************************/
502// METHOD: dumpToTree(ClientData p)
503/// dump the object to a Rappture1.1 based tree
504/**
505 * Dump the object to a Rappture1.1 based tree
506 */
507
508void
509Object::__dumpToTree(ClientData c)
510{
511    if (c == NULL) {
512        // FIXME: setup error
513        return;
514    }
515
516    Rp_ParserXml *parser = (Rp_ParserXml *)c;
517
518    Path p;
519
520    p.parent(path());
521    p.last();
522
523    p.add("object");
524    p.id(name());
525
526    p.add("about");
527
528    p.add("label");
529    Rp_ParserXmlPutF(parser,p.path(),"%s",label());
530
531    p.type("description");
532    Rp_ParserXmlPutF(parser,p.path(),"%s",desc());
533
534    p.type("hints");
535    Rp_ParserXmlPutF(parser,p.path(),"%s", hints());
536
537    p.type("color");
538    Rp_ParserXmlPutF(parser,p.path(),"%s", color());
539
540    return;
541}
542
543Outcome &
544Object::outcome() const
545{
546    return _status;
547}
548
549const int
550Object::is() const
551{
552    // return "var" in hex
553    return 0x766172;
554}
555
556// -------------------------------------------------------------------- //
557
Note: See TracBrowser for help on using the repository browser.