Home | History | Annotate | Download | only in marisa_alpha
      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_alpha {
     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_ALPHA_THROW_IF(is_open(), MARISA_ALPHA_STATE_ERROR);
     34   MARISA_ALPHA_THROW_IF(filename == NULL, MARISA_ALPHA_PARAM_ERROR);
     35 #ifdef _MSC_VER
     36   std::FILE *file = NULL;
     37   if (::fopen_s(&file, filename, "rb") != 0) {
     38     MARISA_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
     39   }
     40 #else  // _MSC_VER
     41   std::FILE * const file = ::fopen(filename, "rb");
     42   MARISA_ALPHA_THROW_IF(file == NULL, MARISA_ALPHA_IO_ERROR);
     43 #endif  // _MSC_VER
     44   if (::fseek(file, offset, whence) != 0) {
     45     ::fclose(file);
     46     MARISA_ALPHA_THROW(MARISA_ALPHA_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_ALPHA_THROW_IF(rhs == NULL, MARISA_ALPHA_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_ALPHA_THROW_IF(size_read <= 0, MARISA_ALPHA_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_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
     81     }
     82   } else if (stream_ != NULL) {
     83     try {
     84       if (!stream_->read(static_cast<char *>(buf), size)) {
     85         MARISA_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
     86       }
     87     } catch (const std::ios_base::failure &) {
     88       MARISA_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
     89     }
     90   } else {
     91     MARISA_ALPHA_THROW(MARISA_ALPHA_STATE_ERROR);
     92   }
     93 }
     94 
     95 }  // namespace marisa_alpha
     96