// Copyright (C) 1999-2017 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "socketgz.h" #ifndef __WIN32 #include #include #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ FitsSocketGZ::FitsSocketGZ(int s, const char* ext) { parse(ext); if (!valid_) return; // reset valid_ =0; if (!s) return; stream_ = new gzStream_; stream_->id = s; stream_->transparent = 0; memset(stream_->header,'\0',2); stream_->useHeader = 0; stream_->buf = new unsigned char[B4KB]; // magic bytes if (recv(stream_->id , stream_->header, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read magic bytes in header"); return; } if (stream_->header[0] != 0x1f || stream_->header[1] != 0x8b) { stream_->transparent = 1; stream_->useHeader = 1; } else { ((z_stream*)stream_)->next_in = NULL; ((z_stream*)stream_)->avail_in = 0; ((z_stream*)stream_)->zalloc = NULL; ((z_stream*)stream_)->zfree = NULL; ((z_stream*)stream_)->opaque = NULL; if (inflateInit2((z_stream*)stream_, -MAX_WBITS) != Z_OK) { internalError("Fitsy++ socketgz inflateInit error"); return; } unsigned char buf[128]; // method/flags if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read method/flags bytes in header"); return; } int method = buf[0]; int flags = buf[1]; if (method != Z_DEFLATED || (flags & RESERVED) != 0) { internalError("Fitsy++ socketgz bad method/flags"); return; } // Discard time, xflags and OS code if (recv(stream_->id , buf, 6, 0) != 6) { internalError("Fitsy++ socketgz can't read time/xflags/os bytes in header"); return; } // skip the extra field if ((flags & EXTRA_FIELD) != 0) { if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read extra field length bytes in header"); return; } int len = buf[0]; len += buf[1]<<8; if (recv(stream_->id , buf, len, 0) != len) { internalError("Fitsy++ socketgz can't read extra field bytes in header"); return; } } // skip the original file name if ((flags & ORIG_NAME) != 0) { while (recv(stream_->id , buf, 1, 0) == 1 && buf[0] != 0) ; } // skip the .gz file comment if ((flags & COMMENT) != 0) { while (recv(stream_->id , buf, 1, 0) == 1 && buf[0] != 0) ; } // skip the header crc if ((flags & HEAD_CRC) != 0) { if (recv(stream_->id , buf, 2, 0) != 2) { internalError("Fitsy++ socketgz can't read header crc bytes in header"); return; } } } if (DebugGZ) cerr << "inflateInt Complete" << endl; // so far, so good valid_ = 1; } FitsSocketGZ::~FitsSocketGZ() { if (stream_->buf) delete [] stream_->buf; if (stream_) delete stream_; stream_ = NULL; } #else FitsSocketGZ::FitsSocketGZ(int s, const char* ext) { valid_ =0; } FitsSocketGZ::~FitsSocketGZ() {} #endif