refactor xml parser, uses faster string to double conversion
This commit is contained in:
parent
b7704f0c7f
commit
a1ecab2f95
@ -42,249 +42,307 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <boost/ref.hpp>
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) {
|
XMLParser::XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se)
|
||||||
inputReader = inputReaderFactory(filename);
|
: BaseParser(ec, se)
|
||||||
|
{
|
||||||
|
inputReader = inputReaderFactory(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLParser::ReadHeader() {
|
bool XMLParser::ReadHeader() { return (xmlTextReaderRead(inputReader) == 1); }
|
||||||
return (xmlTextReaderRead( inputReader ) == 1);
|
bool XMLParser::Parse()
|
||||||
}
|
{
|
||||||
bool XMLParser::Parse() {
|
while (xmlTextReaderRead(inputReader) == 1)
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
{
|
||||||
const int type = xmlTextReaderNodeType( inputReader );
|
const int type = xmlTextReaderNodeType(inputReader);
|
||||||
|
|
||||||
//1 is Element
|
// 1 is Element
|
||||||
if ( type != 1 ) {
|
if (type != 1)
|
||||||
continue;
|
{
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
xmlChar* currentName = xmlTextReaderName( inputReader );
|
xmlChar *currentName = xmlTextReaderName(inputReader);
|
||||||
if ( currentName == NULL ) {
|
if (currentName == NULL)
|
||||||
continue;
|
{
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
|
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
|
||||||
ImportNode n = _ReadXMLNode();
|
{
|
||||||
ParseNodeInLua( n, lua_state );
|
ImportNode n = ReadXMLNode();
|
||||||
extractor_callbacks->nodeFunction(n);
|
ParseNodeInLua(n, lua_state);
|
||||||
// if(!extractor_callbacks->nodeFunction(n))
|
extractor_callbacks->nodeFunction(n);
|
||||||
// std::cerr << "[XMLParser] dense node not parsed" << std::endl;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
|
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
|
||||||
ExtractionWay way = _ReadXMLWay( );
|
{
|
||||||
ParseWayInLua( way, lua_state );
|
ExtractionWay way = ReadXMLWay();
|
||||||
extractor_callbacks->wayFunction(way);
|
ParseWayInLua(way, lua_state);
|
||||||
// if(!extractor_callbacks->wayFunction(way))
|
extractor_callbacks->wayFunction(way);
|
||||||
// std::cerr << "[PBFParser] way not parsed" << std::endl;
|
}
|
||||||
}
|
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
|
||||||
if( use_turn_restrictions ) {
|
{
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
|
InputRestrictionContainer r = ReadXMLRestriction();
|
||||||
InputRestrictionContainer r = _ReadXMLRestriction();
|
if ((UINT_MAX != r.fromWay) && !extractor_callbacks->restrictionFunction(r))
|
||||||
if(r.fromWay != UINT_MAX) {
|
{
|
||||||
if(!extractor_callbacks->restrictionFunction(r)) {
|
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
|
||||||
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
|
}
|
||||||
}
|
}
|
||||||
}
|
xmlFree(currentName);
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
xmlFree( currentName );
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputRestrictionContainer XMLParser::_ReadXMLRestriction() {
|
InputRestrictionContainer XMLParser::ReadXMLRestriction()
|
||||||
|
{
|
||||||
InputRestrictionContainer restriction;
|
InputRestrictionContainer restriction;
|
||||||
std::string except_tag_string;
|
std::string except_tag_string;
|
||||||
|
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
|
||||||
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
{
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
const int depth = xmlTextReaderDepth(inputReader);
|
||||||
if ( childType != 1 && childType != 15 ) {
|
while (xmlTextReaderRead(inputReader) == 1)
|
||||||
continue;
|
{
|
||||||
}
|
const int childType = xmlTextReaderNodeType(inputReader);
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
if (childType != 1 && childType != 15)
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
{
|
||||||
if ( childName == NULL ) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
const int childDepth = xmlTextReaderDepth(inputReader);
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) {
|
xmlChar *childName = xmlTextReaderName(inputReader);
|
||||||
xmlFree( childName );
|
if (childName == NULL)
|
||||||
break;
|
{
|
||||||
}
|
continue;
|
||||||
if ( childType != 1 ) {
|
}
|
||||||
xmlFree( childName );
|
if (depth == childDepth && childType == 15 &&
|
||||||
continue;
|
xmlStrEqual(childName, (const xmlChar *)"relation") == 1)
|
||||||
}
|
{
|
||||||
|
xmlFree(childName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (childType != 1)
|
||||||
|
{
|
||||||
|
xmlFree(childName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
{
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
|
||||||
if ( k != NULL && value != NULL ) {
|
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
|
||||||
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){
|
if (k != NULL && value != NULL)
|
||||||
if(0 == std::string((const char *) value).find("only_")) {
|
{
|
||||||
restriction.restriction.flags.isOnly = true;
|
if (xmlStrEqual(k, (const xmlChar *)"restriction") &&
|
||||||
}
|
(0 == std::string((const char *)value).find("only_")))
|
||||||
}
|
{
|
||||||
if ( xmlStrEqual(k, (const xmlChar *) "except") ) {
|
restriction.restriction.flags.isOnly = true;
|
||||||
except_tag_string = (const char*) value;
|
}
|
||||||
}
|
if (xmlStrEqual(k, (const xmlChar *)"except"))
|
||||||
}
|
{
|
||||||
|
except_tag_string = (const char *)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( k != NULL ) {
|
if (k != NULL)
|
||||||
xmlFree( k );
|
{
|
||||||
}
|
xmlFree(k);
|
||||||
if ( value != NULL ) {
|
}
|
||||||
xmlFree( value );
|
if (value != NULL)
|
||||||
}
|
{
|
||||||
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) {
|
xmlFree(value);
|
||||||
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
}
|
||||||
if ( ref != NULL ) {
|
}
|
||||||
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
|
else if (xmlStrEqual(childName, (const xmlChar *)"member") == 1)
|
||||||
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
|
{
|
||||||
|
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
|
||||||
|
if (ref != NULL)
|
||||||
|
{
|
||||||
|
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
|
||||||
|
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
|
||||||
|
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
if (xmlStrEqual(role, (const xmlChar *)"to") &&
|
||||||
restriction.toWay = stringToUint((const char*) ref);
|
xmlStrEqual(type, (const xmlChar *)"way"))
|
||||||
}
|
{
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
restriction.toWay = stringToUint((const char *)ref);
|
||||||
restriction.fromWay = stringToUint((const char*) ref);
|
}
|
||||||
}
|
if (xmlStrEqual(role, (const xmlChar *)"from") &&
|
||||||
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
|
xmlStrEqual(type, (const xmlChar *)"way"))
|
||||||
restriction.restriction.viaNode = stringToUint((const char*) ref);
|
{
|
||||||
}
|
restriction.fromWay = stringToUint((const char *)ref);
|
||||||
|
}
|
||||||
|
if (xmlStrEqual(role, (const xmlChar *)"via") &&
|
||||||
|
xmlStrEqual(type, (const xmlChar *)"node"))
|
||||||
|
{
|
||||||
|
restriction.restriction.viaNode = stringToUint((const char *)ref);
|
||||||
|
}
|
||||||
|
|
||||||
if(NULL != type) {
|
if (NULL != type)
|
||||||
xmlFree( type );
|
{
|
||||||
}
|
xmlFree(type);
|
||||||
if(NULL != role) {
|
}
|
||||||
xmlFree( role );
|
if (NULL != role)
|
||||||
}
|
{
|
||||||
if(NULL != ref) {
|
xmlFree(role);
|
||||||
xmlFree( ref );
|
}
|
||||||
}
|
if (NULL != ref)
|
||||||
}
|
{
|
||||||
}
|
xmlFree(ref);
|
||||||
xmlFree( childName );
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xmlFree(childName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ShouldIgnoreRestriction(except_tag_string) ) {
|
if (ShouldIgnoreRestriction(except_tag_string))
|
||||||
restriction.fromWay = UINT_MAX; //workaround to ignore the restriction
|
{
|
||||||
}
|
restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
|
||||||
return restriction;
|
}
|
||||||
|
return restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractionWay XMLParser::_ReadXMLWay() {
|
ExtractionWay XMLParser::ReadXMLWay()
|
||||||
ExtractionWay way;
|
{
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
ExtractionWay way;
|
||||||
const int depth = xmlTextReaderDepth( inputReader );
|
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
{
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
const int depth = xmlTextReaderDepth(inputReader);
|
||||||
if ( childType != 1 && childType != 15 ) {
|
while (xmlTextReaderRead(inputReader) == 1)
|
||||||
continue;
|
{
|
||||||
}
|
const int childType = xmlTextReaderNodeType(inputReader);
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
if (childType != 1 && childType != 15)
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
{
|
||||||
if ( childName == NULL ) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
const int childDepth = xmlTextReaderDepth(inputReader);
|
||||||
|
xmlChar *childName = xmlTextReaderName(inputReader);
|
||||||
|
if (childName == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
|
if (depth == childDepth && childType == 15 &&
|
||||||
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
xmlStrEqual(childName, (const xmlChar *)"way") == 1)
|
||||||
way.id = stringToUint((char*)id);
|
{
|
||||||
xmlFree(id);
|
xmlChar *id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
|
||||||
xmlFree( childName );
|
way.id = stringToUint((char *)id);
|
||||||
break;
|
xmlFree(id);
|
||||||
}
|
xmlFree(childName);
|
||||||
if ( childType != 1 ) {
|
break;
|
||||||
xmlFree( childName );
|
}
|
||||||
continue;
|
if (childType != 1)
|
||||||
}
|
{
|
||||||
|
xmlFree(childName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
{
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
|
||||||
// cout << "->k=" << k << ", v=" << value << endl;
|
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
|
||||||
if ( k != NULL && value != NULL ) {
|
|
||||||
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
|
if (k != NULL && value != NULL)
|
||||||
}
|
{
|
||||||
if ( k != NULL ) {
|
way.keyVals.Add(std::string((char *)k), std::string((char *)value));
|
||||||
xmlFree( k );
|
}
|
||||||
}
|
if (k != NULL)
|
||||||
if ( value != NULL ) {
|
{
|
||||||
xmlFree( value );
|
xmlFree(k);
|
||||||
}
|
}
|
||||||
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
|
if (value != NULL)
|
||||||
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
{
|
||||||
if ( ref != NULL ) {
|
xmlFree(value);
|
||||||
way.path.push_back( stringToUint(( const char* ) ref ) );
|
}
|
||||||
xmlFree( ref );
|
}
|
||||||
}
|
else if (xmlStrEqual(childName, (const xmlChar *)"nd") == 1)
|
||||||
}
|
{
|
||||||
xmlFree( childName );
|
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
|
||||||
}
|
if (ref != NULL)
|
||||||
}
|
{
|
||||||
return way;
|
way.path.push_back(stringToUint((const char *)ref));
|
||||||
|
xmlFree(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlFree(childName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return way;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportNode XMLParser::_ReadXMLNode() {
|
ImportNode XMLParser::ReadXMLNode()
|
||||||
ImportNode node;
|
{
|
||||||
|
ImportNode node;
|
||||||
|
|
||||||
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
|
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
|
||||||
if ( attribute != NULL ) {
|
if (attribute != NULL)
|
||||||
node.lat = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ) );
|
{
|
||||||
xmlFree( attribute );
|
node.lat = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
|
||||||
}
|
xmlFree(attribute);
|
||||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
|
}
|
||||||
if ( attribute != NULL ) {
|
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
|
||||||
node.lon = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ));
|
if (attribute != NULL)
|
||||||
xmlFree( attribute );
|
{
|
||||||
}
|
node.lon = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
|
||||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
xmlFree(attribute);
|
||||||
if ( attribute != NULL ) {
|
}
|
||||||
node.id = stringToUint(( const char* ) attribute );
|
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
|
||||||
xmlFree( attribute );
|
if (attribute != NULL)
|
||||||
}
|
{
|
||||||
|
node.id = stringToUint((const char *)attribute);
|
||||||
|
xmlFree(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
|
||||||
const int depth = xmlTextReaderDepth( inputReader );
|
{
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
const int depth = xmlTextReaderDepth(inputReader);
|
||||||
const int childType = xmlTextReaderNodeType( inputReader );
|
while (xmlTextReaderRead(inputReader) == 1)
|
||||||
// 1 = Element, 15 = EndElement
|
{
|
||||||
if ( childType != 1 && childType != 15 ) {
|
const int childType = xmlTextReaderNodeType(inputReader);
|
||||||
continue;
|
// 1 = Element, 15 = EndElement
|
||||||
}
|
if (childType != 1 && childType != 15)
|
||||||
const int childDepth = xmlTextReaderDepth( inputReader );
|
{
|
||||||
xmlChar* childName = xmlTextReaderName( inputReader );
|
continue;
|
||||||
if ( childName == NULL ) {
|
}
|
||||||
continue;
|
const int childDepth = xmlTextReaderDepth(inputReader);
|
||||||
}
|
xmlChar *childName = xmlTextReaderName(inputReader);
|
||||||
|
if (childName == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
|
if (depth == childDepth && childType == 15 &&
|
||||||
xmlFree( childName );
|
xmlStrEqual(childName, (const xmlChar *)"node") == 1)
|
||||||
break;
|
{
|
||||||
}
|
xmlFree(childName);
|
||||||
if ( childType != 1 ) {
|
break;
|
||||||
xmlFree( childName );
|
}
|
||||||
continue;
|
if (childType != 1)
|
||||||
}
|
{
|
||||||
|
xmlFree(childName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
|
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
|
||||||
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
|
{
|
||||||
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
|
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
|
||||||
if ( k != NULL && value != NULL ) {
|
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
|
||||||
node.keyVals.emplace(std::string(reinterpret_cast<char*>(k)), std::string(reinterpret_cast<char*>(value)));
|
if (k != NULL && value != NULL)
|
||||||
}
|
{
|
||||||
if ( k != NULL ) {
|
node.keyVals.emplace(std::string((char *)(k)),
|
||||||
xmlFree( k );
|
std::string((char *)(value)));
|
||||||
}
|
}
|
||||||
if ( value != NULL ) {
|
if (k != NULL)
|
||||||
xmlFree( value );
|
{
|
||||||
}
|
xmlFree(k);
|
||||||
}
|
}
|
||||||
|
if (value != NULL)
|
||||||
|
{
|
||||||
|
xmlFree(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xmlFree( childName );
|
xmlFree(childName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -33,20 +33,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <libxml/xmlreader.h>
|
#include <libxml/xmlreader.h>
|
||||||
|
|
||||||
class XMLParser : public BaseParser {
|
class XMLParser : public BaseParser
|
||||||
public:
|
{
|
||||||
XMLParser(
|
public:
|
||||||
const char* filename,
|
XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se);
|
||||||
ExtractorCallbacks * ec,
|
|
||||||
ScriptingEnvironment & se
|
|
||||||
);
|
|
||||||
bool ReadHeader();
|
bool ReadHeader();
|
||||||
bool Parse();
|
bool Parse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InputRestrictionContainer _ReadXMLRestriction();
|
InputRestrictionContainer ReadXMLRestriction();
|
||||||
ExtractionWay _ReadXMLWay();
|
ExtractionWay ReadXMLWay();
|
||||||
ImportNode _ReadXMLNode();
|
ImportNode ReadXMLNode();
|
||||||
xmlTextReaderPtr inputReader;
|
xmlTextReaderPtr inputReader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,6 +126,40 @@ static inline uint64_t stringToInt64(const std::string& input) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// source: http://tinodidriksen.com/2011/05/28/cpp-convert-string-to-double-speed/
|
||||||
|
static inline double StringToDouble(const char *p)
|
||||||
|
{
|
||||||
|
double r = 0.0;
|
||||||
|
bool neg = false;
|
||||||
|
if (*p == '-')
|
||||||
|
{
|
||||||
|
neg = true;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
while (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
r = (r*10.0) + (*p - '0');
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
if (*p == '.')
|
||||||
|
{
|
||||||
|
double f = 0.0;
|
||||||
|
int n = 0;
|
||||||
|
++p;
|
||||||
|
while (*p >= '0' && *p <= '9')
|
||||||
|
{
|
||||||
|
f = (f*10.0) + (*p - '0');
|
||||||
|
++p;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
r += f / std::pow(10.0, n);
|
||||||
|
}
|
||||||
|
if (neg)
|
||||||
|
{
|
||||||
|
r = -r;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void doubleToString(const double value, std::string & output){
|
static inline void doubleToString(const double value, std::string & output){
|
||||||
output.clear();
|
output.clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user