1f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <limits.h> 2f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <stdio.h> 3f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 4f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef _MSC_VER 5f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <io.h> 6f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else // _MSC_VER 7f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <unistd.h> 8f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif // _MSC_VER 9f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 10f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include "writer.h" 11f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 12f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathnamespace marisa { 13f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 14f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan KamathWriter::Writer() 15f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath : file_(NULL), fd_(-1), stream_(NULL), needs_fclose_(false) {} 16f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 17f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan KamathWriter::Writer(std::FILE *file) 18f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath : file_(file), fd_(-1), stream_(NULL), needs_fclose_(false) {} 19f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 20f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan KamathWriter::Writer(int fd) 21f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath : file_(NULL), fd_(fd), stream_(NULL), needs_fclose_(false) {} 22f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 23f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan KamathWriter::Writer(std::ostream *stream) 24f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath : file_(NULL), fd_(-1), stream_(stream), needs_fclose_(false) {} 25f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 26f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan KamathWriter::~Writer() { 27f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (needs_fclose_) { 28f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath ::fclose(file_); 29f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 30f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} 31f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 32f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathvoid Writer::open(const char *filename, bool trunc_flag, 33f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath long offset, int whence) { 34f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW_IF(is_open(), MARISA_STATE_ERROR); 35f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW_IF(filename == NULL, MARISA_PARAM_ERROR); 36f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef _MSC_VER 37f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath std::FILE *file = NULL; 38f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (!trunc_flag) { 39f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath ::fopen_s(&file, filename, "rb+"); 40f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 41f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (file == NULL) { 42f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (::fopen_s(&file, filename, "wb") != 0) { 43f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW(MARISA_IO_ERROR); 44f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 45f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 46f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else // _MSC_VER 47f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath std::FILE *file = NULL; 48f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (!trunc_flag) { 49f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath file = ::fopen(filename, "rb+"); 50f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 51f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (file == NULL) { 52f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath file = ::fopen(filename, "wb"); 53f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW_IF(file == NULL, MARISA_IO_ERROR); 54f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 55f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif // _MSC_VER 56f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (::fseek(file, offset, whence) != 0) { 57f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath ::fclose(file); 58f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW(MARISA_IO_ERROR); 59f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 60f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath file_ = file; 61f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath needs_fclose_ = true; 62f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} 63f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 64f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathvoid Writer::clear() { 65f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath Writer().swap(this); 66f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} 67f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 68f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathvoid Writer::swap(Writer *rhs) { 69f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW_IF(rhs == NULL, MARISA_PARAM_ERROR); 70f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath Swap(&file_, &rhs->file_); 71f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath Swap(&fd_, &rhs->fd_); 72f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath Swap(&stream_, &rhs->stream_); 73f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath Swap(&needs_fclose_, &rhs->needs_fclose_); 74f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} 75f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 76f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathvoid Writer::write_data(const void *data, std::size_t size) { 77f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if (fd_ != -1) { 78f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath while (size != 0) { 79f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef _MSC_VER 80f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath const unsigned int count = (size < INT_MAX) ? size : INT_MAX; 81f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath const int size_written = _write(fd_, data, count); 82f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else // _MSC_VER 83f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath const ::size_t count = (size < SSIZE_MAX) ? size : SSIZE_MAX; 84f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath const ::ssize_t size_written = ::write(fd_, data, count); 85f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif // _MSC_VER 86f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW_IF(size_written <= 0, MARISA_IO_ERROR); 87f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath data = static_cast<const char *>(data) + size_written; 88f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath size -= size_written; 89f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 90f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } else if (file_ != NULL) { 91f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath if ((::fwrite(data, 1, size, file_) != size) || (::fflush(file_) != 0)) { 92f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW(MARISA_IO_ERROR); 93f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 94f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } else if (stream_ != NULL) { 95132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin if (!stream_->write(static_cast<const char *>(data), size)) { 96f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW(MARISA_IO_ERROR); 97f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 98f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } else { 99f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath MARISA_THROW(MARISA_STATE_ERROR); 100f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath } 101f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} 102f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath 103f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} // namespace marisa 104