added limited support for COLLADA_DOM. Will need to add jam/msvcgen build support.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
Version="8.00"
|
||||
Name="LIBXMLPlugin_vc8"
|
||||
ProjectGUID="{4A974C64-D51F-4D0F-85B8-0C876EF29F2E}"
|
||||
RootNamespace="LIBXMLPlugin_vc8"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
@@ -40,7 +41,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include;../../../../FCollada/LibXML/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LIBXML_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -105,7 +106,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include;../../../../FCollada/LibXML/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LIBXML_STATIC"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
@@ -169,7 +170,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include;../../../../FCollada/LibXML/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LIBXML_STATIC"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -234,7 +235,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include"
|
||||
AdditionalIncludeDirectories=""../../../external-libs/libxml2/win32/include";../../../include;../../../../FCollada/LibXML/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LIBXML_STATIC"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
|
||||
797
Extras/COLLADA_DOM/src/modules/LIBXMLPlugin/daeLIBXMLPlugin.cpp
Normal file
797
Extras/COLLADA_DOM/src/modules/LIBXMLPlugin/daeLIBXMLPlugin.cpp
Normal file
@@ -0,0 +1,797 @@
|
||||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
// This is a rework of the XML plugin that contains a complete interface to libxml2 "readXML"
|
||||
// This is intended to be a seperate plugin but I'm starting out by rewriting it in daeLIBXMLPlugin
|
||||
// because I'm not sure if all the plugin handling stuff has been tested. Once I get a working
|
||||
// plugin I'll look into renaming it so the old daeLIBXMLPlugin can coexist with it.
|
||||
//
|
||||
#include <modules/daeLIBXMLPlugin.h>
|
||||
#include <dae.h>
|
||||
#include <dom.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
|
||||
daeLIBXMLPlugin::daeLIBXMLPlugin():topMeta(NULL),database(NULL)
|
||||
{
|
||||
xmlInitParser();
|
||||
}
|
||||
|
||||
daeLIBXMLPlugin::~daeLIBXMLPlugin()
|
||||
{
|
||||
xmlCleanupParser();
|
||||
}
|
||||
|
||||
daeInt daeLIBXMLPlugin::setMeta(daeMetaElement *_topMeta)
|
||||
{
|
||||
topMeta = _topMeta;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
void daeLIBXMLPlugin::setDatabase(daeDatabase* _database)
|
||||
{
|
||||
database = _database;
|
||||
}
|
||||
|
||||
void daeLIBXMLPlugin::getProgress(daeInt* bytesParsed,
|
||||
daeInt* lineNumber,
|
||||
daeInt* totalBytes,
|
||||
daeBool reset)
|
||||
{
|
||||
// Need to interface this to libxml
|
||||
if (reset)
|
||||
{
|
||||
//daeChunkBuffer::resetProgress();
|
||||
}
|
||||
#if LIBXML_VERSION >= 20620
|
||||
if (bytesParsed)
|
||||
*bytesParsed= 0; //xmlTextReaderByteConsumed(reader); // Not sure if this is the right data
|
||||
if (lineNumber)
|
||||
*lineNumber = 0; //xmlTextReaderGetParserLineNumber(reader);
|
||||
#else
|
||||
if (bytesParsed)
|
||||
*bytesParsed= 0;
|
||||
if (lineNumber)
|
||||
*lineNumber = 0;
|
||||
#endif
|
||||
if (totalBytes)
|
||||
*totalBytes = 0; // Not available
|
||||
}
|
||||
// This function needs to be re-entrant, it can be called recursively from inside of resolveAll
|
||||
// to load files that the first file depends on.
|
||||
daeInt daeLIBXMLPlugin::read(daeURI& uri, daeString docBuffer)
|
||||
{
|
||||
// Make sure topMeta has been set before proceeding
|
||||
|
||||
if (topMeta == NULL)
|
||||
{
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// Generate a version of the URI with the fragment removed
|
||||
|
||||
daeURI fileURI(uri.getURI(),true);
|
||||
|
||||
// Create the right type of xmlTextReader on the stack so this function can be re-entrant
|
||||
|
||||
xmlTextReaderPtr reader;
|
||||
|
||||
if(docBuffer)
|
||||
{
|
||||
// Load from memory (experimental)
|
||||
#if 0 //debug stuff
|
||||
printf("Reading %s from memory buffer\n", fileURI.getURI());
|
||||
#endif
|
||||
reader = xmlReaderForDoc((xmlChar*)docBuffer, fileURI.getURI(), NULL,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load from URI
|
||||
#if 0 //debug stuff
|
||||
printf("Opening %s\n", fileURI.getURI());
|
||||
#endif
|
||||
reader = xmlReaderForFile(fileURI.getURI(), NULL,0);
|
||||
}
|
||||
|
||||
if(!reader)
|
||||
{
|
||||
printf( "no libxml2 reader\n");
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// Start parsing the file
|
||||
|
||||
daeElementRef domObject = startParse(topMeta, reader);
|
||||
|
||||
// Parsing done, free the xmlReader and error check to make sure we got a valid DOM back
|
||||
|
||||
xmlFreeTextReader(reader);
|
||||
|
||||
if (!domObject)
|
||||
{
|
||||
#if defined(_DEBUG) && defined(WIN32)
|
||||
fprintf(stderr,"daeLIBXMLPlugin::read(%s) failed - XML Parse Failed\n",
|
||||
fileURI.getFile());
|
||||
fflush(stdout);
|
||||
#endif
|
||||
printf("not able to load\n");
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// Insert the document into the database, the Database will keep a ref on the main dom, so it won't gets deleted
|
||||
// until we clear the database
|
||||
|
||||
daeDocument *document = NULL;
|
||||
|
||||
int res = database->insertDocument(fileURI.getURI(),domObject,&document);
|
||||
if (res!= DAE_OK)
|
||||
return res;
|
||||
|
||||
// Make a vector to store a list of the integration items that need to be processed later
|
||||
// postProcessDom will fill this in for us (this should probably not be done in the IOPlugin)
|
||||
|
||||
std::vector<INTEGRATION_ITEM> intItems;
|
||||
|
||||
//insert the elements into the database, for this DB the elements are the Collada object which have
|
||||
//an ID.
|
||||
//this function will fill the _integrationItems array as well
|
||||
postProcessDom(document, domObject, intItems);
|
||||
database->validate();
|
||||
daeElement::resolveAll();
|
||||
|
||||
//create the integration objects
|
||||
int size = (int)intItems.size();
|
||||
int i;
|
||||
for (i=0;i<size;i++)
|
||||
intItems[i].intObject->createFromChecked(intItems[i].element);
|
||||
|
||||
for (i=0;i<size;i++)
|
||||
intItems[i].intObject->fromCOLLADAChecked();
|
||||
|
||||
for (i=0;i<size;i++)
|
||||
intItems[i].intObject->fromCOLLADAPostProcessChecked();
|
||||
|
||||
//clear the temporary integration items array
|
||||
intItems.clear();
|
||||
|
||||
return DAE_OK;
|
||||
}
|
||||
daeElementRef
|
||||
daeLIBXMLPlugin::startParse(daeMetaElement* thisMetaElement, xmlTextReaderPtr reader)
|
||||
{
|
||||
// The original parsing system would drop everything up to the first element open, usually <COLLADA>
|
||||
// This behavior will have to be replicated here till we have someplace to put the headers/comments
|
||||
|
||||
int ret = xmlTextReaderRead(reader);
|
||||
if(ret != 1)
|
||||
{
|
||||
// empty or hit end of file
|
||||
return NULL;
|
||||
}
|
||||
//printf("xmlTextReaderConstBaseUri is %s\n",xmlTextReaderConstBaseUri(reader));
|
||||
//printf("xmlTextReaderConstNamespaceUri is %s\n",xmlTextReaderConstNamespaceUri(reader));
|
||||
//printf("xmlTextReaderConstPrefix is %s\n",xmlTextReaderConstPrefix(reader));
|
||||
//printf("xmlTextReaderName is %s\n",xmlTextReaderName(reader));
|
||||
|
||||
// Process the current element
|
||||
// Skip over things we don't understand
|
||||
while(xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
ret = xmlTextReaderRead(reader);
|
||||
if(ret != 1)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// Create the element that we found
|
||||
daeElementRef element = thisMetaElement->create((const daeString)xmlTextReaderConstName(reader));
|
||||
if(!element)
|
||||
{
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
const xmlChar * mine =xmlTextReaderConstName(reader);
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to create an element type %s at line %d\nProbably a schema violation.\n", mine,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to create an element type %s\nProbably a schema violation.\n", mine);
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
xmlTextReaderNext(reader);
|
||||
return NULL;
|
||||
}
|
||||
int currentDepth = xmlTextReaderDepth(reader);
|
||||
|
||||
//try and read attributes
|
||||
readAttributes( element, reader );
|
||||
|
||||
//Check COLLADA Version
|
||||
if ( strcmp( element->getTypeName(), "COLLADA" ) != 0 ) {
|
||||
//invalid root
|
||||
daeErrorHandler::get()->handleError("Loading document with invalid root element!");
|
||||
return NULL;
|
||||
}
|
||||
daeURI *xmlns = (daeURI*)(element->getMeta()->getMetaAttribute( "xmlns" )->getWritableMemory( element ));
|
||||
if ( strcmp( xmlns->getURI(), COLLADA_NAMESPACE ) != 0 ) {
|
||||
//invalid COLLADA version
|
||||
daeErrorHandler::get()->handleError("Trying to load an invalid COLLADA version for this DOM build!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ret = xmlTextReaderRead(reader);
|
||||
// If we're out of data, return the element
|
||||
if(ret != 1)
|
||||
return(element);
|
||||
|
||||
// Read all the tags that are part of this tag
|
||||
bool trew = true;
|
||||
while(trew)
|
||||
{
|
||||
int thisType = xmlTextReaderNodeType(reader);
|
||||
if(thisType == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
// Is the new element at the same depth as this one?
|
||||
if(currentDepth == xmlTextReaderDepth(reader))
|
||||
{
|
||||
// Same depth means the current element ended in a /> so this is a sibling
|
||||
// so we return and let our parent process it.
|
||||
return(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The element is a child of this one, so we recurse
|
||||
if(!element->placeElement(nextElement(element->getMeta(), reader)))
|
||||
{
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"placeElement failed at line %d\n", xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"placeElement failed\n");
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning(err);
|
||||
ret = xmlTextReaderRead(reader);
|
||||
if ( ret != 1 ) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(thisType == XML_READER_TYPE_TEXT)
|
||||
{
|
||||
readValue( element, reader );
|
||||
}
|
||||
else if(thisType == XML_READER_TYPE_END_ELEMENT)
|
||||
{
|
||||
// Done with this element so read again and return
|
||||
ret = xmlTextReaderRead(reader);
|
||||
return(element);
|
||||
}
|
||||
else
|
||||
{ // Skip element types we don't care about
|
||||
ret = xmlTextReaderRead(reader);
|
||||
// If we're out of data, return the element
|
||||
if(ret != 1)
|
||||
return(element);
|
||||
}
|
||||
}
|
||||
// Return NULL on an error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void daeLIBXMLPlugin::readAttributes( daeElement *element, xmlTextReaderPtr reader ) {
|
||||
// See if the element has attributes
|
||||
if(xmlTextReaderHasAttributes(reader))
|
||||
{
|
||||
// Read in and set all the attributes
|
||||
while(xmlTextReaderMoveToNextAttribute(reader))
|
||||
{
|
||||
daeMetaAttribute *ma = element->getMeta()->getMetaAttribute((const daeString)xmlTextReaderConstName(reader));
|
||||
if( ( ma != NULL && ma->getType() != NULL && ma->getType()->getUsesStrings() ) ||
|
||||
strcmp(element->getMeta()->getName(), "any") == 0 )
|
||||
{
|
||||
// String is used as one piece
|
||||
if(!element->setAttribute( (const daeString)xmlTextReaderConstName(reader),
|
||||
(const daeString)xmlTextReaderConstValue(reader) ) )
|
||||
{
|
||||
const xmlChar * attName = xmlTextReaderConstName(reader);
|
||||
const xmlChar * attValue = xmlTextReaderConstValue(reader);
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s at line %d\nProbably a schema violation.\n", attName, attValue ,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s \nProbably a schema violation.\n", attName, attValue);
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// String needs to be broken up into whitespace seperated items. The "set" methods for numbers are smart enough to
|
||||
// grab just the first number in a string, but the ones for string lists require a null terminator between each
|
||||
// string. If this could be fixed we could avoid a copy and memory allocation by using xmlTextReaderConstValue(reader)
|
||||
if ( ma == NULL ) {
|
||||
const xmlChar * attName = xmlTextReaderConstName(reader);
|
||||
const xmlChar * attValue = xmlTextReaderConstValue(reader);
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s at line %d\nProbably a schema violation.\n", attName, attValue ,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s \nProbably a schema violation.\n", attName, attValue);
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
continue;
|
||||
}
|
||||
xmlChar* value = xmlTextReaderValue(reader);
|
||||
daeChar* current = (daeChar *)value;
|
||||
while(*current != 0)
|
||||
{
|
||||
// !!!GAC NEEDS TO BE CHANGED to use XML standard whitespace parsing
|
||||
// Skip leading whitespace
|
||||
while(*current == ' ' || *current == '\r' || *current == '\n' || *current == '\t') current++;
|
||||
if(*current != 0)
|
||||
{
|
||||
daeChar* start=current;
|
||||
// Find end of string and insert a zero terminator
|
||||
while(*current != ' ' && *current != '\r' && *current != '\n' && *current != '\t' && *current != 0) current++;
|
||||
if(*current != 0)
|
||||
{
|
||||
*current = 0;
|
||||
current++;
|
||||
}
|
||||
if(!element->setAttribute( (const daeString)xmlTextReaderConstName(reader), start) )
|
||||
{
|
||||
const xmlChar * attName = xmlTextReaderConstName(reader);
|
||||
const xmlChar * attValue = xmlTextReaderConstValue(reader);
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s at line %d\nProbably a schema violation.\n", attName, attValue ,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to create an attribute %s = %s \nProbably a schema violation.\n", attName, attValue);
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlFree(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void daeLIBXMLPlugin::readValue( daeElement *element, xmlTextReaderPtr reader ) {
|
||||
if ( element->getMeta()->getValueAttribute() == NULL ) {
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to set a value for element of type %s at line %d\nProbably a schema violation.\n", element->getTypeName() ,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to set a value for element of type %s at line %d\nProbably a schema violation.\n", element->getTypeName() );
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
}
|
||||
else if(element->getMeta()->getUsesStringContents())
|
||||
{
|
||||
// String is used as one piece
|
||||
element->getMeta()->getValueAttribute()->set(element,(const daeString)xmlTextReaderConstValue(reader));
|
||||
}
|
||||
else
|
||||
{
|
||||
// String needs to be broken up into whitespace seperated items. The "set" methods for numbers are smart enough to
|
||||
// grab just the first number in a string, but the ones for string lists require a null terminator between each
|
||||
// string. If this could be fixed we could avoid a copy and memory allocation by using xmlTextReaderConstValue(reader)
|
||||
xmlChar* value = xmlTextReaderValue(reader);
|
||||
daeChar* current = (daeChar *)value;
|
||||
while(*current != 0)
|
||||
{
|
||||
// !!!GAC NEEDS TO BE CHANGED to use XML standard whitespace parsing
|
||||
// Skip leading whitespace
|
||||
while(*current == ' ' || *current == '\r' || *current == '\n' || *current == '\t') current++;
|
||||
if(*current != 0)
|
||||
{
|
||||
daeChar* start=current;
|
||||
// Find end of string and insert a zero terminator
|
||||
while(*current != ' ' && *current != '\r' && *current != '\n' && *current != '\t' && *current != 0) current++;
|
||||
if(*current != 0)
|
||||
{
|
||||
*current = 0;
|
||||
current++;
|
||||
}
|
||||
element->getMeta()->getValueAttribute()->set(element,start);
|
||||
// eat the characters we just read (would be nice if set returned characters used.
|
||||
}
|
||||
}
|
||||
xmlFree(value);
|
||||
}
|
||||
int ret = xmlTextReaderRead(reader);
|
||||
assert(ret==1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
daeElementRef
|
||||
daeLIBXMLPlugin::nextElement(daeMetaElement* thisMetaElement, xmlTextReaderPtr reader)
|
||||
{
|
||||
int ret;
|
||||
// Process the current element
|
||||
// Skip over things we don't understand
|
||||
while(xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
ret = xmlTextReaderRead(reader);
|
||||
if(ret != 1)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// Create the element that we found
|
||||
daeElementRef element = thisMetaElement->create((const daeString)xmlTextReaderConstName(reader));
|
||||
if(!element)
|
||||
{
|
||||
const xmlChar * mine =xmlTextReaderConstName(reader);
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"The DOM was unable to create an element type %s at line %d\nProbably a schema violation.\n", mine,xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"The DOM was unable to create an element type %s\nProbably a schema violation.\n", mine);
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
if ( xmlTextReaderNext(reader) == -1 ) {
|
||||
int x = 12312412;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int currentDepth = xmlTextReaderDepth(reader);
|
||||
|
||||
//try and read attributes
|
||||
readAttributes( element, reader );
|
||||
|
||||
ret = xmlTextReaderRead(reader);
|
||||
// If we're out of data, return the element
|
||||
if(ret != 1)
|
||||
return(element);
|
||||
|
||||
// Read all the tags that are part of this tag
|
||||
bool trew = true;
|
||||
while(trew)
|
||||
{
|
||||
int thisType = xmlTextReaderNodeType(reader);
|
||||
if(thisType == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
// Is the new element at the same depth as this one?
|
||||
if(currentDepth == xmlTextReaderDepth(reader))
|
||||
{
|
||||
// Same depth means the current element ended in a /> so this is a sibling
|
||||
// so we return and let our parent process it.
|
||||
return(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The element is a child of this one, so we recurse
|
||||
if(!element->placeElement(nextElement(element->getMeta(), reader)))
|
||||
{
|
||||
char err[256];
|
||||
memset( err, 0, 256 );
|
||||
#if LIBXML_VERSION >= 20620
|
||||
sprintf(err,"placeElement failed at line %d\n", xmlTextReaderGetParserLineNumber(reader));
|
||||
#else
|
||||
sprintf(err,"placeElement failed\n");
|
||||
#endif
|
||||
daeErrorHandler::get()->handleWarning( err );
|
||||
ret = xmlTextReaderRead(reader);
|
||||
if ( ret != 1 ) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(thisType == XML_READER_TYPE_TEXT)
|
||||
{
|
||||
readValue( element, reader );
|
||||
}
|
||||
else if(thisType == XML_READER_TYPE_END_ELEMENT)
|
||||
{
|
||||
// Done with this element so read again and return
|
||||
ret = xmlTextReaderRead(reader);
|
||||
return(element);
|
||||
}
|
||||
else
|
||||
{ // Skip element types we don't care about
|
||||
ret = xmlTextReaderRead(reader);
|
||||
// If we're out of data, return the element
|
||||
if(ret != 1)
|
||||
return(element);
|
||||
}
|
||||
}
|
||||
//program will never get here but this line is needed to supress a warning
|
||||
return NULL;
|
||||
}
|
||||
// postProcessDom traverses all elements below the passed in one and creates a list of all the integration objects.
|
||||
// this should probably NOT be done in the IO plugin.
|
||||
void daeLIBXMLPlugin::postProcessDom(daeDocument *document, daeElement* element, std::vector<INTEGRATION_ITEM> &intItems)
|
||||
{
|
||||
// Null element? Return
|
||||
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
element->setDocument(document);
|
||||
// If this element has an integration object, add it to a list so we can process them all in a bunch later
|
||||
|
||||
if (element->getIntObject(daeElement::int_uninitialized))
|
||||
{
|
||||
INTEGRATION_ITEM item;
|
||||
item.element = element;
|
||||
item.intObject = element->getIntObject(daeElement::int_uninitialized);
|
||||
intItems.push_back(item);
|
||||
}
|
||||
|
||||
// Recursively call postProcessDom on all of this element's children
|
||||
|
||||
if (element->getMeta()->getContents() != NULL) {
|
||||
daeMetaElementArrayAttribute *contents = element->getMeta()->getContents();
|
||||
for ( int i = 0; i < contents->getCount( element ); i++ ) {
|
||||
//array.append( *(daeElementRef*)contents->get( this, i ) );
|
||||
daeElementRef elem = *(daeElementRef*)contents->get(element,i);
|
||||
postProcessDom(document,elem, intItems);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
daeMetaElementAttributeArray& children = element->getMeta()->getMetaElements();
|
||||
int cnt = (int)children.getCount();
|
||||
for(int i=0;i<cnt;i++)
|
||||
{
|
||||
daeMetaElementAttribute* mea = children[i];
|
||||
int elemCnt = mea->getCount(element);
|
||||
int j;
|
||||
for(j=0;j<elemCnt;j++)
|
||||
{
|
||||
daeElementRef elem = *(daeElementRef*)mea->get(element,j);
|
||||
postProcessDom(document,elem, intItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
daeInt daeLIBXMLPlugin::write(daeURI *name, daeDocument *document, daeBool replace)
|
||||
{
|
||||
// Make sure database and document are both set
|
||||
if (!database)
|
||||
return DAE_ERR_INVALID_CALL;
|
||||
if(!document)
|
||||
return DAE_ERR_COLLECTION_DOES_NOT_EXIST;
|
||||
|
||||
// Extract just the file path from the URI
|
||||
daeFixedName finalname;
|
||||
if (!name->getPath(finalname,sizeof(finalname)))
|
||||
{
|
||||
printf( "can't get path in write\n" );
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// If replace=false, don't replace existing files
|
||||
if(!replace)
|
||||
{
|
||||
// Using "stat" would be better, but it's not available on all platforms
|
||||
FILE *tempfd = fopen(finalname,"r");
|
||||
if(tempfd != NULL)
|
||||
{
|
||||
// File exists, return error
|
||||
fclose(tempfd);
|
||||
return DAE_ERR_BACKEND_FILE_EXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
// Open the file we will write to
|
||||
writer = xmlNewTextWriterFilename(name->getURI(), 0);
|
||||
if ( !writer ) {
|
||||
printf( "no libxml2 writer\n" );
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
xmlChar indentString[10] = " ";
|
||||
xmlTextWriterSetIndentString( writer, indentString );
|
||||
xmlTextWriterSetIndent( writer, 1 );
|
||||
xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
|
||||
|
||||
writeElement( document->getDomRoot() );
|
||||
|
||||
xmlTextWriterEndDocument( writer );
|
||||
xmlTextWriterFlush( writer );
|
||||
xmlFreeTextWriter( writer );
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
void daeLIBXMLPlugin::writeElement( daeElement* element )
|
||||
{
|
||||
daeIntegrationObject* _intObject = element->getIntObject();
|
||||
daeMetaElement* _meta = element->getMeta();
|
||||
if(_intObject)
|
||||
{
|
||||
// added in response to bug 478
|
||||
_intObject->toCOLLADAChecked();
|
||||
_intObject->toCOLLADAPostProcessChecked();
|
||||
}
|
||||
if (!_meta->getIsTransparent() ) {
|
||||
if ( element->getElementName() ) {
|
||||
xmlTextWriterStartElement(writer, (xmlChar*)element->getElementName());
|
||||
}
|
||||
else {
|
||||
xmlTextWriterStartElement(writer, (xmlChar*)(daeString)_meta->getName());
|
||||
}
|
||||
daeMetaAttributeRefArray& attrs = _meta->getMetaAttributes();
|
||||
|
||||
int acnt = (int)attrs.getCount();
|
||||
|
||||
for(int i=0;i<acnt;i++) {
|
||||
writeAttribute( attrs[i], element);
|
||||
}
|
||||
}
|
||||
daeMetaAttribute* valueAttr = _meta->getValueAttribute();
|
||||
if (valueAttr!=NULL)
|
||||
writeAttribute(valueAttr, element);
|
||||
|
||||
if (_meta->getContents() != NULL) {
|
||||
daeElementRefArray* era = (daeElementRefArray*)_meta->getContents()->getWritableMemory(element);
|
||||
int elemCnt = (int)era->getCount();
|
||||
for(int i = 0; i < elemCnt; i++) {
|
||||
daeElementRef elem = (daeElementRef)era->get(i);
|
||||
if (elem != NULL) {
|
||||
writeElement( elem );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
daeMetaElementAttributeArray& children = _meta->getMetaElements();
|
||||
int cnt = (int)children.getCount();
|
||||
for(int i=0;i<cnt;i++) {
|
||||
daeMetaElement *type = children[i]->getElementType();
|
||||
if ( !type->getIsAbstract() ) {
|
||||
for (int c = 0; c < children[i]->getCount(element); c++ ) {
|
||||
writeElement( *(daeElementRef*)children[i]->get(element,c) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_meta->getIsTransparent() ) {
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
}
|
||||
|
||||
#define TYPE_BUFFER_SIZE 4096
|
||||
|
||||
void daeLIBXMLPlugin::writeAttribute( daeMetaAttribute* attr, daeElement* element )
|
||||
{
|
||||
static daeChar atomicTypeBuf[TYPE_BUFFER_SIZE];
|
||||
|
||||
if (element == NULL)
|
||||
return;
|
||||
if ( attr->getCount(element) == 0 ) {
|
||||
//we don't have a value if its required print it empty else just skip
|
||||
if ( attr->getIsRequired() ) {
|
||||
xmlTextWriterStartAttribute( writer, (xmlChar*)(daeString)attr->getName() );
|
||||
xmlTextWriterEndAttribute( writer );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( attr->getCount(element) == 1 ) {
|
||||
//single value or an array of a single value
|
||||
char* elemMem = attr->get(element, 0);
|
||||
|
||||
// !!!GAC recoded the suppression logic so you could enable suppressions individually
|
||||
if(!attr->getIsRequired())
|
||||
{
|
||||
// This attribute was not required and might get suppressed
|
||||
int typeSize = attr->getType()->getSize();
|
||||
if(attr->getDefault() != NULL)
|
||||
{
|
||||
#if 1
|
||||
// The attribute has a default, convert the default to binary and suppress
|
||||
// output of the attribute if the value matches the default.
|
||||
// DISABLE THIS CODE IF YOU WANT DEFAULT VALUES TO ALWAYS EXPORT
|
||||
if(typeSize >= TYPE_BUFFER_SIZE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"daeMetaAttribute::print() - buffer too small for default value of %s in %s\n",
|
||||
(daeString)attr->getName(),(daeString)attr->getContainer()->getName());
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
attr->getType()->stringToMemory((daeChar*)attr->getDefault(),atomicTypeBuf);
|
||||
if(memcmp(atomicTypeBuf,elemMem,typeSize) == 0)
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
// The attribute does not have a default, suppress it if its value is all zeros (binary)
|
||||
// DISABLE THIS CODE IF YOU WANT OPTIONAL ATTRIBUTES THAT HAVE A VALUE OF ZERO TO EXPORT
|
||||
// Disabling this code may cause some unused attributes to be exported if _isValid is not
|
||||
// enabled and properly used.
|
||||
int i;
|
||||
for(i=0; i<typeSize;i++)
|
||||
{
|
||||
if(elemMem[i] != 0)
|
||||
break;
|
||||
}
|
||||
if(i == typeSize && attr->getContainer()->getValueAttribute() != attr &&
|
||||
attr->getType()->getTypeEnum() != daeAtomicType::BoolType &&
|
||||
attr->getType()->getTypeEnum() != daeAtomicType::EnumType )
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the attribute to a string
|
||||
|
||||
if (attr->getType()->memoryToString(elemMem, atomicTypeBuf, TYPE_BUFFER_SIZE)== false) {
|
||||
fprintf(stderr,
|
||||
"daeMetaAttribute::print() - buffer too small for %s in %s\n",
|
||||
(daeString)attr->getName(),(daeString)attr->getContainer()->getName());
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
// Suppress attributes that convert to an empty string.
|
||||
|
||||
if (strlen(atomicTypeBuf) == 0)
|
||||
return;
|
||||
|
||||
// Is this a value attribute or something else?
|
||||
|
||||
if (attr->getContainer()->getValueAttribute() == attr)
|
||||
{
|
||||
// Always export value attributes
|
||||
xmlTextWriterWriteString( writer, (xmlChar*)atomicTypeBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Suppress attributes not marked as containing valid values
|
||||
// DO NOT TURN THIS ON TILL ALL USER CODE HAS BEEN CHANGED TO SET _isValid OR
|
||||
// ATTRIBUTES THAT WERE CREATED/SET BY USER CODE MAY NOT EXPORT.
|
||||
#if 0
|
||||
// NOTE: even if a value is marked REQUIRED by the schema, if _isValid isn't true it means
|
||||
// the value in this parameter was never set and may be garbage, so we suppress it even though it is required.
|
||||
// To change this add && !_isRequired to the expression below.
|
||||
if(!attr->getIsValid() )
|
||||
return;
|
||||
#endif
|
||||
// Export the attribute name and value
|
||||
xmlTextWriterWriteAttribute( writer, (xmlChar*)(daeString)attr->getName(), (xmlChar*)atomicTypeBuf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (attr->getContainer()->getValueAttribute() != attr)
|
||||
{
|
||||
xmlTextWriterStartAttribute( writer, (xmlChar*)(daeString)attr->getName() );
|
||||
}
|
||||
for( int i = 0; i < attr->getCount(element); i++ ) {
|
||||
char* elemMem = attr->get(element, i);
|
||||
if (attr->getType()->memoryToString(elemMem, atomicTypeBuf, TYPE_BUFFER_SIZE)== false)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"daeMetaArrayAttribute::print() - buffer too small for %s in %s\n",
|
||||
(daeString)attr->getName(),(daeString)attr->getContainer()->getName());
|
||||
fflush(stderr);
|
||||
}
|
||||
xmlTextWriterWriteFormatString( writer, "%s ", (xmlChar*)atomicTypeBuf );
|
||||
}
|
||||
if (attr->getContainer()->getValueAttribute() != attr)
|
||||
{
|
||||
xmlTextWriterEndAttribute( writer );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <modules/daeLIBXMLResolver.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <modules/daeLIBXMLPlugin.h>
|
||||
|
||||
daeLIBXMLResolver::daeLIBXMLResolver(daeDatabase* database,daeIOPlugin* plugin)
|
||||
{
|
||||
_database = database;
|
||||
_plugin = plugin;
|
||||
}
|
||||
|
||||
daeLIBXMLResolver::~daeLIBXMLResolver()
|
||||
{
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeLIBXMLResolver::resolveURI(daeURI& uri)
|
||||
{
|
||||
(void)uri;
|
||||
return false;
|
||||
}
|
||||
|
||||
daeString
|
||||
daeLIBXMLResolver::getName()
|
||||
{
|
||||
return "XMLResolver";
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeLIBXMLResolver::isExtensionSupported(daeString extension)
|
||||
{
|
||||
if ((extension!=NULL) &&
|
||||
(strlen(extension) > 0) &&
|
||||
((strncmp(extension,"xml",3)==0) ||
|
||||
(strncmp(extension,"XML",3)==0) ||
|
||||
(strncmp(extension,"DAE",3)==0) ||
|
||||
(strncmp(extension,"dae",3)==0)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeLIBXMLResolver::isProtocolSupported(daeString protocol)
|
||||
{
|
||||
if ((protocol!=NULL) &&
|
||||
(strlen(protocol) > 0) &&
|
||||
((strncmp(protocol,"file",4) == 0) ||
|
||||
(strncmp(protocol,"http",4) == 0)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeLIBXMLResolver::resolveElement(daeURI& uri, daeString typeNameHint)
|
||||
{
|
||||
// Make sure the URI is validated
|
||||
if (uri.getState() == daeURI::uri_loaded)
|
||||
{
|
||||
uri.validate();
|
||||
}
|
||||
|
||||
daeElement* resolved = NULL;
|
||||
int status;
|
||||
|
||||
// Does the URI have a document reference?
|
||||
if ( (uri.getFile() != NULL) && (strlen(uri.getFile())>0))
|
||||
{
|
||||
// The URI contains a document reference, see if it is loaded and try to load it if it's not
|
||||
if (!_database->isDocumentLoaded(uri.getURI())) {
|
||||
if ( _loadExternalDocuments ) {
|
||||
_plugin->read(uri,NULL);
|
||||
}
|
||||
else {
|
||||
uri.setState( daeURI::uri_failed_external_document );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Try to find the id by searching this document only
|
||||
status = _database->getElement(&resolved,0,uri.getID(),typeNameHint,uri.getURI());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The URI was just a fragment, so try to find it in the document that contains it.
|
||||
// !!!GAC not sure if all these pointers will be set when we get here, so assert if any of them aren't
|
||||
daeElement *tempElement = uri.getContainer();
|
||||
//assert(tempElement);
|
||||
daeDocument *tempDocument;
|
||||
if ( tempElement == NULL || (tempDocument = tempElement->getDocument()) == NULL ) {
|
||||
uri.setState(daeURI::uri_failed_missing_container);
|
||||
fprintf(stderr,
|
||||
"daeLIBXMLResolver::resolveElement() - failed to resolve %s\n",
|
||||
uri.getURI());
|
||||
fflush(stderr);
|
||||
return false;
|
||||
}
|
||||
//assert(tempDocument);
|
||||
daeURI *tempURI = tempDocument->getDocumentURI();
|
||||
//assert(tempURI);
|
||||
status = _database->getElement(&resolved,0,uri.getID(),typeNameHint,tempURI->getURI());
|
||||
}
|
||||
|
||||
uri.setElement(resolved);
|
||||
|
||||
// Error if we didn't successfully resolve the uri
|
||||
|
||||
if (status ||(resolved==NULL))
|
||||
{
|
||||
uri.setState(daeURI::uri_failed_id_not_found);
|
||||
fprintf(stderr,
|
||||
"daeLIBXMLResolver::resolveElement() - failed to resolve %s\n",
|
||||
uri.getURI());
|
||||
fflush(stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
uri.setState(daeURI::uri_success);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
574
Extras/COLLADA_DOM/src/modules/STLDatabase/daeSTLDatabase.cpp
Normal file
574
Extras/COLLADA_DOM/src/modules/STLDatabase/daeSTLDatabase.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <modules/daeSTLDatabase.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
|
||||
daeSTLDatabase::daeSTLDatabase():validated(true)
|
||||
{}
|
||||
|
||||
daeSTLDatabase::~daeSTLDatabase()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::setMeta(daeMetaElement *_topMeta)
|
||||
{
|
||||
topMeta = _topMeta;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeSTLDatabase::isDocumentLoaded(daeString name)
|
||||
{
|
||||
daeDocument* document = getDocument(name);
|
||||
if(document)
|
||||
return(true);
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
// Element Types of all Elements
|
||||
daeUInt daeSTLDatabase::getTypeCount()
|
||||
{
|
||||
validate();
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator it = elements.begin();
|
||||
daeUInt count = 0;
|
||||
while (it != elements.end())
|
||||
{
|
||||
DAE_STL_DATABASE_CELL &tmp = (*it);
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator it_up = std::upper_bound(it,elements.end(),tmp,daeSTLDatabaseTypeLess());
|
||||
it = it_up;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
daeString daeSTLDatabase::getTypeName(daeUInt index)
|
||||
{
|
||||
validate();
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator it = elements.begin();
|
||||
unsigned int count = 0;
|
||||
while (it != elements.end() && count<index)
|
||||
{
|
||||
DAE_STL_DATABASE_CELL &tmp = (*it);
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator it_up = std::upper_bound(it,elements.end(),tmp,daeSTLDatabaseTypeLess());
|
||||
it = it_up;
|
||||
count++;
|
||||
}
|
||||
if (it != elements.end())
|
||||
return (*it).type;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Documents
|
||||
daeInt daeSTLDatabase::insertDocument(const char *name, daeElement* dom, daeDocument** document)
|
||||
{
|
||||
return createDocument( name, dom, document );
|
||||
}
|
||||
daeInt daeSTLDatabase::createDocument(const char *name, daeElement* dom, daeDocument** document)
|
||||
{
|
||||
// If a document already exists with the same name, error
|
||||
if(isDocumentLoaded(name))
|
||||
{
|
||||
if (document)
|
||||
*document = NULL;
|
||||
return DAE_ERR_COLLECTION_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
// Make a new document
|
||||
daeDocument *newDocument = new daeDocument;
|
||||
// Create a Reference on the domCOLLADA passed into us
|
||||
newDocument->setDomRoot(dom);
|
||||
// Set the domCollada's document to this one
|
||||
dom->setDocument(newDocument);
|
||||
// Set and resolve the document URI
|
||||
newDocument->getDocumentURI()->setURI(name);
|
||||
newDocument->getDocumentURI()->validate();
|
||||
insertElement( newDocument, dom );
|
||||
newDocument->setModified(true);
|
||||
// Push the connection into the database
|
||||
documents.push_back(newDocument);
|
||||
|
||||
if (document)
|
||||
*document = newDocument;
|
||||
|
||||
//check if an already loaded document has external references to this one and resolve them.
|
||||
for ( unsigned int i = 0; i < documents.size(); i++ ) {
|
||||
if ( documents[i] != newDocument ) {
|
||||
documents[i]->resolveExternals( name );
|
||||
}
|
||||
}
|
||||
|
||||
return DAE_OK;
|
||||
}
|
||||
// !!!GAC revised version of insertDocument, creates a domCollada and fills it in for you.
|
||||
daeInt daeSTLDatabase::insertDocument(const char *name, daeDocument** document)
|
||||
{
|
||||
return createDocument( name, document );
|
||||
}
|
||||
daeInt daeSTLDatabase::createDocument(const char *name, daeDocument** document)
|
||||
{
|
||||
|
||||
// If a document already exists with the same name, error
|
||||
if(isDocumentLoaded(name))
|
||||
{
|
||||
if (document)
|
||||
*document = NULL;
|
||||
return DAE_ERR_COLLECTION_ALREADY_EXISTS;
|
||||
}
|
||||
// Make the new document
|
||||
daeDocument *newDocument = new daeDocument;
|
||||
// Make a domCOLLADA to be the root of this new document (this makes a reference so the domCOLLADA won't delete itself
|
||||
daeElementRef myCOLLADA = topMeta->create();
|
||||
// Set the domCollada's document to this one
|
||||
myCOLLADA->setDocument(newDocument);
|
||||
newDocument->setDomRoot(myCOLLADA);
|
||||
// Set and resolve the document URI
|
||||
newDocument->getDocumentURI()->setURI(name);
|
||||
newDocument->getDocumentURI()->validate();
|
||||
|
||||
newDocument->setModified(true);
|
||||
// Add this document to the list.
|
||||
documents.push_back(newDocument);
|
||||
// If the user gave us a place to put the document, send it back to them.
|
||||
if (document)
|
||||
*document = newDocument;
|
||||
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::insertDocument( daeDocument *c ) {
|
||||
documents.push_back(c);
|
||||
insertElement( c, c->getDomRoot() );
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::removeDocument(daeDocument *document)
|
||||
{
|
||||
// Copy the elements that are not in this collection into
|
||||
// a new list.
|
||||
std::vector<DAE_STL_DATABASE_CELL> newElements;
|
||||
newElements.reserve(elements.size());
|
||||
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator iter = elements.begin();
|
||||
while ( iter != elements.end() ) {
|
||||
if ( (*iter).document != document ) {
|
||||
newElements.push_back(*iter);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
// Replace our existing element list with the new one (that is missing
|
||||
// the elements from this collection).
|
||||
elements = newElements;
|
||||
|
||||
//remove the document from its vector
|
||||
std::vector<daeDocument*>::iterator iter2 = documents.begin();
|
||||
while ( iter2 != documents.end() ) {
|
||||
if ( (*iter2) == document ) {
|
||||
iter2 = documents.erase(iter2);
|
||||
}
|
||||
else {
|
||||
iter2++;
|
||||
}
|
||||
}
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeUInt daeSTLDatabase::getDocumentCount()
|
||||
{
|
||||
return (daeUInt)documents.size();
|
||||
}
|
||||
|
||||
daeDocument* daeSTLDatabase::getDocument(daeUInt index)
|
||||
{
|
||||
if (index<documents.size())
|
||||
return (documents[index]);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeDocument* daeSTLDatabase::getDocument(daeString name)
|
||||
{
|
||||
// Normalize the input string to an absolute URI with no fragment
|
||||
|
||||
daeURI tempURI(name, true);
|
||||
daeString targetURI = tempURI.getURI();
|
||||
|
||||
// Try to find a document that matches
|
||||
|
||||
daeDocument *document;
|
||||
int documentCount = getDocumentCount();
|
||||
for (int i=0;i<documentCount;i++)
|
||||
{
|
||||
document = getDocument(i);
|
||||
if(strcmp(document->getDocumentURI()->getURI(), targetURI)==0)
|
||||
return(document);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
daeString daeSTLDatabase::getDocumentName(daeUInt index)
|
||||
{
|
||||
if (index<documents.size())
|
||||
return getDocument(index)->getDocumentURI()->getURI();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Elements
|
||||
daeInt daeSTLDatabase::insertElement(daeDocument* document,daeElement* element)
|
||||
{
|
||||
insertChildren( document, element );
|
||||
|
||||
if ((element->getMeta() != NULL) &&
|
||||
(!element->getMeta()->getIsTrackableForQueries()))
|
||||
return DAE_OK;
|
||||
|
||||
DAE_STL_DATABASE_CELL tmp;
|
||||
validated = false;
|
||||
tmp.document = document;
|
||||
tmp.name = element->getID();
|
||||
if (tmp.name == NULL)
|
||||
tmp.name = ""; //static string in the executable
|
||||
tmp.type = element->getTypeName();
|
||||
tmp.element = element;
|
||||
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator it = std::upper_bound(elements.begin(), elements.end(), tmp, daeSTLDatabaseLess());
|
||||
elements.insert(it, tmp);
|
||||
//elements.push_back(tmp);
|
||||
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::insertChildren( daeDocument *c, daeElement *element )
|
||||
{
|
||||
daeElementRefArray era;
|
||||
element->getChildren( era );
|
||||
for ( unsigned int i = 0; i < era.getCount(); i++ ) {
|
||||
insertElement( c, era[i] );
|
||||
}
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::removeElement(daeDocument* document,daeElement* element)
|
||||
{
|
||||
if ( !element ) {
|
||||
return DAE_ERR_INVALID_CALL;
|
||||
}
|
||||
removeChildren( document, element );
|
||||
std::vector<DAE_STL_DATABASE_CELL>::iterator iter = elements.begin();
|
||||
while ( iter != elements.end() ) {
|
||||
if ( (*iter).element == element ) {
|
||||
iter = elements.erase(iter);
|
||||
}
|
||||
else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
validated = false;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::removeChildren( daeDocument *c, daeElement *element )
|
||||
{
|
||||
daeElementRefArray era;
|
||||
element->getChildren( era );
|
||||
for ( unsigned int i = 0; i < era.getCount(); i++ ) {
|
||||
removeElement( c, era[i] );
|
||||
}
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
|
||||
daeInt daeSTLDatabase::clear()
|
||||
{
|
||||
elements.clear();
|
||||
int i;
|
||||
for (i=0;i<(int)documents.size();i++)
|
||||
delete documents[i];
|
||||
documents.clear(); //this will free the daeElement
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeUInt daeSTLDatabase::getElementCount(daeString name,daeString type,daeString file)
|
||||
{
|
||||
// This sorts the vector if necessary
|
||||
validate();
|
||||
|
||||
// If none of the search keys was specified, return the total element count in the database
|
||||
|
||||
if ( !name && !type && !file )
|
||||
{
|
||||
return (daeUInt)elements.size();
|
||||
}
|
||||
|
||||
std::pair< std::vector<DAE_STL_DATABASE_CELL>::iterator, std::vector<DAE_STL_DATABASE_CELL>::iterator> range;
|
||||
int sz = 0;
|
||||
// The database is sorted by type so if type was one of the keys, find the range of items with that type
|
||||
if ( type )
|
||||
{
|
||||
// if a type was specified, range = elements of that type
|
||||
DAE_STL_DATABASE_CELL a;
|
||||
a.type = type;
|
||||
a.name = NULL;
|
||||
a.document = NULL;
|
||||
range = std::equal_range(elements.begin(),elements.end(),a,daeSTLDatabaseTypeLess());
|
||||
sz = (int)(range.second - range.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
//no type specified, range = all elements
|
||||
range.first = elements.begin();
|
||||
range.second = elements.end();
|
||||
sz = (int)elements.size();
|
||||
}
|
||||
|
||||
if ( name )
|
||||
{
|
||||
// name specified
|
||||
int count = 0;
|
||||
if ( file )
|
||||
{
|
||||
// If a document URI was a search key (in file) resolve it to a text URI with no fragment
|
||||
daeURI tempURI(file,true);
|
||||
daeDocument *col = getDocument( tempURI.getURI() );
|
||||
if ( col == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
// a document was specified
|
||||
//for ( int i = 0; i < sz; i++ )
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *(i);
|
||||
if ( col == e.document && !strcmp(name, e.name) )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no file specified
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *(i);
|
||||
if ( !strcmp( name, e.name ) ) {
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//no name specified
|
||||
if ( file )
|
||||
{
|
||||
// If a document URI was a search key (in file) resolve it to a text URI with no fragment
|
||||
daeURI tempURI(file,true);
|
||||
daeDocument *col = getDocument( tempURI.getURI() );
|
||||
if ( col == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
//a document was specified
|
||||
int count = 0;
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *(i);
|
||||
if( col == e.document )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
//if you get to this point only a type was specified
|
||||
return sz;
|
||||
}
|
||||
|
||||
daeInt daeSTLDatabase::getElement(daeElement** pElement,daeInt index,daeString name,daeString type,daeString file)
|
||||
{
|
||||
// this sorts the vector if necessary
|
||||
validate();
|
||||
|
||||
// If the index is out of range, there can be no match
|
||||
if ( index < 0 || index >= (int)elements.size() )
|
||||
{
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
|
||||
// If no name, type or file was specified we return the element at "index"
|
||||
if ( !name && !type && !file )
|
||||
{
|
||||
*pElement = elements[index].element;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
std::pair< std::vector<DAE_STL_DATABASE_CELL>::iterator, std::vector<DAE_STL_DATABASE_CELL>::iterator> range;
|
||||
int sz = 0;
|
||||
if ( type )
|
||||
{
|
||||
//a type was specified, range = elements of that type
|
||||
DAE_STL_DATABASE_CELL a;
|
||||
a.type = type;
|
||||
a.name = NULL;
|
||||
a.document = NULL;
|
||||
range = std::equal_range(elements.begin(),elements.end(),a,daeSTLDatabaseTypeLess());
|
||||
sz = (int)(range.second - range.first);
|
||||
if ( index >= sz )
|
||||
{
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//no type specified, range = all elements
|
||||
range.first = elements.begin();
|
||||
range.second = elements.end();
|
||||
sz = (int)elements.size();
|
||||
}
|
||||
|
||||
if ( name )
|
||||
{
|
||||
//name specified
|
||||
int count = 0;
|
||||
if ( file )
|
||||
{
|
||||
// If a document URI was a search key (in file) resolve it to a text URI with no fragment
|
||||
daeURI tempURI(file,true);
|
||||
daeDocument *col = getDocument( tempURI.getURI() );
|
||||
if ( col == NULL ) {
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
//a document was specified
|
||||
//for ( int i = 0; i < sz; i++ )
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *i;
|
||||
if ( col == e.document && !strcmp(name, e.name) )
|
||||
{
|
||||
if ( count == index )
|
||||
{
|
||||
*pElement = e.element;
|
||||
return DAE_OK;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no document specified
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *(i);
|
||||
if ( !strcmp( name, e.name ) )
|
||||
{
|
||||
if ( count == index )
|
||||
{
|
||||
*pElement = e.element;
|
||||
return DAE_OK;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//no name specified
|
||||
if ( file )
|
||||
{
|
||||
// If a document URI was a search key (in file) resolve it to a text URI with no fragment
|
||||
daeURI tempURI(file,true);
|
||||
daeDocument *col = getDocument( tempURI.getURI() );
|
||||
if ( col == NULL ) {
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
//a document was specified
|
||||
int count = 0;
|
||||
std::vector< DAE_STL_DATABASE_CELL >::iterator i = range.first;
|
||||
while ( i != range.second )
|
||||
{
|
||||
DAE_STL_DATABASE_CELL e = *(i);
|
||||
if( col == e.document )
|
||||
{
|
||||
if( count == index )
|
||||
{
|
||||
*pElement = e.element;
|
||||
return DAE_OK;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return DAE_ERR_QUERY_NO_MATCH;
|
||||
}
|
||||
}
|
||||
//if you get to this point only a type was specified
|
||||
*pElement = (*(range.first+index)).element;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
// Generic Query
|
||||
daeInt daeSTLDatabase::queryElement(daeElement** pElement, daeString genericQuery)
|
||||
{
|
||||
(void)pElement;
|
||||
(void)genericQuery;
|
||||
return DAE_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void daeSTLDatabase::validate()
|
||||
{
|
||||
for( unsigned int i = 0; i < documents.size(); i++ ) {
|
||||
if (documents[i]->getModified() ) {
|
||||
daeDocument *tmp = documents[i];
|
||||
//removeDocument( tmp );
|
||||
//insertDocument( tmp );
|
||||
const daeElementRefArray &iea = tmp->getInsertedArray();
|
||||
for ( unsigned int x = 0; x < iea.getCount(); x++ ) {
|
||||
insertElement( tmp, iea[x] );
|
||||
}
|
||||
const daeElementRefArray &rea = tmp->getRemovedArray();
|
||||
for ( unsigned int x = 0; x < rea.getCount(); x++ ) {
|
||||
removeElement( tmp, rea[x] );
|
||||
}
|
||||
tmp->setModified(false);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
//if (!validated)
|
||||
//{
|
||||
// //sort the array by type then by name
|
||||
// std::sort(elements.begin(),elements.end(),daeSTLDatabaseLess());
|
||||
// validated = true;
|
||||
//}
|
||||
}
|
||||
|
||||
33
Extras/COLLADA_DOM/src/modules/stdErrPlugin/stdErrPlugin.cpp
Normal file
33
Extras/COLLADA_DOM/src/modules/stdErrPlugin/stdErrPlugin.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <modules/stdErrPlugin.h>
|
||||
#include <stdio.h>
|
||||
|
||||
stdErrPlugin::stdErrPlugin() {
|
||||
}
|
||||
|
||||
stdErrPlugin::~stdErrPlugin() {
|
||||
}
|
||||
|
||||
void stdErrPlugin::handleError( daeString msg ) {
|
||||
//fprintf( stderr, "Error: %s\n", msg );
|
||||
//fflush( stderr );
|
||||
printf( "Error: %s\n", msg );
|
||||
}
|
||||
|
||||
void stdErrPlugin::handleWarning( daeString msg ) {
|
||||
//fprintf( stderr, "Warning: %s\n", msg );
|
||||
//fflush( stderr );
|
||||
printf( "Warning: %s\n", msg );
|
||||
}
|
||||
Reference in New Issue
Block a user