summaryrefslogtreecommitdiffstats
path: root/libdimensionxx/cookie.cpp
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-04-13 21:53:43 +0000
committerTavian Barnes <tavianator@gmail.com>2009-04-13 21:53:43 +0000
commitf9471e983baccaa4f43cfa43463c7a26bcb16c55 (patch)
treeeee3a8fee8071d78821444ef5b871557253b156d /libdimensionxx/cookie.cpp
parent11c2b9bbc790216eeb22a1e4d4de8161394c3fbf (diff)
downloaddimension-f9471e983baccaa4f43cfa43463c7a26bcb16c55.tar.xz
Use an RAII interface to fopencookie().
Diffstat (limited to 'libdimensionxx/cookie.cpp')
-rw-r--r--libdimensionxx/cookie.cpp114
1 files changed, 49 insertions, 65 deletions
diff --git a/libdimensionxx/cookie.cpp b/libdimensionxx/cookie.cpp
index c3b1541..962137a 100644
--- a/libdimensionxx/cookie.cpp
+++ b/libdimensionxx/cookie.cpp
@@ -26,34 +26,24 @@
// 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,
-// but that would require an fclosecookie() function as well, to copy the
-// buffer to the stream potentially.
+// use too. Failing in all that, we should fall back on a tmpfile() buffer.
namespace Dimension
{
namespace
{
- // Internal cookie type to hold the C++ streams.
- struct Cookie
- {
- public:
- std::istream* istr;
- std::ostream* ostr;
- };
-
// Cookie read function
ssize_t
cookie_read(void* cookie, char* buf, size_t size)
{
- Cookie* streams = reinterpret_cast<Cookie*>(cookie);
+ FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie);
// Do the unformatted read
- streams->istr->read(buf, size);
+ 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.
+ 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;
@@ -64,12 +54,12 @@ namespace Dimension
ssize_t
cookie_write(void* cookie, const char* buf, size_t size)
{
- Cookie* streams = reinterpret_cast<Cookie*>(cookie);
+ FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie);
// Do the unformatted write
- streams->ostr->write(buf, size);
+ streams->ostr().write(buf, size);
- if (streams->ostr->good()) {
+ if (streams->ostr().good()) {
// Write operation succeeded, so we must've written size bytes
return size;
} else {
@@ -82,42 +72,42 @@ namespace Dimension
int
cookie_seek(void* cookie, off64_t* offset, int whence)
{
- Cookie* streams = reinterpret_cast<Cookie*>(cookie);
+ FILE_Cookie* streams = reinterpret_cast<FILE_Cookie*>(cookie);
- if (streams->istr) {
+ if (streams->is_input()) {
// If we have an input stream, seek it
switch (whence) {
case SEEK_SET:
- streams->istr->seekg(*offset, std::ios::beg);
+ streams->istr().seekg(*offset, std::ios::beg);
break;
case SEEK_CUR:
- streams->istr->seekg(*offset, std::ios::cur);
+ streams->istr().seekg(*offset, std::ios::cur);
break;
case SEEK_END:
- streams->istr->seekg(*offset, std::ios::end);
+ streams->istr().seekg(*offset, std::ios::end);
break;
}
- if (!streams->istr->good()) {
+ if (!streams->istr().good()) {
// Seek failed
return 1;
}
}
- if (streams->ostr) {
+ 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);
+ streams->ostr().seekp(*offset, std::ios::beg);
break;
case SEEK_CUR:
- streams->ostr->seekp(*offset, std::ios::cur);
+ streams->ostr().seekp(*offset, std::ios::cur);
break;
case SEEK_END:
- streams->ostr->seekp(*offset, std::ios::end);
+ streams->ostr().seekp(*offset, std::ios::end);
}
- if (!streams->ostr->good()) {
+ if (!streams->ostr().good()) {
// Seek failed
return 1;
}
@@ -126,64 +116,58 @@ namespace Dimension
// Seek succeeded
return 0;
}
-
- // Cookie delete function
- int
- cookie_close(void* cookie)
- {
- // Free the cookie
- delete reinterpret_cast<Cookie*>(cookie);
- }
}
- // Make an input FILE*
- std::FILE*
- fcookie(std::istream& istr)
+ // Make an input FILE_Cookie
+ FILE_Cookie::FILE_Cookie(std::istream& istr)
+ : m_istr(&istr), m_ostr(0)
{
- 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;
+ io_funcs.close = 0;
- return fopencookie(reinterpret_cast<void*>(cookie), "r", io_funcs);
+ m_file = fopencookie(reinterpret_cast<void*>(this), "r", io_funcs);
}
- // Make an output FILE*
- std::FILE*
- fcookie(std::ostream& ostr)
+ // Make an output FILE_Cookie
+ FILE_Cookie::FILE_Cookie(std::ostream& ostr)
+ : m_istr(0), m_ostr(&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;
+ io_funcs.close = 0;
- return fopencookie(reinterpret_cast<void*>(cookie), "w", io_funcs);
+ m_file = fopencookie(reinterpret_cast<void*>(this), "w", io_funcs);
}
- // Make an I/O FILE*
- std::FILE*
- fcookie(std::iostream& iostr)
+ // Make an I/O FILE_Cookie
+ FILE_Cookie::FILE_Cookie(std::istream& istr, std::ostream& ostr)
+ : m_istr(&istr), m_ostr(&ostr)
{
- 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;
+ io_funcs.close = 0;
- return fopencookie(reinterpret_cast<void*>(cookie), "r+", io_funcs);
+ 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; }
}