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
|
// Copyright (C) 1999-2018
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"
#include "socketgz.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
|