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

Last change on this file since 1581 was 1581, checked in by dkearney, 15 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: 5.3 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture Library Storage Source
4 *
5 * ======================================================================
6 *  AUTHOR:  Derrick S. Kearney, Purdue University
7 *  Copyright (c) 2005-2009  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 "RpLibStorage.h"
15#include "RpHashHelper.h"
16
17#include <stdlib.h>
18
19using namespace Rappture;
20
21#define RP_LIBSTORE_FIND    0
22#define RP_LIBSTORE_REMOVE  1
23
24LibraryStorage::LibraryStorage ()
25{
26    _objList = NULL;
27    _objNameHash = NULL;
28
29    __libStoreInit();
30}
31
32LibraryStorage::~LibraryStorage ()
33{
34    __libStoreFree();
35
36    _objList = NULL;
37    _objNameHash = NULL;
38}
39
40void
41LibraryStorage::__libStoreInit()
42{
43    _status.addContext("Rappture::LibraryStorage::__libStoreInit");
44
45    _objList = Rp_ChainCreate();
46    if (_objList == NULL) {
47        _status.addError("Error while allocating space for list");
48    }
49
50    _objNameHash = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
51    if (_objNameHash == NULL) {
52        _status.addError("Error while allocating space for hash table");
53    } else {
54        Rp_InitHashTable(_objNameHash,RP_STRING_KEYS);
55    }
56
57    return;
58}
59
60void
61LibraryStorage::__libStoreFree()
62{
63    _status.addContext("Rappture::LibraryStorage::__libStoreFree");
64
65    if (_objList != NULL) {
66        Rp_ChainLink *l = NULL;
67        Rappture::Object *objVal = NULL;
68        l = Rp_ChainFirstLink(_objList);
69        while(l) {
70            objVal = (Rappture::Object *) Rp_ChainGetValue(l);
71            delete objVal;
72            objVal = NULL;;
73            l = Rp_ChainNextLink(l);
74        }
75        Rp_ChainDestroy(_objList);
76        _objList = NULL;
77    }
78
79    if (_objNameHash != NULL) {
80        // we dont need to delete the hash table entries because
81        // they point into the chain and the chain has already
82        // deleted the objects.
83
84        Rp_DeleteHashTable(_objNameHash);
85        free(_objNameHash);
86        _objNameHash = NULL;
87    }
88    return;
89}
90
91/*
92Outcome &
93LibraryStorage::backup ()
94{
95    _status.addContext("Rappture::LibraryStorage::backup");
96
97    return _status;
98}
99
100Outcome &
101LibraryStorage::restore ()
102{
103    _status.addContext("Rappture::LibraryStorage::restore");
104
105    return _status;
106}
107*/
108
109Outcome &
110LibraryStorage::store (const char *key, Rappture::Object *o)
111{
112    _status.addContext("Rappture::LibraryStorage::store");
113
114    if (key == NULL) {
115        return _status;
116    }
117
118    if (o == NULL) {
119        return _status;
120    }
121
122    Rp_ChainLink *l = Rp_ChainAppend(_objList, (ClientData)o);
123    if (l == NULL) {
124        _status.addError("Error appending object to list");
125        return _status;
126    }
127
128    Rp_HashAddNode(_objNameHash, key, (ClientData)l);
129
130    return _status;
131}
132
133Outcome &
134LibraryStorage::link (const char *oldkey, const char *newkey)
135{
136    _status.addContext("Rappture::LibraryStorage::link");
137
138    if (oldkey == NULL) {
139        return _status;
140    }
141
142    if (newkey == NULL) {
143        return _status;
144    }
145
146    Rp_HashEntry *hEntry = Rp_FindHashEntry(_objNameHash,oldkey);
147    if (hEntry != NULL) {
148        Rp_ChainLink *l = (Rp_ChainLink *) Rp_GetHashValue(hEntry);
149        if (l != NULL) {
150            Rp_HashAddNode(_objNameHash, newkey, (ClientData)l);
151        }
152    }
153
154    return _status;
155}
156
157Rappture::Object *
158LibraryStorage::find (const char *key)
159{
160    _status.addContext("Rappture::LibraryStorage::find");
161    return __find(key,RP_LIBSTORE_FIND);
162}
163
164Rappture::Object *
165LibraryStorage::remove (const char *key)
166{
167    _status.addContext("Rappture::LibraryStorage::remove");
168    return __find(key,RP_LIBSTORE_REMOVE);
169}
170
171Rappture::Object *
172LibraryStorage::__find(const char *key, size_t flags)
173{
174    _status.addContext("Rappture::LibraryStorage::__find");
175
176    if (key == NULL) {
177        return NULL;
178    }
179
180    Rappture::Object *o = NULL;
181
182    Rp_HashEntry *hEntry = Rp_FindHashEntry(_objNameHash,key);
183    if (hEntry != NULL) {
184        Rp_ChainLink *l = (Rp_ChainLink *) Rp_GetHashValue(hEntry);
185        if (l != NULL) {
186            // chain link exists, try to return its data
187            o = (Rappture::Object *) Rp_ChainGetValue(l);
188            if (o == NULL) {
189                // invalid data in the chain, set remove flag
190                flags |= RP_LIBSTORE_REMOVE;
191            }
192
193            if (RP_LIBSTORE_REMOVE & flags) {
194                // remove flag set
195                // remove it from the chain and hash
196                Rp_ChainDeleteLink(_objList,l);
197                Rp_DeleteHashEntry(_objNameHash,hEntry);
198            }
199        } else {
200            // chain link does not exist, remove hash entry
201            Rp_DeleteHashEntry(_objNameHash,hEntry);
202        }
203    }
204
205    return o;
206}
207
208Outcome &
209LibraryStorage::outcome() const
210{
211    _status.addContext("Rappture::LibraryStorage::outcome");
212    return _status;
213}
214
215const Rp_Chain *
216LibraryStorage::contains() const
217{
218    _status.addContext("Rappture::LibraryStorage::contains");
219    //FIXME: run through hash table and remove invalid entries
220    //       and holes from list before sending it to user
221    return _objList;
222}
223
224Outcome &
225LibraryStorage::clear ()
226{
227    _status.addContext("Rappture::LibraryStorage::clear");
228    __libStoreFree();
229    __libStoreInit();
230    return _status;
231}
Note: See TracBrowser for help on using the repository browser.