stringio.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 // [+|-][nnnnn][.nnnnn][e|E[+|-]nnnnn]
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 // format same as float
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 // <float><space><float><space><float>
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 // decimal signed integer
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 // decimal unsigned integer
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

Generated by  doxygen 1.6.2