void daeDocument::addExternalReference( daeURI &uri ) { if ( uri.getContainer() == NULL || uri.getContainer()->getDocument() != this ) { return; } daeURI tempURI( *dae, uri.getURI(), true ); // Remove fragment referencedDocuments.appendUnique( tempURI.getURI() ); }
daeInt daeTinyXMLPlugin::write(const 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; string fileName = cdom::uriToNativePath(name.str()); if (fileName.empty()) { daeErrorHandler::get()->handleError( "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(fileName.c_str(), "r"); if(tempfd != NULL) { // File exists, return error fclose(tempfd); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(tempfd); } m_doc = new TiXmlDocument(name.getURI()); if (m_doc) { m_doc->SetTabSize(4); TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); m_doc->LinkEndChild( decl ); writeElement(document->getDomRoot()); // TODO check if writing to zae // if( 0 ) { // // Declare a printer // TiXmlPrinter printer; // // // attach it to the document you want to convert in to a std::string // m_doc->Accept(&printer); // // // Create a std::string and copy your document data in to the string // std::string str = printer.CStr(); // // // compress str and size to fileName // // } m_doc->SaveFile(fileName.c_str()); delete m_doc; m_doc = NULL; } return DAE_OK; }
daeElementRef daeTinyXMLPlugin::readFromFile(const daeURI& uri) { string file = cdom::uriToNativePath(uri.str()); if (file.empty()) return NULL; TiXmlDocument doc; doc.LoadFile(file.c_str()); if (!doc.RootElement()) { daeErrorHandler::get()->handleError((std::string("Failed to open ") + uri.str() + " in daeTinyXMLPlugin::readFromFile\n").c_str()); return NULL; } return readElement(doc.RootElement(), NULL); }
void daeURIResolver::attemptResolveElement(daeURI& uri, daeString typeNameHint) { int i; int cnt =(int) _KnownResolvers.getCount(); for(i=0;i<cnt;i++) if ((_KnownResolvers[i]->isProtocolSupported(uri.getProtocol()))&& ((uri.getFile() == NULL) || (uri.getFile()[0] == '\0') || (_KnownResolvers[i]->isExtensionSupported(uri.getExtension()))) && (_KnownResolvers[i]->resolveElement(uri, typeNameHint))) return; }
void daeURI::copyFrom(const daeURI& copyFrom) { if (!container) container = copyFrom.container; set(copyFrom.originalStr()); }
daeURI::daeURI(daeURI& copyFrom) { initialize(); setURI(copyFrom.getOriginalURI()); element = copyFrom.element; // !!!GAC SetURI immediately clears element so we must do this after state = copyFrom.state; }
void daeURI::copyFrom(daeURI& copyFrom) { setURI(copyFrom.getOriginalURI()); element = copyFrom.element; // !!!GAC SetURI immediately clears element so we must do this after state = copyFrom.state; // !!!GAC Should there be a call to validate in here? }
void daeURIResolver::attemptResolveURI(daeURI& uri) { int i,cnt = (int)_KnownResolvers.getCount(); daeBool foundProtocol = false; for(i=0;i<cnt;i++) if (_KnownResolvers[i]->isProtocolSupported(uri.getProtocol())) { foundProtocol = true; if (_KnownResolvers[i]->resolveURI(uri)) return; } #if defined(_DEBUG) && defined(WIN32) fprintf(stderr, "daeURIResolver::attemptResolveURI(%s) - failed\n", uri.getURI()); #endif if (!foundProtocol) { uri.setState(daeURI::uri_failed_unsupported_protocol); #if defined(_DEBUG) && defined(WIN32) fprintf(stderr,"**protocol '%s' is not supported**\n",uri.getProtocol()); fflush(stderr); #endif } else { #if defined(_DEBUG) && defined(WIN32) fprintf(stderr,"**file(%s/%s) or id(%s) failed to resolve\n", uri.getFilepath(),uri.getFile(),uri.getID()); fflush(stderr); #endif } }
daeElementRef daeLIBXMLPlugin::readFromFile(const daeURI& uri) { xmlTextReaderHelper readerHelper(uri); if (!readerHelper.reader) { daeErrorHandler::get()->handleError((string("Failed to open ") + uri.str() + " in daeLIBXMLPlugin::readFromFile\n").c_str()); return NULL; } return read(readerHelper.reader); }
daeInt daeTinyXMLPlugin::write(const 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; string fileName = cdom::uriToNativePath(name.str()); if (fileName.empty()) { daeErrorHandler::get()->handleError( "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(fileName.c_str(), "r"); if(tempfd != NULL) { // File exists, return error fclose(tempfd); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(tempfd); } m_doc = new TiXmlDocument(name.getURI()); if (m_doc) { m_doc->SetTabSize(4); TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); m_doc->LinkEndChild( decl ); writeElement(document->getDomRoot()); m_doc->SaveFile(fileName.c_str()); delete m_doc; m_doc = NULL; } return DAE_OK; }
daeInt daeLIBXMLPlugin::write(const 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; // Convert the URI to a file path, to see if we're about to overwrite a file string file = cdom::uriToNativePath(name.str()); if (file.empty() && saveRawFile) { daeErrorHandler::get()->handleError( "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(file.c_str(), "r"); if(tempfd != NULL) { // File exists, return error fclose(tempfd); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(tempfd); } if ( saveRawFile ) { string rawFilePath = file + ".raw"; if ( !replace ) { rawFile = fopen(rawFilePath.c_str(), "rb" ); if ( rawFile != NULL ) { fclose(rawFile); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(rawFile); } rawFile = fopen(rawFilePath.c_str(), "wb"); if ( rawFile == NULL ) { return DAE_ERR_BACKEND_IO; } rawRelPath.set(cdom::nativePathToUri(rawFilePath)); rawRelPath.makeRelativeTo( &name ); } // Open the file we will write to writer = xmlNewTextWriterFilename(cdom::fixUriForLibxml(name.str()).c_str(), 0); if ( !writer ) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") failed\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } xmlTextWriterSetIndentString( writer, (const xmlChar*)"\t" ); // Don't change this to spaces xmlTextWriterSetIndent( writer, 1 ); // Turns indentation on xmlTextWriterStartDocument( writer, "1.0", "UTF-8", NULL ); writeElement( document->getDomRoot() ); xmlTextWriterEndDocument( writer ); xmlTextWriterFlush( writer ); xmlFreeTextWriter( writer ); if ( saveRawFile && rawFile != NULL ) { fclose( rawFile ); } return DAE_OK; }
daeURI::daeURI(const daeURI& baseURI, const string& uriStr) : dae(baseURI.getDAE()) { initialize(); set(uriStr, &baseURI); }
void daeURI::setBaseURI(daeURI& uri) { ApplicationURI.reset(); ApplicationURI.setURI(uri.getURI()); }
daeInt daeLIBXMLPlugin::write(const 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; } // Convert the URI to a file path, to see if we're about to overwrite a file string file = cdom::uriToNativePath(name.str()); if (file.empty() && saveRawFile) { daeErrorHandler::get()->handleError( "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(file.c_str(), "r"); if(tempfd != NULL) { // File exists, return error fclose(tempfd); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(tempfd); } if ( saveRawFile ) { string rawFilePath = file + ".raw"; if ( !replace ) { rawFile = fopen(rawFilePath.c_str(), "rb" ); if ( rawFile != NULL ) { fclose(rawFile); return DAE_ERR_BACKEND_FILE_EXISTS; } fclose(rawFile); } rawFile = fopen(rawFilePath.c_str(), "wb"); if ( rawFile == NULL ) { return DAE_ERR_BACKEND_IO; } rawRelPath.set(cdom::nativePathToUri(rawFilePath)); rawRelPath.makeRelativeTo( &name ); } std::string fileName = cdom::uriToNativePath(name.str()); bool bcompress = fileName.size() >= 4 && fileName[fileName.size()-4] == '.' && ::tolower(fileName[fileName.size()-3]) == 'z' && ::tolower(fileName[fileName.size()-2]) == 'a' && ::tolower(fileName[fileName.size()-1]) == 'e'; int err=0; xmlBufferHandler bufhandler; if( bcompress ) { // taken from http://xmlsoft.org/examples/testWriter.c // Create a new XML buffer, to which the XML document will be written bufhandler.buf = xmlBufferCreate(); if (!bufhandler.buf) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") testXmlwriterMemory: Error creating the xml buffer\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } // Create a new XmlWriter for memory, with no compression. Remark: there is no compression for this kind of xmlTextWriter writer = xmlNewTextWriterMemory(bufhandler.buf, 0); } else { // Open the file we will write to writer = xmlNewTextWriterFilename(cdom::fixUriForLibxml(name.str()).c_str(), 0); } if (!writer) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") Error creating the xml writer\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } err = xmlTextWriterSetIndentString( writer, (const xmlChar*)"\t" ); // Don't change this to spaces if( err < 0 ) { } err = xmlTextWriterSetIndent( writer, 1 ); // Turns indentation on if( err < 0 ) { } err = xmlTextWriterStartDocument( writer, "1.0", "UTF-8", NULL ); if( err < 0 ) { } writeElement( document->getDomRoot() ); xmlTextWriterEndDocument( writer ); xmlTextWriterFlush( writer ); xmlFreeTextWriter( writer ); writer = NULL; // reset pointer if( bcompress ) { std::string savefilenameinzip; size_t namestart = fileName.find_last_of(s_filesep); if( namestart == string::npos ) { namestart = 0; } else { namestart+=1; } if(namestart+4>=fileName.size()) { daeErrorHandler::get()->handleError("invalid fileName when removing zae extension"); return DAE_ERR_BACKEND_IO; } savefilenameinzip = fileName.substr(namestart,fileName.size()-namestart-4); savefilenameinzip += ".dae"; zipFileHandler zfh; #ifdef _WIN32 #if 0 zlib_filefunc_def ffunc; fill_win32_filefunc(&ffunc); zfh.zf = zipOpen2(fileName.c_str(),APPEND_STATUS_CREATE,NULL,&ffunc); #else zfh.zf = zipOpen(fileName.c_str(),APPEND_STATUS_CREATE); #endif #else zfh.zf = zipOpen64(fileName.c_str(),APPEND_STATUS_CREATE); #endif if (!zfh.zf) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") Error opening zip file for writing\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } time_t curtime = time(NULL); struct tm* timeofday = localtime(&curtime); zip_fileinfo zi; zi.tmz_date.tm_sec = timeofday->tm_sec; zi.tmz_date.tm_min = timeofday->tm_min; zi.tmz_date.tm_hour = timeofday->tm_hour; zi.tmz_date.tm_mday = timeofday->tm_mday; zi.tmz_date.tm_mon = timeofday->tm_mon; zi.tmz_date.tm_year = timeofday->tm_year; zi.dosDate = 0; zi.internal_fa = 0; zi.external_fa = 0; int zip64 = bufhandler.buf->use >= 0xffffffff; char* password=NULL; unsigned long crcFile=0; int opt_compress_level = 9; #ifdef _WIN32 err = zipOpenNewFileInZip3(zfh.zf,savefilenameinzip.c_str(),&zi,NULL,0,NULL,0,"collada file generated by collada-dom",Z_DEFLATED, opt_compress_level,0,-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,password,crcFile); #else err = zipOpenNewFileInZip3_64(zfh.zf,savefilenameinzip.c_str(),&zi,NULL,0,NULL,0,"collada file generated by collada-dom",Z_DEFLATED, opt_compress_level,0,-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,password,crcFile, zip64); #endif if (err != ZIP_OK) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipOpenNewFileInZip3_64 error" << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } err = zipWriteInFileInZip (zfh.zf,bufhandler.buf->content, bufhandler.buf->use); if (err<0) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipWriteInFileInZip error for dae file " << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } err = zipCloseFileInZip(zfh.zf); if (err!=ZIP_OK) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipCloseFileInZip error for dae file " << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } // add the manifest string smanifest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<dae_root>./"; smanifest += savefilenameinzip; smanifest += "</dae_root>\n"; #if _WIN32 err = zipOpenNewFileInZip3(zfh.zf,"manifest.xml",&zi,NULL,0,NULL,0,NULL,Z_DEFLATED, opt_compress_level,0,-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,password,crcFile); #else err = zipOpenNewFileInZip3_64(zfh.zf,"manifest.xml",&zi,NULL,0,NULL,0,NULL,Z_DEFLATED, opt_compress_level,0,-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,password,crcFile, zip64); #endif if (err != ZIP_OK) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipOpenNewFileInZip3_64 error for manifest.xml file " << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } err = zipWriteInFileInZip (zfh.zf,&smanifest[0],smanifest.size()); if (err != ZIP_OK) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipWriteInFileInZip error for manifest.xml file " << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } err = zipCloseFileInZip(zfh.zf); if (err != ZIP_OK) { ostringstream msg; msg << "daeLIBXMLPlugin::write(" << name.str() << ") zipCloseFileInZip error for manifest.xml file " << err << "\n"; daeErrorHandler::get()->handleError(msg.str().c_str()); return DAE_ERR_BACKEND_IO; } } if ( saveRawFile && rawFile != NULL ) { fclose( rawFile ); } return DAE_OK; }
void daeRawRefCache::add(const daeURI& uri, daeElement* elt) { (*lookupTable)[uri.str()] = elt; }
void daeRawRefCache::remove(const daeURI& uri) { lookupTable->erase(uri.str()); }
xmlTextReaderHelper(const daeURI& uri) { if((reader = xmlReaderForFile(cdom::fixUriForLibxml(uri.str()).c_str(), NULL, 0))) xmlTextReaderSetErrorHandler(reader, libxmlErrorHandler, NULL); }
daeURI::daeURI(const daeURI& copyFrom_) : dae(copyFrom_.getDAE()), container(NULL) { initialize(); copyFrom(copyFrom_); }
xmlTextReaderHelper(daeString buffer, const daeURI& baseUri) { if((reader = xmlReaderForDoc((xmlChar*)buffer, cdom::fixUriForLibxml(baseUri.str()).c_str(), NULL, 0))) xmlTextReaderSetErrorHandler(reader, libxmlErrorHandler, NULL); };
// 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; }
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); char msg[256]; sprintf(msg, "daeLIBXMLResolver::resolveElement() - failed to resolve %s\n", uri.getURI()); daeErrorHandler::get()->handleError( msg ); 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); char msg[256]; sprintf(msg, "daeLIBXMLResolver::resolveElement() - failed to resolve %s\n", uri.getURI()); daeErrorHandler::get()->handleError( msg ); return false; } uri.setState(daeURI::uri_success); return true; }