1 /* *************************************************************************
2    io.hpp  -  GDL classes for file io
3    -------------------
4    begin                : July 22 2002
5    copyright            : (C) 2002 by Marc Schellens
6    email                : m_schellens@users.sf.net
7 ***************************************************************************/
8 
9 /* *************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef IO_HPP_
19 #define IO_HPP_
20 
21 #include "includefirst.hpp"
22 
23 #include <fstream>
24 #include <iostream>
25 #include <string>
26 #include <cmath>
27 #include <cassert>
28 
29 #include <sys/types.h>
30 #if defined(_WIN32) && !defined(__CYGWIN__)
31 #else
32 	#include <sys/socket.h>
33 	#include <netinet/in.h>
34 	#include <netdb.h>
35 	#include <arpa/inet.h>
36 	#include <unistd.h>
37 #endif
38 
39 #include <string.h>  // for memcpy
40 #include "gzstream.hpp"
41 
42 #include "gdlexception.hpp"
43 
44 // GGH ggh hack to implement SPAWN keyword UNIT
45 #ifdef HAVE_EXT_STDIO_FILEBUF_H
46 #  include <ext/stdio_filebuf.h>
47 #endif
48 //#include <bits/basic_ios.h>
49 
50 
51 // the file IO system consists of 128 GDLStream objects
52 
53 const int maxLun=128;    // within GDL, internal max LUN is 127
54 const int maxUserLun=99; // within GDL, internal always lun-1 is used
55 
56 const std::string StreamInfo( std::ios* searchStream);
57 
58 const SizeT defaultStreamWidth = 80; // used by open_lun
59 
60 class AnyStream
61 {
62 // GGH ggh made all these public
63 public:
64   std::fstream* fStream;
65   igzstream* igzStream; // for gzip compressed input
66   ogzstream* ogzStream; // for gzip compressed output
67 
68 //public:
AnyStream()69   AnyStream()
70     : fStream(NULL)
71     , igzStream(NULL)
72     , ogzStream(NULL) {}
73 
74   void Flush() ;
75   void Close();
76 
77   void Open(const std::string& name_,
78 	    std::ios_base::openmode mode_ , bool compress_);
79 
FStream()80   std::fstream* FStream(){return fStream;}
IgzStream()81   igzstream* IgzStream(){return igzStream;} // for gzip compressed input
OgzStream()82   ogzstream* OgzStream(){return ogzStream;} // for gzip compressed output
83 
84   void ClearEof();
85 
86   void Write( char* buf, std::streamsize nBytes);
87 
88 
89   void Read( char* buf, std::streamsize nBytes);
90   std::streamsize Gcount();
91   bool Good();
92 
93   bool EofRaw();
94 
95 
96  void SeekEof();
97 
98   bool Eof();
99 
100   void Seek( std::streampos pos);
101   DLong64 Skip( std::streampos pos, bool doThrow=true);
102   DLong SkipLines( DLong nlines, bool doThrow);
103   std::streampos Size();
104 
105   std::streampos Tell();
106 
107  void SeekPad(std::streampos pos);
108 
InUse()109   bool InUse() { return (fStream != NULL || igzStream != NULL || ogzStream != NULL);}
IsOpen()110   bool IsOpen()
111   { return (fStream != NULL && fStream->is_open()) || (igzStream != NULL && igzStream->rdbuf()->is_open()) || (ogzStream != NULL && ogzStream->rdbuf()->is_open());}
112 
113   void Pad( std::streamsize nBytes);
114 
Clear()115   void Clear()
116   {
117   }
118 
119 };
120 
121 
122 
123 class GDLStream
124 {
125   bool getLunLock;
126 
127   std::string name;
128   std::ios_base::openmode mode;
129 
130   AnyStream* anyStream;
131 
132   //    std::fstream* fStream;
133   //    igzstream* igzStream; // for gzip compressed input
134   //    ogzstream* ogzStream; // for gzip compressed output
135 
136 
137   bool f77; // FORTRAN unformatted
138   bool swapEndian;
139   bool deleteOnClose;
140   bool varlenVMS;
141   bool compress;
142   XDR *xdrs;
143 
144   std::istringstream* iSocketStream;
145   int sockNum;
146   std::string* recvBuf;
147   DDouble c_timeout;
148   DDouble r_timeout;
149   DDouble w_timeout;
150 
151 #ifdef HAVE_EXT_STDIO_FILEBUF_H
152 // GGH ggh hack to implement SPAWN keyword UNIT
153   __gnu_cxx::stdio_filebuf<char> *readbuf_frb_destroy_on_close_p;
154   std::basic_streambuf<char> *readbuf_bsrb_destroy_on_close_p;
155   int fd_close_on_close;
156 #endif
157 
158   SizeT width;
159 
160   std::streampos lastSeekPos;
161 
162   // for F77
163   std::streampos lastRecord;
164   std::streampos lastRecordStart;
165 
166   void Pad( std::streamsize nBytes); // puts out nBytes zero bytes
167 
168 public:
GDLStream()169   GDLStream():
170     getLunLock(false),
171     name(),
172     mode(),
173     anyStream(NULL),
174     /*    fStream(NULL),
175 	  igzStream(NULL),
176 	  ogzStream(NULL), */
177     f77(false),
178     swapEndian(false),
179     deleteOnClose(false),
180     varlenVMS(false),
181     compress(false),
182     xdrs(NULL),
183 
184     iSocketStream(NULL),
185     sockNum( -1),
186     recvBuf(NULL),
187     c_timeout(0.0),
188     r_timeout(0.0),
189     w_timeout(0.0),
190 
191     width( defaultStreamWidth),
192     lastSeekPos( 0),
193     lastRecord( 0),
194     lastRecordStart( 0)
195     {
196 #ifdef HAVE_EXT_STDIO_FILEBUF_H
197       readbuf_frb_destroy_on_close_p = NULL;
198       readbuf_bsrb_destroy_on_close_p = NULL;
199       fd_close_on_close = -1;
200 #endif
201     }
202 
~GDLStream()203   ~GDLStream()
204   {
205     delete xdrs;
206 
207     delete anyStream;
208     /*    delete fStream;
209 	  delete igzStream;
210 	  delete ogzStream;*/
211     delete iSocketStream;
212   }
213 
214   void Open( const std::string& name_,
215 	     std::ios_base::openmode,
216 	     bool swapEndian_, bool deleteOnClose_, bool xdr_,
217 	     SizeT width, bool f77, bool compress);
218 
219   void Socket( const std::string& host,
220 	       DUInt port, bool swapEndian_,
221 	       DDouble c_timeout, DDouble r_timeout, DDouble w_timeout);
222 
223   void Flush();
224 
225   void Close();
226 
227   bool Eof();
228 
229   void SeekEof();
230   void Seek( std::streampos pos);
231   DLong64 Skip( std::streampos pos, bool doThrow=true);
232   void Truncate();
233 
234   DLong SkipLines( DLong nlines, bool doThrow=true);
235   DLong64 CopySomeTo( DLong64 pos, GDLStream& to, bool doThrow=true);
236   DLong CopySomeLinesTo( DLong nlines, GDLStream& to, bool doThrow=true);
237 
Size()238   std::streampos Size()
239   {
240     return anyStream->Size();
241   }
242 
Tell()243   std::streampos Tell()
244   {
245     return anyStream->Tell();
246   }
247 
Width()248   SizeT Width()
249   {
250     return width;
251   }
252 
253   void SeekPad( std::streampos pos);
254 
InUse()255   bool InUse() { return (anyStream != NULL && anyStream->InUse());}
256 
IsOpen()257   bool IsOpen()
258   { return (anyStream != NULL && anyStream->IsOpen());}
IsReadable()259   bool IsReadable()
260   { return (IsOpen() && (mode & std::ios::in));}
IsWriteable()261   bool IsWriteable()
262   { return (IsOpen() && (mode & std::ios::out));}
263 
264   void Free();
265 
SetGetLunLock(bool b)266   void SetGetLunLock( bool b) { getLunLock = b;}
GetGetLunLock()267   bool GetGetLunLock() { return getLunLock;}
268 
Name()269   const std::string& Name() { return name;}
270 
SwapEndian()271   bool SwapEndian() { return swapEndian;}
272 
VarLenVMS()273   bool VarLenVMS() { return varlenVMS;}
PutVarLenVMS(bool varlenVMS_)274   void PutVarLenVMS( bool varlenVMS_) { varlenVMS = varlenVMS_;}
275 
Compress()276   bool Compress() { return compress;}
277   /*  void PutCompress( bool compress_) { compress = compress_;}*/
278   igzstream& IgzStream();
279   ogzstream& OgzStream();
280 
Xdr()281   XDR *Xdr() { return xdrs;}
282 
283   std::fstream& IStream();
284   std::fstream& OStream();
285 
SockNum()286   int SockNum() { return sockNum;}
287   std::istringstream& ISocketStream();
RecvBuf()288   std::string& RecvBuf() { return *recvBuf;}
cTimeout()289   DDouble cTimeout() { return c_timeout;}
rTimeout()290   DDouble rTimeout() { return r_timeout;}
wTimeout()291   DDouble wTimeout() { return w_timeout;}
292 
293 //   friend const std::string StreamInfo( AnyStream* searchStream);
294   friend const std::string StreamInfo( std::ios* searchStream);
295 
296   // F77_UNFORMATTED stuff
F77()297   bool F77() { return f77;}
298   void F77Write( DULong tCount);
299 
300   DULong F77ReadStart();
301   void   F77ReadEnd();
302 
303 
304 #ifdef HAVE_EXT_STDIO_FILEBUF_H
305 // GGH ggh hack to implement SPAWN keyword UNIT
306   std::basic_streambuf<char> *get_stream_readbuf_bsrb();
307   int set_stream_readbuf_bsrb_from_frb(__gnu_cxx::stdio_filebuf<char> *frb_p);
308   int set_readbuf_frb_destroy_on_close(__gnu_cxx::stdio_filebuf<char> *frb_p);
309   int set_readbuf_bsrb_destroy_on_close(std::basic_streambuf<char> *bsrb_p);
310   int set_fd_close_on_close(int fd);
311 #endif
312 
313 };
314 
315 
316 typedef std::vector<GDLStream> GDLFileListT;
317 
318 #endif
319