summaryrefslogtreecommitdiffstats
path: root/libdimensionxx
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-06-26 15:31:34 +0000
committerTavian Barnes <tavianator@gmail.com>2009-06-26 15:31:34 +0000
commit3ee98f3bac24fd1c70a9de3e0fbe774e762c25b3 (patch)
treeddc8d088662a88101670150c491012427c85b5bf /libdimensionxx
parentd56d643d412e06ff1e5239f8ebbd96f716b416bd (diff)
downloaddimension-3ee98f3bac24fd1c70a9de3e0fbe774e762c25b3.tar.xz
Add lots of comments, and some code fixes discovered in the process.
Diffstat (limited to 'libdimensionxx')
-rw-r--r--libdimensionxx/cookie-fopencookie.cpp52
-rw-r--r--libdimensionxx/cookie-tmpfile.cpp83
-rw-r--r--libdimensionxx/dimensionxx/array.hpp7
-rw-r--r--libdimensionxx/dimensionxx/canvas.hpp4
-rw-r--r--libdimensionxx/dimensionxx/color.hpp4
-rw-r--r--libdimensionxx/dimensionxx/cookie.hpp4
-rw-r--r--libdimensionxx/dimensionxx/error.hpp6
-rw-r--r--libdimensionxx/dimensionxx/geometry.hpp55
-rw-r--r--libdimensionxx/dimensionxx/object.hpp4
-rw-r--r--libdimensionxx/dimensionxx/png.hpp4
-rw-r--r--libdimensionxx/dimensionxx/progress.hpp4
-rw-r--r--libdimensionxx/progress.cpp25
12 files changed, 208 insertions, 44 deletions
diff --git a/libdimensionxx/cookie-fopencookie.cpp b/libdimensionxx/cookie-fopencookie.cpp
index 78b6e8b..070b038 100644
--- a/libdimensionxx/cookie-fopencookie.cpp
+++ b/libdimensionxx/cookie-fopencookie.cpp
@@ -21,6 +21,7 @@
#include "dimensionxx.hpp"
#ifndef _GNU_SOURCE
+// For fopencookie()
# define _GNU_SOURCE
#endif
#include <stdio.h>
@@ -99,7 +100,7 @@ namespace Dimension
}
if (streams->is_output()) {
- // If we have an output stream, seek it too
+ // If we have an output stream, seek it
switch (whence) {
case SEEK_SET:
streams->ostr().seekp(*offset, std::ios::beg);
@@ -164,14 +165,55 @@ namespace Dimension
// Close the file
FILE_Cookie::~FILE_Cookie() { std::fclose(m_file); }
+ // Get the 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; }
+ // Get the C++ streams
+
+ std::istream&
+ FILE_Cookie::istr()
+ {
+ if (is_input()) {
+ return *m_istr;
+ } else {
+ throw Dimension_Error("Attempted to get input stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ const std::istream&
+ FILE_Cookie::istr() const
+ {
+ if (is_input()) {
+ return *m_istr;
+ } else {
+ throw Dimension_Error("Attempted to get input stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ std::ostream&
+ FILE_Cookie::ostr()
+ {
+ if (is_output()) {
+ return *m_ostr;
+ } else {
+ throw Dimension_Error("Attempted to get output stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ const std::ostream& FILE_Cookie::ostr() const
+ {
+ if (is_output()) {
+ return *m_ostr;
+ } else {
+ throw Dimension_Error("Attempted to get output stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
}
diff --git a/libdimensionxx/cookie-tmpfile.cpp b/libdimensionxx/cookie-tmpfile.cpp
index ec320d8..6a41f09 100644
--- a/libdimensionxx/cookie-tmpfile.cpp
+++ b/libdimensionxx/cookie-tmpfile.cpp
@@ -27,74 +27,85 @@ namespace Dimension
{
namespace
{
+ // Write an input stream completely to a FILE*; this works poorly for
+ // console input, which may not have an EOF in the near future
void
write_cookie(FILE* file, std::istream& istr)
{
+ const unsigned int bs = 8192; // Bytes to read at once
unsigned int count, pos;
- const unsigned int bs = 8192;
char buffer[bs];
- pos = istr.tellg();
- istr.seekg(0);
+ pos = istr.tellg(); // Get the stream's current position
+ istr.seekg(0); // Seek to the beginning
while (true) {
+ // Read the whole stream into `file', `bs' bytes at a time
istr.read(buffer, bs);
count = istr.gcount();
if (count != bs) {
if (istr.eof()) {
+ // We reached EOF; write the last count bytes
fwrite(buffer, 1, count, file);
break;
} else {
+ // Some other error
throw Dimension_Error("Error reading from input stream.");
}
}
+ // Write the next `bs' bytes
fwrite(buffer, 1, bs, file);
}
- fseek(file, pos, SEEK_SET);
+ fseek(file, pos, SEEK_SET); // Seek to the stream's initial position
}
+ // Read a C++ stream completely from a file
void
read_cookie(std::ostream& ostr, FILE* file)
{
+ const unsigned int bs = 8192; // Bytes to read at a time
unsigned int count, pos;
- const unsigned int bs = 8192;
char buffer[bs];
- pos = ftell(file);
- rewind(file);
+ pos = ftell(file); // Get the initial position
+ rewind(file); // Seek to the beginning
while (true) {
count = fread(buffer, 1, bs, file);
if (count != bs) {
if (feof(file)) {
+ // Reached EOF, write the last `count' bytes
ostr.write(buffer, count);
break;
} else {
+ // Some other error
throw Dimension_Error("Error reading from temporary file.");
}
}
+ // Write the next `bs' bytes
ostr.write(buffer, bs);
}
- ostr.seekp(pos);
+ ostr.seekp(pos); // Seek to the initial position of `file'
}
}
// Make an input FILE_Cookie
FILE_Cookie::FILE_Cookie(std::istream& istr)
- : m_file(tmpfile()), m_istr(&istr), m_ostr(0)
+ : m_file(std::tmpfile()), m_istr(&istr), m_ostr(0)
{
if (!m_file) {
throw Dimension_Error("Error opening temporary file for C++/C I/O"
" interface.");
}
+ // Write the input stream to the temporary file
write_cookie(m_file, *m_istr);
}
// Make an output FILE_Cookie
FILE_Cookie::FILE_Cookie(std::ostream& ostr)
- : m_file(tmpfile()), m_istr(0), m_ostr(&ostr)
+ : m_file(std::tmpfile()), m_istr(0), m_ostr(&ostr)
{
if (!m_file) {
throw Dimension_Error("Error opening temporary file for C++/C I/O"
@@ -104,13 +115,14 @@ namespace Dimension
// Make an I/O FILE_Cookie
FILE_Cookie::FILE_Cookie(std::iostream& iostr)
- : m_file(tmpfile()), m_istr(&iostr), m_ostr(&iostr)
+ : m_file(std::tmpfile()), m_istr(&iostr), m_ostr(&iostr)
{
if (!m_file) {
throw Dimension_Error("Error opening temporary file for C++/C I/O"
" interface.");
}
+ // Write the input stream to the temporary file
write_cookie(m_file, *m_istr);
}
@@ -123,14 +135,55 @@ namespace Dimension
std::fclose(m_file);
}
+ // Get the 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; }
+ // Get the C++ streams
+
+ std::istream&
+ FILE_Cookie::istr()
+ {
+ if (is_input()) {
+ return *m_istr;
+ } else {
+ throw Dimension_Error("Attempted to get input stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ const std::istream&
+ FILE_Cookie::istr() const
+ {
+ if (is_input()) {
+ return *m_istr;
+ } else {
+ throw Dimension_Error("Attempted to get input stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ std::ostream&
+ FILE_Cookie::ostr()
+ {
+ if (is_output()) {
+ return *m_ostr;
+ } else {
+ throw Dimension_Error("Attempted to get output stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
+
+ const std::ostream& FILE_Cookie::ostr() const
+ {
+ if (is_output()) {
+ return *m_ostr;
+ } else {
+ throw Dimension_Error("Attempted to get output stream from non-input"
+ " FILE_Cookie.");
+ }
+ }
}
diff --git a/libdimensionxx/dimensionxx/array.hpp b/libdimensionxx/dimensionxx/array.hpp
index dfbf1c8..735e17a 100644
--- a/libdimensionxx/dimensionxx/array.hpp
+++ b/libdimensionxx/dimensionxx/array.hpp
@@ -18,14 +18,14 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// dmnsn_array* wrapper.
+
#ifndef DIMENSIONXX_ARRAY_HPP
#define DIMENSIONXX_ARRAY_HPP
#include <tr1/memory> // For tr1::shared_ptr
#include <cstdlib> // For size_t
-// dmnsn_array* wrapper.
-
namespace Dimension
{
// RAII scoped read-lock
@@ -148,6 +148,8 @@ namespace Dimension
return ret;
}
+ // Access the underlying dmnsn_array*
+
template <typename T>
dmnsn_array*
Array<T>::dmnsn()
@@ -170,6 +172,7 @@ namespace Dimension
return *m_array;
}
+ // Release the dmnsn_array*, if we are the only Array holding it
template <typename T>
dmnsn_array*
Array<T>::release()
diff --git a/libdimensionxx/dimensionxx/canvas.hpp b/libdimensionxx/dimensionxx/canvas.hpp
index eda9ad3..f9e77e5 100644
--- a/libdimensionxx/dimensionxx/canvas.hpp
+++ b/libdimensionxx/dimensionxx/canvas.hpp
@@ -18,11 +18,11 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// dmnsn_canvas* wrapper.
+
#ifndef DIMENSIONXX_CANVAS_HPP
#define DIMENSIONXX_CANVAS_HPP
-// dmnsn_canvas* wrapper.
-
namespace Dimension
{
// Base canvas class. Wraps a dmnsn_canvas*.
diff --git a/libdimensionxx/dimensionxx/color.hpp b/libdimensionxx/dimensionxx/color.hpp
index c79f86b..9289479 100644
--- a/libdimensionxx/dimensionxx/color.hpp
+++ b/libdimensionxx/dimensionxx/color.hpp
@@ -18,11 +18,11 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// Wrappers for libdimension colors.
+
#ifndef DIMENSIONXX_COLOR_HPP
#define DIMENSIONXX_COLOR_HPP
-// Wrappers for libdimension colors.
-
namespace Dimension
{
// Forward declarations
diff --git a/libdimensionxx/dimensionxx/cookie.hpp b/libdimensionxx/dimensionxx/cookie.hpp
index df26b93..0d8b4da 100644
--- a/libdimensionxx/dimensionxx/cookie.hpp
+++ b/libdimensionxx/dimensionxx/cookie.hpp
@@ -18,11 +18,11 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// Some internal magic to use C FILE* I/O with C++ streams.
+
#ifndef DIMENSIONXX_COOKIE_HPP
#define DIMENSIONXX_COOKIE_HPP
-// Some internal magic to use C FILE* I/O with C++ streams.
-
#include <istream>
#include <ostream>
#include <cstdio>
diff --git a/libdimensionxx/dimensionxx/error.hpp b/libdimensionxx/dimensionxx/error.hpp
index 99670cb..7fb0e53 100644
--- a/libdimensionxx/dimensionxx/error.hpp
+++ b/libdimensionxx/dimensionxx/error.hpp
@@ -18,14 +18,14 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
-#ifndef DIMENSIONXX_ERROR_HPP
-#define DIMENSIONXX_ERROR_HPP
-
// Wrappers for libdimension error handling, and an exception class.
// dmnsn_error is still used by libdimensionxx whenever an exception shouldn't
// be thrown, like in destructors, and whenever libdimension or libdimension-*
// use it internally. Exceptions are thrown otherwise to report errors.
+#ifndef DIMENSIONXX_ERROR_HPP
+#define DIMENSIONXX_ERROR_HPP
+
#include <dimension.h>
#include <stdexcept>
#include <string>
diff --git a/libdimensionxx/dimensionxx/geometry.hpp b/libdimensionxx/dimensionxx/geometry.hpp
index f623eda..606f83a 100644
--- a/libdimensionxx/dimensionxx/geometry.hpp
+++ b/libdimensionxx/dimensionxx/geometry.hpp
@@ -18,15 +18,17 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// Wrappers for geometric types (Vectors, Matricies, Lines (rays)).
+
#ifndef DIMENSIONXX_GEOMETRY_HPP
#define DIMENSIONXX_GEOMETRY_HPP
-// Wrappers for geometric types (Vectors, Matricies, Lines (rays)).
-
#include <dimension.h>
namespace Dimension
{
+ class Vector;
+
// Wrapper for dmnsn_matrix
class Matrix
{
@@ -56,6 +58,12 @@ namespace Dimension
// Get the wrapped matrix
dmnsn_matrix dmnsn() const { return m_matrix; }
+ // Special constructors
+ static inline Matrix identity();
+ static inline Matrix scale(const Vector& factor);
+ static inline Matrix translation(const Vector& d);
+ static inline Matrix rotation(const Vector& theta);
+
private:
dmnsn_matrix m_matrix;
};
@@ -126,6 +134,49 @@ namespace Dimension
dmnsn_line m_line;
};
+ // Matrix operators
+
+ inline Matrix
+ operator*(const Matrix& lhs, const Matrix& rhs)
+ {
+ // This order is important!
+ Matrix r = rhs;
+ r *= lhs;
+ return r;
+ }
+
+ inline Matrix
+ inverse(const Matrix& M)
+ {
+ return Matrix(dmnsn_matrix_inverse(M.dmnsn()));
+ }
+
+ // Special Matrix constructors
+
+ inline Matrix
+ Matrix::identity()
+ {
+ return Matrix(dmnsn_identity_matrix());
+ }
+
+ inline Matrix
+ Matrix::scale(const Vector& factor)
+ {
+ return Matrix(dmnsn_scale_matrix(factor.dmnsn()));
+ }
+
+ inline Matrix
+ Matrix::translation(const Vector& d)
+ {
+ return Matrix(dmnsn_translation_matrix(d.dmnsn()));
+ }
+
+ inline Matrix
+ Matrix::rotation(const Vector& theta)
+ {
+ return Matrix(dmnsn_rotation_matrix(theta.dmnsn()));
+ }
+
// Vector operators
inline Vector
diff --git a/libdimensionxx/dimensionxx/object.hpp b/libdimensionxx/dimensionxx/object.hpp
index 3b2c6c1..40dcb25 100644
--- a/libdimensionxx/dimensionxx/object.hpp
+++ b/libdimensionxx/dimensionxx/object.hpp
@@ -18,11 +18,11 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// dmnsn_object* wrapper.
+
#ifndef DIMENSIONXX_OBJECT_HPP
#define DIMENSIONXX_OBJECT_HPP
-// dmnsn_object* wrapper.
-
namespace Dimension
{
// Abstract base object class. Wraps a dmnsn_object*.
diff --git a/libdimensionxx/dimensionxx/png.hpp b/libdimensionxx/dimensionxx/png.hpp
index d768287..980840c 100644
--- a/libdimensionxx/dimensionxx/png.hpp
+++ b/libdimensionxx/dimensionxx/png.hpp
@@ -18,11 +18,11 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// C++ wrapper for libdimension PNG support. PNG_Canvas derives from Canvas.
+
#ifndef DIMENSIONXX_PNG_HPP
#define DIMENSIONXX_PNG_HPP
-// C++ wrapper for libdimension PNG support. PNG_Canvas derives from Canvas.
-
#include <istream>
#include <ostream>
diff --git a/libdimensionxx/dimensionxx/progress.hpp b/libdimensionxx/dimensionxx/progress.hpp
index b9df870..3fff1bc 100644
--- a/libdimensionxx/dimensionxx/progress.hpp
+++ b/libdimensionxx/dimensionxx/progress.hpp
@@ -18,14 +18,14 @@
* <http://www.gnu.org/licenses/>. *
*************************************************************************/
+// dmnsn_progress* wrapper.
+
#ifndef DIMENSIONXX_PROGRESS_HPP
#define DIMENSIONXX_PROGRESS_HPP
#include <tr1/memory> // For tr1::shared_ptr
#include <list>
-// dmnsn_canvas* wrapper.
-
namespace Dimension
{
// Base class for persisting objects
diff --git a/libdimensionxx/progress.cpp b/libdimensionxx/progress.cpp
index ca74571..0a32b72 100644
--- a/libdimensionxx/progress.cpp
+++ b/libdimensionxx/progress.cpp
@@ -25,14 +25,17 @@ namespace Dimension
Persist_Base::~Persist_Base()
{ }
+ // Construct a dmnsn_progress* wrapper
Progress::Progress(dmnsn_progress* progress)
: m_progress(new dmnsn_progress*(progress))
{ }
+ // Construct a dmnsn_progress* wrapper, with a known persister
Progress::Progress(dmnsn_progress* progress, const Persister& persister)
: m_progress(new dmnsn_progress*(progress)), m_persister(persister)
{ }
+ // Finish the progress if not yet finished and we are unique
Progress::~Progress()
{
if (m_progress && m_progress.unique()) {
@@ -45,45 +48,55 @@ namespace Dimension
}
}
+ // Get the current progress
double
Progress::progress() const
{
return dmnsn_get_progress(dmnsn());
}
+ // Wait until progress() >= progress
void
Progress::wait(double progress) const
{
dmnsn_wait_progress(dmnsn(), progress);
}
+ // Start a new level of loop nesting
void
Progress::new_element(unsigned int total)
{
dmnsn_new_progress_element(dmnsn(), total);
}
+ // Increment the progress
void
Progress::increment()
{
dmnsn_increment_progress(dmnsn());
}
+ // Immediately finish the progress
void
Progress::done()
{
- dmnsn_progress_done(dmnsn());
+ dmnsn_done_progress(dmnsn());
}
+ // Wait for progress completion
void
Progress::finish()
{
- if (m_progress.unique()) {
- dmnsn_finish_progress(dmnsn());
- m_progress.reset();
- } else {
+ if (!m_progress) {
+ throw Dimension_Error("Attempt to finish Progress twice.");
+ }
+
+ if (!m_progress.unique()) {
throw Dimension_Error("Attempt to finish non-unique Progress.");
}
+
+ dmnsn_finish_progress(dmnsn());
+ m_progress.reset(); // Don't try again
}
// Access the set of persisted objects
@@ -93,6 +106,8 @@ namespace Dimension
return m_persister;
}
+ // Access the underlying dmnsn_progress*
+
dmnsn_progress*
Progress::dmnsn()
{