00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <fstream>
00020 #include "common.hpp"
00021 #include "format_string.hpp"
00022 #include "serialise/error.hpp"
00023 #include "serialise/parser.hpp"
00024
00025 obby::serialise::parser::parser()
00026 {
00027 }
00028
00029 void obby::serialise::parser::deserialise(const std::string& file)
00030 {
00031 std::ifstream in(file.c_str() );
00032
00033 if(!in)
00034 {
00035 obby::format_string str(_(
00036 "Could not open file '%0%' for reading"
00037 ) );
00038
00039 str << file;
00040 throw error(str.str(), 0);
00041 }
00042
00043 deserialise(in);
00044 }
00045
00046 void obby::serialise::parser::deserialise(std::istream& stream)
00047 {
00048 const unsigned int bufsize = 1024;
00049 char readbuf[bufsize];
00050 std::string result;
00051
00052
00053 result.reserve(bufsize << 3);
00054
00055 #ifdef WIN32
00056
00057
00058
00059 std::string line;
00060 while(std::getline(stream, line) )
00061 {
00062
00063
00064 if(result.capacity() < result.length() + bufsize)
00065 result.reserve(result.capacity() * 2);
00066
00067 result += line;
00068 result += '\n';
00069 }
00070 #else
00071 while(stream)
00072 {
00073
00074
00075 if(result.capacity() < result.length() + bufsize)
00076 result.reserve(result.capacity() * 2);
00077
00078
00079 stream.read(readbuf, bufsize);
00080 result.append(readbuf, stream.gcount() );
00081 }
00082 #endif
00083
00084 deserialise_memory(result);
00085 }
00086
00087 void obby::serialise::parser::deserialise_memory(const std::string& mem)
00088 {
00089 token_list list;
00090 list.deserialise(mem);
00091 token_list::iterator iter = list.begin();
00092
00093
00094 if(iter->get_type() != token::TYPE_EXCLAMATION)
00095 {
00096 throw error(
00097 _("Expected initial exclamation mark"),
00098 iter->get_line()
00099 );
00100 }
00101 list.next_token(iter);
00102
00103
00104 if(iter->get_type() != token::TYPE_IDENTIFIER)
00105 {
00106 throw error(
00107 _("Expected document type after '!'"),
00108 iter->get_line()
00109 );
00110 }
00111 m_type = iter->get_text();
00112 list.next_token(iter);
00113
00114
00115 if(iter->get_type() != token::TYPE_INDENTATION)
00116 {
00117 throw error(
00118 _("Expected newline after document type"),
00119 iter->get_line()
00120 );
00121 }
00122
00123
00124 if(iter->get_text().length() > 0)
00125 {
00126 throw error(
00127 _("Expected top-level object after document type"),
00128 iter->get_line()
00129 );
00130 }
00131 list.next_token(iter);
00132
00133
00134 if(iter->get_type() != token::TYPE_IDENTIFIER)
00135 {
00136 throw error(
00137 _("Expected root object after document type"),
00138 iter->get_line()
00139 );
00140 }
00141
00142 m_object.deserialise(list, iter);
00143
00144
00145 if(iter != list.end() )
00146 {
00147 format_string str(_("Expected end of input instead of '%0%'") );
00148 str << iter->get_text();
00149 throw error(str.str(), iter->get_line() );
00150 }
00151 }
00152
00153 void obby::serialise::parser::serialise(const std::string& file) const
00154 {
00155 std::ofstream out(file.c_str() );
00156 if(!out)
00157 {
00158 obby::format_string str(
00159 _("Could not open file '%0%' for writing")
00160 );
00161
00162 str << file;
00163 throw std::runtime_error(str.str() );
00164 }
00165
00166 serialise(out);
00167 }
00168
00169 void obby::serialise::parser::serialise(std::ostream& stream) const
00170 {
00171
00172 std::string result;
00173 serialise_memory(result);
00174
00175
00176 stream << result;
00177 stream.flush();
00178 }
00179
00180 void obby::serialise::parser::serialise_memory(std::string& mem) const
00181 {
00182
00183 token_list list;
00184
00185
00186 list.add(token::TYPE_EXCLAMATION, "!", 0);
00187 list.add(token::TYPE_IDENTIFIER, m_type, 0);
00188
00189
00190 list.add(token::TYPE_INDENTATION, "", 0);
00191
00192
00193 m_object.serialise(list);
00194 list.serialise(mem);
00195 }
00196
00197 const std::string& obby::serialise::parser::get_type() const
00198 {
00199 return m_type;
00200 }
00201
00202 void obby::serialise::parser::set_type(const std::string& type)
00203 {
00204 m_type = type;
00205 }
00206
00207 const obby::serialise::object& obby::serialise::parser::get_root() const
00208 {
00209 return m_object;
00210 }
00211
00212 obby::serialise::object& obby::serialise::parser::get_root()
00213 {
00214 return m_object;
00215 }