// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: Rstzip.C
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
#include "rstzip_v3/rstzip3.h"
#include "rstzip_v2/rstzip2if.H"
/* the latest rstzip version supported by this rstzip library is rstzip3_major_version.rstzip3_minor_version */
enum agent_e {agent_NIL = 0, rstzip3_agent, rstzip2_agent, rstzip1_agent, rstzip0_agent} agent; // rstzip0 is raw (uncompressed) rst
// rstzip1 and 2 agents goes here
records_checked_for_traceid = 0;
free(filename); filename = NULL;
void process_opt_str(const char * opts) {
if (strstr(opts, "verbose=1") != NULL) {
if (strstr(opts, "stats=1") != NULL) {
if (strstr(opts, "version=0") != NULL) {
} else if (strstr(opts, "version=1") != NULL) {
} else if (strstr(opts, "version=2") != NULL) {
} else if (strstr(opts, "version=3") != NULL) {
} // else - leave agent undefined
const char * getVersionStr();
int records_checked_for_traceid;
int Rstzip_impl::getMajorVersion()
return rz2obj->getMajorVersion();
return rz3obj->getMajorVersion();
} // int Rstzip::getMajorVersion()
int Rstzip_impl::getMinorVersion()
return rz2obj->getMajorVersion();
return rz3obj->getMinorVersion();
} // int Rstzip_impl::getMinorVersion()
const char * Rstzip_impl::getVersionStr()
// return rz2obj->getVersionStr();
return rz3obj->getVersionStr();
} // const char * Rstzip_impl::getVersionStr()
int Rstzip::getMajorVersion()
return impl->getMajorVersion();
int Rstzip::getMinorVersion()
return impl->getMinorVersion();
const char * Rstzip::getVersionStr()
return impl->getVersionStr();
int Rstzip::open(const char * filename, const char * mode, const char *opts)
impl->filename = strdup(filename);
impl->filename = strdup("NULL");
// If open for writing: use latest rstzip (rz3).
// If open for reading, there are many possibilities:
// 1. pipe or file (seekable or not)
// 2. gzip'ed or raw rstzip or RAW RST
// We work under those parameters.
// We do not allocate a compressor object until we know the exact version
// of the input from the rstzip header in the input.
// We use gzread to take care of gzip/non-gzip data.
// If we do not find an rstzip header OR an rst header, we bail.
// process the options string
impl->process_opt_str(opts);
if ((mode == NULL) || (mode[0] == 0)) {
fprintf(stderr, "ERROR: Rstzip::open(): mode must be \"r\" or \"w\"\n");
} else if (strcmp(mode, "r") == 0) {
} else if (strcmp(mode, "w") == 0) {
fprintf(stderr, "ERROR: Rstzip::open(): mode must be \"r\" or \"w\"\n. Specified=%s\n", mode);
impl->agent = Rstzip_impl::rstzip3_agent; // default
impl->rz3obj = new rstzip3(filename, "w");
if (impl->rz3obj->error()) {
if (impl->verbose) impl->rz3obj->setverbose();
if (impl->stats) impl->rz3obj->setstats();
/* if input is not stdin read in a few bytes to determine rstzip version */
gzFile gzf = gzopen(filename, "r");
fprintf(stderr, "ERROR: Rstzip::open(): failed gzopen of output file "); perror(filename);
// if version hasn't been specified, try to determine version using input data */
enum Rstzip_impl::agent_e agent = Rstzip_impl::agent_NIL;
// read the first 24 bytes to check version
int rv = gzread(gzf, b24, 24);
if ((b24[0] == 'R') && (b24[1] == 'Z')) {
agent = Rstzip_impl::rstzip3_agent;
agent = Rstzip_impl::rstzip2_agent;
agent = Rstzip_impl::rstzip1_agent;
if (impl->agent != Rstzip_impl::rstzip0_agent) {
fprintf(stderr, "ERROR: Rstzip::open(): invalid rstzip signature RZ%c (\\%03o) in input file %s\n", (isprint(b24[2])? b24[2] : '?'), b24[2], filename);
} // which RZ version in input file?
} else if (strstr(filename, ".rst\0") != NULL) {
agent = Rstzip_impl::rstzip0_agent;
} else /* no rstzip signature */ {
// if we find a valid rst header, open it as an uncompressed rst file
rstf_headerT * hdr = (rstf_headerT *) b24;
if ((hdr->rtype == RSTHEADER_T) && (hdr->percent == '%') && (hdr->header_str[0] != 0) && (strcmp(hdr->header_str, RSTF_MAGIC) == 0)) {
agent = Rstzip_impl::rstzip0_agent;
} else if (impl->agent == Rstzip_impl::agent_NIL){
fprintf(stderr, "ERROR: Rstzip::open(): could not determine input file type\n");
} // RZ or uncompressed rstzip?
// at this point, we have either determined version information from the file, or it was specified using the option string.
// if neither of these two cases is true, or if the two don't match, signal an error
if (impl->agent == Rstzip_impl::agent_NIL) {
if (agent == Rstzip_impl::agent_NIL) {
fprintf(stderr, "ERROR: Rstzip::open(): could not determine input file type\n");
if ((agent != Rstzip_impl::agent_NIL) && (agent != impl->agent)) {
fprintf(stderr, "Warning: rstzip: specified rstzip major version does not match input data\n");
} else /* input from stdin */ {
if (impl->agent == Rstzip_impl::agent_NIL) {
impl->agent = Rstzip_impl::rstzip3_agent;
} // else - version specified in options string
} // input from stdin or disk file?
case Rstzip_impl::rstzip3_agent:
impl->rz3obj = new rstzip3(filename, "r");
if (impl->rz3obj->error()) {
if (impl->verbose) impl->rz3obj->setverbose();
if (impl->stats) impl->rz3obj->setstats();
case Rstzip_impl::rstzip2_agent:
impl->rz2obj = new Rstzip2if();
impl->rz2obj->openRstunzip(filename, 40000, /* gzip */ 1, (impl->stats? 1: 0));
case Rstzip_impl::rstzip1_agent:
case Rstzip_impl::rstzip0_agent:
impl->rz0gzf = gzopen(filename, "r");
if (impl->rz0gzf == NULL) {
fprintf(stderr, "ERROR: Rstzip::open(): failed gzopen of output file "); perror(filename);
} // compress/decompress?
} // int Rstzip::open(const char * filename, const char * mode, const char *obs)
int Rstzip::compress(rstf_unionT * rstbuf, int nrecs)
fprintf(stderr, "ERROR: Rstzip::compress() - cannot compress in \"r\" (decompress) mode\n");
return impl->rz3obj->compress(rstbuf, nrecs);
} // int Rstzip::compress(rstf_unionT * rstbuf, int nrecs)
int Rstzip::decompress(rstf_unionT * rstbuf, int nrecs)
fprintf(stderr, "ERROR: Rstzip::decompress() - cannot decompress in \"w\" (compress) mode\n");
case Rstzip_impl::rstzip3_agent:
rv = impl->rz3obj->decompress(rstbuf, nrecs);
case Rstzip_impl::rstzip2_agent:
int n = (more >= 40000) ? 40000 : more; // magic buffer size from old rstzip2 main
int actual = impl->rz2obj->decompress(rstbuf + (nrecs-more), n);
case Rstzip_impl::rstzip1_agent:
fprintf(stderr, "rstzip1 decompress: unimplmented");
case Rstzip_impl::rstzip0_agent:
rv = gzread(impl->rz0gzf, rstbuf, nrecs*sizeof(rstf_unionT))/24;
fprintf(stderr, "Rstzip::decompress: invalid state (Rstzip_impl::agent)\n");
} // int Rstzip::decompress(rstf_unionT * rstbuf, int nrecs)
case Rstzip_impl::rstzip1_agent:
case Rstzip_impl::rstzip2_agent:
impl->rz2obj->closeRstunzip();
case Rstzip_impl::rstzip3_agent:
case Rstzip_impl::rstzip0_agent:
gzclose(impl->rz0gzf); impl->rz0gzf = NULL;
} // void Rstzip::close()
int rzGetMajorVersion(Rstzip* rz)
return rz->getMajorVersion();
int GetMinorVersion(Rstzip * rz)
return rz->getMinorVersion();
const char * rzGetVersionStr(Rstzip * rz)
return rz->getVersionStr();
int rzOpen(Rstzip * rz, const char * file, const char * md, const char * options)
return rz->open(file, md, options);
int rzCompress(Rstzip * rz, rstf_unionT * rstbuf, int nrecs)
return rz->compress(rstbuf, nrecs);
int rzDecompress(Rstzip * rz, rstf_unionT * rstbuf, int nrecs)
return rz->decompress(rstbuf, nrecs);
void rzClose(Rstzip * rz)