• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Reader()14 Reader::Reader()
15     : file_(NULL), fd_(-1), stream_(NULL), needs_fclose_(false) {}
16 
Reader(std::FILE * file)17 Reader::Reader(std::FILE *file)
18     : file_(file), fd_(-1), stream_(NULL), needs_fclose_(false) {}
19 
Reader(int fd)20 Reader::Reader(int fd)
21     : file_(NULL), fd_(fd), stream_(NULL), needs_fclose_(false) {}
22 
Reader(std::istream * stream)23 Reader::Reader(std::istream *stream)
24     : file_(NULL), fd_(-1), stream_(stream), needs_fclose_(false) {}
25 
~Reader()26 Reader::~Reader() {
27   if (needs_fclose_) {
28     ::fclose(file_);
29   }
30 }
31 
open(const char * filename,long offset,int whence)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 
clear()52 void Reader::clear() {
53   Reader().swap(this);
54 }
55 
swap(Reader * rhs)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 
read_data(void * buf,std::size_t size)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