Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / rst / rstzip3 / Rstzip.C
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: Rstzip.C
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <strings.h>
26#include <sys/types.h>
27#include <time.h>
28#include <unistd.h>
29#include <ctype.h>
30#include <limits.h>
31
32#include <netdb.h>
33#include <sys/socket.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36
37#include <pwd.h>
38
39#include "Rstzip.H"
40
41#include "rstzip_v3/rstzip3.h"
42
43#include "rstzip_v2/rstzip2if.H"
44
45#include <zlib.h>
46
47/* the latest rstzip version supported by this rstzip library is rstzip3_major_version.rstzip3_minor_version */
48
49struct Rstzip_impl {
50 enum agent_e {agent_NIL = 0, rstzip3_agent, rstzip2_agent, rstzip1_agent, rstzip0_agent} agent; // rstzip0 is raw (uncompressed) rst
51 // rstzip1 and 2 agents goes here
52
53
54 Rstzip_impl() {
55 agent = agent_NIL;
56 c_nd = false;
57 verbose = false;
58 stats = false;
59 records_checked_for_traceid = 0;
60 filename = NULL;
61 rz3obj = NULL;
62 rz2obj = NULL;
63 rz0gzf = NULL;
64 }
65
66 ~Rstzip_impl() {
67
68 if (filename != NULL) {
69 free(filename); filename = NULL;
70 }
71 }
72
73 void process_opt_str(const char * opts) {
74 if (opts != NULL) {
75 if (strstr(opts, "verbose=1") != NULL) {
76 verbose = true;
77 }
78 if (strstr(opts, "stats=1") != NULL) {
79 stats = true;
80 }
81
82 if (strstr(opts, "version=0") != NULL) {
83 agent = rstzip0_agent;
84 } else if (strstr(opts, "version=1") != NULL) {
85 agent = rstzip1_agent;
86 } else if (strstr(opts, "version=2") != NULL) {
87 agent = rstzip2_agent;
88 } else if (strstr(opts, "version=3") != NULL) {
89 agent = rstzip3_agent;
90 } // else - leave agent undefined
91 }
92 }
93
94 int getMajorVersion();
95 int getMinorVersion();
96 const char * getVersionStr();
97
98 char * filename;
99
100 bool c_nd;
101 bool verbose;
102 bool stats;
103 int records_checked_for_traceid;
104
105 struct rstzip3 * rz3obj;
106 Rstzip2if * rz2obj;
107 gzFile rz0gzf;
108}; // struct Rstzip_impl
109
110
111int Rstzip_impl::getMajorVersion()
112{
113 switch(agent) {
114 case rstzip1_agent:
115 return -1;
116 break;
117 case rstzip2_agent:
118 return rz2obj->getMajorVersion();
119 break;
120 case rstzip3_agent:
121 default:
122 return rz3obj->getMajorVersion();
123 }
124} // int Rstzip::getMajorVersion()
125
126
127
128
129int Rstzip_impl::getMinorVersion()
130{
131 switch(agent) {
132 case rstzip1_agent:
133 return -1;
134 break;
135 case rstzip2_agent:
136 return rz2obj->getMajorVersion();
137 break;
138 case rstzip3_agent:
139 default:
140 return rz3obj->getMinorVersion();
141 }
142} // int Rstzip_impl::getMinorVersion()
143
144
145
146const char * Rstzip_impl::getVersionStr()
147{
148 switch(agent) {
149 case rstzip1_agent:
150 return "error";
151 break;
152 case rstzip2_agent:
153 // return rz2obj->getVersionStr();
154 return "2.1";
155 break;
156 case rstzip3_agent:
157 default:
158 return rz3obj->getVersionStr();
159 }
160} // const char * Rstzip_impl::getVersionStr()
161
162
163
164
165
166
167Rstzip::Rstzip()
168{
169 impl = new Rstzip_impl;
170}
171
172Rstzip::~Rstzip()
173{
174 delete impl;
175} // Rstzip::~Rstzip()
176
177
178int Rstzip::getMajorVersion()
179{
180 return impl->getMajorVersion();
181}
182
183
184
185int Rstzip::getMinorVersion()
186{
187 return impl->getMinorVersion();
188}
189
190
191const char * Rstzip::getVersionStr()
192{
193 return impl->getVersionStr();
194}
195
196
197
198
199
200int Rstzip::open(const char * filename, const char * mode, const char *opts)
201{
202
203 if (filename != NULL) {
204 impl->filename = strdup(filename);
205 } else {
206 impl->filename = strdup("NULL");
207 }
208
209 // If open for writing: use latest rstzip (rz3).
210 // If open for reading, there are many possibilities:
211 // 1. pipe or file (seekable or not)
212 // 2. gzip'ed or raw rstzip or RAW RST
213 // We work under those parameters.
214 // We do not allocate a compressor object until we know the exact version
215 // of the input from the rstzip header in the input.
216 // We use gzread to take care of gzip/non-gzip data.
217 // If we do not find an rstzip header OR an rst header, we bail.
218
219 // process the options string
220 impl->process_opt_str(opts);
221
222 if ((mode == NULL) || (mode[0] == 0)) {
223 fprintf(stderr, "ERROR: Rstzip::open(): mode must be \"r\" or \"w\"\n");
224 return RSTZIP_ERROR;
225 } else if (strcmp(mode, "r") == 0) {
226 impl->c_nd = false;
227 } else if (strcmp(mode, "w") == 0) {
228 impl->c_nd = true;
229 } else {
230 fprintf(stderr, "ERROR: Rstzip::open(): mode must be \"r\" or \"w\"\n. Specified=%s\n", mode);
231 }
232
233 if (impl->c_nd) {
234
235 impl->agent = Rstzip_impl::rstzip3_agent; // default
236 impl->rz3obj = new rstzip3(filename, "w");
237 if (impl->rz3obj->error()) {
238 return RSTZIP_ERROR;
239 }
240 if (impl->verbose) impl->rz3obj->setverbose();
241 if (impl->stats) impl->rz3obj->setstats();
242
243 } else {
244
245
246 if (filename != NULL) {
247 /* if input is not stdin read in a few bytes to determine rstzip version */
248 gzFile gzf = gzopen(filename, "r");
249 if (gzf == NULL) {
250 fprintf(stderr, "ERROR: Rstzip::open(): failed gzopen of output file "); perror(filename);
251 return RSTZIP_ERROR;
252 }
253
254 // if version hasn't been specified, try to determine version using input data */
255
256 enum Rstzip_impl::agent_e agent = Rstzip_impl::agent_NIL;
257
258 // read the first 24 bytes to check version
259 uint8_t b24[24];
260 int rv = gzread(gzf, b24, 24);
261 if (rv != 24) {
262 return RSTZIP_ERROR;
263 }
264 gzclose(gzf);
265
266 // check version string
267 if ((b24[0] == 'R') && (b24[1] == 'Z')) {
268 int ver = b24[2]-'0';
269 if (ver == 3) {
270 agent = Rstzip_impl::rstzip3_agent;
271 } else if (ver == 2) {
272 agent = Rstzip_impl::rstzip2_agent;
273 } else if (ver == 1) {
274 agent = Rstzip_impl::rstzip1_agent;
275 } else {
276 if (impl->agent != Rstzip_impl::rstzip0_agent) {
277 fprintf(stderr, "ERROR: Rstzip::open(): invalid rstzip signature RZ%c (\\%03o) in input file %s\n", (isprint(b24[2])? b24[2] : '?'), b24[2], filename);
278 return RSTZIP_ERROR;
279 }
280 } // which RZ version in input file?
281 } else if (strstr(filename, ".rst\0") != NULL) {
282 agent = Rstzip_impl::rstzip0_agent;
283 } else /* no rstzip signature */ {
284 // if we find a valid rst header, open it as an uncompressed rst file
285 rstf_headerT * hdr = (rstf_headerT *) b24;
286 if ((hdr->rtype == RSTHEADER_T) && (hdr->percent == '%') && (hdr->header_str[0] != 0) && (strcmp(hdr->header_str, RSTF_MAGIC) == 0)) {
287 agent = Rstzip_impl::rstzip0_agent;
288 } else if (impl->agent == Rstzip_impl::agent_NIL){
289 fprintf(stderr, "ERROR: Rstzip::open(): could not determine input file type\n");
290 return RSTZIP_ERROR;
291 }
292 } // RZ or uncompressed rstzip?
293
294 // at this point, we have either determined version information from the file, or it was specified using the option string.
295 // if neither of these two cases is true, or if the two don't match, signal an error
296 if (impl->agent == Rstzip_impl::agent_NIL) {
297 if (agent == Rstzip_impl::agent_NIL) {
298 fprintf(stderr, "ERROR: Rstzip::open(): could not determine input file type\n");
299 return RSTZIP_ERROR;
300 } else {
301 impl->agent = agent;
302 }
303 } else {
304 if ((agent != Rstzip_impl::agent_NIL) && (agent != impl->agent)) {
305 fprintf(stderr, "Warning: rstzip: specified rstzip major version does not match input data\n");
306 }
307 }
308
309 } else /* input from stdin */ {
310 // for now, assume rz3
311 if (impl->agent == Rstzip_impl::agent_NIL) {
312 impl->agent = Rstzip_impl::rstzip3_agent;
313 } // else - version specified in options string
314 } // input from stdin or disk file?
315
316
317 switch(impl->agent) {
318
319 case Rstzip_impl::rstzip3_agent:
320
321 impl->rz3obj = new rstzip3(filename, "r");
322 if (impl->rz3obj->error()) {
323 return RSTZIP_ERROR;
324 }
325 if (impl->verbose) impl->rz3obj->setverbose();
326 if (impl->stats) impl->rz3obj->setstats();
327
328 break;
329
330 case Rstzip_impl::rstzip2_agent:
331 impl->rz2obj = new Rstzip2if();
332 impl->rz2obj->openRstunzip(filename, 40000, /* gzip */ 1, (impl->stats? 1: 0));
333 break;
334
335 case Rstzip_impl::rstzip1_agent:
336
337 break;
338 case Rstzip_impl::rstzip0_agent:
339 impl->rz0gzf = gzopen(filename, "r");
340 if (impl->rz0gzf == NULL) {
341 fprintf(stderr, "ERROR: Rstzip::open(): failed gzopen of output file "); perror(filename);
342 return RSTZIP_ERROR;
343 }
344
345 break;
346 default:
347 return RSTZIP_ERROR;
348
349 } // which agent?
350
351 } // compress/decompress?
352
353 return RSTZIP_OK;
354} // int Rstzip::open(const char * filename, const char * mode, const char *obs)
355
356
357
358
359int Rstzip::compress(rstf_unionT * rstbuf, int nrecs)
360{
361 if (! impl->c_nd) {
362 fprintf(stderr, "ERROR: Rstzip::compress() - cannot compress in \"r\" (decompress) mode\n");
363 return 0;
364 }
365
366 return impl->rz3obj->compress(rstbuf, nrecs);
367} // int Rstzip::compress(rstf_unionT * rstbuf, int nrecs)
368
369
370int Rstzip::decompress(rstf_unionT * rstbuf, int nrecs)
371{
372 if (impl->c_nd) {
373 fprintf(stderr, "ERROR: Rstzip::decompress() - cannot decompress in \"w\" (compress) mode\n");
374 return 0;
375 }
376
377 int rv;
378 switch(impl->agent) {
379 case Rstzip_impl::rstzip3_agent:
380 rv = impl->rz3obj->decompress(rstbuf, nrecs);
381 break;
382 case Rstzip_impl::rstzip2_agent:
383 {
384 int more = nrecs;
385 while(more) {
386 int n = (more >= 40000) ? 40000 : more; // magic buffer size from old rstzip2 main
387 int actual = impl->rz2obj->decompress(rstbuf + (nrecs-more), n);
388 if (actual == 0) break;
389 more -= n;
390 } // while more
391 rv = nrecs - more;
392 }
393 break;
394 case Rstzip_impl::rstzip1_agent:
395 fprintf(stderr, "rstzip1 decompress: unimplmented");
396 return 0;
397 break;
398 case Rstzip_impl::rstzip0_agent:
399 rv = gzread(impl->rz0gzf, rstbuf, nrecs*sizeof(rstf_unionT))/24;
400
401 default:
402 fprintf(stderr, "Rstzip::decompress: invalid state (Rstzip_impl::agent)\n");
403 return 0;
404 }
405
406 return rv;
407} // int Rstzip::decompress(rstf_unionT * rstbuf, int nrecs)
408
409
410void Rstzip::close()
411{
412 if (impl->c_nd) {
413 delete impl->rz3obj;
414 } else {
415 switch(impl->agent) {
416 case Rstzip_impl::rstzip1_agent:
417 case Rstzip_impl::rstzip2_agent:
418 impl->rz2obj->closeRstunzip();
419 break; // unsupported
420 case Rstzip_impl::rstzip3_agent:
421 delete impl->rz3obj;
422 impl->rz3obj = NULL;
423 break;
424 case Rstzip_impl::rstzip0_agent:
425 gzclose(impl->rz0gzf); impl->rz0gzf = NULL;
426 default:
427 break;
428 }
429 }
430} // void Rstzip::close()
431
432
433
434// C interface (legacy)
435
436Rstzip * rzMakeRstzip()
437{
438 return new Rstzip;
439}
440
441int rzGetMajorVersion(Rstzip* rz)
442{
443 return rz->getMajorVersion();
444}
445
446int GetMinorVersion(Rstzip * rz)
447{
448 return rz->getMinorVersion();
449}
450
451const char * rzGetVersionStr(Rstzip * rz)
452{
453 return rz->getVersionStr();
454}
455
456
457int rzOpen(Rstzip * rz, const char * file, const char * md, const char * options)
458{
459 return rz->open(file, md, options);
460}
461
462int rzCompress(Rstzip * rz, rstf_unionT * rstbuf, int nrecs)
463{
464 return rz->compress(rstbuf, nrecs);
465}
466
467int rzDecompress(Rstzip * rz, rstf_unionT * rstbuf, int nrecs)
468{
469 return rz->decompress(rstbuf, nrecs);
470}
471
472void rzClose(Rstzip * rz)
473{
474 rz->close();
475}