static void writeDNAComponent(DNAComponent* com) { if (!com) return; xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DNACOMPONENT)); if (!alreadyProcessed((void *)com)) { markProcessed((void *)com); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_ABOUT), xmlCharStrdup(getDNAComponentURI(com))); // properties char* data; data = getDNAComponentDisplayID(com); if (data) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DISPLAYID), xmlCharStrdup(data)); data = getDNAComponentName(com); if (data) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_NAME), xmlCharStrdup(data)); data = getDNAComponentDescription(com); if (data) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DESCRIPTION), xmlCharStrdup(data)); data = getDNAComponentType(com); if (data) { xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_TYPE)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RESOURCE), xmlCharStrdup(data)); xmlTextWriterEndElement(WRITER); } // sequence if (com->dnaSequence) { xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DNASEQUENCE_REF)); indentMore(); /// @todo sometimes no contents? writeDNASequence(com->dnaSequence); markProcessed(com->dnaSequence); indentLess(); xmlTextWriterEndElement(WRITER); } // annotations int n; int num = getNumSequenceAnnotationsFor(com); SequenceAnnotation* ann; indentMore(); if (num>0) { for (n=0; n<num; n++) { ann = getNthSequenceAnnotationFor(com, n); indentMore(); xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_ANNOTATION)); writeSequenceAnnotation(ann); xmlTextWriterEndElement(WRITER); indentLess(); } } indentLess(); } else xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RESOURCE), xmlCharStrdup(getDNAComponentURI(com))); xmlTextWriterEndElement(WRITER); }
// writes a start tag. should only be called from // IPersistent::xmlExportBegin(). void ExportContext::beginElement( const char* name) { ASSERT(name); if(!m_objectStack.size()) { reportError("beginElement(): no object being written.\n"); return; } if(m_state != WRITE_BEGIN && m_state != WRITE_CONTENT) { reportError("beginElement(): not allowed.\n"); return; } // push tag onto element stack, and link to entry for the current object m_elementStack.push_back(element_entry()); m_elementStack.back().name = name; m_objectStack.back().element = m_elementStack.back().name.String(); // write tag BString out; out << "\n" << indentString() << '<' << name; writeString(out); indentMore(); }
static void writeSequenceAnnotation(SequenceAnnotation* ann) { if (!ann) return; markProcessed((void *)ann); xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_SEQUENCEANNOTATION)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_ABOUT), xmlCharStrdup(getSequenceAnnotationURI(ann))); // precedes int n; SequenceAnnotation* ann2; indentMore(); for (n=0; n<getNumPrecedes(ann); n++) { ann2 = getNthPrecedes(ann, n); xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_PRECEDES)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RESOURCE), xmlCharStrdup(getSequenceAnnotationURI(ann2))); xmlTextWriterEndElement(WRITER); } indentLess(); // start, end int start = getSequenceAnnotationStart(ann); int end = getSequenceAnnotationEnd(ann); if (start>0) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_BIOSTART), xmlCharStrdup(intToStr(start))); if (end>0) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_BIOEND), xmlCharStrdup(intToStr(end))); // subComponent char* uri; indentMore(); if (ann->subComponent) { uri = getDNAComponentURI(ann->subComponent); xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_SUBCOMPONENT)); if (alreadyProcessed((void *)(ann->subComponent))) xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RESOURCE), xmlCharStrdup(uri)); else { indentMore(); writeDNAComponent(ann->subComponent); indentLess(); } xmlTextWriterEndElement(WRITER); } indentLess(); xmlTextWriterEndElement(WRITER); }
static void startSBOLDocument() { resetProcessed(); createSBOLWriter(); xmlTextWriterStartDocument(WRITER, NULL, NULL, NULL); xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RDF)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup("xmlns:" NSPREFIX_RDF), xmlCharStrdup(NSURL_RDF)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup("xmlns:" NSPREFIX_RDFS), xmlCharStrdup(NSURL_RDFS)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup("xmlns:" NSPREFIX_SO), xmlCharStrdup(NSURL_SO)); xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup("xmlns:" NSPREFIX_SBOL), xmlCharStrdup(NSURL_SBOL)); indentMore(); }
static void writeCollection(Collection* col) { if (!col) return; xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_COLLECTION)); if (!alreadyProcessed((void *)col)) { markProcessed((void *)col); int n; int num; // properties if (getCollectionURI(col)) xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_ABOUT), xmlCharStrdup(getCollectionURI(col))); if(getCollectionDisplayID(col)) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DISPLAYID), xmlCharStrdup(getCollectionDisplayID(col))); if (getCollectionName(col)) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_NAME), xmlCharStrdup(getCollectionName(col))); if (getCollectionDescription(col)) xmlTextWriterWriteElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_DESCRIPTION), xmlCharStrdup(getCollectionDescription(col))); // components DNAComponent* com; num = getNumDNAComponentsIn(col); if (num>0) { indentMore(); for (n=0; n<num; n++) { xmlTextWriterStartElement(WRITER, xmlCharStrdup(NSPREFIX_SBOL ":" NODENAME_COMPONENT)); com = getNthDNAComponentIn(col, n); indentMore(); writeDNAComponent(com); indentLess(); xmlTextWriterEndElement(WRITER); } indentLess(); } } else xmlTextWriterWriteAttribute(WRITER, xmlCharStrdup(NSPREFIX_RDF ":" NODENAME_RESOURCE), xmlCharStrdup(getCollectionURI(col))); xmlTextWriterEndElement(WRITER); }
//---------------------------------------------------------------- // IElement::load // uint64 IElement::load(IStorage & storage, uint64 bytesToRead, IDelegateLoad * loader) { if (!bytesToRead) { return 0; } // save a storage receipt so that element position references // can be resolved later: IStorage::IReceiptPtr storageReceipt = storage.receipt(); // save current seek position, so it can be restored if necessary: IStorage::TSeek storageStart(storage); uint64 eltId = loadEbmlId(storage); if (eltId != getId()) { // element id wrong for my type: return 0; } #if 0 // !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG)) Indent::More indentMore(Indent::depth_); { IStorage::TSeek restore(storage); uint64 vsizeSize = 0; uint64 vsize = vsizeDecode(storage, vsizeSize); std::cout << indent() << std::setw(8) << uintEncode(getId()) << " @ " << std::hex << "0x" << storageStart.absolutePosition() << std::dec << " -- " << getName() << ", payload " << vsize << " bytes" << std::endl; } #endif // this appears to be a good payload: storageStart.doNotRestore(); // store the storage receipt: receipt_ = storageReceipt; // read payload size: uint64 vsizeSize = 0; uint64 payloadSize = vsizeDecode(storage, vsizeSize); const bool payloadSizeUnknown = (payloadSize == uintMax[8]); // keep track of the number of bytes read successfully: receipt_->add(uintNumBytes(eltId)); receipt_->add(vsizeSize); // clear the payload checksum: setCrc32(false); storedCrc32_ = 0; computedCrc32_ = 0; // save the payload storage receipt so that element position references // can be resolved later: IStorage::IReceiptPtr receiptPayload = storage.receipt(); offsetToPayload_ = receiptPayload->position() - receipt_->position(); offsetToCrc32_ = kUndefinedOffset; // shortcut: IPayload & payload = getPayload(); // container elements may be present in any order, therefore // not every load will succeed -- keep trying until all // load attempts fail: uint64 payloadBytesToRead = payloadSize; uint64 payloadBytesReadTotal = 0; while (payloadBytesToRead) { uint64 prevPayloadBytesToRead = payloadBytesToRead; // try to load some part of the payload: uint64 partialPayloadSize = 0; if (loader) { uint64 bytesRead = loader->load(storage, payloadBytesToRead, eltId, payload); if (bytesRead == uintMax[8]) { // special case, indicating that the loader doesn't // want to read any more data: storageStart.doRestore(); loader->loaded(*this); return 0; } partialPayloadSize += bytesRead; payloadBytesToRead -= bytesRead; } if (!partialPayloadSize) { uint64 bytesRead = payload.load(storage, payloadBytesToRead, loader); partialPayloadSize += bytesRead; payloadBytesToRead -= bytesRead; } // consume any void elements that may exist: IPayload::TVoid eltVoid; uint64 voidPayloadSize = eltVoid.load(storage, payloadBytesToRead, loader); if (voidPayloadSize) { payloadBytesToRead -= voidPayloadSize; // find an element to store the Void element, so that // the relative element order would be preserved: IStorage::IReceiptPtr voidReceipt = eltVoid.storageReceipt(); FindElement crawler(voidReceipt->position() - 2); if (partialPayloadSize) { crawler.evalPayload(payload); assert(crawler.eltFound_); } if (crawler.eltFound_) { IPayload & dstPayload = crawler.eltFound_->getPayload(); dstPayload.voids_.push_back(eltVoid); } else { payload.voids_.push_back(eltVoid); } } // consume the CRC-32 element if it exists: payloadBytesToRead -= loadCrc32(storage, payloadBytesToRead); uint64 payloadBytesRead = prevPayloadBytesToRead - payloadBytesToRead; payloadBytesReadTotal += payloadBytesRead; if (payloadBytesRead == 0) { break; } } if (payloadBytesReadTotal < payloadSize && !payloadSizeUnknown) { // skip unrecognized alien data: uint64 alienDataSize = payloadSize - payloadBytesReadTotal; #if !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG)) std::cerr << indent() << "WARNING: " << getName() << " 0x" << uintEncode(getId()) << " -- skipping " << alienDataSize << " bytes of unrecognized alien data @ 0x" << std::hex << storage.receipt()->position() << std::dec << std::endl; #endif storage.skip(alienDataSize); payloadBytesReadTotal = payloadSize; } receiptPayload->add(payloadBytesReadTotal); *receipt_ += receiptPayload; // verify stored payload CRC-32 checksum: if (shouldComputeCrc32()) { IStorage::IReceiptPtr receiptCrc32 = crc32Receipt(); Crc32 crc32; receiptPayload->calcCrc32(crc32, receiptCrc32); computedCrc32_ = crc32.checksum(); if (computedCrc32_ != storedCrc32_) { #if 1 // !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG)) std::cerr << indent() << "WARNING: " << getName() << " 0x" << uintEncode(getId()) << " -- checksum mismatch, loaded " << std::hex << storedCrc32_ << ", computed " << computedCrc32_ << ", CRC-32 @ 0x" << receiptCrc32->position() << ", payload @ 0x" << receiptPayload->position() << ":" << receiptPayload->numBytes() << std::dec << std::endl; Crc32 doOverCrc32; receiptPayload->calcCrc32(doOverCrc32, receiptCrc32); #endif } } if (loader && receipt_->numBytes()) { // allow the delegate to perform post-processing on the loaded element: loader->loaded(*this); } return receipt_->numBytes(); }