Function ir_tcl_get_grs_r enhanced so that specific elements can be
[ir-tcl-moved-to-github.git] / grs.c
1 /*
2  * IR toolkit for tcl/tk
3  * (c) Index Data 1995
4  * See the file LICENSE for details.
5  * Sebastian Hammer, Adam Dickmeiss
6  *
7  * $Log: grs.c,v $
8  * Revision 1.4  1996-05-29 06:37:42  adam
9  * Function ir_tcl_get_grs_r enhanced so that specific elements can be
10  * extracted.
11  *
12  * Revision 1.3  1996/03/05 09:21:01  adam
13  * Bug fix: memory used by GRS records wasn't freed.
14  * Rewrote some of the error handling code - the connection is always
15  * closed before failback is called.
16  * If failback is defined the send APDU methods (init, search, ...) will
17  * return OK but invoke failback (as is the case if the write operation
18  * fails).
19  * Bug fix: ref_count in assoc object could grow if fraction of PDU was
20  * read.
21  *
22  * Revision 1.2  1995/09/20  11:37:01  adam
23  * Configure searches for tk4.1 and tk7.5.
24  * Work on GRS.
25  *
26  * Revision 1.1  1995/08/29  15:38:34  adam
27  * Added grs.c. new version.
28  *
29  */
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <assert.h>
35
36 #include "ir-tclp.h"
37
38 void ir_tcl_grs_del (IrTcl_GRS_Record **grs_record)
39 {
40     struct GRS_Record_entry *e;
41     int i;
42
43     while (!*grs_record)
44         return;
45     e = (*grs_record)->entries;
46     for (i = 0; i < (*grs_record)->noTags; i++, e++)
47     {
48         switch (e->tagType)
49         {
50         case Z_StringOrNumeric_numeric:
51             break;
52         default:
53             free (e->tagVal.str);
54         }
55         switch (e->dataWhich)
56         {
57         case Z_ElementData_octets:
58             free (e->tagData.octets.buf);
59             break;
60         case Z_ElementData_numeric:
61             break;
62         case Z_ElementData_date:
63             free (e->tagData.str);
64             break;            
65         case Z_ElementData_ext:
66             break;
67         case Z_ElementData_string:
68             free (e->tagData.str);
69             break;
70         case Z_ElementData_trueOrFalse:
71         case Z_ElementData_oid:
72         case Z_ElementData_intUnit:
73         case Z_ElementData_elementNotThere:
74         case Z_ElementData_elementEmpty:
75         case Z_ElementData_noDataRequested:
76         case Z_ElementData_diagnostic:
77             break;
78         case Z_ElementData_subtree:
79             ir_tcl_grs_del (&e->tagData.sub);
80             break;
81         }
82     }
83     free ((*grs_record)->entries);
84     free (*grs_record);
85     *grs_record = NULL;
86 }
87
88 void ir_tcl_grs_mk (Z_GenericRecord *r, IrTcl_GRS_Record **grs_record)
89 {
90     int i;
91     struct GRS_Record_entry *e;
92
93     *grs_record = NULL;
94     if (!r)
95         return;
96     *grs_record = ir_tcl_malloc (sizeof(**grs_record));
97     if (!((*grs_record)->noTags = r->num_elements))
98     {
99         (*grs_record)->entries = NULL;
100         return;
101     }
102     e = (*grs_record)->entries = ir_tcl_malloc (r->num_elements *
103                                                 sizeof(*e));
104     for (i = 0; i < r->num_elements; i++, e++)
105     {
106         Z_TaggedElement *t;
107
108         t = r->elements[i];
109         if (t->tagType)
110             e->tagType = *t->tagType;
111         else
112             e->tagType = 0;
113         e->tagWhich = t->tagValue->which;
114         if (t->tagValue->which == Z_StringOrNumeric_numeric)
115             e->tagVal.num = *t->tagValue->u.numeric;
116         else
117             ir_tcl_strdup (NULL, &e->tagVal.str, t->tagValue->u.string);
118         e->dataWhich = t->content->which;
119
120         switch (t->content->which)
121         {
122         case Z_ElementData_octets:
123             e->tagData.octets.len = t->content->u.octets->len;
124             e->tagData.octets.buf = ir_tcl_malloc (t->content->u.octets->len);
125             memcpy (e->tagData.octets.buf, t->content->u.octets->buf, 
126                     t->content->u.octets->len);
127             break;
128         case Z_ElementData_numeric:
129             e->tagData.num = *t->content->u.numeric;
130             break;
131         case Z_ElementData_date:
132             ir_tcl_strdup (NULL, &e->tagData.str, t->content->u.string);
133             break;            
134         case Z_ElementData_ext:
135             break;
136         case Z_ElementData_string:
137             ir_tcl_strdup (NULL, &e->tagData.str, t->content->u.string);
138             break;
139         case Z_ElementData_trueOrFalse:
140             e->tagData.bool = *t->content->u.trueOrFalse;
141             break;
142         case Z_ElementData_oid:
143             break;
144         case Z_ElementData_intUnit:
145             break;
146         case Z_ElementData_elementNotThere:
147         case Z_ElementData_elementEmpty:
148         case Z_ElementData_noDataRequested:
149             break;
150         case Z_ElementData_diagnostic:
151             break;
152         case Z_ElementData_subtree:
153             ir_tcl_grs_mk (t->content->u.subtree, &e->tagData.sub);
154             break;
155         }
156     }
157 }
158
159 static int ir_tcl_get_grs_r (Tcl_Interp *interp, IrTcl_GRS_Record *grs_record,
160                              int argc, char **argv, int argno)
161 {
162     static char tmpbuf[32];
163     int i;
164     struct GRS_Record_entry *e = grs_record->entries;
165
166     for (i = 0; i<grs_record->noTags; i++, e++)
167     {
168         int yes = 0;
169         if (argno >= argc)
170             yes = 1;
171         else
172         {
173             const char *cp0 = argv[argno];
174             const char *cp1 = strchr (cp0, '.');
175
176             if (!cp1 || cp1-cp0 < 1)
177                 yes = 1;
178             else
179             {
180                 if (atoi(cp0) == e->tagType) 
181                 {
182                     if (e->tagWhich == Z_StringOrNumeric_numeric)
183                     {
184                         if (atoi (cp1+1) == e->tagVal.num)
185                             yes = 1;
186                     }
187                     else
188                     {
189                         if (!strcmp (cp1+1, e->tagVal.str))
190                             yes = 1;
191                     }
192                 }
193             }
194         }
195         if (!yes)
196             continue;
197         Tcl_AppendResult (interp, "{ ", NULL);
198         sprintf (tmpbuf, "%d", e->tagType);
199         Tcl_AppendElement (interp, tmpbuf);
200
201         if (e->tagWhich == Z_StringOrNumeric_numeric)
202         {
203             Tcl_AppendResult (interp, " numeric ", NULL);
204             sprintf (tmpbuf, "%d", e->tagVal.num);
205             Tcl_AppendElement (interp, tmpbuf);
206         }
207         else
208         {
209             Tcl_AppendResult (interp, " string ", NULL);
210             Tcl_AppendElement (interp, e->tagVal.str);
211         }
212         switch (e->dataWhich)
213         {
214         case Z_ElementData_octets:
215             Tcl_AppendResult (interp, " octets {} ", NULL);
216             break;
217         case Z_ElementData_numeric:
218             Tcl_AppendResult (interp, " numeric ", NULL);
219             sprintf (tmpbuf, "%d", e->tagData.num);
220             Tcl_AppendElement (interp, tmpbuf);
221             break;
222         case Z_ElementData_date:
223             Tcl_AppendResult (interp, " date {} ", NULL);
224             break;
225         case Z_ElementData_ext:
226             Tcl_AppendResult (interp, " ext {} ", NULL);
227             break;
228         case Z_ElementData_string:
229             Tcl_AppendResult (interp, " string ", NULL);
230             Tcl_AppendElement (interp, e->tagData.str);
231             break;
232         case Z_ElementData_trueOrFalse:
233             Tcl_AppendResult (interp, " bool ",
234                               e->tagData.bool ? "1" : "0", " ", NULL);
235             break;
236         case Z_ElementData_oid:
237             Tcl_AppendResult (interp, " oid {} ", NULL);
238             break;
239         case Z_ElementData_intUnit:
240             Tcl_AppendResult (interp, " intUnit {} ", NULL);
241             break;
242         case Z_ElementData_elementNotThere:
243             Tcl_AppendResult (interp, " notThere {} ", NULL);
244             break;
245         case Z_ElementData_elementEmpty:
246             Tcl_AppendResult (interp, " empty {} ", NULL);
247             break;
248         case Z_ElementData_noDataRequested:
249             Tcl_AppendResult (interp, " notRequested {} ", NULL);
250             break;
251         case Z_ElementData_diagnostic:
252             Tcl_AppendResult (interp, " diagnostic {} ", NULL);
253             break;
254         case Z_ElementData_subtree:
255             Tcl_AppendResult (interp, " subtree { ", NULL);
256             ir_tcl_get_grs_r (interp, e->tagData.sub, argc, argv, argno+1);
257             Tcl_AppendResult (interp, " } ", NULL);
258             break;
259         }
260         Tcl_AppendResult (interp, " } ", NULL);
261     }
262     return TCL_OK;
263 }
264
265 int ir_tcl_get_grs (Tcl_Interp *interp, IrTcl_GRS_Record *grs_record, 
266                      int argc, char **argv)
267 {
268     return ir_tcl_get_grs_r (interp, grs_record, argc, argv, 3);
269 }
270