00001
00025 #include "magic/mdatastream.h"
00026 #include "magic/mpararr.h"
00027
00028 BEGIN_NAMESPACE (MagiC);
00029
00031
00032
00033
00034
00035
00036
00037
00039
00055 DataOStream::DataOStream (FILE* strm) : OStream (strm) {
00056 mDepth = 0;
00057 mPrevDepth = -1;
00058 mFormatMode = FMT_TEXT;
00059 mAttribs = NULL;
00060 }
00061
00062 DataOStream::DataOStream (OStream& o) : OStream (o) {
00063 mDepth = 0;
00064 mPrevDepth = -1;
00065 mFormatMode = FMT_TEXT;
00066 mAttribs = NULL;
00067 }
00068
00069 DataOStream::~DataOStream () {
00070 delete mAttribs;
00071 }
00072
00076 #define CHECKRECORD(rtype,var) \
00077 if (mFormatMode & FMT_RECORD) {\
00078 if (mNextName.isEmpty())\
00079 mNextName = "?";\
00080 mAttribs->add (new String (strformat ("%s %s", #rtype, (CONSTR)mNextName)));\
00081 return *this;\
00082 }
00083
00084 DataOStream& DataOStream::operator<< (char i)
00085 {
00086 CHECKRECORD (char, i);
00087
00088 if (!mpDevice)
00089 return *this;
00090
00091 if (mFormatMode & FMT_TEXT) {
00092 printComma ();
00093 printName ();
00094 mpDevice->writeBlock ((char*) &i, sizeof(char));
00095 } else {
00096 mpDevice->writeBlock ((char*) &i, sizeof(i));
00097 }
00098
00099 return *this;
00100 }
00101
00102 DataOStream& DataOStream::operator<< (int i)
00103 {
00104 CHECKRECORD (int, i);
00105
00106 operator<< ((long) i);
00107 return *this;
00108 }
00109
00110 DataOStream& DataOStream::operator<< (long i)
00111 {
00112 CHECKRECORD (long, int (i));
00113
00114 if (!mpDevice)
00115 return *this;
00116
00117 if (mFormatMode & FMT_TEXT) {
00118 printComma ();
00119 printName ();
00120 mpDevice->writeBlock (String(i));
00121 } else {
00122 mpDevice->writeBlock ((char*) &i, sizeof(i));
00123 }
00124
00125 return *this;
00126 }
00127
00128 DataOStream& DataOStream::operator<< (float i)
00129 {
00130 CHECKRECORD (float, i);
00131 operator<< ((double) i);
00132 return *this;
00133 }
00134
00135 DataOStream& DataOStream::operator<< (double i)
00136 {
00137 CHECKRECORD (double, float(i));
00138
00139 if (!mpDevice)
00140 return *this;
00141
00142 if (mFormatMode & FMT_TEXT) {
00143 printComma ();
00144 printName ();
00145 mpDevice->writeBlock (String(i));
00146 } else {
00147 mpDevice->writeBlock ((char*) &i, sizeof(i));
00148 }
00149
00150 return *this;
00151 }
00152
00153 DataOStream& DataOStream::operator<< (CONSTR str)
00154 {
00155 CHECKRECORD (char*, p);
00156
00157 if (!mpDevice)
00158 return *this;
00159
00160 if (mFormatMode & FMT_TEXT) {
00161 printComma ();
00162 printName ();
00163 }
00164
00165 mpDevice->writeBlock (str, strlen(str));
00166 return *this;
00167 }
00168
00169 DataOStream& DataOStream::operator<< (const String& str)
00170 {
00171 CHECKRECORD (char*, p);
00172
00173 if (!mpDevice)
00174 return *this;
00175
00176 return str.operator>> (*this);
00177 }
00178
00179 uint DataOStream::writeRawBytes (const char* p, uint n)
00180 {
00181
00182
00183 if (!mpDevice)
00184 return 0;
00185
00186 if (mFormatMode & FMT_TEXT) {
00187 printIndent ();
00188 printComma ();
00189 printName ();
00190
00191 if (!p)
00192 return mpDevice->writeBlock ("(null)");
00193 else {
00194 String zeroterm (p, n);
00195 mpDevice->putch ('"');
00196 uint wrote = mpDevice->writeBlock (zeroterm);
00197 mpDevice->putch ('"');
00198 return wrote + 2;
00199 }
00200 } else
00201 return mpDevice->writeBlock (p, n);
00202
00203 return 0;
00204 }
00205
00207 DataOStream& DataOStream::printName ()
00208 {
00209 if ((mFormatMode & FMT_TEXT) && !mNextName.isEmpty()) {
00210 mpDevice->writeBlock (mNextName);
00211 mpDevice->writeBlock ("=", 1);
00212 mNextName="";
00213 }
00214 return *this;
00215 }
00216
00218 void DataOStream::printIndent ()
00219 {
00220 if ((mFormatMode & FMT_TEXT) && false)
00221 for (int j=0; j<mDepth; j++)
00222 mpDevice->writeBlock (" ", 4);
00223 }
00224
00228 void DataOStream::printComma ()
00229 {
00230 if (mDepth <= mPrevDepth)
00231 mpDevice->writeBlock (", ", 2);
00232 mPrevDepth = mDepth;
00233 }
00234
00235
00236
00238
00239
00240
00241
00242
00243
00244
00246
00248 DataIStream& DataIStream::operator>> (int& i)
00249 {
00250 long i2=i;
00251 operator>> (i2);
00252 i=i2;
00253 return *this;
00254 }
00255
00257 DataIStream& DataIStream::operator>> (long& i)
00258 {
00259 int retval = mpDevice->readBlock ((char*) &i, sizeof(i));
00260 if (retval != sizeof(i))
00261 throw io_error ("Reading long value from text stream failed.");
00262 return *this;
00263 }
00264
00266 DataIStream& DataIStream::operator>> (char& i)
00267 {
00268 int retval = mpDevice->readBlock ((char*) &i, sizeof(i));
00269 if (retval != sizeof(i))
00270 throw io_error ("Reading char value from text stream failed.");
00271 return *this;
00272 }
00273
00275 DataIStream& DataIStream::operator>> (float& i)
00276 {
00277 int retval = mpDevice->readBlock ((char*) &i, sizeof(i));
00278 if (retval != sizeof(i))
00279 throw io_error ("Reading float value from text stream failed.");
00280 return *this;
00281 }
00282
00284 DataIStream& DataIStream::operator>> (double& i )
00285 {
00286 int retval = mpDevice->readBlock ((char*) &i, sizeof(i));
00287 if (retval != sizeof(i))
00288 throw io_error ("Reading double value from text stream failed.");
00289 return *this;
00290 }
00291
00292 DataIStream& DataIStream::operator>> (String& s)
00293 {
00294
00295 s.String::operator<< (*this);
00296
00297 return *this;
00298 }
00299
00301 uint DataIStream::readRawBytes (char* p,
00302 uint n )
00303 {
00304 if (!mpDevice)
00305 return 0;
00306
00307 uint retval = mpDevice->readBlock (p, n);
00308
00309 if (retval != n)
00310 throw io_error (String("Data stream ended unexpectedly (expected %1 bytes, got %2.")
00311 .arg((int) n).arg((int) retval));
00312
00313 return retval;
00314 }
00315
00317 #if 0
00318 DataIStream& operator<< (DataIStream& out,
00319 const char* str)
00320 {
00321
00322
00323 return out;
00324 }
00325
00327 TextIStream& TextIStream::operator>> (int& i)
00328 {
00329 long i2=i;
00330 operator>> (i2);
00331 i=i2;
00332 return *this;
00333 }
00334
00336 TextIStream& TextIStream::operator>> (long& i)
00337 {
00338 if (fread ((char*) &i, sizeof(i), 1, stream) != 1)
00339 throw IOError ();
00340 return *this;
00341 }
00342
00344 TextIStream& TextIStream::operator>> (char& i)
00345 {
00346 if (fread ((char*) &i, sizeof(i), 1, stream) != 1)
00347 throw IOError ();
00348 return *this;
00349 }
00350
00352 TextIStream& TextIStream::operator>> (float& i)
00353 {
00354 double i2=i;
00355 operator>> (i2);
00356 i=i2;
00357 return *this;
00358 }
00359
00361 TextIStream& TextIStream::operator>> (double& i )
00362 {
00363 if (fread ((char*) &i, sizeof(i), 1, stream) != 1)
00364 throw IOError ();
00365 return *this;
00366 }
00367
00369 TextIStream& TextIStream::read (char* p,
00370 int n )
00371 {
00372 int bytesread = fread (p, 1, n, stream);
00373 if (bytesread != n)
00374 throw IOError (i18n("%1 bytes read instead of %2 that were asked")
00375 .arg(bytesread).arg(n));
00376 return *this;
00377 }
00378
00379 TextIStream& TextIStream::operator>> (char* p)
00380 {
00381 if (in)
00382 in->read (p, n);
00383 return *this;
00384 }
00385 #endif
00386
00387 END_NAMESPACE;
00388