00001
00002
00003
00004
00005
00011 #if HAVE_CONFIG_H
00012 #include <config.h>
00013 #endif
00014
00015 #include <assert.h>
00016
00017 #include "odr-priv.h"
00018
00019 void odr_setlenlen(ODR o, int len)
00020 {
00021 o->op->lenlen = len;
00022 }
00023
00024 int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag,
00025 const char *name)
00026 {
00027 int res;
00028 int cons = 1;
00029 int lenlen = o->op->lenlen;
00030
00031 if (o->error)
00032 return 0;
00033 o->op->lenlen = 1;
00034 if (o->op->t_class < 0)
00035 {
00036 o->op->t_class = zclass;
00037 o->op->t_tag = tag;
00038 }
00039 res = ber_tag(o, xxp, o->op->t_class, o->op->t_tag, &cons, 1, name);
00040 if (res < 0)
00041 return 0;
00042 if (!res || !cons)
00043 return 0;
00044
00045
00046 if (o->op->stack_top && o->op->stack_top->next)
00047 {
00048
00049 o->op->stack_top = o->op->stack_top->next;
00050 }
00051 else if (o->op->stack_top && !o->op->stack_top->next)
00052 {
00053
00054 int sz = 0;
00055 struct odr_constack *st;
00056
00057 for (st = o->op->stack_top; st; st = st->prev)
00058 sz++;
00059
00060 if (sz >= ODR_MAX_STACK)
00061 {
00062 odr_seterror(o, OSTACK, 30);
00063 return 0;
00064 }
00065 o->op->stack_top->next = (struct odr_constack *)
00066 odr_malloc(o, sizeof(*o->op->stack_top));
00067 o->op->stack_top->next->prev = o->op->stack_top;
00068 o->op->stack_top->next->next = 0;
00069
00070 o->op->stack_top = o->op->stack_top->next;
00071 }
00072 else if (!o->op->stack_top)
00073 {
00074
00075 if (!o->op->stack_first)
00076 {
00077
00078 o->op->stack_first = (struct odr_constack *)
00079 odr_malloc(o, sizeof(*o->op->stack_top));
00080 o->op->stack_first->prev = 0;
00081 o->op->stack_first->next = 0;
00082 }
00083 o->op->stack_top = o->op->stack_first;
00084 assert(o->op->stack_top->prev == 0);
00085 }
00086 o->op->stack_top->lenb = o->bp;
00087 o->op->stack_top->len_offset = odr_tell(o);
00088 o->op->stack_top->name = name ? name : "?";
00089 if (o->direction == ODR_ENCODE)
00090 {
00091 static unsigned char dummy[sizeof(int)+1];
00092
00093 o->op->stack_top->lenlen = lenlen;
00094
00095 if (odr_write(o, dummy, lenlen) < 0)
00096 {
00097 ODR_STACK_POP(o);
00098 return 0;
00099 }
00100 }
00101 else if (o->direction == ODR_DECODE)
00102 {
00103 if ((res = ber_declen(o->bp, &o->op->stack_top->len,
00104 odr_max(o))) < 0)
00105 {
00106 odr_seterror(o, OOTHER, 31);
00107 ODR_STACK_POP(o);
00108 return 0;
00109 }
00110 o->op->stack_top->lenlen = res;
00111 o->bp += res;
00112 if (o->op->stack_top->len > odr_max(o))
00113 {
00114 odr_seterror(o, OOTHER, 32);
00115 ODR_STACK_POP(o);
00116 return 0;
00117 }
00118 }
00119 else if (o->direction == ODR_PRINT)
00120 {
00121 odr_prname(o, name);
00122 odr_printf(o, "{\n");
00123 o->op->indent++;
00124 }
00125 else
00126 {
00127 odr_seterror(o, OOTHER, 33);
00128 ODR_STACK_POP(o);
00129 return 0;
00130 }
00131 o->op->stack_top->base = o->bp;
00132 o->op->stack_top->base_offset = odr_tell(o);
00133 return 1;
00134 }
00135
00136 int odr_constructed_more(ODR o)
00137 {
00138 if (o->error)
00139 return 0;
00140 if (ODR_STACK_EMPTY(o))
00141 return 0;
00142 if (o->op->stack_top->len >= 0)
00143 return o->bp - o->op->stack_top->base < o->op->stack_top->len;
00144 else
00145 return (!(*o->bp == 0 && *(o->bp + 1) == 0));
00146 }
00147
00148 int odr_constructed_end(ODR o)
00149 {
00150 int res;
00151 int pos;
00152
00153 if (o->error)
00154 return 0;
00155 if (ODR_STACK_EMPTY(o))
00156 {
00157 odr_seterror(o, OOTHER, 34);
00158 return 0;
00159 }
00160 switch (o->direction)
00161 {
00162 case ODR_DECODE:
00163 if (o->op->stack_top->len < 0)
00164 {
00165 if (*o->bp++ == 0 && *(o->bp++) == 0)
00166 {
00167 ODR_STACK_POP(o);
00168 return 1;
00169 }
00170 else
00171 {
00172 odr_seterror(o, OOTHER, 35);
00173 return 0;
00174 }
00175 }
00176 else if (o->bp - o->op->stack_top->base !=
00177 o->op->stack_top->len)
00178 {
00179 odr_seterror(o, OCONLEN, 36);
00180 return 0;
00181 }
00182 ODR_STACK_POP(o);
00183 return 1;
00184 case ODR_ENCODE:
00185 pos = odr_tell(o);
00186 odr_seek(o, ODR_S_SET, o->op->stack_top->len_offset);
00187 if ((res = ber_enclen(o, pos - o->op->stack_top->base_offset,
00188 o->op->stack_top->lenlen, 1)) < 0)
00189 {
00190 odr_seterror(o, OLENOV, 37);
00191 return 0;
00192 }
00193 odr_seek(o, ODR_S_END, 0);
00194 if (res == 0)
00195 {
00196 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
00197 return 0;
00198 }
00199 ODR_STACK_POP(o);
00200 return 1;
00201 case ODR_PRINT:
00202 ODR_STACK_POP(o);
00203 o->op->indent--;
00204 odr_prname(o, 0);
00205 odr_printf(o, "}\n");
00206 return 1;
00207 default:
00208 odr_seterror(o, OOTHER, 38);
00209 return 0;
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219