*/
void monitor_memory (const unsigned int true_dimension) const;
+ /**
+ * Write out the data of this object
+ * in a raw format, i.e. binary or almost
+ * binary.
+ */
+ void block_write (ostream &out) const;
+
+ /**
+ * Read back the data written by the above
+ * function. By doing so, all content
+ * which may have been in this object will
+ * be lost.
+ */
+ void block_read (istream &in);
+
/**
* Exception
*/
int, int,
<< "The containers have sizes " << arg1 << " and "
<< arg2 << ", which is not as expected.");
+ /**
+ * Exception
+ */
+ DeclException0 (ExcIO);
+
+ protected:
+
+ /**
+ * Write out a vector of anything
+ * in a binary format. To be exact,
+ * what we write is the memory content
+ * between #v.begin()# and #v.end()#;
+ * this function is therefore only
+ * useful if the whole information of
+ * the objects stored in this vector
+ * are contained within the objects,
+ * i.e. they do not have pointers,
+ * references, other vectors, etc.
+ *
+ * For all other vectors, specialized
+ * functions need to be written; the
+ * following one is an example for
+ * this.
+ */
+ template <typename T>
+ static void write_raw_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ ostream &out);
+
+ /**
+ * Write a bool vector to the given stream,
+ * writing a pre- and a postfix magica
+ * number. The vector is written in an
+ * almost binary format, i.e. the bool
+ * flags are packed but the data is written
+ * as ASCII text.
+ *
+ * The flags are stored in a binary
+ * format: for each #true#, a #1#
+ * bit is stored, a #0# bit otherwise.
+ * The bits are stored as #unsigned char#,
+ * thus avoiding endianess. They are
+ * written to #out# in plain text, thus
+ * amounting to 3.6 bits per flag
+ * on the overage. Other information
+ * (magic numbers ans number of elements)
+ * is stored as plain text
+ * as well. The format should therefore be
+ * interplatform compatible.
+ */
+ static void write_raw_vector (const unsigned int magic_number1,
+ const vector<bool> &v,
+ const unsigned int magic_number2,
+ ostream &out);
+
+ /**
+ * Write out a vector almost raw: we
+ * use a run-length encoding (rle) scheme
+ * to reduce the size of a vector. This
+ * function yields better results than the
+ * above ones if frequently larger chunks
+ * of data have the same value.
+ */
+ template <typename T>
+ static void write_rle_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ ostream &out);
+
+ /**
+ * Read back a vector written by
+ * #write_raw_vector#.
+ */
+ template <typename T>
+ static void read_raw_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ istream &in);
+
+ /**
+ * Read back a vector written by
+ * the version of #write_raw_vector#
+ * for #bool# vectors.
+ */
+ static void read_raw_vector (const unsigned int magic_number1,
+ const vector<bool> &v,
+ const unsigned int magic_number2,
+ istream &in);
+
+ /**
+ * Read back a run-length encoded
+ * vector, as written by
+ * #write_rle_vector#.
+ */
+ template <typename T>
+ static void read_rle_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ istream &in);
};
* #TriangulationLevel# classes.
*/
void monitor_memory (const unsigned int true_dimension) const;
+
+ /**
+ * Write out the data of this object
+ * in a raw format, i.e. binary or almost
+ * binary.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<0>#.
+ */
+ void block_write (ostream &out) const;
+
+ /**
+ * Read back the data written by the above
+ * function. By doing so, all content
+ * which may have been in this object will
+ * be lost.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<0>#.
+ */
+ void block_read (istream &in);
};
* #TriangulationLevel# classes.
*/
void monitor_memory (const unsigned int true_dimension) const;
+
+ /**
+ * Write out the data of this object
+ * in a raw format, i.e. binary or almost
+ * binary.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<1>#.
+ */
+ void block_write (ostream &out) const;
+
+ /**
+ * Read back the data written by the above
+ * function. By doing so, all content
+ * which may have been in this object will
+ * be lost.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<1>#.
+ */
+ void block_read (istream &in);
};
* #TriangulationLevel# classes.
*/
void monitor_memory (const unsigned int true_dimension) const;
+
+ /**
+ * Write out the data of this object
+ * in a raw format, i.e. binary or almost
+ * binary.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<2>#.
+ */
+ void block_write (ostream &out) const;
+
+ /**
+ * Read back the data written by the above
+ * function. By doing so, all content
+ * which may have been in this object will
+ * be lost.
+ *
+ * Calls the respective function of
+ * #TriangulationLevel<2>#.
+ */
+ void block_read (istream &in);
};
+template <typename T>
+void TriangulationLevel<0>::write_raw_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ ostream &out)
+{
+ AssertThrow (out, ExcIO());
+
+ out << magic_number1 << ' ' << v.size() << '[';
+ out.write (reinterpret_cast<const char*>(v.begin()),
+ reinterpret_cast<const char*>(v.end())
+ - reinterpret_cast<const char*>(v.begin()));
+ out << ']' << magic_number2 << endl;
+
+ AssertThrow (out, ExcIO());
+};
+
+
+
+void TriangulationLevel<0>::write_raw_vector (const unsigned int magic_number1,
+ const vector<bool> &v,
+ const unsigned int magic_number2,
+ ostream &out) {
+ const unsigned int N = v.size();
+ unsigned char *flags = new unsigned char[N/8+1];
+ for (unsigned int i=0; i<N/8+1; ++i) flags[i]=0;
+
+ for (unsigned int position=0; position<N; ++position)
+ flags[position/8] |= (v[position] ? (1<<(position%8)) : 0);
+
+ AssertThrow (out, ExcIO());
+
+ // format:
+ // 0. magic number
+ // 1. number of flags
+ // 2. the flags
+ // 3. magic number
+ out << magic_number1 << ' ' << N << '[';
+ for (unsigned int i=0; i<N/8+1; ++i)
+ out << static_cast<unsigned int>(flags[i]) << " ";
+
+ out << ']' << magic_number2 << endl;
+
+ delete[] flags;
+
+ AssertThrow (out, ExcIO());
+};
+
+
+
+template <typename T>
+void TriangulationLevel<0>::write_rle_vector (const unsigned int magic_number1,
+ const vector<T> &v,
+ const unsigned int magic_number2,
+ ostream &out)
+{
+ AssertThrow (out, ExcIO());
+
+ // store the position of the last
+ // break in the data stream from
+ // which on nothing was yet written
+ // to #out#
+ typename vector<T>::const_iterator last_major_break = v.begin();
+ // pointer to an element against
+ // which we want to compare following
+ // elements
+ typename vector<T>::const_iterator comparator;
+ // name says all
+ typename vector<T>::const_iterator present_element;
+ // same here
+ typename vector<T>::const_iterator end_of_vector = v.end();
+
+ out << magic_number1 << ' ' << v.size() << '[';
+
+ while (last_major_break < end_of_vector)
+ {
+ // from the present position onward:
+ // find how many elements are equal
+ comparator = last_major_break;
+
+ while (true)
+ {
+ present_element = comparator+1;
+ while ((present_element != end_of_vector) &&
+ (*present_element == *comparator) &&
+ (present_element-comparator < 255))
+ ++present_element;
+
+ // now present_element points to the
+ // first element which is not equal
+ // to #comparator# or alternatively
+ // to #end_of_vector# or to
+ // #comparator+255#
+ //
+ // if #present_element# is
+ // #comparator+1#, i.e. the
+ // sequence of equal
+ // elements consisted of
+ // only one elements then
+ // discard this sequence
+ // and find the next one
+ //
+ // otherwise leave the loop
+ if ((present_element != end_of_vector) &&
+ (present_element < comparator+1))
+ comparator = present_element;
+ else
+ break;
+ };
+
+ // if the loop broke because we have
+ // reached the end of the vector:
+ // maybe set comparator to
+ // present_element
+ if ((present_element == end_of_vector) &&
+ (present_element < comparator+1))
+ comparator = present_element;
+
+ // now comparator points to the start
+ // of the sequence of equal elements
+ // and present_element points past its
+ // end; they may be the same if the
+ // length of the sequence of unequal
+ // elements was 255
+ //
+ // now do the following: write out
+ // the elements of
+ // last_major_break...comparator,
+ // then write
+ // comparator...present_element
+ // if necessary; note that we need
+ // only write *one* element (that is why
+ // we do all this here)
+ out << '<' << comparator-last_major_break << '>';
+ if (comparator != last_major_break)
+ out.write (reinterpret_cast<const char*>(last_major_break),
+ reinterpret_cast<const char*>(comparator)
+ - reinterpret_cast<const char*>(last_major_break));
+ out << '<' << present_element-comparator << '>';
+ if (present_element != comparator)
+ out.write (reinterpret_cast<const char*>(comparator),
+ reinterpret_cast<const char*>(comparator+1)
+ - reinterpret_cast<const char*>(comparator));
+
+ last_major_break = present_element;
+ };
+
+ out << ']' << magic_number2 << endl;
+
+ AssertThrow (out, ExcIO());
+};
+
+
+
+void TriangulationLevel<0>::block_write (ostream &out) const
+{
+ write_raw_vector (0, refine_flags, 0, out);
+ write_raw_vector (0, coarsen_flags, 0, out);
+ write_raw_vector (0, neighbors, 0, out);
+};
+
+
+
+
+
void TriangulationLevel<1>::reserve_space (const unsigned int new_lines) {
const unsigned int new_size = new_lines +
count_if (lines.used.begin(),
+void TriangulationLevel<1>::block_write (ostream &out) const
+{
+ TriangulationLevel<0>::block_write (out);
+
+ write_raw_vector (0, lines.lines, 0, out);
+ write_rle_vector (0, lines.children, 0, out);
+ write_raw_vector (0, lines.used, 0, out);
+ write_raw_vector (0, lines.user_flags, 0, out);
+ write_rle_vector (0, lines.material_id, 0, out);
+ // note: user_pointers are not written
+};
+
+
+
void TriangulationLevel<2>::reserve_space (const unsigned int new_quads) {
const unsigned int new_size = new_quads +
+void TriangulationLevel<2>::block_write (ostream &out) const
+{
+ TriangulationLevel<1>::block_write (out);
+
+ write_raw_vector (0, quads.quads, 0, out);
+ write_rle_vector (0, quads.children, 0, out);
+ write_raw_vector (0, quads.used, 0, out);
+ write_raw_vector (0, quads.user_flags, 0, out);
+ write_rle_vector (0, quads.material_id, 0, out);
+ // note: user_pointers are not written
+};
+
+
+
+
void TriangulationLevel<3>::reserve_space (const unsigned int new_hexes) {
+void TriangulationLevel<3>::block_write (ostream &out) const
+{
+ TriangulationLevel<2>::block_write (out);
+
+ write_raw_vector (0, hexes.hexes, 0, out);
+ write_rle_vector (0, hexes.children, 0, out);
+ write_raw_vector (0, hexes.used, 0, out);
+ write_raw_vector (0, hexes.user_flags, 0, out);
+ write_rle_vector (0, hexes.material_id, 0, out);
+ // note: user_pointers are not written
+};
+