diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-04-20 04:02:15 +0000 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-04-20 04:02:15 +0000 |
commit | 4e2f7c8e8fdcdb1dbf6f2346e13f46f8ce3eca48 (patch) | |
tree | dc679317f6b432fc872422476922d05a8aaab388 /libdimensionxx/cookie.cpp | |
parent | e15353792ff60640e55e8a97c7737e0338289f97 (diff) | |
download | dimension-4e2f7c8e8fdcdb1dbf6f2346e13f46f8ce3eca48.tar.xz |
Add tmpfile() implementation of FILE_Cookie.
Diffstat (limited to 'libdimensionxx/cookie.cpp')
-rw-r--r-- | libdimensionxx/cookie.cpp | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/libdimensionxx/cookie.cpp b/libdimensionxx/cookie.cpp deleted file mode 100644 index 962137a..0000000 --- a/libdimensionxx/cookie.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/************************************************************************* - * Copyright (C) 2008 Tavian Barnes <tavianator@gmail.com> * - * * - * This file is part of The Dimension Library. * - * * - * The Dimension Library is free software; you can redistribute it and/ * - * or modify it under the terms of the GNU Lesser General Public License * - * as published by the Free Software Foundation; either version 3 of the * - * License, or (at your option) any later version. * - * * - * The Dimension Library is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this program. If not, see * - * <http://www.gnu.org/licenses/>. * - *************************************************************************/ - -#include "dimensionxx.hpp" -#include <stdio.h> - -// The conundrum: libdimension and libdimension-* use C I/O, with FILE*'s. -// We want to use C++ I/O with std::i/ostreams. Unfortunately, there's no -// standard way to map between them, so we use the nonportable GNU stdio -// extension fopencookie(), which creates a FILE* with custom read/write/seek -// functions. BSD also has a similar function, funopen(), which we should -// use too. Failing in all that, we should fall back on a tmpfile() buffer. - -namespace Dimension -{ - namespace - { - // Cookie read function - ssize_t - cookie_read(void* cookie, char* buf, size_t size) - { - FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie); - - // Do the unformatted read - streams->istr().read(buf, size); - - if (streams->istr().eof() || streams->istr().good()) { - return streams->istr().gcount(); // This returns 0 on an immediate EOF - // for us. - } else { - // Some non-EOF error - return -1; - } - } - - // Cookie write function - ssize_t - cookie_write(void* cookie, const char* buf, size_t size) - { - FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie); - - // Do the unformatted write - streams->ostr().write(buf, size); - - if (streams->ostr().good()) { - // Write operation succeeded, so we must've written size bytes - return size; - } else { - // Write operation failed - return -1; - } - } - - // Cookie seek function - int - cookie_seek(void* cookie, off64_t* offset, int whence) - { - FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie); - - if (streams->is_input()) { - // If we have an input stream, seek it - switch (whence) { - case SEEK_SET: - streams->istr().seekg(*offset, std::ios::beg); - break; - case SEEK_CUR: - streams->istr().seekg(*offset, std::ios::cur); - break; - case SEEK_END: - streams->istr().seekg(*offset, std::ios::end); - break; - } - - if (!streams->istr().good()) { - // Seek failed - return 1; - } - } - - if (streams->is_output()) { - // If we have an output stream, seek it too - switch (whence) { - case SEEK_SET: - streams->ostr().seekp(*offset, std::ios::beg); - break; - case SEEK_CUR: - streams->ostr().seekp(*offset, std::ios::cur); - break; - case SEEK_END: - streams->ostr().seekp(*offset, std::ios::end); - } - - if (!streams->ostr().good()) { - // Seek failed - return 1; - } - } - - // Seek succeeded - return 0; - } - } - - // Make an input FILE_Cookie - FILE_Cookie::FILE_Cookie(std::istream& istr) - : m_istr(&istr), m_ostr(0) - { - cookie_io_functions_t io_funcs; - io_funcs.read = &cookie_read; - io_funcs.write = 0; - io_funcs.seek = &cookie_seek; - io_funcs.close = 0; - - m_file = fopencookie(reinterpret_cast<void*>(this), "r", io_funcs); - } - - // Make an output FILE_Cookie - FILE_Cookie::FILE_Cookie(std::ostream& ostr) - : m_istr(0), m_ostr(&ostr) - { - cookie_io_functions_t io_funcs; - io_funcs.read = 0; - io_funcs.write = &cookie_write; - io_funcs.seek = &cookie_seek; - io_funcs.close = 0; - - m_file = fopencookie(reinterpret_cast<void*>(this), "w", io_funcs); - } - - // Make an I/O FILE_Cookie - FILE_Cookie::FILE_Cookie(std::istream& istr, std::ostream& ostr) - : m_istr(&istr), m_ostr(&ostr) - { - cookie_io_functions_t io_funcs; - io_funcs.read = &cookie_read; - io_funcs.write = &cookie_write; - io_funcs.seek = &cookie_seek; - io_funcs.close = 0; - - m_file = fopencookie(reinterpret_cast<void*>(this), "r+", io_funcs); - } - - // Close the file - FILE_Cookie::~FILE_Cookie() { std::fclose(m_file); } - - FILE* FILE_Cookie::file() { return m_file; } - const FILE* FILE_Cookie::file() const { return m_file; } - - bool FILE_Cookie::is_input() const { return m_istr; } - bool FILE_Cookie::is_output() const { return m_ostr; } - - std::istream& FILE_Cookie::istr() { return *m_istr; } - const std::istream& FILE_Cookie::istr() const { return *m_istr; } - std::ostream& FILE_Cookie::ostr() { return *m_ostr; } - const std::ostream& FILE_Cookie::ostr() const { return *m_ostr; } -} |