1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// Copyright (C) 1999-2018
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"
#include "socketgz.h"
#include "util.h"
#ifndef __WIN32
#include <sys/types.h>
#include <sys/socket.h>
#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
|