void MemIo::transfer(BasicIo& src) { MemIo *memIo = dynamic_cast<MemIo*>(&src); if (memIo) { // Optimization if src is another instance of MemIo if (true == isMalloced_) { std::free(data_); } idx_ = 0; data_ = memIo->data_; size_ = memIo->size_; isMalloced_ = memIo->isMalloced_; memIo->idx_ = 0; memIo->data_ = 0; memIo->size_ = 0; memIo->isMalloced_ = false; } else { // Generic reopen to reset position to start if (src.open() != 0) { throw Error(9, src.path(), strError()); } idx_ = 0; write(src); src.close(); } if (error() || src.error()) throw Error(19, strError()); }
int ImageFactory::getType(BasicIo& io) { if (io.open() != 0) return ImageType::none; IoCloser closer(io); for (unsigned int i = 0; registry_[i].imageType_ != ImageType::none; ++i) { if (registry_[i].isThisType_(io, false)) { return registry_[i].imageType_; } } return ImageType::none; } // ImageFactory::getType
void FileIo::transfer(BasicIo& src) { const bool wasOpen = (fp_ != 0); const std::string lastMode(openMode_); FileIo *fileIo = dynamic_cast<FileIo*>(&src); if (fileIo) { // Optimization if src is another instance of FileIo fileIo->close(); // Check if the file can be written to, if it already exists if (open("w+b") != 0) { // Remove the (temporary) file std::remove(fileIo->path_.c_str()); throw Error(10, path_, "w+b", strError()); } close(); struct stat buf; if (::stat(path_.c_str(), &buf) == -1) { throw Error(2, path_, strError(), "stat"); } // MSVCRT rename that does not overwrite existing files if (fileExists(path_) && std::remove(path_.c_str()) != 0) { throw Error(2, path_, strError(), "std::remove"); } if (std::rename(fileIo->path_.c_str(), path_.c_str()) == -1) { throw Error(17, fileIo->path_, path_, strError()); } std::remove(fileIo->path_.c_str()); // Set original file permissions if (::chmod(path_.c_str(), buf.st_mode) == -1) { throw Error(2, fileIo->path_, strError(), "chmod"); } } else { // Generic handling, reopen both to reset to start if (open("w+b") != 0) { throw Error(10, path_, "w+b", strError()); } if (src.open() != 0) { throw Error(9, src.path(), strError()); } write(src); src.close(); } if (wasOpen) { if (open(lastMode) != 0) { throw Error(10, path_, lastMode, strError()); } } else close(); if (error() || src.error()) throw Error(18, path_, strError()); }
Image::Type ImageFactory::getType(BasicIo& io) { IoCloser closer(io); if (io.open() != 0) return Image::none; Image::Type type = Image::none; Registry::const_iterator b = registry_->begin(); Registry::const_iterator e = registry_->end(); for (Registry::const_iterator i = b; i != e; ++i) { if (i->second.isThisType(io, false)) { type = i->first; break; } } return type; } // ImageFactory::getType
int WriteReadSeek(BasicIo &io) { byte buf[4096]; const char tester1[] = "this is a little test of MemIo"; const char tester2[] = "Appending this on the end"; const char expect[] = "this is a little teAppending this on the end"; const long insert = 19; const long len1 = (long)std::strlen(tester1) + 1; const long len2 = (long)std::strlen(tester2) + 1; if (io.open() != 0) { throw Error(9, io.path(), strError()); } IoCloser closer(io); if (io.write((byte*)tester1, len1) != len1) { std::cerr << ": WRS initial write failed\n"; return 2; } if (io.size() != len1) { std::cerr << ": WRS size is not " << len1 << "\n"; return 2; } io.seek(-len1, BasicIo::cur); int c = EOF; std::memset(buf, -1, sizeof(buf)); for (int i = 0; (c=io.getb()) != EOF; ++i) { buf[i] = (byte)c; } // Make sure we got the null back if(buf[len1-1] != 0) { std::cerr << ": WRS missing null terminator 1\n"; return 3; } if (strcmp(tester1, (char*)buf) != 0 ) { std::cerr << ": WRS strings don't match 1\n"; return 4; } io.seek(-2, BasicIo::end); if (io.getb() != 'o') { std::cerr << ": WRS bad getb o\n"; return 5; } io.seek(-2, BasicIo::cur); if (io.getb() != 'I') { std::cerr << ": WRS bad getb I\n"; return 6; } if (io.putb('O') != 'O') { std::cerr << ": WRS bad putb\n"; return 7; } io.seek(-1, BasicIo::cur); if (io.getb() != 'O') { std::cerr << ": WRS bad getb O\n"; return 8; } io.seek(insert, BasicIo::beg); if(io.write((byte*)tester2, len2) != len2) { std::cerr << ": WRS bad write 1\n"; return 9; } // open should seek to beginning if (io.open() != 0) { throw Error(9, io.path(), strError()); } std::memset(buf, -1, sizeof(buf)); if (io.read(buf, sizeof(buf)) != insert + len2) { std::cerr << ": WRS something went wrong\n"; return 10; } // Make sure we got the null back if(buf[insert + len2 - 1] != 0) { std::cerr << ": WRS missing null terminator 2\n"; return 11; } if (std::strcmp(expect, (char*)buf) != 0 ) { std::cerr << ": WRS strings don't match 2\n"; return 12; } return 0; }
void FileIo::transfer(BasicIo& src) { const bool wasOpen = (p_->fp_ != 0); const std::string lastMode(p_->openMode_); FileIo *fileIo = dynamic_cast<FileIo*>(&src); if (fileIo) { // Optimization if src is another instance of FileIo fileIo->close(); // Check if the file can be written to, if it already exists if (open("a+b") != 0) { // Remove the (temporary) file #ifdef EXV_UNICODE_PATH if (fileIo->p_->wpMode_ == Impl::wpUnicode) { ::_wremove(fileIo->wpath().c_str()); } else #endif { ::remove(fileIo->path().c_str()); } #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { throw WError(10, wpath(), "a+b", strError().c_str()); } else #endif { throw Error(10, path(), "a+b", strError()); } } close(); bool statOk = true; mode_t origStMode = 0; std::string spf; char* pf = 0; #ifdef EXV_UNICODE_PATH std::wstring wspf; wchar_t* wpf = 0; if (p_->wpMode_ == Impl::wpUnicode) { wspf = wpath(); wpf = const_cast<wchar_t*>(wspf.c_str()); } else #endif { spf = path(); pf = const_cast<char*>(spf.c_str()); } // Get the permissions of the file, or linked-to file, on platforms which have lstat #ifdef EXV_HAVE_LSTAT # ifdef EXV_UNICODE_PATH # error EXV_UNICODE_PATH and EXV_HAVE_LSTAT are not compatible. Stop. # endif struct stat buf1; if (::lstat(pf, &buf1) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, pf, strError(), "::lstat") << "\n"; #endif } origStMode = buf1.st_mode; DataBuf lbuf; // So that the allocated memory is freed. Must have same scope as pf // In case path() is a symlink, get the path of the linked-to file if (statOk && S_ISLNK(buf1.st_mode)) { lbuf.alloc(buf1.st_size + 1); memset(lbuf.pData_, 0x0, lbuf.size_); pf = reinterpret_cast<char*>(lbuf.pData_); if (::readlink(path().c_str(), pf, lbuf.size_ - 1) == -1) { throw Error(2, path(), strError(), "readlink"); } // We need the permissions of the file, not the symlink if (::stat(pf, &buf1) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, pf, strError(), "::stat") << "\n"; #endif } origStMode = buf1.st_mode; } #else // EXV_HAVE_LSTAT Impl::StructStat buf1; if (p_->stat(buf1) == -1) { statOk = false; } origStMode = buf1.st_mode; #endif // !EXV_HAVE_LSTAT // MSVCRT rename that does not overwrite existing files #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { if (fileExists(wpf) && ::_wremove(wpf) != 0) { throw WError(2, wpf, strError().c_str(), "::_wremove"); } if (::_wrename(fileIo->wpath().c_str(), wpf) == -1) { throw WError(17, fileIo->wpath(), wpf, strError().c_str()); } ::_wremove(fileIo->wpath().c_str()); // Check permissions of new file struct _stat buf2; if (statOk && ::_wstat(wpf, &buf2) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, wpf, strError(), "::_wstat") << "\n"; #endif } if (statOk && origStMode != buf2.st_mode) { // Set original file permissions if (::_wchmod(wpf, origStMode) == -1) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, wpf, strError(), "::_wchmod") << "\n"; #endif } } } // if (p_->wpMode_ == Impl::wpUnicode) else #endif // EXV_UNICODE_PATH { if (fileExists(pf) && ::remove(pf) != 0) { throw Error(2, pf, strError(), "::remove"); } if (::rename(fileIo->path().c_str(), pf) == -1) { throw Error(17, fileIo->path(), pf, strError()); } ::remove(fileIo->path().c_str()); // Check permissions of new file struct stat buf2; if (statOk && ::stat(pf, &buf2) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, pf, strError(), "::stat") << "\n"; #endif } if (statOk && origStMode != buf2.st_mode) { // Set original file permissions if (::chmod(pf, origStMode) == -1) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << Error(2, pf, strError(), "::chmod") << "\n"; #endif } } } } // if (fileIo) else { // Generic handling, reopen both to reset to start if (open("w+b") != 0) { #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { throw WError(10, wpath(), "w+b", strError().c_str()); } else #endif { throw Error(10, path(), "w+b", strError()); } } if (src.open() != 0) { #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { throw WError(9, src.wpath(), strError().c_str()); } else #endif { throw Error(9, src.path(), strError()); } } write(src); src.close(); } if (wasOpen) { if (open(lastMode) != 0) { #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { throw WError(10, wpath(), lastMode.c_str(), strError().c_str()); } else #endif { throw Error(10, path(), lastMode, strError()); } } } else close(); if (error() || src.error()) { #ifdef EXV_UNICODE_PATH if (p_->wpMode_ == Impl::wpUnicode) { throw WError(18, wpath(), strError().c_str()); } else #endif { throw Error(18, path(), strError()); } } } // FileIo::transfer
void FileIo::transfer(BasicIo& src) { const bool wasOpen = (fp_ != 0); const std::string lastMode(openMode_); FileIo *fileIo = dynamic_cast<FileIo*>(&src); if (fileIo) { // Optimization if src is another instance of FileIo fileIo->close(); // Check if the file can be written to, if it already exists if (open("w+b") != 0) { // Remove the (temporary) file std::remove(fileIo->path_.c_str()); throw Error(10, path_, "w+b", strError()); } close(); bool statOk = true; struct stat buf1; char* pf = const_cast<char*>(path_.c_str()); #ifdef EXV_HAVE_LSTAT if (::lstat(pf, &buf1) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: " << Error(2, pf, strError(), "lstat") << "\n"; #endif } DataBuf lbuf; // So that the allocated memory is freed. Must have same scope as pf // In case path_ is a symlink, get the path of the linked-to file if (statOk && S_ISLNK(buf1.st_mode)) { lbuf.alloc(buf1.st_size + 1); memset(lbuf.pData_, 0x0, lbuf.size_); pf = reinterpret_cast<char*>(lbuf.pData_); if (readlink(path_.c_str(), pf, lbuf.size_ - 1) == -1) { throw Error(2, path_, strError(), "readlink"); } // We need the permissions of the file, not the symlink if (::stat(pf, &buf1) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: " << Error(2, pf, strError(), "stat") << "\n"; #endif } } #else if (::stat(pf, &buf1) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: " << Error(2, pf, strError(), "stat") << "\n"; #endif } #endif // !EXV_HAVE_LSTAT // MSVCRT rename that does not overwrite existing files if (fileExists(pf) && std::remove(pf) != 0) { throw Error(2, pf, strError(), "std::remove"); } if (std::rename(fileIo->path_.c_str(), pf) == -1) { throw Error(17, fileIo->path_, pf, strError()); } std::remove(fileIo->path_.c_str()); // Check permissions of new file struct stat buf2; if (statOk && ::stat(pf, &buf2) == -1) { statOk = false; #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: " << Error(2, pf, strError(), "stat") << "\n"; #endif } if (statOk && buf1.st_mode != buf2.st_mode) { // Set original file permissions if (::chmod(pf, buf1.st_mode) == -1) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: " << Error(2, pf, strError(), "chmod") << "\n"; #endif } } } else { // Generic handling, reopen both to reset to start if (open("w+b") != 0) { throw Error(10, path_, "w+b", strError()); } if (src.open() != 0) { throw Error(9, src.path(), strError()); } write(src); src.close(); } if (wasOpen) { if (open(lastMode) != 0) { throw Error(10, path_, lastMode, strError()); } } else close(); if (error() || src.error()) throw Error(18, path_, strError()); }