From 4f9f95a05a41bfbcc9965eaaf7f2d14c6af9f261 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 12 Apr 2009 15:42:04 +0000 Subject: Write C++ libdimension-png wrapper. --- libdimensionxx/cookie.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 libdimensionxx/cookie.cpp (limited to 'libdimensionxx/cookie.cpp') diff --git a/libdimensionxx/cookie.cpp b/libdimensionxx/cookie.cpp new file mode 100644 index 0000000..dd8a06d --- /dev/null +++ b/libdimensionxx/cookie.cpp @@ -0,0 +1,163 @@ +/************************************************************************* + * Copyright (C) 2008 Tavian Barnes * + * * + * 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 * + * . * + *************************************************************************/ + +#include "dimensionxx.hpp" +#include + +namespace Dimension +{ + namespace + { + struct Cookie + { + public: + std::istream* istr; + std::ostream* ostr; + }; + + ssize_t + cookie_read(void* cookie, char* buf, size_t size) + { + Cookie* streams = reinterpret_cast(cookie); + + streams->istr->read(buf, size); + + if (streams->istr->eof()) { + return streams->istr->gcount(); + } else if (!streams->istr->good()) { + return -1; + } else { + return streams->istr->gcount(); + } + } + + ssize_t + cookie_write(void* cookie, const char* buf, size_t size) + { + Cookie* streams = reinterpret_cast(cookie); + + streams->ostr->write(buf, size); + + if (!streams->ostr->good()) { + return -1; + } else { + return size; + } + } + + int + cookie_seek(void* cookie, off64_t* offset, int whence) + { + Cookie* streams = reinterpret_cast(cookie); + bool success = true; + + if (streams->istr) { + 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()) { + success = false; + } + } + + if (streams->ostr) { + 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()) { + success = false; + } + } + + return !success; + } + + int + cookie_close(void* cookie) + { + delete reinterpret_cast(cookie); + } + } + + std::FILE* + fcookie(std::istream& istr) + { + Cookie* cookie = new Cookie; + cookie->istr = &istr; + cookie->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 = &cookie_close; + + return fopencookie(reinterpret_cast(cookie), "r", io_funcs); + } + + std::FILE* + fcookie(std::ostream& ostr) + { + Cookie* cookie = new Cookie; + cookie->istr = 0; + cookie->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 = &cookie_close; + + return fopencookie(reinterpret_cast(cookie), "w", io_funcs); + } + + std::FILE* + fcookie(std::iostream& iostr) + { + Cookie* cookie = new Cookie; + cookie->istr = &iostr; + cookie->ostr = &iostr; + + cookie_io_functions_t io_funcs; + io_funcs.read = &cookie_read; + io_funcs.write = &cookie_write; + io_funcs.seek = &cookie_seek; + io_funcs.close = &cookie_close; + + return fopencookie(reinterpret_cast(cookie), "r+", io_funcs); + } +} -- cgit v1.2.3