#ifndef EXTRACT_HPP #define EXTRACT_HPP // extract.hpp - a simple, hierarchical, tokenizer // // Copyright © 2012-2013 Ben Longbons // // This file is part of The Mana World (Athena server) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "sanity.hpp" #include #include "const_array.hpp" #include "mmo.hpp" #include "utils.hpp" template::value && !std::is_same::value>::type> bool extract(const_string str, T *iv) { if (!str || str.size() > 20) return false; if (!((str.front() == '-' && std::is_signed::value) || ('0' <= str.front() && str.front() <= '9'))) return false; char buf[20 + 1]; std::copy(str.begin(), str.end(), buf); buf[str.size()] = '\0'; char *end; errno = 0; if (std::is_signed::value) { long long v = strtoll(buf, &end, 10); if (errno || *end) return false; *iv = v; return *iv == v; } else { unsigned long long v = strtoull(buf, &end, 10); if (errno || *end) return false; *iv = v; return *iv == v; } } inline bool extract(const_string str, TimeT *tv) { return extract(str, &tv->value); } // extra typename=void to workaround some duplicate overload rule template::value>::type, typename=void> bool extract(const_string str, T *iv) { typedef typename underlying_type::type U; U v; // defer to integer version if (!extract(str, &v)) return false; // TODO check bounds using enum min/max as in SSCANF *iv = static_cast(v); return true; } bool extract(const_string str, const_string *rv); bool extract(const_string str, std::string *rv); template __attribute__((deprecated)) bool extract(const_string str, char (*out)[N]) { if (str.size() >= N) return false; std::copy(str.begin(), str.end(), *out); std::fill(*out + str.size() , *out + N, '\0'); return true; } // basically just a std::tuple // but it provides its data members publically template class Record; template class Record { }; template class Record { public: F frist; Record rest; public: Record(F f, R... r) : frist(f), rest(r...) {} }; template Record record(T... t) { return Record(t...); } template bool extract(const_string str, Record) { return !str; } template bool extract(const_string str, Record rec) { const char *s = std::find(str.begin(), str.end(), split); if (s == str.end()) return sizeof...(R) == 0 && extract(str, rec.frist); return extract(const_string(str.begin(), s), rec.frist) && extract(const_string(s + 1, str.end()), rec.rest); } template struct VRecord { std::vector *arr; }; template VRecord vrec(std::vector *arr) { return {arr}; } template bool extract(const_string str, VRecord rec) { if (str.empty()) return true; const char *s = std::find(str.begin(), str.end(), split); rec.arr->emplace_back(); if (s == str.end()) return extract(str, &rec.arr->back()); return extract(const_string(str.begin(), s), &rec.arr->back()) && extract(const_string(s + 1, str.end()), rec); } bool extract(const_string str, struct global_reg *var); bool extract(const_string str, struct item *it); #endif // EXTRACT_HPP