Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/opaque/opaque.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-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
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* opaque method
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
static const char usage[] =
29
"[+DESCRIPTION?The \bdss\b opaque method handles anonymous fixed record "
30
"data. Field names and expressions are not supported.]"
31
"[n:name?The magic header generic data/application name.]:[name]"
32
"[s:size?The fixed record size; must be specified.]#[size]"
33
"[t:type?The magic header specific data type.]:[type]"
34
"[v:version?The magic header version stamp, either \aYYYYMMDD\a or"
35
" \a0xWWXXYYZZ\a.]#[version]"
36
;
37
38
#include <dsslib.h>
39
#include <magicid.h>
40
41
struct Opaque_s; typedef struct Opaque_s Opaque_t;
42
43
struct Opaque_s
44
{
45
Dssmeth_t meth;
46
Magicid_t magic;
47
};
48
49
extern Dsslib_t dss_lib_opaque;
50
51
/*
52
* identf
53
*/
54
55
static int
56
opaqueident(Dssfile_t* file, void* buf, size_t size, Dssdisc_t* disc)
57
{
58
register Opaque_t* opaque = (Opaque_t*)file->dss->meth->data;
59
register Magicid_t* magic = (Magicid_t*)buf;
60
61
if (size < opaque->magic.size)
62
return 0;
63
if (opaque->magic.magic)
64
{
65
if (magic->magic != opaque->magic.magic)
66
return 0;
67
if (magic->size != opaque->magic.size)
68
return 0;
69
if (!streq(magic->name, opaque->magic.name))
70
return 0;
71
if (!streq(magic->type, opaque->magic.type))
72
return 0;
73
if (opaque->magic.version && magic->version > opaque->magic.version)
74
return 0;
75
file->skip = opaque->magic.size;
76
}
77
return 1;
78
}
79
80
/*
81
* opaque fopenf
82
*/
83
84
static int
85
opaquefopen(Dssfile_t* file, Dssdisc_t* disc)
86
{
87
file->data = &((Opaque_t*)file->dss->meth->data)->magic.size;
88
if (file->skip && !sfreserve(file->io, file->skip, 0))
89
{
90
if (disc->errorf)
91
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "header read error");
92
return -1;
93
}
94
return 0;
95
}
96
97
/*
98
* opaque fclosef
99
*/
100
101
static int
102
opaquefclose(Dssfile_t* file, Dssdisc_t* disc)
103
{
104
if (!file)
105
return -1;
106
return 0;
107
}
108
109
/*
110
* opaque readf
111
*/
112
113
static int
114
opaqueread(register Dssfile_t* file, register Dssrecord_t* record, Dssdisc_t* disc)
115
{
116
record->data = sfreserve(file->io, *((size_t*)file->data), 0);
117
record->size = sfvalue(file->io);
118
if (record->data)
119
return 1;
120
if (record->size && disc->errorf)
121
(*disc->errorf)(NiL, disc, 2, "%slast record truncated -- record ignored", cxlocation(file->dss->cx, record));
122
return 0;
123
}
124
125
/*
126
* opaque writef
127
*/
128
129
static int
130
opaquewrite(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
131
{
132
return sfwrite(file->io, record->data, record->size) == record->size ? 0 : -1;
133
}
134
135
static Dssformat_t opaque_format =
136
{
137
"opaque",
138
"opaque format (2010-05-28)",
139
CXH,
140
opaqueident,
141
opaquefopen,
142
opaqueread,
143
opaquewrite,
144
0,
145
opaquefclose,
146
0,
147
0,
148
0
149
};
150
151
/*
152
* methf
153
*/
154
155
static Dssmeth_t*
156
opaquemeth(const char* name, const char* options, const char* schema, Dssdisc_t* disc, Dssmeth_t* meth)
157
{
158
register Opaque_t* opaque;
159
char* s;
160
161
if (!(opaque = newof(0, Opaque_t, 1, 0)))
162
{
163
if (disc->errorf)
164
(*disc->errorf)(NiL, disc, 2, "out of space");
165
return 0;
166
}
167
opaque->meth = *meth;
168
opaque->meth.data = opaque;
169
if (options)
170
{
171
if (dssoptlib(meth->cx->buf, &dss_lib_opaque, usage, disc))
172
goto drop;
173
s = sfstruse(meth->cx->buf);
174
for (;;)
175
{
176
switch (optstr(options, s))
177
{
178
case 'n':
179
opaque->magic.magic = MAGICID;
180
strncopy(opaque->magic.name, opt_info.arg, sizeof(opaque->magic.name));
181
continue;
182
case 's':
183
opaque->magic.size = opt_info.num;
184
continue;
185
case 't':
186
opaque->magic.magic = MAGICID;
187
strncopy(opaque->magic.type, opt_info.arg, sizeof(opaque->magic.type));
188
continue;
189
case 'v':
190
opaque->magic.magic = MAGICID;
191
opaque->magic.version = opt_info.num;
192
continue;
193
case '?':
194
if (disc->errorf)
195
(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
196
goto drop;
197
case ':':
198
if (disc->errorf)
199
(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
200
goto drop;
201
}
202
break;
203
}
204
}
205
if (!opaque->magic.size)
206
{
207
if (disc->errorf)
208
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "data size must be specified");
209
goto drop;
210
}
211
dtinsert(opaque->meth.formats, &opaque_format);
212
return &opaque->meth;
213
drop:
214
free(opaque);
215
return 0;
216
}
217
218
static Dssmeth_t method =
219
{
220
"opaque",
221
"opaque fixed record data with optional magic",
222
CXH,
223
opaquemeth
224
};
225
226
Dsslib_t dss_lib_opaque =
227
{
228
"opaque",
229
"opaque method"
230
"[-1ls5Pp0?\n@(#)$Id: dss opaque method (AT&T Research) 2002-11-22 $\n]"
231
USAGE_LICENSE,
232
CXH,
233
0,
234
&method
235
};
236
237