00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <iostream>
00027 #include <cstring>
00028 #include <cstdlib>
00029 #include <fstream>
00030 #include <streambuf>
00031 #include <cstdio>
00032
00033 using namespace std;
00034
00035 #ifndef MF_STREAM_H
00036 #define MF_STREAM_H
00037
00038 extern "C" {
00039 ssize_t write (int fd, const void* buf, size_t num);
00040 ssize_t read (int fd, void* buf, size_t num);
00041 FILE *popen(const char *command, const char *type);
00042 int pclose(FILE *stream);
00043 int fseek( FILE *stream, long offset, int whence);
00044 long ftell( FILE *stream);
00045 };
00046
00047
00049 class fdbuf : public std::streambuf
00050 {
00051
00052 protected:
00053 int fd;
00054
00055
00056 virtual int_type overflow (int_type c) {
00057 char z = c;
00058 if (c != EOF) {
00059 if (write (fd, &z, 1) != 1) {
00060 return EOF;
00061 }
00062 }
00063
00064
00065 return c;
00066 }
00067
00068
00069 virtual
00070 std::streamsize xsputn (const char* s,
00071 std::streamsize num) {
00072 return write(fd,s,num);
00073
00074 }
00075
00076 virtual streampos seekpos ( streampos , ios_base::openmode = ios_base::in | ios_base::out ) {
00077 std::cerr << "mfstream::seekpos is not implemented" << std::endl;;
00078
00079 return (streampos) 0;
00080 }
00081
00082
00083 virtual int_type underflow () {
00084
00085 if (gptr() < egptr()) {
00086 return traits_type::to_int_type(*gptr());
00087 }
00088
00089
00090
00091
00092
00093 int numPutback;
00094 numPutback = gptr() - eback();
00095 if (numPutback > 4) {
00096 numPutback = 4;
00097 }
00098
00099
00100
00101
00102 std::memmove (buffer+(4-numPutback), gptr()-numPutback,
00103 numPutback);
00104
00105
00106 int num;
00107 num = read (fd, buffer+4, bufferSize-4);
00108 if (num <= 0) {
00109
00110 return EOF;
00111 }
00112
00113
00114 setg (buffer+(4-numPutback),
00115 buffer+4,
00116 buffer+4+num);
00117
00118
00119 return traits_type::to_int_type(*gptr());
00120 }
00121
00122
00123
00124 virtual
00125 std::streamsize xsgetn (char* s,
00126 std::streamsize num) {
00127 return read(fd,s,num);
00128 }
00129
00130 static const int bufferSize = 10;
00131 char buffer[bufferSize];
00132
00133 public:
00134
00135
00136 fdbuf (int _fd) : fd(_fd) {
00137 setg (buffer+4,
00138 buffer+4,
00139 buffer+4);
00140 }
00141
00142 };
00143
00144
00145
00147
00148 class mfstream : public std::fstream
00149 {
00150
00151 protected:
00152 fdbuf* buf;
00153 int _cmd;
00154 openmode _mode;
00155 FILE* _FILE;
00156
00157
00158 int swapbytes(char *p, int sz, int n);
00159
00160 public:
00161
00162 char _cmdname[500];
00163
00165 mfstream () : std::fstream(), _cmd(0) {
00166 }
00167
00169 mfstream (const char* name,openmode mode) : std::fstream() {
00170 _cmdname[0]='\0';
00171 _mode=mode;
00172 open(name,mode);
00173 }
00174
00176 ~mfstream() {
00177 if (_cmd<2) close();
00178 }
00179
00181 void open(const char *name,openmode mode);
00182
00184 void close();
00185
00187 mfstream& writex(void *p, int sz,int n=1);
00188
00190 mfstream& readx(void *p, int sz,int n=1);
00191
00193 mfstream& iwritex(streampos loc,void *ptr,int size,int n=1);
00194
00196 streampos tellp() {
00197 if (_cmd==0) return (streampos) fstream::tellg();
00198 cerr << "tellp not allowed on commands\n";
00199 exit(1);
00200 }
00201
00203 mfstream& seekp(streampos loc) {
00204 if (_cmd==0)
00205 fstream::seekg(loc);
00206 else {
00207 cerr << "seekp not allowed on commands\n";
00208 exit(1);
00209 }
00210 return *this;
00211 }
00212
00214
00215 mfstream& reopen() {
00216
00217 if (_mode != in) {
00218 cerr << "mfstream::reopen() openmode must be ios:in\n";
00219 exit(1);
00220 }
00221
00222 if (strlen(_cmdname)>0) {
00223 char *a=new char[strlen(_cmdname)+1];
00224 strcpy(a,_cmdname);
00225 cerr << "close/open " << a <<"\n";
00226 close();
00227 open(a,ios::in);
00228 } else
00229 seekp(0);
00230
00231 return *this;
00232 }
00233
00234 };
00235
00236
00237 #endif