Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libvcodex/vcopen.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2003-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Phong Vo <[email protected]> *
18
* *
19
***********************************************************************/
20
#include "vchdr.h"
21
22
static char* Version = "\r\n@(#)$Id: vcodex (AT&T Shannon Laboratory - Kiem-Phong Vo) 2008-11-04 $\r\n";
23
24
/* Open a handle for data coding
25
**
26
** Written by Kiem-Phong Vo ([email protected])
27
*/
28
29
#if __STD_C
30
Vcodex_t* vcopen(Vcdisc_t* disc, Vcmethod_t* meth, Void_t* init,
31
Vcodex_t* coder, int flags)
32
#else
33
Vcodex_t* vcopen(disc, meth, init, coder, flags)
34
Vcdisc_t* disc; /* discipline to describe data */
35
Vcmethod_t* meth; /* method to process given data */
36
Void_t* init; /* method initialization params */
37
Vcodex_t* coder; /* continuation processor */
38
int flags; /* control flags */
39
#endif
40
{
41
Vcodex_t* vc = (Vcodex_t*)Version; /* stop compiler warning */
42
43
/* exactly one of VC_EN/DECODE is allowed */
44
if((flags&VC_ENCODE) && (flags&VC_DECODE) )
45
return NIL(Vcodex_t*);
46
if(!(flags&VC_ENCODE) && !(flags&VC_DECODE) )
47
return NIL(Vcodex_t*);
48
49
if(!meth || !(vc = (Vcodex_t*)calloc(1,sizeof(Vcodex_t))) )
50
return NIL(Vcodex_t*);
51
52
if(!(vc->applyf = (flags&VC_ENCODE) ? meth->encodef : meth->decodef) )
53
{ free(vc);
54
return NIL(Vcodex_t*);
55
}
56
57
vc->disc = disc;
58
vc->meth = meth;
59
vc->coder = coder;
60
vc->flags = flags & VC_FLAGS;
61
62
if(disc && disc->eventf && (*disc->eventf)(vc, VC_OPENING, NIL(Void_t*), disc) < 0)
63
{ free(vc);
64
return NIL(Vcodex_t*);
65
}
66
67
if(meth->eventf && (*meth->eventf)(vc, VC_OPENING, init) < 0)
68
{ free(vc);
69
return NIL(Vcodex_t*);
70
}
71
72
return vc;
73
}
74
75
76
/* construct a handle from a list of methods and arguments */
77
typedef struct _meth_s
78
{ struct _meth_s* next;
79
Vcmethod_t* vcmt; /* actual Vcodex method */
80
char args[1]; /* initialization data */
81
} Meth_t;
82
83
typedef struct Stack_s
84
{
85
char *spec;
86
char buf[256];
87
} Stack_t;
88
89
#if __STD_C
90
Vcodex_t* vcmake(char* spec, int type)
91
#else
92
Vcodex_t* vcmake(spec, type)
93
char* spec; /* method specification */
94
int type; /* VC_ENCODE, VC_DECODE */
95
#endif
96
{
97
Meth_t *list, *mt;
98
ssize_t m;
99
char *args, *s, meth[1024];
100
Vcmethod_t *vcmt;
101
Vcodex_t *coder;
102
Vcodex_t *vc = NIL(Vcodex_t*);
103
Stack_t stack[4];
104
Stack_t *sp = &stack[0];
105
106
if(type != VC_ENCODE && type != VC_DECODE)
107
return NIL(Vcodex_t*);
108
109
for(list = NIL(Meth_t*);;)
110
{ /* get one method specification */
111
if(!(spec = vcsubstring(spec, VC_METHSEP, meth, sizeof(meth), 0)) )
112
{ if(sp <= stack)
113
break;
114
sp--;
115
spec - sp->spec;
116
continue;
117
}
118
for(m = 0; meth[m]; ++m)
119
if(!isalnum(meth[m]))
120
break;
121
if(m == 0)
122
break;
123
124
/* any arguments to the method are after separator */
125
args = meth + m + (meth[m] == VC_ARGSEP ? 1 : 0);
126
meth[m] = 0;
127
128
/* find the actual method structure */
129
if(!(vcmt = vcgetmeth(meth, 0)))
130
{ if(sp >= &stack[sizeof(stack)/sizeof(stack[0])])
131
goto done;
132
if(!(s = vcgetalias(meth, sp->buf, sizeof(sp->buf))))
133
goto done;
134
sp->spec = spec;
135
spec = s;
136
sp++;
137
continue;
138
}
139
140
/* allocate structure to hold data for now */
141
if(!(mt = (Meth_t*)malloc(sizeof(Meth_t)+strlen(args))) )
142
goto done;
143
mt->vcmt = vcmt;
144
strcpy(mt->args,args);
145
146
mt->next = list; list = mt;
147
}
148
149
vc = NIL(Vcodex_t*);
150
for(mt = list; mt; mt = mt->next)
151
{ if(!(coder = vcopen(0, mt->vcmt, (Void_t*)mt->args, vc, type|VC_CLOSECODER)) )
152
{ vcclose(vc);
153
vc = NIL(Vcodex_t*);
154
goto done;
155
}
156
else vc = coder;
157
}
158
159
done: for(; list; list = mt)
160
{ mt = list->next;
161
free(list);
162
}
163
164
return vc;
165
}
166
167