source: trunk/SECEDIT/SEC_toggle.cxx

Last change on this file was 16763, checked in by westram, 7 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1// ================================================================= //
2//                                                                   //
3//   File      : SEC_toggle.cxx                                      //
4//   Purpose   :                                                     //
5//                                                                   //
6//   Coded by Ralf Westram (coder@reallysoft.de) in September 2007   //
7//   Institute of Microbiology (Technical University Munich)         //
8//   http://www.arb-home.de/                                         //
9//                                                                   //
10// ================================================================= //
11
12#include "SEC_toggle.hxx"
13#include "SEC_graphic.hxx"
14#include "SEC_defs.hxx"
15
16#include <arbdbt.h>
17
18#include <climits>
19
20
21using namespace std;
22
23GB_ERROR SEC_structure_toggler::store(GBDATA *gb_struct) {
24    char     *data    = NULp;
25    char     *xstring = NULp;
26    GB_ERROR  error   = gfx->read_data_from_db(&data, &xstring);
27
28    if (!error) error = GBT_write_string(gb_struct, "data", data);
29    if (!error) error = GBT_write_string(gb_struct, "ref", xstring);
30
31    free(xstring);
32    free(data);
33
34    return error;
35}
36
37GB_ERROR SEC_structure_toggler::restore(GBDATA *gb_struct) {
38    char     *data    = NULp;
39    char     *xstring = NULp;
40    GB_ERROR  error   = NULp;
41
42    GBDATA *gb_data   = GB_search(gb_struct, "data", GB_FIND);
43    if (gb_data) data = GB_read_string(gb_data);
44    if (!data) error  = GB_await_error();
45
46    if (!error) {
47        GBDATA *gb_ref      = GB_search(gb_struct, "ref", GB_FIND);
48        if (gb_ref) xstring = GB_read_string(gb_ref);
49        if (!xstring) error = GB_await_error();
50    }
51
52    if (!error) {
53        sec_assert(data && xstring);
54        error = gfx->write_data_to_db(data, xstring);
55    }
56
57    free(xstring);
58    free(data);
59    return error;
60}
61
62int SEC_structure_toggler::current() {
63    return *GBT_read_int(gb_structures, "current");
64}
65
66GB_ERROR SEC_structure_toggler::set_current(int idx) {
67    GBDATA   *gb_num = GB_search(gb_structures, "current", GB_INT);
68    GB_ERROR  error;
69
70    if (!gb_num) error = GB_await_error();
71    else {
72        sec_assert(find(idx));                      // oops - nonexisting container
73        error = GB_write_int(gb_num, idx);
74    }
75    return error;
76}
77
78GBDATA *SEC_structure_toggler::find(int num) {
79    int     cnt      = 0;
80    GBDATA *gb_found = GB_entry(gb_structures, "struct");
81    while (gb_found && num>0) {
82        cnt++;
83        num--;
84        gb_found = GB_nextEntry(gb_found);
85    }
86    if (!gb_found) Count = cnt;  // seen all -> set count
87    return gb_found;
88}
89
90GBDATA *SEC_structure_toggler::create(const char *structure_name) {
91    sec_assert(!st_error);
92    if (st_error) return NULp;
93
94    GBDATA *gb_new        = GB_create_container(gb_structures, "struct");
95    if (!gb_new) st_error = GB_await_error();
96    else {
97        st_error = setName(gb_new, structure_name);
98
99        if (!st_error) st_error = store(gb_new);
100        if (!st_error) st_error = set_current(Count);
101        if (!st_error) {
102            gb_current = gb_new;
103            sec_assert(find(current()) == gb_current);
104            Count++;
105        }
106    }
107
108    return gb_new;
109}
110
111// --------------------------------------------------------------------------------
112// public
113
114SEC_structure_toggler::SEC_structure_toggler(GBDATA *gb_main, const char *ali_name, SEC_graphic *Gfx) :
115    gfx(Gfx),
116    st_error(NULp),
117    Count(0)
118{
119    GB_transaction ta(gb_main);
120    gb_structures = GB_search(gb_main, GBS_global_string("secedit/structs/%s", ali_name), GB_CREATE_CONTAINER);
121    if (!gb_structures) {
122        st_error   = GB_await_error();
123        gb_current = NULp;
124    }
125    else {
126        find(INT_MAX); // sets Count
127        if (Count == 0) { // init
128            gb_current = create(ali_name);
129            st_error   = set_current(0);
130        }
131        else {
132            int curr = current();
133            if (curr<Count) {
134                gb_current = find(current());
135            }
136            else { // wrong -> reset
137                st_error   = set_current(0);
138                gb_current = find(0);
139            }
140        }
141        sec_assert(gb_current);
142    }
143}
144
145GB_ERROR SEC_structure_toggler::next() {
146    GB_ERROR       error = NULp;
147    GB_transaction ta(gb_structures);
148
149    if (Count<2) {
150        error = "No other structure in DB";
151    }
152    else {
153        int nextNum = current()+1;
154        if (nextNum >= Count) nextNum = 0;
155
156        sec_assert(find(current()) == gb_current);
157
158        error             = store(gb_current);
159        if (!error) error = set_current(nextNum);
160        if (!error) {
161            gb_current = find(nextNum);
162            if (!gb_current) {
163                error = GBS_global_string("Failed to find structure #%i", nextNum);
164            }
165            else {
166                error = restore(gb_current);
167            }
168        }
169    }
170    return ta.close(error);
171}
172
173GB_ERROR SEC_structure_toggler::copyTo(const char *structure_name) {
174    GB_transaction ta(gb_structures);
175
176    sec_assert(find(current()) == gb_current);
177
178    GB_ERROR error = store(gb_current);
179    if (!error) {
180        GBDATA *gb_new = create(structure_name);
181        if (!gb_new) {
182            sec_assert(st_error);
183            error = st_error;
184        }
185        else {
186            gb_current = gb_new;
187        }
188    }
189    sec_assert(error || (find(current()) == gb_current));
190    return ta.close(error);
191}
192
193GB_ERROR SEC_structure_toggler::remove() {
194    GB_transaction ta(gb_structures);
195
196    sec_assert(Count > 1);
197
198    GBDATA   *gb_del = gb_current;
199    int       del    = current();
200    GB_ERROR  error  = next();
201
202    if (!error) {
203        int curr = current();
204        error    = GB_delete(gb_del);
205        if (!error) {
206            Count--;
207            if (curr >= del) error = set_current(curr-1);
208        }
209    }
210    return ta.close(error);
211}
212
213const char *SEC_structure_toggler::name() {
214    const char     *structure_name = NULp;
215    GB_transaction  ta(gb_structures);
216
217    GBDATA *gb_name               = GB_search(gb_current, "name", GB_FIND);
218    if (gb_name) structure_name   = GB_read_char_pntr(gb_name);
219    if (!structure_name) st_error = GB_await_error();
220
221    st_error = ta.close(st_error);
222    return structure_name;
223}
224
225GB_ERROR SEC_structure_toggler::setName(GBDATA *gb_struct, const char *new_name) {
226    return GBT_write_string(gb_struct, "name", new_name);
227}
228
229GB_ERROR SEC_structure_toggler::setName(const char *new_name) {
230    GB_transaction ta(gb_structures);
231    GB_ERROR       error = setName(gb_current, new_name);
232    return ta.close(error);
233}
234
Note: See TracBrowser for help on using the repository browser.