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