deba@1409: /* -*- C++ -*- ladanyi@1435: * lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library deba@1409: * deba@1409: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@1409: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@1409: * deba@1409: * Permission to use, modify and distribute this software is granted deba@1409: * provided that this copyright notice appears in all copies. For deba@1409: * precise terms see the accompanying LICENSE file. deba@1409: * deba@1409: * This software is provided "AS IS" with no warranty of any kind, deba@1409: * express or implied, and with no claim as to its suitability for any deba@1409: * purpose. deba@1409: * deba@1409: */ deba@1409: deba@1415: /// \ingroup item_io deba@1409: /// \file deba@1409: /// \brief Item writer bits for lemon output. deba@1409: deba@1409: #ifndef LEMON_BITS_ITEM_WRITER_H deba@1409: #define LEMON_BITS_ITEM_WRITER_H deba@1409: deba@1409: #include deba@1409: #include deba@1409: deba@1409: #include deba@1409: #include deba@1409: #include deba@1409: #include deba@1409: deba@1409: namespace lemon { deba@1409: deba@1409: template deba@1409: class DefaultWriter; deba@1409: deba@1415: /// \ingroup item_io deba@1409: /// \brief Writer class for quoted strings. deba@1409: /// deba@1409: /// Writer class for quoted strings. It can process the escape deba@1409: /// sequences in the string. deba@1409: /// \author Balazs Dezso deba@1409: class QuotedStringWriter { deba@1409: public: deba@1409: typedef std::string Value; deba@1409: deba@1409: /// \brief Constructor for the writer. deba@1409: /// deba@1409: /// Constructor for the writer. If the given parameter is true deba@1409: /// the writer creates escape sequences from special characters. deba@1409: QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {} deba@1409: deba@1409: /// \brief Writes a quoted string to the given stream. deba@1409: /// deba@1409: /// Writes a quoted string to the given stream. deba@1852: void write(std::ostream& os, const std::string& value) const { deba@1409: os << "\""; deba@1409: if (escaped) { klao@1535: std::ostringstream ls; deba@1409: for (int i = 0; i < (int)value.size(); ++i) { deba@1409: writeEscape(ls, value[i]); deba@1409: } deba@1409: os << ls.str(); deba@1409: } else { deba@1409: os << value; deba@1409: } deba@1409: os << "\""; deba@1409: } deba@1409: deba@1409: private: deba@1409: deba@1409: static void writeEscape(std::ostream& os, char c) { deba@1409: switch (c) { deba@1409: case '\\': deba@1409: os << "\\\\"; deba@1409: return; deba@1409: case '\"': deba@1409: os << "\\\""; deba@1409: return; deba@1409: case '\'': deba@1409: os << "\\\'"; deba@1409: return; deba@1409: case '\?': deba@1409: os << "\\\?"; deba@1409: return; deba@1409: case '\a': deba@1409: os << "\\a"; deba@1409: return; deba@1409: case '\b': deba@1409: os << "\\b"; deba@1409: return; deba@1409: case '\f': deba@1409: os << "\\f"; deba@1409: return; deba@1409: case '\r': deba@1409: os << "\\r"; deba@1409: return; deba@1409: case '\n': deba@1409: os << "\\n"; deba@1409: return; deba@1409: case '\t': deba@1409: os << "\\t"; deba@1409: return; deba@1409: case '\v': deba@1409: os << "\\v"; deba@1409: return; deba@1409: default: deba@1409: if (c < 0x20) { deba@1409: os << '\\' << std::oct << (int)c; deba@1409: } else { deba@1409: os << c; deba@1409: } deba@1409: return; deba@1409: } deba@1409: } deba@1409: private: deba@1409: bool escaped; deba@1409: }; deba@1409: deba@1415: /// \ingroup item_io deba@1533: /// \brief Writer class for quoted char array. deba@1533: /// deba@1533: /// Writer class for quoted char array. It can process the escape deba@1533: /// sequences in the char array. deba@1533: /// \author Balazs Dezso deba@1533: class QuotedCharArrayWriter { deba@1533: public: deba@1533: typedef const char* Value; deba@1533: deba@1533: /// \brief Constructor for the writer. deba@1533: /// deba@1533: /// Constructor for the writer. If the given parameter is true deba@1533: /// the writer creates escape sequences from special characters. deba@1533: QuotedCharArrayWriter(bool _escaped = true) : escaped(_escaped) {} deba@1533: deba@1533: /// \brief Writes a quoted char array to the given stream. deba@1533: /// deba@1533: /// Writes a quoted char array to the given stream. deba@1852: void write(std::ostream& os, const char* value) const { deba@1533: QuotedStringWriter(escaped).write(os, std::string(value)); deba@1533: } deba@1533: deba@1533: private: deba@1533: bool escaped; deba@1533: }; deba@1533: deba@1533: deba@1533: /// \ingroup item_io deba@1409: /// deba@1409: /// \brief Writer for standard containers. deba@1409: /// deba@1409: /// Writer for each iterable standard containers. The representation deba@1409: /// of the container is the values enumerated between an open and a deba@1409: /// close parse. deba@1409: /// deba@1409: /// \author Balazs Dezso deba@1409: template < deba@1409: typename _Container, deba@1409: typename _ItemWriter = DefaultWriter deba@1409: > deba@1409: class IterableWriter { deba@1409: public: deba@1409: typedef _Container Value; deba@1409: typedef _ItemWriter ItemWriter; deba@1409: deba@1409: private: deba@1409: deba@1409: ItemWriter item_writer; deba@1409: deba@1409: public: deba@1409: deba@1852: IterableWriter(const ItemWriter& _item_writer = ItemWriter()) deba@1852: : item_writer(_item_writer) {} deba@1852: deba@1409: /// \brief Writes the values of the container to the given stream. deba@1409: /// deba@1409: /// Writes the values of the container to the given stream. deba@1409: void write(std::ostream& os, const Value& value) const { deba@1409: typename Value::const_iterator it; deba@1409: os << '('; deba@1409: for (it = value.begin(); it != value.end(); ++it) { deba@1409: item_writer.write(os, *it); deba@1409: os << ' '; deba@1409: } deba@1409: os << ')'; deba@1409: } deba@1409: deba@1409: }; deba@1409: deba@1415: /// \ingroup item_io deba@1852: /// deba@1852: /// \brief Writer for standard pairs. deba@1852: /// deba@1852: /// Writer for standard pairs. The representation of a pair is deba@1852: /// \code ( first_value => second_value ) \endcode. deba@1852: /// \author Balazs Dezso deba@1852: template , deba@1852: typename _SecondWriter = deba@1852: DefaultWriter > deba@1852: class PairWriter { deba@1852: public: deba@1852: deba@1852: typedef _Pair Value; deba@1852: deba@1852: typedef _FirstWriter FirstWriter; deba@1852: typedef _SecondWriter SecondWriter; deba@1852: deba@1852: private: deba@1852: deba@1852: FirstWriter first_writer; deba@1852: SecondWriter second_writer; deba@1852: deba@1852: public: deba@1852: deba@1852: /// \brief Constructor. deba@1852: /// deba@1852: /// Constructor for the PairWriter. deba@1852: PairWriter(const FirstWriter& _first_writer = FirstWriter(), deba@1852: const SecondWriter& _second_writer = SecondWriter()) deba@1852: : first_writer(_first_writer), second_writer(_second_writer) {} deba@1852: deba@1852: /// \brief Writes the pair from the given stream. deba@1852: /// deba@1852: /// Writes the pair from the given stream. deba@1852: void write(std::ostream& os, const Value& value) const { deba@1852: os << "( "; deba@1852: first_writer.write(os, value.first); deba@1852: os << " => "; deba@1852: second_writer.write(os, value.second); deba@1852: os << " )"; deba@1852: } deba@1852: deba@1852: }; deba@1852: deba@1852: /// \ingroup item_io deba@1409: /// deba@1409: /// \brief The default item writer template class. deba@1409: /// deba@1409: /// The default item writer template class. If some section writer deba@1409: /// needs to write a value to the stream it will give the default way for it. deba@1409: /// deba@1409: /// \author Balazs Dezso deba@1409: template deba@1409: class DefaultWriter { deba@1409: public: deba@1409: /// The value type. deba@1409: typedef _Value Value; deba@1409: /// \brief Writes the value to the given stream. deba@1409: /// deba@1409: /// Writes the value to the given stream. deba@1409: void write(std::ostream& os, const Value& value) const { deba@1409: os << value; deba@1409: } deba@1409: }; deba@1409: deba@1429: template <> deba@1429: class DefaultWriter ladanyi@1434: : public QuotedStringWriter {}; deba@1429: deba@1533: template deba@1533: class DefaultWriter deba@1533: : public QuotedCharArrayWriter {}; deba@1533: deba@1533: template deba@1533: class DefaultWriter deba@1533: : public QuotedCharArrayWriter {}; deba@1533: deba@1852: template <> deba@1852: class DefaultWriter deba@1852: : public QuotedCharArrayWriter {}; deba@1852: deba@1852: template <> deba@1852: class DefaultWriter deba@1852: : public QuotedCharArrayWriter {}; deba@1852: deba@1409: template deba@1409: class DefaultWriter > deba@1409: : public IterableWriter > {}; deba@1409: deba@1409: template deba@1409: class DefaultWriter > deba@1409: : public IterableWriter > {}; deba@1409: deba@1409: template deba@1409: class DefaultWriter > deba@1409: : public IterableWriter > {}; deba@1409: deba@1409: template deba@1409: class DefaultWriter > deba@1409: : public IterableWriter > {}; deba@1409: deba@1852: template deba@1852: class DefaultWriter > deba@1852: : public IterableWriter > {}; deba@1852: deba@1409: template deba@1409: class DefaultWriter > deba@1409: : public IterableWriter > {}; deba@1409: deba@1852: template deba@1852: class DefaultWriter > deba@1852: : public IterableWriter > {}; deba@1852: deba@1852: template deba@1852: class DefaultWriter > deba@1852: : public PairWriter > {}; deba@1852: deba@1415: /// \ingroup item_io deba@1409: /// \brief Standard WriterTraits for the section writers. deba@1409: /// deba@1409: /// Standard WriterTraits for the section writers. deba@1409: /// It defines standard writing method for all type of value. deba@1409: /// \author Balazs Dezso deba@1409: struct DefaultWriterTraits { deba@1409: deba@1409: template deba@1533: struct Writer : DefaultWriter<_Value> { deba@1533: typedef DefaultWriter<_Value> Parent; deba@1533: }; deba@1409: deba@1409: }; deba@1409: deba@1409: } deba@1409: deba@1409: #endif