00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined (INCLUDED_STRINGIO_H)
00023 #define INCLUDED_STRINGIO_H
00024
00025 #include <stdlib.h>
00026 #include <cctype>
00027
00028 #include "math/Vector3.h"
00029 #include "iscriplib.h"
00030 #include "string/string.h"
00031 #include "generic/callback.h"
00032
00033 inline double buffer_parse_floating_literal (const char*& buffer)
00034 {
00035 return strtod(buffer, const_cast<char**> (&buffer));
00036 }
00037
00038 inline int buffer_parse_signed_decimal_integer_literal (const char*& buffer)
00039 {
00040 return strtol(buffer, const_cast<char**> (&buffer), 10);
00041 }
00042
00043 inline int buffer_parse_unsigned_decimal_integer_literal (const char*& buffer)
00044 {
00045 return strtoul(buffer, const_cast<char**> (&buffer), 10);
00046 }
00047
00048
00049 inline bool string_parse_float (const char* string, float& f)
00050 {
00051 if (string_empty(string)) {
00052 return false;
00053 }
00054 f = float(buffer_parse_floating_literal(string));
00055 return string_empty(string);
00056 }
00057
00058
00059 inline bool string_parse_double (const char* string, double& f)
00060 {
00061 if (string_empty(string)) {
00062 return false;
00063 }
00064 f = buffer_parse_floating_literal(string);
00065 return string_empty(string);
00066 }
00067
00068
00069 template<typename Element>
00070 inline bool string_parse_vector3 (const char* string, BasicVector3<Element>& v)
00071 {
00072 if (string_empty(string) || *string == ' ') {
00073 return false;
00074 }
00075 v[0] = float(buffer_parse_floating_literal(string));
00076 if (*string++ != ' ') {
00077 return false;
00078 }
00079 v[1] = float(buffer_parse_floating_literal(string));
00080 if (*string++ != ' ') {
00081 return false;
00082 }
00083 v[2] = float(buffer_parse_floating_literal(string));
00084 return string_empty(string);
00085 }
00086
00087 template<typename Float>
00088 inline bool string_parse_vector (const char* string, Float* first, Float* last)
00089 {
00090 if (first != last && (string_empty(string) || *string == ' ')) {
00091 return false;
00092 }
00093 for (;;) {
00094 *first = float(buffer_parse_floating_literal(string));
00095 if (++first == last) {
00096 return string_empty(string);
00097 }
00098 if (*string++ != ' ') {
00099 return false;
00100 }
00101 }
00102 }
00103
00104
00105 inline bool string_parse_int (const char* string, int& i)
00106 {
00107 if (string_empty(string)) {
00108 return false;
00109 }
00110 i = buffer_parse_signed_decimal_integer_literal(string);
00111 return string_empty(string);
00112 }
00113
00114
00115 inline bool string_parse_size (const char* string, std::size_t& i)
00116 {
00117 if (string_empty(string)) {
00118 return false;
00119 }
00120 i = buffer_parse_unsigned_decimal_integer_literal(string);
00121 return string_empty(string);
00122 }
00123
00124 #define RETURN_FALSE_IF_FAIL(expression) if(!expression) return false; else
00125
00126 inline void Tokeniser_unexpectedError (Tokeniser& tokeniser, const std::string& token, const std::string& expected)
00127 {
00128 globalErrorStream() << Unsigned(tokeniser.getLine()) << ":" << Unsigned(tokeniser.getColumn())
00129 << ": parse error at '" << (token.length() ? token : "#EOF") << "': expected '" << expected.c_str()
00130 << "'\n";
00131 }
00132
00133 inline bool Tokeniser_getFloat (Tokeniser& tokeniser, float& f)
00134 {
00135 const std::string token = tokeniser.getToken();
00136 if (token.length() && string_parse_float(token.c_str(), f)) {
00137 return true;
00138 }
00139 Tokeniser_unexpectedError(tokeniser, token, "#number");
00140 return false;
00141 }
00142
00143 inline bool Tokeniser_getDouble (Tokeniser& tokeniser, double& f)
00144 {
00145 const std::string token = tokeniser.getToken();
00146 if (token.length() && string_parse_double(token.c_str(), f)) {
00147 return true;
00148 }
00149 Tokeniser_unexpectedError(tokeniser, token, "#number");
00150 return false;
00151 }
00152
00153 inline bool Tokeniser_getInteger (Tokeniser& tokeniser, int& i)
00154 {
00155 const std::string token = tokeniser.getToken();
00156 if (token.length() && string_parse_int(token.c_str(), i)) {
00157 return true;
00158 }
00159 Tokeniser_unexpectedError(tokeniser, token, "#integer");
00160 return false;
00161 }
00162
00163 inline bool Tokeniser_getSize (Tokeniser& tokeniser, std::size_t& i)
00164 {
00165 const std::string token = tokeniser.getToken();
00166 if (token.length() && string_parse_size(token.c_str(), i)) {
00167 return true;
00168 }
00169 Tokeniser_unexpectedError(tokeniser, token, "#unsigned-integer");
00170 return false;
00171 }
00172
00173 inline bool Tokeniser_parseToken (Tokeniser& tokeniser, const char* expected)
00174 {
00175 const std::string token = tokeniser.getToken();
00176 if (token.length() && string_equal(token.c_str(), expected)) {
00177 return true;
00178 }
00179 Tokeniser_unexpectedError(tokeniser, token, expected);
00180 return false;
00181 }
00182
00183 inline bool Tokeniser_nextTokenIsDigit (Tokeniser& tokeniser)
00184 {
00185 const std::string token = tokeniser.getToken();
00186 if (token.empty()) {
00187 return false;
00188 }
00189 char c = *token.c_str();
00190 tokeniser.ungetToken();
00191 return std::isdigit(c) != 0;
00192 }
00193
00194 template<typename TextOutputStreamType>
00195 inline TextOutputStreamType& ostream_write (TextOutputStreamType& outputStream, const Vector3& v)
00196 {
00197 return outputStream << '(' << v.x() << ' ' << v.y() << ' ' << v.z() << ')';
00198 }
00199
00200 inline void StdString_importString (std::string& self, const char* string)
00201 {
00202 self = string;
00203 }
00204 typedef ReferenceCaller1<std::string, const char*, StdString_importString> StringImportStringCaller;
00205 inline void StdString_exportString (const std::string& self, const StringImportCallback& importer)
00206 {
00207 importer(self.c_str());
00208 }
00209 typedef ConstReferenceCaller1<std::string, const StringImportCallback&, StdString_exportString>
00210 StringExportStringCaller;
00211
00212 inline void Bool_importString (bool& self, const char* string)
00213 {
00214 self = string_equal(string, "true");
00215 }
00216 typedef ReferenceCaller1<bool, const char*, Bool_importString> BoolImportStringCaller;
00217 inline void Bool_exportString (const bool& self, const StringImportCallback& importer)
00218 {
00219 importer(self ? "true" : "false");
00220 }
00221 typedef ConstReferenceCaller1<bool, const StringImportCallback&, Bool_exportString> BoolExportStringCaller;
00222
00223 inline void Int_importString (int& self, const char* string)
00224 {
00225 if (!string_parse_int(string, self)) {
00226 self = 0;
00227 }
00228 }
00229 typedef ReferenceCaller1<int, const char*, Int_importString> IntImportStringCaller;
00230 inline void Int_exportString (const int& self, const StringImportCallback& importer)
00231 {
00232 char buffer[16];
00233 sprintf(buffer, "%d", self);
00234 importer(buffer);
00235 }
00236 typedef ConstReferenceCaller1<int, const StringImportCallback&, Int_exportString> IntExportStringCaller;
00237
00238 inline void Size_importString (std::size_t& self, const char* string)
00239 {
00240 int i;
00241 if (string_parse_int(string, i) && i >= 0) {
00242 self = i;
00243 } else {
00244 self = 0;
00245 }
00246 }
00247 typedef ReferenceCaller1<std::size_t, const char*, Size_importString> SizeImportStringCaller;
00248 inline void Size_exportString (const std::size_t& self, const StringImportCallback& importer)
00249 {
00250 char buffer[16];
00251 sprintf(buffer, "%u", Unsigned(self));
00252 importer(buffer);
00253 }
00254 typedef ConstReferenceCaller1<std::size_t, const StringImportCallback&, Size_exportString> SizeExportStringCaller;
00255
00256 inline void Float_importString (float& self, const char* string)
00257 {
00258 if (!string_parse_float(string, self)) {
00259 self = 0;
00260 }
00261 }
00262 typedef ReferenceCaller1<float, const char*, Float_importString> FloatImportStringCaller;
00263 inline void Float_exportString (const float& self, const StringImportCallback& importer)
00264 {
00265 char buffer[16];
00266 sprintf(buffer, "%g", self);
00267 importer(buffer);
00268 }
00269 typedef ConstReferenceCaller1<float, const StringImportCallback&, Float_exportString> FloatExportStringCaller;
00270
00271 inline void Vector3_importString (Vector3& self, const char* string)
00272 {
00273 if (!string_parse_vector3(string, self)) {
00274 self = Vector3(0, 0, 0);
00275 }
00276 }
00277 typedef ReferenceCaller1<Vector3, const char*, Vector3_importString> Vector3ImportStringCaller;
00278 inline void Vector3_exportString (const Vector3& self, const StringImportCallback& importer)
00279 {
00280 char buffer[64];
00281 sprintf(buffer, "%g %g %g", self[0], self[1], self[2]);
00282 importer(buffer);
00283 }
00284 typedef ConstReferenceCaller1<Vector3, const StringImportCallback&, Vector3_exportString> Vector3ExportStringCaller;
00285
00286 template<typename FirstArgument, typename Caller, typename FirstConversion>
00287 class ImportConvert1
00288 {
00289 public:
00290 static void thunk (void* environment, FirstArgument firstArgument)
00291 {
00292 Caller::thunk(environment, FirstConversion(firstArgument));
00293 }
00294 };
00295
00296 class BoolFromString
00297 {
00298 bool m_value;
00299 public:
00300 BoolFromString (const char* string)
00301 {
00302 Bool_importString(m_value, string);
00303 }
00304 operator bool () const
00305 {
00306 return m_value;
00307 }
00308 };
00309
00310 inline void Bool_toString (const StringImportCallback& self, bool value)
00311 {
00312 Bool_exportString(value, self);
00313 }
00314 typedef ConstReferenceCaller1<StringImportCallback, bool, Bool_toString> BoolToString;
00315
00316 template<typename Caller>
00317 inline StringImportCallback makeBoolStringImportCallback (const Caller& caller)
00318 {
00319 return StringImportCallback(caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type,
00320 Caller, BoolFromString>::thunk);
00321 }
00322
00323 template<typename Caller>
00324 inline StringExportCallback makeBoolStringExportCallback (const Caller& caller)
00325 {
00326 return StringExportCallback(caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type,
00327 Caller, BoolToString>::thunk);
00328 }
00329
00330 class IntFromString
00331 {
00332 int m_value;
00333 public:
00334 IntFromString (const char* string)
00335 {
00336 Int_importString(m_value, string);
00337 }
00338 operator int () const
00339 {
00340 return m_value;
00341 }
00342 };
00343
00344 inline void Int_toString (const StringImportCallback& self, int value)
00345 {
00346 Int_exportString(value, self);
00347 }
00348 typedef ConstReferenceCaller1<StringImportCallback, int, Int_toString> IntToString;
00349
00350 template<typename Caller>
00351 inline StringImportCallback makeIntStringImportCallback (const Caller& caller)
00352 {
00353 return StringImportCallback(caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type,
00354 Caller, IntFromString>::thunk);
00355 }
00356
00357 template<typename Caller>
00358 inline StringExportCallback makeIntStringExportCallback (const Caller& caller)
00359 {
00360 return StringExportCallback(caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type,
00361 Caller, IntToString>::thunk);
00362 }
00363
00364 class SizeFromString
00365 {
00366 std::size_t m_value;
00367 public:
00368 SizeFromString (const char* string)
00369 {
00370 Size_importString(m_value, string);
00371 }
00372 operator std::size_t () const
00373 {
00374 return m_value;
00375 }
00376 };
00377
00378 inline void Size_toString (const StringImportCallback& self, std::size_t value)
00379 {
00380 Size_exportString(value, self);
00381 }
00382 typedef ConstReferenceCaller1<StringImportCallback, std::size_t, Size_toString> SizeToString;
00383
00384 template<typename Caller>
00385 inline StringImportCallback makeSizeStringImportCallback (const Caller& caller)
00386 {
00387 return StringImportCallback(caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type,
00388 Caller, SizeFromString>::thunk);
00389 }
00390
00391 template<typename Caller>
00392 inline StringExportCallback makeSizeStringExportCallback (const Caller& caller)
00393 {
00394 return StringExportCallback(caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type,
00395 Caller, SizeToString>::thunk);
00396 }
00397
00398 #endif