Readers.cc

00001 // ----------------------------------------------------------------------^
00002 // Copyright (C) 2004, 2005, 2006, 2007, 2008 Giorgio Calderone
00003 // (mailto: <gcalderone@ifc.inaf.it>)
00004 // 
00005 // This file is part of MCS.
00006 // 
00007 // MCS is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 // 
00012 // MCS is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 // 
00017 // You should have received a copy of the GNU General Public License
00018 // along with MCS; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 // 
00021 // ----------------------------------------------------------------------$
00022 #include "mcs.hh"
00023 using namespace mcs;
00024 
00025 //CURL includes
00026 #include <curl/curl.h>
00027 
00028 //CFITSIO include
00029 #if ENABLE_CFITSIO
00030 #include <fitsio.h>
00031 //#include <fstream>
00032 #endif  //ENABLE_CFITSIO
00033 
00034 
00035 Synchro Pipe::synchro;
00036 int Pipe::filecount = 0;
00037 
00038 Pipe::Pipe()
00039 {
00040   pipefn = "";
00041   pipefd[0] = 0;
00042   pipefd[1] = 0;
00043   flcreated = false;
00044   named = false;
00045 }
00046 
00047 Pipe::~Pipe()
00048 {
00049   //Assume that is always the thread who reads from the pipe that
00050   //manages the object creation/destruction
00051     //closeRead();
00052 }
00053 
00054 bool Pipe::isReady()
00055 { return flcreated; }
00056 
00057 string Pipe::filename()
00058 { return pipefn; }
00059 
00060 
00061 bool Pipe::consumerHasGone()
00062 {
00063   if (pipefd[1])
00064     if (Select(pipefd[1], 0, 1, MCS_SELECT_WRITE) == -1)
00065       return true;
00066 
00067   return false;
00068 }
00069 
00070 
00071 void Pipe::create()
00072 {
00073   if (flcreated)
00074     throw MCS_ERROR(MSG_PIPE_YET_OPENED);
00075 
00076   if (pipefd[0] + pipefd[1])
00077     throw MCS_ERROR(MSG_PIPE_YET_OPENED);
00078 
00079   if (pipe(pipefd) != 0)
00080     throw MCS_ERROR(MSG_CALLING_PIPE);
00081 
00082   flcreated = true;
00083   named = false;
00084 }
00085 
00086 string Pipe::createNamed()
00087 {
00088   char filename[20];
00089 
00090   if (flcreated)
00091     throw MCS_ERROR(MSG_PIPE_YET_OPENED);
00092 
00093   if (pipefd[0] + pipefd[1])
00094     throw MCS_ERROR(MSG_PIPE_YET_OPENED);
00095 
00096   do {
00097     /*
00098       Due to the fact that a Pipe object is typically used by two
00099       concurrent threads, and that the FIFO file is not open just as
00100       it is created (instead it is opened in the openRead() method)
00101       it is not safe to use tempnam-like functions. So we provide our
00102       own mechanisms to solve filename conflicts.
00103     */
00104     synchro.enter();
00105     sprintf(filename, "/tmp/mcspipe%04d", filecount);
00106     filecount++;
00107     filecount = filecount % 10000;
00108     synchro.leave();
00109 
00110     if (mkfifo(filename, S_IREAD | S_IWRITE) == 0)
00111       break;
00112 
00113     sleep_ms(20);
00114   } while (1);
00115 
00116   pipefn = filename;
00117   flcreated = true;
00118   named = true;
00119 
00120   return pipefn;
00121 }
00122 
00123 
00124 
00125 
00126 
00127 
00128 int Pipe::openRead()
00129 {
00130   if (! flcreated)
00131     throw MCS_ERROR(MSG_PIPE_NOT_CREATED);
00132 
00133   if (! pipefd[0]) {
00134       if (named) {
00135       pipefd[0] = open(pipefn.c_str(), O_RDONLY);
00136       unlink(pipefn.c_str()); //Remove the FIFO, it is no longer needed
00137       if (pipefd[0] == -1) throw MCS_ERROR(MSG_CANT_OPEN_FILE, pipefn.c_str());
00138       }
00139 
00140       //Ensure the other side hand of the pipe has been opened
00141       while (Select(pipefd[0], 0, 100, MCS_SELECT_READ) != 1) ;
00142   }
00143 
00144   return pipefd[0];
00145 }
00146 
00147 
00148 int Pipe::openWrite()
00149 {
00150   if (! flcreated)
00151     throw MCS_ERROR(MSG_PIPE_NOT_CREATED);
00152 
00153   if (! pipefd[1]) {
00154       if (named) {
00155       pipefd[1] = open(pipefn.c_str(), O_WRONLY);
00156       unlink(pipefn.c_str()); //Remove the FIFO, it is no longer needed
00157       if (pipefd[1] == -1) throw MCS_ERROR(MSG_CANT_OPEN_FILE, pipefn.c_str());
00158       }
00159 
00160       //Ensure the other side hand of the pipe has been opened
00161       while (Select(pipefd[1], 0, 100, MCS_SELECT_WRITE) != 1) ;
00162   }
00163 
00164   return pipefd[1];
00165 }
00166 
00167 
00168 void Pipe::closeRead()
00169 {
00170   if (! flcreated) return;  //Already closed
00171   if (named) unlink(pipefn.c_str()); //Remove the FIFO
00172 
00173   if (pipefd[0]) {
00174       //Close read side of the pipe
00175       close(pipefd[0]);
00176       pipefd[0] = 0;
00177   }
00178 
00179   pipefn = "";
00180   flcreated = false;
00181   named = false;
00182 }
00183 
00184 void Pipe::closeWrite()
00185 {
00186   if (! flcreated) return;  //Already closed
00187   if (named) unlink(pipefn.c_str()); //Remove the FIFO
00188 
00189   if (pipefd[1]) {
00190       //Close write side of the pipe
00191       close(pipefd[1]);
00192       pipefd[1] = 0;
00193   }
00194 }
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 bool mcs::URLReader::fl_curl_global_init = false;
00206 
00207 mcs::URLReader::URLReader() : Pipe()
00208 {
00209   if (! fl_curl_global_init) {
00210     fl_curl_global_init = true;
00211     curl_global_init(CURL_GLOBAL_ALL);
00212   }
00213 
00214   thr = NULL;
00215 }
00216 
00217 
00218 mcs::URLReader::~URLReader()
00219 { Close(); }
00220 
00221 
00222 string mcs::URLReader::url()
00223 { return lurl; }
00224 
00225 bool mcs::URLReader::chkLocal(string& url)
00226 {
00227   bool local = (bool) (
00228                (url.find("://") == string::npos)   ||
00229                (url.find("file://") == 0)
00230                );
00231 
00232   if (local) url = subst(url, "file://", "", MCS_SUBST_LEADING);
00233   return local;
00234 }
00235 
00236 
00237 int mcs::URLReader::OpenAsFD(string url)
00238 {
00239   local = chkLocal(url);
00240   this->lurl = url;
00241 
00242   create();
00243 
00244   thr = new ThreadFunc(thread_run, this);
00245   thr->startDetached();
00246   return openRead();
00247 }
00248 
00249 
00250 const char* mcs::URLReader::OpenAsFifo(string url)
00251 {
00252   local = chkLocal(url);
00253   this->lurl = url;
00254 
00255   string fn = createNamed();
00256 
00257   thr = new ThreadFunc(thread_run, this);
00258   thr->startDetached();
00259 
00260   return fn.c_str();
00261 }
00262 
00263 
00264 
00265 void mcs::URLReader::Download(string url, string fn)
00266 {
00267   ofstream out(fn.c_str());
00268 
00269   if (! out.is_open())
00270     throw MCS_ERROR(MSG_CANT_OPEN_FILE, fn.csz);
00271 
00272   int fd = OpenAsFD(url);
00273   char buf[1024];
00274   int n;
00275 
00276   while ((n = read(fd, buf, 1024)))
00277     out.write(buf, n);
00278 
00279   out.close();
00280   Close();
00281 }
00282 
00283 
00284 
00285 void mcs::URLReader::Close()
00286 {
00287   if (thr) {
00288     closeRead();
00289     lurl = "";
00290 
00291     while (thr->state() <= MCS_STATE_RUNNING)
00292       sleep_ms(20);
00293 
00294     if (thr->error())
00295     {
00296       Event e = *thr->error();
00297       delete thr;
00298       thr = NULL;
00299       throw e;
00300     }
00301     delete thr;
00302     thr = NULL;
00303   }
00304 }
00305 
00306 
00307 
00308 int mcs::URLReader::thread_run(void* p)
00309 {
00310   URLReader* This = (URLReader*) p;
00311   This->thread_fetch();
00312   return 0;
00313 }
00314 
00315 
00316 void mcs::URLReader::thread_fetch()
00317 {
00318   openWrite();  //Open file for writing, it is necessary here otherwise the
00319         //openRead() on the other thread won't return
00320 
00321   if (local) {
00322     int fd = open(lurl.c_str(), O_RDONLY);
00323     char buf[1024];
00324     int len;
00325 
00326     if (fd == -1) {
00327       closeWrite();
00328       throw MCS_ERROR(MSG_CANT_OPEN_FILE, lurl.c_str());
00329     }
00330 
00331     while ((len = read(fd, buf, 1024)))
00332       cb_write(buf, len, 1, this);
00333 
00334     closeWrite();
00335   }
00336   else {
00337     CURLcode res;
00338     CURL* curl = curl_easy_init();
00339 
00340     if (! curl)
00341       throw MCS_ERROR(MSG_CURL_INIT);
00342 
00343     res = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
00344     if (res != CURLE_OK) goto error;
00345 
00346     //Timeout in seconds
00347     res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 60);
00348     if (res != CURLE_OK) goto error;
00349 
00350     res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
00351     if (res != CURLE_OK) goto error;
00352 
00353     res = curl_easy_setopt(curl, CURLOPT_URL, lurl.c_str());
00354     if (res != CURLE_OK) goto error;
00355 
00356     //res = curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cb_progress);
00357     //if (res != CURLE_OK) goto error;
00358 
00359     res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb_write);
00360     if (res != CURLE_OK) goto error;
00361 
00362     res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
00363     if (res != CURLE_OK) goto error;
00364 
00365     res = curl_easy_setopt(curl, CURLOPT_PRIVATE, this);
00366     if (res != CURLE_OK) goto error;
00367 
00368     res = curl_easy_perform(curl);
00369     if (res != 0) goto error;
00370 
00371     closeWrite();
00372     return;
00373 
00374   error:
00375     closeWrite();
00376     curl_easy_cleanup((CURL*) curl);
00377     throw MCS_ERROR(MSG_CURL_ERROR, curl_easy_strerror(res));
00378   }
00379 }
00380 
00381 
00382 size_t mcs::URLReader::cb_write(void *ptr, size_t size, size_t nmemb,
00383                 void *This)
00384 {
00385   URLReader* p = (URLReader*) This;
00386 
00387   if (p->consumerHasGone())  //The pipe has been closed on the consumer side
00388     return 0;  //This will abort CURL data fetching
00389 
00390   //The Write() method is virtual because some derived class may wants
00391   //to write in a different manner
00392   return p->Write(ptr, size, nmemb);
00393 }
00394 
00395 
00396 void mcs::URLReader::flush()
00397 { fsync(openWrite()); }
00398 
00399 
00400 //In the base class version of the Write() method simply writes on
00401 //output file descriptor.
00402 unsigned int mcs::URLReader::Write(void *ptr, unsigned int size,
00403                    unsigned int nmemb)
00404 {  return write(openWrite(), ptr, size * nmemb); }
00405 
00406 
00407 
00408 
00409 int mcs::URLReader::Read(char* buf, int maxlen)
00410 { return read(openRead(), buf, maxlen); }
00411 
00412 
00413 //Event* mcs::URLReader::thread_error()
00414 //{
00415 //  if (thr)
00416 //    return thr->error();
00417 //
00418 //  return NULL;
00419 //}
00420 
00421 
00422 //int mcs::URLReader::cb_progress(void *clientp,
00423 //              double dltotal, double dlnow,
00424 //              double ultotal, double ulnow)
00425 //{
00426 //  cout << "Download statistics: " << dlnow << " : " << dltotal << endl;
00427 //  return 0; //Continue reading
00428 //}
00429 
00430 
00431 
00432 
00433 #if ENABLE_CFITSIO
00434 string mcs::fitsError(int status) {
00435   char buf[31];
00436   fits_get_errstatus(status, buf);
00437   return string(buf);
00438 }
00439 
00440 
00441 FITSReader::FITSReader() : RecordSet()
00442 { fptr = NULL; }
00443 
00444 
00445 FITSReader::~FITSReader()
00446 {}
00447 
00448 
00449 #define FITSKEYLEN 70
00450 #define CHECK_FITS_ERROR if (status) throw MCS_ERROR(MSG_FITS_ERROR, fitsError(status).c_str())
00451 
00452 
00453 int FITSReader::HDUCount()
00454 {
00455   int status = 0;
00456   fitsfile *fptr = (fitsfile*) this->fptr;
00457 
00458   fits_get_num_hdus(fptr, &nhdu, &status);
00459 
00460   return nhdu;
00461 }
00462 
00463 
00464 int FITSReader::currentHDU()
00465 {
00466   int i;
00467   fitsfile *fptr = (fitsfile*) this->fptr;
00468   fits_get_hdu_num(fptr, &i);
00469 
00470   return i;
00471 }
00472 
00473 void FITSReader::selectHDU(string name, int extver)
00474 {
00475   int status, i;
00476   fitsfile *fptr = (fitsfile*) this->fptr;
00477 
00478   status = 0;
00479   fits_movnam_hdu(fptr, ANY_HDU, (char*) name.c_str(), extver, &status);
00480   CHECK_FITS_ERROR;
00481 
00482   fits_get_hdu_num(fptr, &i);
00483   selectHDU(i);
00484 }
00485 
00486 
00487 bool FITSReader::selectNextHDU()
00488 {
00489   int status = 0;
00490   int exttype = ANY_HDU;
00491 
00492   fitsfile *fptr = (fitsfile*) this->fptr;
00493 
00494   fits_movrel_hdu(fptr, 1, &exttype, &status);
00495   if (status == END_OF_FILE)
00496     return false;
00497 
00498   CHECK_FITS_ERROR;
00499   selectHDU(currentHDU());
00500 
00501   return true;
00502 }
00503 
00504 
00505 void FITSReader::selectHDU(int hdunum)
00506 {
00507   int status;
00508   long int repeat, width;
00509   int i, j;
00510   int fits_type;
00511   Types type;
00512   bool flunsign;
00513   string s;
00514   char buf[FITSKEYLEN];
00515   char reqColName[5];
00516   char head_name[80];
00517   char head_val[80];
00518   char head_comment[80];
00519   Record meta;
00520   int nkeys;
00521   int hdutype;
00522 
00523   fitsfile *fptr = (fitsfile*) this->fptr;
00524   fits_get_num_hdus(fptr, &nhdu, &status);
00525 
00526   if ((hdunum <= 0)   ||   (hdunum > nhdu))
00527       throw; //ERROR
00528 
00529   status = 0;
00530   hdutype = ANY_HDU;
00531   fits_movabs_hdu(fptr, hdunum, &hdutype, &status);
00532   CHECK_FITS_ERROR;
00533 
00534   fits_get_hdrspace(fptr, &nkeys, NULL, &status);
00535   CHECK_FITS_ERROR;
00536 
00537   header.clear();
00538   header_comments.clear();
00539 
00540   for (i=1; i<=nkeys; i++) {
00541     fits_read_keyn(fptr, i, head_name, head_val, head_comment, &status);
00542     CHECK_FITS_ERROR;
00543 
00544     Data* d = new Data(string(head_val));
00545     d->setName(string(head_name));
00546     header.addField(d);
00547 
00548     d = new Data(string(head_comment));
00549     d->setName(string(head_name));
00550     header_comments.addField(d);
00551   }
00552 
00553   fits_get_hdu_type(fptr, &hdutype, &status);
00554   CHECK_FITS_ERROR;
00555 
00556   if ((hdutype == BINARY_TBL)   ||
00557       (hdutype == ASCII_TBL)       ) {
00558     //Number of records
00559     fits_get_num_rows(fptr, &nrows, &status);
00560     CHECK_FITS_ERROR;
00561 
00562     //Number of fields
00563     fits_get_num_cols(fptr, &ncols, &status);
00564     CHECK_FITS_ERROR;
00565 
00566     for (i=0; i< ncols; i++) {
00567       sprintf(reqColName, "%d", i+1);
00568       fits_get_colname(fptr, CASEINSEN, reqColName, buf, &j, &status);
00569       fits_get_coltype(fptr, j, &fits_type, &repeat, &width, &status);
00570       CHECK_FITS_ERROR;
00571 
00572       if (! FITS2Types(fits_type, type, flunsign))
00573     throw MCS_ERROR(MSG_TYPE_NOT_HANDLED, i, fits_type);
00574 
00575       if (! VarLenType(type))
00576     width = 0;
00577 
00578       Data* d = new Data(NULL, type, buf, width, flunsign);
00579       meta.addField(d);
00580     }
00581 
00582     i = MCS_RS_USEMETAREC | MCS_RS_KNOW_NROWS;
00583     if (local)
00584       i |= MCS_RS_RANDOM;
00585 
00586     init(i, nrows, &meta);
00587     startFetch();
00588   }
00589   else {  //Empty recordset
00590     i = MCS_RS_USEMETAREC | MCS_RS_KNOW_NROWS;
00591     init(i, 0, &meta);
00592   }
00593 }
00594 
00595 //static FILE* _origstdin_ = stdin;
00596 
00597 //int fits_open_pipe(fitsfile** fptr, int filedes, int rwmode, int* status)
00598 //{
00599 //  if (filedes == 0)
00600 //    stdin = _origstdin_;
00601 //  else
00602 //    _origstdin_ = fdopen(filedes, "r");
00603 //
00604 //  return fits_open_file(fptr, "-", READONLY, status);
00605 //}
00606 
00607 
00608 //void FITSReader::open(int fd)
00609 //{
00610 //  int status = 0;
00611 //  fitsfile *fptr;
00612 //
00613 //  fits_open_pipe(&fptr, fd, READONLY, &status);
00614 //  CHECK_FITS_ERROR;
00615 //  this->fptr = fptr;
00616 //
00617 //  fits_get_num_hdus(fptr, &nhdu, &status);
00618 //  CHECK_FITS_ERROR;
00619 //
00620 //  selectHDU(1);
00621 //}
00622 
00623 
00624 //static FILE* _origstdin_ = stdin;
00625 
00626 void FITSReader::open(Buffer& buf)
00627 {
00628   int status;
00629   fitsfile *fptr;
00630 
00631   memfile.set(buf[0], buf.size(), AUTO_FREE);
00632 
00633   memfilep = memfile[0];
00634   memfilesize = memfile.size();
00635   fits_open_memfile(&fptr, "mem.fits", READONLY,
00636             &memfilep, &memfilesize,
00637             0, NULL, &status);
00638 
00639   CHECK_FITS_ERROR;
00640   this->fptr = fptr;
00641 
00642   fits_get_num_hdus(fptr, &nhdu, &status);
00643   CHECK_FITS_ERROR;
00644 
00645   selectHDU(1);
00646 }
00647 
00648 
00649 
00650 
00651 void FITSReader::open(string fn)
00652 {
00653   int status;
00654   fitsfile *fptr;
00655 
00656   local = URLReader::chkLocal(fn);
00657   //local = false;
00658 
00659   status = 0;
00660   //if (local) {
00661   if (local && this->ffile_is_compressed(fn)) {
00662     fits_open_file(&fptr, fn.c_str(), READONLY, &status);
00663   }
00664   else {
00665     //The FITSReader can read also remote files (using its parent class
00666     //URLReader). Note that CFITSIO cannot read a FITS file as a
00667     //stream so actually it is entirely loaded into memory and then
00668     //parsed.
00669 
00670     //Open the remote file as a file descriptor
00671     URLReader url;
00672     int fd = url.OpenAsFD(fn.c_str());
00673     int n;
00674     char tmp[8192];
00675 
00676     //Load the FITS file into memory
00677     memfile.free();
00678     while ((n = read(fd, tmp, 8192)))
00679     memfile(n) << tmp;
00680 
00681     memfilep = memfile[0];
00682     memfilesize = memfile.size();
00683     fits_open_memfile(&fptr, "mem.fits", READONLY,
00684               &memfilep, &memfilesize,
00685               0, NULL, &status);
00686 
00688     //stdin = fdopen(fd, "r");
00689     //
00691     //fits_open_file(&fptr, "-", READONLY, &status);
00692     //
00694     //stdin = _origstdin_;
00695 
00696     //Close the remote file descriptor. If an error occurred during timeout
00697     //an exception will be thrown here.
00698     url.Close();
00699   }
00700 
00701   CHECK_FITS_ERROR;
00702   this->fptr = fptr;
00703 
00704   fits_get_num_hdus(fptr, &nhdu, &status);
00705   CHECK_FITS_ERROR;
00706 
00707   selectHDU(1);
00708 }
00709 
00710 
00711 
00712 bool FITSReader::fetch(unsigned int newpos, bool random)
00713 {
00714   int i, status = 0;
00715   fitsfile *fptr = (fitsfile*) this->fptr;
00716 
00717   if (newpos >= nrows)
00718     return false;
00719 
00720   for (i=0; i<ncols; i++) {
00721     void* p = rec()[i].buffer();
00722     int fitstype;
00723     int isnull;
00724 
00725     Types2FITS(rec()[i].type(), rec()[i].isUnsigned(), fitstype);
00726 
00727     fits_read_col(fptr, fitstype, i+1, newpos+1, 1, 1, NULL,
00728           (VarLenType(rec()[i].type())  ?   &p   :   p),
00729           &isnull, &status);
00730     CHECK_FITS_ERROR;
00731 
00732     rec()[i].setNull(isnull);
00733   }
00734 
00735   return true;
00736 }
00737 
00738 
00739 void FITSReader::close() {
00740   int status = 0;
00741   fitsfile *fptr = (fitsfile*) this->fptr;
00742 
00743   if (fptr) {
00744     fits_close_file(fptr, &status);
00745     fptr = NULL;
00746     CHECK_FITS_ERROR;
00747   }
00748 }
00749 
00750 bool FITSReader::ffile_is_compressed(string fn) {
00751   char buf[2];
00752 
00753   try {
00754     std::ifstream in(fn.c_str(), ios_base::in | ios_base::binary);
00755 
00756     in.read(&buf[0], 2);
00757 
00758     in.close();
00759 
00760     if ( (memcmp(buf, "\037\213", 2) == 0) ||  /* GZIP  */
00761          (memcmp(buf, "\120\113", 2) == 0) ||  /* PKZIP */
00762          (memcmp(buf, "\037\036", 2) == 0) ||  /* PACK  */
00763          (memcmp(buf, "\037\235", 2) == 0) ||  /* LZW   */
00764          (memcmp(buf, "\037\240", 2) == 0) )   /* LZH   */
00765     {
00766       return true;  /* compressed file */
00767     } else {
00768       return false;  /* not a compressed file */
00769     }
00770   } catch(Event& e) {
00771     cerr <<"ffile_is_compressed: "<< e.msg() << endl;
00772     return false;
00773   }
00774 
00775 }
00776 #endif //ENABLE_CFITSIO
00777 
00778 
00779 
00780 
00781 
00782 
00783 //FileReader::FileReader() : RecordSet()
00784 //{
00785 //  fd = 0;
00786 //}
00787 //
00788 //FileReader::~FileReader()
00789 //{
00790 //  this->close();
00791 //}
00792 //
00793 //void FileReader::open(string url)
00794 //{
00795 //  this->close();
00796 //
00797 //  if (master.count() == 0)
00798 //    throw;
00799 //
00800 //  fd = input.OpenAsFD(url);
00801 //  init(0);
00802 //  startFetch();
00803 //}
00804 //
00805 //
00806 //bool FileReader::fetch(unsigned int newpos, bool random)
00807 //{
00808 //  if (sep.length() > 0) {   //Variable length record
00809 //    ;
00810 //
00811 //  }
00812 //  else {  //Fixed length record
00813 //    size_t recsize = 0;
00814 //    int i;
00815 //    for (i=0; i<master.count(); i++)  //Compute record size
00816 //      recsize += master[i].maxLength();
00817 //
00818 //    buf.chkAllocation(recsize);
00819 //    unsigned int size = read(fd, buf[0], recsize);
00820 //
00821 //    if (size < recsize)
00822 //      throw;
00823 //
00824 //    //Copy data into the current record object
00825 //    rec() = master;
00826 //    unsigned int cur = 0;
00827 //    for (i=0; i<master.count(); i++) {
00828 //      buf(cur, rec()[i].maxLength()) >> rec()[i].buffer();
00829 //      cur += rec()[i].maxLength();
00830 //    }
00831 //  }
00832 //
00833 //  return true;
00834 //}
00835 //
00836 //void FileReader::close()
00837 //{
00838 //  sep = "";
00839 //  eor = "";
00840 //  master.clear();
00841 //}
00842 //
00843 //void FileReader::setMaster(Record& rec)
00844 //{
00845 //  sep = "";
00846 //  eor = "";
00847 //  master = rec;
00848 //}
00849 //
00850 //void FileReader::setMaster(Record& rec, string sep)
00851 //{
00852 //  this->sep = sep;
00853 //  eor = "";
00854 //  master = rec;
00855 //}
00856 //
00857 //void FileReader::setMaster(Record& rec, string sep, string eor)
00858 //{
00859 //  this->sep = sep;
00860 //  this->eor = eor;
00861 //  master = rec;
00862 //}

mcslogo

MCS (My Customizable Server) ver. 0.3.3-alpha3
Documentation generated on Thu Mar 22 13:22:23 UTC 2012