add openddl-parser to contrib.

Signed-off-by: Kim Kulling <kim.kulling@googlemail.com>
pull/502/head
Kim Kulling 2015-01-31 11:07:48 +01:00
parent 62225f61e4
commit 1ee4c06e4b
12 changed files with 1986 additions and 2 deletions

2
.gitignore vendored
View File

@ -10,7 +10,7 @@ build
# Output
bin/
lib/
contrib/
# Generated
assimp.pc

View File

@ -154,6 +154,7 @@ else(NOT ZLIB_FOUND)
endif(NOT ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
add_subdirectory( contrib/openddlparser )
# Search for unzip
if (PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(UNZIP minizip)

View File

@ -634,7 +634,6 @@ SET( unzip_SRCS
)
SOURCE_GROUP( unzip FILES ${unzip_SRCS})
# VC2010 fixes
if(MSVC10)
option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF )

View File

@ -0,0 +1,63 @@
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
PROJECT( OpenDDL-Parser )
SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} )
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
find_package(Threads)
else()
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
endif()
add_definitions( -DOPENDDLPARSER_BUILD )
add_definitions( -D_VARIADIC_MAX=10 )
INCLUDE_DIRECTORIES(
./
include/
contrib/gtest-1.7.0/include
contrib/gtest-1.7.0/
)
link_directories(
./
)
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
if( WIN32 AND NOT CYGWIN )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4
if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" )
string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
else()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
endif()
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x")
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
endif()
SET ( openddl_parser_src
code/OpenDDLParser.cpp
code/DDLNode.cpp
code/Value.cpp
include/openddlparser/OpenDDLParser.h
include/openddlparser/OpenDDLParserUtils.h
include/openddlparser/OpenDDLCommon.h
include/openddlparser/DDLNode.h
include/openddlparser/Value.h
README.md
)
SOURCE_GROUP( code FILES ${openddl_parser_src} )
ADD_LIBRARY( openddl_parser SHARED
${openddl_parser_src}
)

View File

@ -0,0 +1,111 @@
The OpenDDL-Parser
==================
A simple and fast OpenDDL Parser
Current build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
Get the source code
===================
You can get the code from our git repository, which is located at GitHub. You can clone the repository like:
> git clone https://github.com/kimkulling/openddl-parser.git
Build from repo
===============
To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler toolchain is installed on your machine.
After installing it you can open a console and type:
> cmake CMakeLists.txt
This command will generate a build environment for your installed build enrironment ( for Visual Studio the project files will be generated, for gcc the makefiles will be generated ).
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
> make
and that's all.
Use the library
===============
To use the OpenDDL-parser you need to build the lib first. Now add the
> <Repo-folder>/include
to your include-path and the
> <Repo-folder>/lib
to your lib-folder. Link the openddl.lib to your application.
Here is a small example how to use the lib:
```cpp
#include <iostream>
#include <cassert>
#include <openddlparser/OpenDDLParser.h>
USE_ODDLPARSER_NS;
int main( int argc, char *argv[] ) {
if( argc < 3 ) {
return 1;
}
char *filename( nullptr );
if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) {
filename = argv[ 2 ];
}
std::cout << "file to import: " << filename << std::endl;
if( nullptr == filename ) {
std::cerr << "Invalid filename." << std::endl;
return Error;
}
FILE *fileStream = fopen( filename, "r+" );
if( NULL == filename ) {
std::cerr << "Cannot open file " << filename << std::endl;
return 1;
}
// obtain file size:
fseek( fileStream, 0, SEEK_END );
const size_t size( ftell( fileStream ) );
rewind( fileStream );
if( size > 0 ) {
char *buffer = new char[ size ];
const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) );
assert( readSize == size );
OpenDDLParser theParser;
theParser.setBuffer( buffer, size );
const bool result( theParser.parse() );
if( !result ) {
std::cerr << "Error while parsing file " << filename << "." << std::endl;
}
}
return 0;
}
```
How to access the imported data
===============================
The data is organized as a tree. You can get the root tree with the following code:
```
OpenDDLParser theParser;
theParser.setBuffer( buffer, size );
const bool result( theParser.parse() );
if ( result ) {
DDLNode *root = theParser.getRoot();
DDLNode::DllNodeList childs = root->getChildNodeList();
for ( size_t i=0; i<childs.size(); i++ ) {
DDLNode *child = childs[ i ];
Property *prop = child->getProperty(); // to get properties
std:.string type = child->getType(); // to get the node type
Value *values = child->getValue(); // to get the data;
}
}
```
The instance called root contains the data.

View File

@ -0,0 +1,162 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLParser.h>
#include <algorithm>
BEGIN_ODDLPARSER_NS
DDLNode::DllNodeList DDLNode::s_allocatedNodes;
template<class T>
inline
static void releaseDataType( T *ptr ) {
if( nullptr == ptr ) {
return;
}
T *current( nullptr );
while( ptr ) {
current = ptr;
ptr = ptr->m_next;
delete current;
}
}
DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent )
: m_type( type )
, m_name( name )
, m_parent( parent )
, m_children()
, m_properties( nullptr )
, m_value( nullptr )
, m_idx( idx )
, m_dtArrayList( nullptr ) {
if( m_parent ) {
m_parent->m_children.push_back( this );
}
}
DDLNode::~DDLNode() {
releaseDataType<Property>( m_properties );
releaseDataType<Value>( m_value );
delete m_dtArrayList;
m_dtArrayList = nullptr;
if( s_allocatedNodes[ m_idx ] == this ) {
s_allocatedNodes[ m_idx ] = nullptr;
}
}
void DDLNode::attachParent( DDLNode *parent ) {
if( m_parent == parent ) {
return;
}
m_parent = parent;
if( nullptr != m_parent ) {
m_parent->m_children.push_back( this );
}
}
void DDLNode::detachParent() {
if( m_parent ) {
std::vector<DDLNode*>::iterator it;
it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
if( m_parent->m_children.end() != it ) {
m_parent->m_children.erase( it );
}
m_parent = nullptr;
}
}
DDLNode *DDLNode::getParent() const {
return m_parent;
}
const DDLNode::DllNodeList &DDLNode::getChildNodeList() const {
return m_children;
}
void DDLNode::setType( const std::string &type ) {
m_type = type;
}
const std::string &DDLNode::getType() const {
return m_type;
}
void DDLNode::setName( const std::string &name ) {
m_name = name;
}
const std::string &DDLNode::getName() const {
return m_name;
}
void DDLNode::setProperties( Property *first ) {
m_properties = first;
}
Property *DDLNode::getProperties() const {
return m_properties;
}
void DDLNode::setValue( Value *val ) {
m_value = val;
}
Value *DDLNode::getValue() const {
return m_value;
}
void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) {
m_dtArrayList = dtArrayList;
}
DataArrayList *DDLNode::getDataArrayList() const {
return m_dtArrayList;
}
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
const size_t idx( s_allocatedNodes.size() );
DDLNode *node = new DDLNode( type, name, idx, parent );
s_allocatedNodes.push_back( node );
return node;
}
void DDLNode::releaseNodes() {
if( s_allocatedNodes.size() > 0 ) {
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
if( *it ) {
delete *it;
}
}
s_allocatedNodes.clear();
}
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,852 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLParser.h>
#include <cassert>
#include <iostream>
#include <sstream>
#include <algorithm>
#ifdef _WIN32
# include <windows.h>
#endif // _WIN32
#define DEBUG_HEADER_NAME
BEGIN_ODDLPARSER_NS
static const char *Version = "0.1.0";
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
"bool",
"int8",
"int16",
"int32",
"int64",
"unsigned_int8",
"unsigned_int16",
"unsigned_int32",
"unsigned_int64",
"half",
"float",
"double",
"string",
"ref"
};
static const char *BoolTrue = "true";
static const char *BoolFalse = "false";
static const char *RefToken = "ref";
static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) {
std::stringstream stream;
stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl;
callback( ddl_error_msg, stream.str() );
}
static bool isIntegerType( Value::ValueType integerType ) {
if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
return false;
}
return true;
}
static DDLNode *createDDLNode( Identifier *id, Property *first, OpenDDLParser *parser ) {
if( nullptr == id || nullptr == parser ) {
return nullptr;
}
const std::string type( id->m_buffer );
DDLNode *parent( parser->top() );
DDLNode *node = DDLNode::create( type, "", parent );
if( nullptr != first ) {
node->setProperties( first );
}
return node;
}
static void logMessage( LogSeverity severity, const std::string &msg ) {
std::string log;
if( ddl_debug_msg == severity ) {
log += "Debug:";
} else if( ddl_info_msg == severity ) {
log += "Info :";
} else if( ddl_warn_msg == severity ) {
log += "Warn :";
} else if( ddl_error_msg == severity ) {
log += "Error:";
} else {
log += "None :";
}
log += msg;
std::cout << log;
}
OpenDDLParser::OpenDDLParser()
: m_logCallback( logMessage )
, m_ownsBuffer( false )
,m_buffer( nullptr )
, m_len( 0 )
, m_stack()
, m_context( nullptr ) {
// empty
}
OpenDDLParser::OpenDDLParser( char *buffer, size_t len, bool ownsIt )
: m_logCallback( &logMessage )
, m_ownsBuffer( false )
, m_buffer( nullptr )
, m_len( 0 )
, m_context( nullptr ) {
if( 0 != m_len ) {
setBuffer( buffer, len, ownsIt );
}
}
OpenDDLParser::~OpenDDLParser() {
clear();
}
void OpenDDLParser::setLogCallback( logCallback callback ) {
if( nullptr != callback ) {
// install user-specific log callback
m_logCallback = callback;
} else {
// install default log callback
m_logCallback = &logMessage;
}
}
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
return m_logCallback;
}
void OpenDDLParser::setBuffer( char *buffer, size_t len, bool ownsIt ) {
if( m_buffer && m_ownsBuffer ) {
delete[] m_buffer;
m_buffer = nullptr;
m_len = 0;
}
m_ownsBuffer = ownsIt;
if( m_ownsBuffer ) {
// when we are owning the buffer we will do a deep copy
m_buffer = new char[ len ];
m_len = len;
::memcpy( m_buffer, buffer, len );
} else {
// when we are not owning the buffer, we just do a shallow copy
m_buffer = buffer;
m_len = len;
}
}
char *OpenDDLParser::getBuffer() const {
return m_buffer;
}
size_t OpenDDLParser::getBufferSize() const {
return m_len;
}
void OpenDDLParser::clear() {
if( m_ownsBuffer ) {
delete [] m_buffer;
}
m_buffer = nullptr;
m_len = 0;
if( m_context ) {
m_context->m_root = nullptr;
}
DDLNode::releaseNodes();
}
bool OpenDDLParser::parse() {
if( 0 == m_len ) {
return false;
}
normalizeBuffer( m_buffer, m_len );
m_context = new Context;
m_context->m_root = DDLNode::create( "root", "", nullptr );
pushNode( m_context->m_root );
// do the main parsing
char *current( &m_buffer[ 0 ] );
char *end( &m_buffer[ m_len - 1 ] + 1 );
while( current != end ) {
current = parseNextNode( current, end );
}
return true;
}
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
in = parseHeader( in, end );
in = parseStructure( in, end );
return in;
}
char *OpenDDLParser::parseHeader( char *in, char *end ) {
if( nullptr == in || in == end ) {
return in;
}
Identifier *id( nullptr );
in = OpenDDLParser::parseIdentifier( in, end, &id );
#ifdef DEBUG_HEADER_NAME
if( id ) {
std::cout << id->m_buffer << std::endl;
}
#endif // DEBUG_HEADER_NAME
in = getNextToken( in, end );
Property *first( nullptr );
if( nullptr != id ) {
if( *in == '(' ) {
in++;
Property *prop( nullptr ), *prev( nullptr );
while( *in != ')' && in != end ) {
in = parseProperty( in, end, &prop );
in = getNextToken( in, end );
if( *in != ',' && *in != ')' ) {
logInvalidTokenError( in, ")", m_logCallback );
return in;
}
if( nullptr != prop && *in != ',' ) {
if( nullptr == first ) {
first = prop;
}
if( nullptr != prev ) {
prev->m_next = prop;
}
prev = prop;
}
}
in++;
}
// store the node
DDLNode *node( createDDLNode( id, first, this ) );
if( nullptr != node ) {
pushNode( node );
} else {
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
}
Name *name( nullptr );
in = OpenDDLParser::parseName( in, end, &name );
if( nullptr != name ) {
const std::string nodeName( name->m_id->m_buffer );
node->setName( nodeName );
}
}
return in;
}
char *OpenDDLParser::parseStructure( char *in, char *end ) {
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
if( *in == '{' ) {
in++;
in = getNextToken( in, end );
Value::ValueType type( Value::ddl_none );
size_t arrayLen( 0 );
in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
if( Value::ddl_none != type ) {
in = getNextToken( in, end );
if( *in == '{' ) {
DataArrayList *dtArrayList( nullptr );
Value *values( nullptr );
if( 1 == arrayLen ) {
in = parseDataList( in, end, &values );
if( nullptr != values ){
DDLNode *currentNode( top() );
if( nullptr != currentNode ) {
currentNode->setValue( values );
}
}
} else if( arrayLen > 1 ) {
in = parseDataArrayList( in, end, &dtArrayList );
if( nullptr != dtArrayList ) {
DDLNode *currentNode( top() );
if( nullptr != currentNode ) {
currentNode->setDataArrayList( dtArrayList );
}
}
} else {
std::cerr << "0 for array is invalid." << std::endl;
}
}
in = getNextToken( in, end );
if( *in != '}' ) {
logInvalidTokenError( in, "}", m_logCallback );
}
} else {
in = parseHeader( in, end );
in = parseStructure( in, end );
}
} else {
in++;
logInvalidTokenError( in, "{", m_logCallback );
return in;
}
in++;
return in;
}
void OpenDDLParser::pushNode( DDLNode *node ) {
if( nullptr == node ) {
return;
}
m_stack.push_back( node );
}
DDLNode *OpenDDLParser::popNode() {
if( m_stack.empty() ) {
return nullptr;
}
DDLNode *topNode( top() );
m_stack.pop_back();
return topNode;
}
DDLNode *OpenDDLParser::top() {
if( m_stack.empty() ) {
return nullptr;
}
DDLNode *top( m_stack.back() );
return top;
}
DDLNode *OpenDDLParser::getRoot() const {
if( nullptr == m_context ) {
return nullptr;
}
return m_context->m_root;
}
Context *OpenDDLParser::getContext() const {
return m_context;
}
void OpenDDLParser::normalizeBuffer( char *buffer, size_t len ) {
if( nullptr == buffer || 0 == len ) {
return;
}
size_t writeIdx( 0 );
char *end( &buffer[ len ] + 1 );
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
char *c( &buffer[readIdx] );
// check for a comment
if( !isComment<char>( c, end ) ) {
buffer[ writeIdx ] = buffer[ readIdx ];
writeIdx++;
} else {
readIdx++;
// skip the comment and the rest of the line
while( !isEndofLine( buffer[ readIdx ] ) ) {
readIdx++;
}
buffer[writeIdx] = '\n';
writeIdx++;
}
}
if( writeIdx < len ) {
buffer[ writeIdx ] = '\0';
}
}
char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
*name = nullptr;
if( nullptr == in || in == end ) {
return in;
}
// ignore blanks
in = getNextToken( in, end );
if( *in != '$' && *in != '%' ) {
return in;
}
NameType ntype( GlobalName );
if( *in == '%' ) {
ntype = LocalName;
}
Name *currentName( nullptr );
Identifier *id( nullptr );
in = parseIdentifier( in, end, &id );
if( id ) {
currentName = new Name( ntype, id );
if( currentName ) {
*name = currentName;
}
}
return in;
}
char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
*id = nullptr;
if( nullptr == in || in == end ) {
return in;
}
// ignore blanks
in = getNextToken( in, end );
// staring with a number is forbidden
if( isNumeric<const char>( *in ) ) {
return in;
}
// get size of id
size_t idLen( 0 );
char *start( in );
while( !isSeparator( *in ) && ( in != end ) && *in != '(' && *in != ')' ) {
in++;
idLen++;
}
const size_t len( idLen + 1 );
Identifier *newId = new Identifier( len, new char[ len ] );
::strncpy( newId->m_buffer, start, newId->m_len-1 );
newId->m_buffer[ newId->m_len - 1 ] = '\0';
*id = newId;
return in;
}
char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) {
type = Value::ddl_none;
len = 0;
if( nullptr == in || in == end ) {
return in;
}
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
const size_t prim_len( strlen( PrimitiveTypeToken[ i ] ) );
if( 0 == strncmp( in, PrimitiveTypeToken[ i ], prim_len ) ) {
type = ( Value::ValueType ) i;
break;
}
}
if( Value::ddl_none == type ) {
in = getNextToken( in, end );
return in;
} else {
in += strlen( PrimitiveTypeToken[ type ] );
}
bool ok( true );
if( *in == '[' ) {
ok = false;
in++;
char *start( in );
while ( in != end ) {
in++;
if( *in == ']' ) {
len = atoi( start );
ok = true;
in++;
break;
}
}
} else {
len = 1;
}
if( !ok ) {
type = Value::ddl_none;
}
return in;
}
char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &names ) {
if( nullptr == in || in == end ) {
return in;
}
if( 0 != strncmp( in, RefToken, strlen( RefToken ) ) ) {
return false;
} else {
const size_t refTokenLen( strlen( RefToken ) );
in += refTokenLen;
}
in = getNextToken( in, end );
if( '{' != *in ) {
return in;
} else {
in++;
}
in = getNextToken( in, end );
Name *nextName( nullptr );
in = parseName( in, end, &nextName );
if( nextName ) {
names.push_back( nextName );
}
while( '}' != *in ) {
in = getNextSeparator( in, end );
if( ',' == *in ) {
in = parseName( in, end, &nextName );
if( nextName ) {
names.push_back( nextName );
}
} else {
break;
}
}
return in;
}
char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) {
*boolean = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
char *start( in );
size_t len( 0 );
while( !isSeparator( *in ) && in != end ) {
in++;
len++;
}
len++;
int res = ::strncmp( BoolTrue, start, strlen( BoolTrue ) );
if( 0 != res ) {
res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) );
if( 0 != res ) {
*boolean = nullptr;
return in;
}
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
(*boolean)->setBool( false );
} else {
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
(*boolean)->setBool( true );
}
return in;
}
char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
*integer = nullptr;
if( nullptr == in || in == end ) {
return in;
}
if( !isIntegerType( integerType ) ) {
return in;
}
in = getNextToken( in, end );
char *start( in );
while( !isSeparator( *in ) && in != end ) {
in++;
}
if( isNumeric( *start ) ) {
const int value( atoi( start ) );
*integer = ValueAllocator::allocPrimData( integerType );
switch( integerType ) {
case Value::ddl_int8:
( *integer )->setInt8( (int8) value );
break;
case Value::ddl_int16:
( *integer )->setInt16( ( int16 ) value );
break;
case Value::ddl_int32:
( *integer )->setInt32( ( int32 ) value );
break;
case Value::ddl_int64:
( *integer )->setInt64( ( int64 ) value );
break;
default:
break;
}
}
return in;
}
char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) {
*floating = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
char *start( in );
while( !isSeparator( *in ) && in != end ) {
in++;
}
// parse the float value
bool ok( false );
if( isNumeric( *start ) ) {
ok = true;
} else {
if( *start == '-' ) {
if( isNumeric( *(start+1) ) ) {
ok = true;
}
}
}
if( ok ) {
const float value( ( float ) atof( start ) );
*floating = ValueAllocator::allocPrimData( Value::ddl_float );
( *floating )->setFloat( value );
}
return in;
}
char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) {
*stringData = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
size_t len( 0 );
char *start( in );
if( *start == '\"' ) {
start++;
in++;
while( *in != '\"' && in != end ) {
in++;
len++;
}
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len + 1 );
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
( *stringData )->m_data[len] = '\0';
in++;
}
return in;
}
static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) {
if( nullptr != primData ) {
( *prop ) = new Property( id );
( *prop )->m_primData = primData;
}
}
char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
*data = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
if( *in != '0' ) {
return in;
}
in++;
if( *in != 'x' && *in != 'X' ) {
return in;
}
in++;
bool ok( true );
char *start( in );
int pos( 0 );
while( !isSeparator( *in ) && in != end ) {
if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) {
ok = false;
break;
}
pos++;
in++;
}
if( !ok ) {
return in;
}
int value( 0 );
while( pos > 0 ) {
pos--;
value += hex2Decimal( *start ) * static_cast<int>( pow( 16.0, pos ) );
start++;
}
*data = ValueAllocator::allocPrimData( Value::ddl_int32 );
(*data)->setInt32( value );
return in;
}
char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
*prop = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
Identifier *id( nullptr );
in = parseIdentifier( in, end, &id );
if( nullptr != id ) {
in = getNextToken( in, end );
if( *in == '=' ) {
in++;
in = getNextToken( in, end );
Value *primData( nullptr );
if( isInteger( in, end ) ) {
in = parseIntegerLiteral( in, end, &primData );
createPropertyWithData( id, primData, prop );
} else if( isFloat( in, end ) ) {
in = parseFloatingLiteral( in, end, &primData );
createPropertyWithData( id, primData, prop );
} else if( isStringLiteral( *in ) ) { // string data
in = parseStringLiteral( in, end, &primData );
createPropertyWithData( id, primData, prop );
} else { // reference data
std::vector<Name*> names;
in = parseReference( in, end, names );
if( !names.empty() ) {
Reference *ref = new Reference( names.size(), &names[ 0 ] );
( *prop ) = new Property( id );
( *prop )->m_ref = ref;
}
}
}
}
return in;
}
char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) {
*data = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
if( *in == '{' ) {
in++;
Value *current( nullptr ), *prev( nullptr );
while( '}' != *in ) {
current = nullptr;
in = getNextToken( in, end );
if( isInteger( in, end ) ) {
in = parseIntegerLiteral( in, end, &current );
} else if( isFloat( in, end ) ) {
in = parseFloatingLiteral( in, end, &current );
} else if( isStringLiteral( *in ) ) {
in = parseStringLiteral( in, end, &current );
} else if( isHexLiteral( in, end ) ) {
in = parseHexaLiteral( in, end, &current );
}
if( nullptr != current ) {
if( nullptr == *data ) {
*data = current;
prev = current;
} else {
prev->setNext( current );
prev = current;
}
}
in = getNextSeparator( in, end );
if( ',' != *in && '}' != *in && !isSpace( *in ) ) {
break;
}
}
in++;
}
return in;
}
char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
*dataList = nullptr;
if( nullptr == in || in == end ) {
return in;
}
in = getNextToken( in, end );
if( *in == '{' ) {
in++;
Value *current( nullptr );
DataArrayList *prev( nullptr ), *currentDataList( nullptr );
do {
in = parseDataList( in, end, &current );
if( nullptr != current ) {
if( nullptr == prev ) {
*dataList = new DataArrayList;
(*dataList)->m_dataList = current;
prev = *dataList;
} else {
currentDataList = new DataArrayList;
if( nullptr != prev ) {
prev->m_next = currentDataList;
prev = currentDataList;
}
}
}
} while( ',' == *in && in != end );
}
return in;
}
const char *OpenDDLParser::getVersion() {
return Version;
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,243 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#include <openddlparser/Value.h>
#include <iostream>
#include <cassert>
BEGIN_ODDLPARSER_NS
Value::Value()
: m_type( ddl_none )
, m_size( 0 )
, m_data( nullptr )
, m_next( nullptr ) {
// empty
}
Value::~Value() {
// empty
}
void Value::setBool( bool value ) {
assert( ddl_bool == m_type );
::memcpy( m_data, &value, m_size );
}
bool Value::getBool() {
assert( ddl_bool == m_type );
return ( bool ) ( *m_data );
}
void Value::setInt8( int8 value ) {
assert( ddl_int8 == m_type );
::memcpy( m_data, &value, m_size );
}
int8 Value::getInt8() {
assert( ddl_int8 == m_type );
return ( int8 ) ( *m_data );
}
void Value::setInt16( int16 value ) {
assert( ddl_int16 == m_type );
::memcpy( m_data, &value, m_size );
}
int16 Value::getInt16() {
assert( ddl_int16 == m_type );
return ( int16 ) ( *m_data );
}
void Value::setInt32( int32 value ) {
assert( ddl_int32 == m_type );
::memcpy( m_data, &value, m_size );
}
int32 Value::getInt32() {
assert( ddl_int32 == m_type );
return ( int32 ) ( *m_data );
}
void Value::setInt64( int64 value ) {
assert( ddl_int32 == m_type );
::memcpy( m_data, &value, m_size );
}
int64 Value::getInt64() {
return ( int64 ) ( *m_data );
}
void Value::setFloat( float value ) {
assert( ddl_float == m_type );
::memcpy( m_data, &value, m_size );
}
float Value::getFloat() const {
float v;
::memcpy( &v, m_data, m_size );
return v;
}
void Value::setDouble( double value ) {
assert( ddl_double == m_type );
::memcpy( m_data, &value, m_size );
}
double Value::getDouble() const {
double v;
::memcpy( &v, m_data, m_size );
return v;
}
void Value::dump() {
switch( m_type ) {
case ddl_none:
std::cout << "None" << std::endl;
break;
case ddl_bool:
std::cout << getBool() << std::endl;
break;
case ddl_int8:
std::cout << getInt8() << std::endl;
break;
case ddl_int16:
std::cout << getInt16() << std::endl;
break;
case ddl_int32:
std::cout << getInt32() << std::endl;
break;
case ddl_int64:
std::cout << getInt64() << std::endl;
break;
case ddl_unsigned_int8:
std::cout << "Not supported" << std::endl;
break;
case ddl_unsigned_int16:
std::cout << "Not supported" << std::endl;
break;
case ddl_unsigned_int32:
std::cout << "Not supported" << std::endl;
break;
case ddl_unsigned_int64:
std::cout << "Not supported" << std::endl;
break;
case ddl_half:
std::cout << "Not supported" << std::endl;
break;
case ddl_float:
std::cout << getFloat() << std::endl;
break;
case ddl_double:
std::cout << getDouble() << std::endl;
break;
case ddl_string:
std::cout << "Not supported" << std::endl;
break;
case ddl_ref:
std::cout << "Not supported" << std::endl;
break;
default:
break;
}
}
void Value::setNext( Value *next ) {
m_next = next;
}
Value *Value::getNext() const {
return m_next;
}
Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
if( type == Value::ddl_none || Value::ddl_types_max == type ) {
return nullptr;
}
Value *data = new Value;
data->m_type = type;
switch( type ) {
case Value::ddl_bool:
data->m_size = sizeof( bool );
break;
case Value::ddl_int8:
data->m_size = sizeof( char );
break;
case Value::ddl_int16:
data->m_size = sizeof( short );
break;
case Value::ddl_int32:
data->m_size = sizeof( int );
break;
case Value::ddl_int64:
data->m_size = sizeof( long );
break;
case Value::ddl_unsigned_int8:
data->m_size = sizeof( unsigned char );
break;
case Value::ddl_unsigned_int32:
data->m_size = sizeof( unsigned int );
break;
case Value::ddl_unsigned_int64:
data->m_size = sizeof( unsigned long );
break;
case Value::ddl_half:
data->m_size = sizeof( short );
break;
case Value::ddl_float:
data->m_size = sizeof( float );
break;
case Value::ddl_double:
data->m_size = sizeof( double );
break;
case Value::ddl_string:
data->m_size = sizeof( char );
break;
case Value::ddl_ref:
data->m_size = sizeof( char );
break;
case Value::ddl_none:
case Value::ddl_types_max:
default:
break;
}
if( data->m_size ) {
data->m_size *= len;
data->m_data = new unsigned char[ data->m_size ];
}
return data;
}
void ValueAllocator::releasePrimData( Value **data ) {
if( !data ) {
return;
}
delete *data;
*data = nullptr;
}
END_ODDLPARSER_NS

View File

@ -0,0 +1,87 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#pragma once
#ifndef OPENDDLPARSER_DDLNODE_H_INC
#define OPENDDLPARSER_DDLNODE_H_INC
#include <openddlparser/OpenDDLCommon.h>
#include <vector>
#include <string>
BEGIN_ODDLPARSER_NS
class Value;
class OpenDDLParser;
struct Identifier;
struct Reference;
struct Property;
struct DataArrayList;
class DLL_ODDLPARSER_EXPORT DDLNode {
public:
friend class OpenDDLParser;
typedef std::vector<DDLNode*> DllNodeList;
public:
~DDLNode();
void attachParent( DDLNode *parent );
void detachParent();
DDLNode *getParent() const;
const DllNodeList &getChildNodeList() const;
void setType( const std::string &name );
const std::string &getType() const;
void setName( const std::string &name );
const std::string &getName() const;
void setProperties( Property *first );
Property *getProperties() const;
void setValue( Value *val );
Value *getValue() const;
void setDataArrayList( DataArrayList *dtArrayList );
DataArrayList *getDataArrayList() const;
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = nullptr );
private:
DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = nullptr );
DDLNode();
DDLNode( const DDLNode & );
DDLNode &operator = ( const DDLNode & );
static void releaseNodes();
private:
std::string m_type;
std::string m_name;
DDLNode *m_parent;
std::vector<DDLNode*> m_children;
Property *m_properties;
Value *m_value;
DataArrayList *m_dtArrayList;
size_t m_idx;
static DllNodeList s_allocatedNodes;
};
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_DDLNODE_H_INC

View File

@ -0,0 +1,148 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#pragma once
#ifndef OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
#define OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
#include <cstddef>
#include <string.h>
#ifdef _WIN32
# define TAG_DLL_EXPORT __declspec(dllexport)
# define TAG_DLL_IMPORT __declspec(dllimport )
# ifdef OPENDDLPARSER_BUILD
# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT
# else
# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT
# endif // OPENDDLPARSER_BUILD
# pragma warning( disable : 4251 )
#else
# define DLL_ODDLPARSER_EXPORT
#endif // _WIN32
#define BEGIN_ODDLPARSER_NS namespace ODDLParser {
#define END_ODDLPARSER_NS }
#define USE_ODDLPARSER_NS using namespace ODDLParser;
BEGIN_ODDLPARSER_NS
class DDLNode;
class Value;
struct Name;
struct Identifier;
struct Reference;
struct Property;
struct DataArrayList;
typedef char int8;
typedef short int16;
typedef int int32;
typedef long int64;
enum NameType {
GlobalName,
LocalName
};
struct Name {
NameType m_type;
Identifier *m_id;
Name( NameType type, Identifier *id )
: m_type( type )
, m_id( id ) {
// empty
}
};
struct Reference {
size_t m_numRefs;
Name **m_referencedName;
Reference( size_t numrefs, Name **names )
: m_numRefs( numrefs )
, m_referencedName( names ) {
// empty
}
};
struct Identifier {
size_t m_len;
char *m_buffer;
Identifier( size_t len, char *buffer )
: m_len( len )
, m_buffer( buffer ) {
// empty
}
};
struct Property {
Identifier *m_id;
Value *m_primData;
Reference *m_ref;
Property *m_next;
Property( Identifier *id )
: m_id( id )
, m_primData( nullptr )
, m_ref( nullptr )
, m_next( nullptr ) {
// empty
}
};
struct DataArrayList {
size_t m_numItems;
Value *m_dataList;
DataArrayList *m_next;
DataArrayList()
: m_numItems( 0 )
, m_dataList( nullptr )
, m_next( nullptr ) {
// empty
}
};
struct Context {
Property *m_properties;
DDLNode *m_root;
Context()
: m_properties( nullptr )
, m_root( nullptr ) {
// empty
}
};
END_ODDLPARSER_NS
#define ODDL_NO_COPYING( classname ) \
private: \
classname( const classname & ); \
classname &operator = ( const classname & );
#endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC

View File

@ -0,0 +1,233 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#pragma once
#ifndef OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
#define OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
#include <openddlparser/OpenDDLCommon.h>
BEGIN_ODDLPARSER_NS
template<class T>
inline
bool isComment( T *in, T *end ) {
if( *in == '/' ) {
if( in + 1 != end ) {
if( *( in + 1 ) == '/' ) {
return true;
}
}
}
return false;
}
template<class T>
inline
bool isUpperCase( T in ) {
return ( in >= 'A' && in <= 'Z' );
}
template<class T>
inline
bool isLowerCase( T in ) {
return ( in >= 'a' && in <= 'z' );
}
template<class T>
inline
bool isSpace( const T in ) {
return ( ' ' == in || '\t' == in );
}
template<class T>
inline
bool isNewLine( const T in ) {
return ( '\n' == in );
}
template<class T>
inline
bool isSeparator( T in ) {
if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in ) {
return true;
}
return false;
}
static const unsigned char chartype_table[ 256 ] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
template<class T>
inline
bool isNumeric( const T in ) {
return ( in >= '0' && in <= '9' );
//return ( chartype_table[in] );
/*if (in >= '0' && in <= '9' )
return true;
return false;*/
}
template<class T>
inline
bool isInteger( T *in, T *end ) {
if( in != end ) {
if( *in == '-' ) {
in++;
}
}
bool result( false );
while( '}' != *in && ',' != *in && !isSpace( *in ) && in != end ) {
result = isNumeric( *in );
if( !result ) {
break;
}
in++;
}
return result;
}
template<class T>
inline
bool isFloat( T *in, T *end ) {
if( in != end ) {
if( *in == '-' ) {
in++;
}
}
// check for <1>.0f
bool result( false );
while( !isSpace( *in ) && in != end ) {
if( *in == '.' ) {
result = true;
break;
}
result = isNumeric( *in );
if( !result ) {
return false;
}
in++;
}
// check for 1<.>0f
if( *in == '.' ) {
in++;
} else {
return false;
}
// check for 1.<0>f
while( !isSpace( *in ) && in != end && *in != ',' ) {
result = isNumeric( *in );
if( !result ) {
return false;
}
in++;
}
return result;
}
template<class T>
inline
bool isCharacter( const T in ) {
return ( in >= 'a' && in <= 'z' || in >= 'A' && in <= 'Z' );
}
template<class T>
inline
bool isStringLiteral( const T in ) {
return ( in == '\"' );
}
template<class T>
inline
bool isHexLiteral( T *in, T *end ) {
if( *in == '0' ) {
if( in + 1 != end ) {
if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) {
return true;
}
}
}
return false;
}
template<class T>
inline
bool isEndofLine( const T in ) {
return ( '\n' == in );
}
template<class T>
inline
static T *getNextSeparator( T *in, T *end ) {
while( !isSeparator( *in ) || in == end ) {
in++;
}
return in;
}
static const int ErrorHex2Decimal = 9999;
inline
int hex2Decimal( char in ) {
if( isNumeric( in ) ) {
return (int) in-48;
}
char hexCodeLower( 'a' ), hexCodeUpper( 'A' );
for( int i = 0; i<16; i++ ) {
if( in == hexCodeLower + i || in == hexCodeUpper + i ) {
return i+10;
}
}
return ErrorHex2Decimal;
}
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC

View File

@ -0,0 +1,85 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#pragma once
#ifndef OPENDDLPARSER_VALUE_H_INC
#define OPENDDLPARSER_VALUE_H_INC
#include <openddlparser/OpenDDLCommon.h>
BEGIN_ODDLPARSER_NS
class DLL_ODDLPARSER_EXPORT Value {
public:
enum ValueType {
ddl_none = -1,
ddl_bool = 0,
ddl_int8,
ddl_int16,
ddl_int32,
ddl_int64,
ddl_unsigned_int8,
ddl_unsigned_int16,
ddl_unsigned_int32,
ddl_unsigned_int64,
ddl_half,
ddl_float,
ddl_double,
ddl_string,
ddl_ref,
ddl_types_max
};
Value();
~Value();
void setBool( bool value );
bool getBool();
void setInt8( int8 value );
int8 getInt8();
void setInt16( int16 value );
int16 getInt16();
void setInt32( int32 value );
int32 getInt32();
void setInt64( int64 value );
int64 getInt64();
void setFloat( float value );
float getFloat() const;
void setDouble( double value );
double getDouble() const;
void dump();
void setNext( Value *next );
Value *getNext() const;
ValueType m_type;
size_t m_size;
unsigned char *m_data;
Value *m_next;
};
struct DLL_ODDLPARSER_EXPORT ValueAllocator {
static Value *allocPrimData( Value::ValueType type, size_t len = 1 );
static void releasePrimData( Value **data );
};
END_ODDLPARSER_NS
#endif // OPENDDLPARSER_VALUE_H_INC