summaryrefslogtreecommitdiffstats
path: root/fitsy++/outsocket.C
diff options
context:
space:
mode:
Diffstat (limited to 'fitsy++/outsocket.C')
-rw-r--r--fitsy++/outsocket.C200
1 files changed, 200 insertions, 0 deletions
diff --git a/fitsy++/outsocket.C b/fitsy++/outsocket.C
new file mode 100644
index 0000000..8739499
--- /dev/null
+++ b/fitsy++/outsocket.C
@@ -0,0 +1,200 @@
+// Copyright (C) 1999-2018
+// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+// For conditions of distribution and use, see copyright notice in "copyright"
+
+#include "outsocket.h"
+#include "util.h"
+
+#ifndef __WIN32
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "file.h"
+
+OutFitsSocket::OutFitsSocket(int s)
+{
+ id_ = s;
+ valid_ = 1;
+}
+
+int OutFitsSocket::write(char* where, size_t size)
+{
+ // size_t size is unsigned
+ long long ss = size;
+ size_t rr =0;
+ int r;
+ do {
+ r = (ss>B4KB) ? B4KB : ss;
+ send(id_, where+rr, r, 0);
+ if (r == -1) {
+ internalError("Fitsy++ outsocket write error");
+ return -1;
+ }
+ ss -= r;
+ rr += r;
+ } while (r>0 && rr<size);
+
+ return rr;
+}
+
+OutFitsSocketGZ::OutFitsSocketGZ(int s)
+{
+ id_ = s;
+ stream_ = new z_stream;
+ buf_ = new unsigned char[B4KB];
+
+ crc_ = crc32(0L, Z_NULL, 0);
+
+ stream_->next_in = NULL;
+ stream_->avail_in = 0;
+ stream_->next_out = NULL;
+ stream_->avail_out = 0;
+
+ stream_->zalloc = NULL;
+ stream_->zfree = NULL;
+ stream_->opaque = NULL;
+
+ if (deflateInit2(stream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ internalError("Fitsy++ outsocket deflateInit error");
+ return;
+ }
+
+ // dump simple header
+ unsigned char header[10] =
+ {0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x03};
+ send(id_, header, 10, 0);
+
+ stream_->next_out = buf_;
+ stream_->avail_out = B4KB;
+
+ valid_ = 1;
+}
+
+OutFitsSocketGZ::~OutFitsSocketGZ()
+{
+ // flush any pending output
+ while (deflategz(Z_FINISH) == Z_OK);
+
+ // output crc/length
+ putlong(crc_);
+ putlong(stream_->total_in);
+
+ if (deflateEnd(stream_) != Z_OK)
+ internalError("Fitsy++ outsocket deflateEnd error");
+
+ if (stream_)
+ delete stream_;
+
+ if (buf_)
+ delete [] buf_;
+}
+
+int OutFitsSocketGZ::write(char* where, size_t size)
+{
+ stream_->next_in = (unsigned char*)where;
+ stream_->avail_in = size;
+
+ if (DebugGZ)
+ cerr << "write " << size << endl;
+
+ while (stream_->avail_in > 0 && deflategz(Z_NO_FLUSH) == Z_OK);
+
+ // update crc
+ crc_ = crc32(crc_, (const Bytef *)where, size);
+
+ return size - stream_->avail_in;
+}
+
+int OutFitsSocketGZ::deflategz(int flush)
+{
+ int result = deflate(stream_, flush);
+
+ switch (result) {
+ case Z_OK:
+ if (DebugGZ)
+ cerr << "deflate OK: avail_in " << stream_->avail_in
+ << " avail_out " << stream_->avail_out << endl;
+ break;
+ case Z_STREAM_END:
+ if (DebugGZ)
+ cerr << "deflate STRM_END: avail_in " << stream_->avail_in
+ << " avail_out " << stream_->avail_out << endl;
+ break;
+ default:
+ if (DebugGZ)
+ cerr << "deflate Error " << result << endl;
+ return result;
+ }
+
+ if (stream_->avail_out == 0 || result != Z_OK) {
+ int s = B4KB - stream_->avail_out;
+ unsigned char* d = buf_;
+
+ while (s>0) {
+ int r = send(id_, d, s, 0);
+
+ if (r == -1) {
+ internalError("Fitsy++ outsocket deflate send error");
+ return Z_ERRNO;
+ }
+
+ if (DebugGZ)
+ cerr << "deflate send " << r << " out of " << s << endl;
+
+ s -= r;
+ d += r;
+ }
+
+ stream_->next_out = buf_;
+ stream_->avail_out = B4KB;
+ }
+
+ return result;
+}
+
+void OutFitsSocketGZ::putlong(unsigned long l)
+{
+ // dump in LSB order
+ for (int n = 0; n < 4; n++) {
+ unsigned char foo = (int)(l & 0xff);
+ send(id_, &foo, 1, 0);
+ l >>= 8;
+ }
+}
+
+#else
+
+OutFitsSocket::OutFitsSocket(int s)
+{
+ id_ = s;
+ valid_ = 0;
+}
+
+int OutFitsSocket::write(char* where, size_t size)
+{
+ return 0;
+}
+
+OutFitsSocketGZ::OutFitsSocketGZ(int s)
+{
+ id_ = s;
+ valid_ = 0;
+}
+
+OutFitsSocketGZ::~OutFitsSocketGZ() {}
+
+int OutFitsSocketGZ::write(char* where, size_t size)
+{
+ return 0;
+}
+
+int OutFitsSocketGZ::deflategz(int flush)
+{
+ return 0;
+}
+
+void OutFitsSocketGZ::putlong(unsigned long l) {}
+
+#endif