Home | History | Annotate | Download | only in marisa
      1 #include <limits.h>
      2 #include <stdio.h>
      3 
      4 #ifdef _MSC_VER
      5 #include <io.h>
      6 #else  // _MSC_VER
      7 #include <unistd.h>
      8 #endif  // _MSC_VER
      9 
     10 #include "reader.h"
     11 
     12 namespace marisa {
     13 
     14 Reader::Reader()
     15     : file_(NULL), fd_(-1), stream_(NULL), needs_fclose_(false) {}
     16 
     17 Reader::Reader(std::FILE *file)
     18     : file_(file), fd_(-1), stream_(NULL), needs_fclose_(false) {}
     19 
     20 Reader::Reader(int fd)
     21     : file_(NULL), fd_(fd), stream_(NULL), needs_fclose_(false) {}
     22 
     23 Reader::Reader(std::istream *stream)
     24     : file_(NULL), fd_(-1), stream_(stream), needs_fclose_(false) {}
     25 
     26 Reader::~Reader() {
     27   if (needs_fclose_) {
     28     ::fclose(file_);
     29   }
     30 }
     31 
     32 void Reader::open(const char *filename, long offset, int whence) {
     33   MARISA_THROW_IF(is_open(), MARISA_STATE_ERROR);
     34   MARISA_THROW_IF(filename == NULL, MARISA_PARAM_ERROR);
     35 #ifdef _MSC_VER
     36   std::FILE *file = NULL;
     37   if (::fopen_s(&file, filename, "rb") != 0) {
     38     MARISA_THROW(MARISA_IO_ERROR);
     39   }
     40 #else  // _MSC_VER
     41   std::FILE * const file = ::fopen(filename, "rb");
     42   MARISA_THROW_IF(file == NULL, MARISA_IO_ERROR);
     43 #endif  // _MSC_VER
     44   if (::fseek(file, offset, whence) != 0) {
     45     ::fclose(file);
     46     MARISA_THROW(MARISA_IO_ERROR);
     47   }
     48   file_ = file;
     49   needs_fclose_ = true;
     50 }
     51 
     52 void Reader::clear() {
     53   Reader().swap(this);
     54 }
     55 
     56 void Reader::swap(Reader *rhs) {
     57   MARISA_THROW_IF(rhs == NULL, MARISA_PARAM_ERROR);
     58   Swap(&file_, &rhs->file_);
     59   Swap(&fd_, &rhs->fd_);
     60   Swap(&stream_, &rhs->stream_);
     61   Swap(&needs_fclose_, &rhs->needs_fclose_);
     62 }
     63 
     64 void Reader::read_data(void *buf, std::size_t size) {
     65   if (fd_ != -1) {
     66     while (size != 0) {
     67 #ifdef _MSC_VER
     68       const unsigned int count = (size < INT_MAX) ? size : INT_MAX;
     69       const int size_read = _read(fd_, buf, count);
     70 #else  // _MSC_VER
     71       const ::size_t count = (size < SSIZE_MAX) ? size : SSIZE_MAX;
     72       const ::ssize_t size_read = ::read(fd_, buf, count);
     73 #endif  // _MSC_VER
     74       MARISA_THROW_IF(size_read <= 0, MARISA_IO_ERROR);
     75       buf = static_cast<char *>(buf) + size_read;
     76       size -= size_read;
     77     }
     78   } else if (file_ != NULL) {
     79     if (::fread(buf, 1, size, file_) != size) {
     80       MARISA_THROW(MARISA_IO_ERROR);
     81     }
     82   } else if (stream_ != NULL) {
     83     if (!stream_->read(static_cast<char *>(buf), size)) {
     84       MARISA_THROW(MARISA_IO_ERROR);
     85     }
     86   } else {
     87     MARISA_THROW(MARISA_STATE_ERROR);
     88   }
     89 }
     90 
     91 }  // namespace marisa
     92