Action::ResultE NFIOBase::clearAttachmentParent(NodePtr &node) { if(node == NullFC) return Action::Continue; FieldContainerPtr fc = node->getCore(); if(fc == NullFC) return Action::Continue; // the core could be shared this would lead to duplicated parent entries. if(_added_cores.count(fc) == 1) return Action::Continue; _added_cores.insert(fc); FieldContainerType &fcType = fc->getType(); //go through all fields for(UInt32 i = 1; i <= fcType.getNumFieldDescs(); ++i) { FieldDescription *fDesc = fcType.getFieldDescription(i); Field *fieldPtr = fc->getField(i); const FieldType &fType = fieldPtr->getType(); std::string fieldType = fType.getCName(); BitVector mask = fDesc->getFieldMask(); if(fDesc->isInternal()) { continue; } if(strstr(fieldType.c_str(), "Ptr") != NULL) { if(fieldType[0] == 'S' && fieldType[1] == 'F') // single field { AttachmentPtr attachment = AttachmentPtr:: dcast(static_cast<SFFieldContainerPtr *>(fieldPtr) ->getValue()); if(attachment != NullFC) { fc.setParentFieldPos(fDesc->getFieldId()); beginEditCP(attachment, Attachment::ParentsFieldMask); attachment->getParents().clear(); endEditCP(attachment, Attachment::ParentsFieldMask); } } else if(fieldType[0] == 'M' && fieldType[1] == 'F') // multi field { MFFieldContainerPtr *mfield = static_cast<MFFieldContainerPtr *>(fieldPtr); UInt32 noe = mfield->size(); for(UInt32 j = 0; j < noe; ++j) { AttachmentPtr attachment = AttachmentPtr::dcast((*(mfield))[j]); if(attachment != NullFC) { fc.setParentFieldPos(fDesc->getFieldId()); beginEditCP(attachment, Attachment::ParentsFieldMask); attachment->getParents().clear(); endEditCP(attachment, Attachment::ParentsFieldMask); } } } } } return Action::Continue; }
void NFIOBase::getFCCount(const FieldContainerPtr &fc, UInt32 &count) { if(fc == NullFC) return; if(_fcSet.count(getContainerId(fc)) > 0) return; _fcSet.insert(getContainerId(fc)); ++count; FieldContainerType &fcType = fc->getType(); //go through all fields for(UInt32 i = 1; i <= fcType.getNumFieldDescs(); ++i) { FieldDescription *fDesc = fcType.getFieldDescription(i); Field *fieldPtr = fc->getField(i); const FieldType &fType = fieldPtr->getType(); if(!fDesc->isInternal()) { // ignore node volume if(fcType == Node::getClassType() && fDesc->getFieldMask() == Node::VolumeFieldMask) { continue; } // ignore parents field. if(!strcmp(fDesc->getCName(), "parents")) { continue; } FDEBUG(("NFIOBase::getFCCount: field: '%s' '%s'\n", fDesc->getCName(), fType.getCName())); if(strstr(fType.getCName(), "Ptr") != NULL) { if(fieldPtr->getCardinality() == FieldType::SINGLE_FIELD) { getFCCount(static_cast<SFFieldContainerPtr *>(fieldPtr)->getValue(), count); } else if(fieldPtr->getCardinality() == FieldType::MULTI_FIELD) { MFFieldContainerPtr *mfield = static_cast<MFFieldContainerPtr *>(fieldPtr); UInt32 noe = mfield->size(); for(UInt32 i = 0; i < noe; ++i) { getFCCount((*(mfield))[i], count); } } } else if(!strcmp(fDesc->getCName(), "attachments")) { SFAttachmentMap *amap = static_cast<SFAttachmentMap *>(fieldPtr); AttachmentMap::const_iterator mapIt = amap->getValue().begin(); AttachmentMap::const_iterator mapEnd = amap->getValue().end(); UInt32 noe = amap->getValue().size(); for(; mapIt != mapEnd; ++mapIt) { getFCCount(mapIt->second, count); } } } } }
void NFIOBase::writeFCFields(const FieldContainerPtr &fc, const std::string &exclude, bool endMarker) { FieldContainerType &fcType = fc->getType(); //go through all fields for(UInt32 i = 1; i <= fcType.getNumFieldDescs(); ++i) { FieldDescription *fDesc = fcType.getFieldDescription(i); Field *fieldPtr = fc->getField(i); const FieldType &fType = fieldPtr->getType(); BitVector mask = fDesc->getFieldMask(); if(!fDesc->isInternal()) { // ignore node volume if(fcType == Node::getClassType() && fDesc->getFieldMask() == Node::VolumeFieldMask) { continue; } // ignore parents field. if(!strcmp(fDesc->getCName(), "parents")) { continue; } FDEBUG(("NFIOBase::writeFCPtr: field: '%s' '%s'\n", fDesc->getCName(), fType.getCName())); std::string fieldName = fDesc->getCName(); std::string fieldType = fType.getCName(); if(!exclude.empty() && exclude.find("'" + fieldName + "'") != std::string::npos) { FDEBUG(("NFIOBase::writeFields: skipping field: '%s'.\n", fieldName.c_str())); continue; } if(strstr(fType.getCName(), "Ptr") != NULL) { if(fieldPtr->getCardinality() == FieldType::SINGLE_FIELD) { _out->putValue(fieldName); _out->putValue(fieldType); _out->putValue(fc->getBinSize(mask)); writeSFFieldContainerPtr(static_cast<SFFieldContainerPtr *>(fieldPtr)); } else if(fieldPtr->getCardinality() == FieldType::MULTI_FIELD) { MFFieldContainerPtr *mfield = static_cast<MFFieldContainerPtr *>(fieldPtr); if(!mfield->empty()) { UInt32 size = sizeof(UInt32) + sizeof(UInt32) * mfield->size(); _out->putValue(fieldName); _out->putValue(fieldType); _out->putValue(size); writeMFFieldContainerPtr(mfield); } } } else if(!strcmp(fDesc->getCName(), "attachments")) { SFAttachmentMap *amap = static_cast<SFAttachmentMap *>(fieldPtr); if(!amap->getValue().empty()) { // number of attachments UInt32 size = sizeof(UInt32); UInt32 noe = 0; // check for non zero bindings AttachmentMap::const_iterator mapIt = amap->getValue().begin(); AttachmentMap::const_iterator mapEnd = amap->getValue().end(); bool hasBinding = false; for(; mapIt != mapEnd; ++mapIt) { if((mapIt->first & 0x0000ffff) != 0) hasBinding = true; // skip internal attachments if(mapIt->second != NullFC && mapIt->second->getSFInternal()->getValue() == true ) { continue; } // count attachments that get written ++noe; } if(hasBinding == true) { // for each attachment write id and binding size += noe * (sizeof(UInt32) + sizeof(UInt16)); } else { // for each attachment write id size += noe * sizeof(UInt32); } _out->putValue(fieldName); _out->putValue(fieldType); _out->putValue(size); writeSFAttachmentMap(amap, noe, hasBinding); } } else { _out->putValue(fieldName); _out->putValue(fieldType); _out->putValue(fc->getBinSize(mask)); fc->copyToBin(*_out, mask); } } } if(endMarker) { // write fieldcontainer end marker writeEndMarker(); } }
std::string NFIOBase::readFCFields(const FieldContainerPtr &fc, const std::string &exclude, const std::string &endMarkers) { FieldContainerType &fcType = fc->getType(); std::string fieldName; while(true) { _in->getValue(fieldName); // check for fieldcontainer end marker. if(fieldName.empty() || (!endMarkers.empty() && endMarkers.find("'" + fieldName + "'") != std::string::npos)) { FDEBUG(("NFIOBase::readFCPtr: found fieldcontainer end marker.\n")); break; } std::string fieldType; _in->getValue(fieldType); UInt32 size; _in->getValue(size); FDEBUG(("NFIOBase::readFCPtr: field: '%s' '%s' %u\n", fieldName.c_str(), fieldType.c_str(), size)); Field *field = fc->getField(fieldName.c_str()); FieldDescription *fDesc = fcType.findFieldDescription(fieldName.c_str()); BitVector mask; if(fDesc != NULL) { mask = fDesc->getFieldMask(); // now check for the same type, ok nobody should change a field type but ... if(fieldType != field->getType().getCName()) { // for equal sizes try to read it, could be a type change from UInt32 to Int32 // and that's tolerable. FWARNING(("NFIOBase::readFCPtr: found conflicting field types field '%s' with " "types '%s' and '%s'!\n", fieldName.c_str(), fieldType.c_str(), field->getType().getCName())); if(size != fc->getBinSize(mask)) { // ok in this case we skip the field! FFATAL(("NFIOBase::readFCPtr: found conflicting field types with different sizes skipping field '%s' with " "types '%s' and '%s'!\n", fieldName.c_str(), fieldType.c_str(), field->getType().getCName())); _in->skip(size); continue; } } } else { FNOTICE(("NFIOBase::readFCPtr: skipping unknown field '%s' with " "type '%s'!\n", fieldName.c_str(), fieldType.c_str())); _in->skip(size); continue; } if(!exclude.empty() && exclude.find("'" + fieldName + "'") != std::string::npos) { FDEBUG(("NFIOBase::readFCPtr: skipping field '%s'!\n", fieldName.c_str())); _in->skip(size); continue; } // ignore parents field. if(!strcmp(fieldName.c_str(), "parents")) { _in->skip(size); continue; } if(strstr(fieldType.c_str(), "Ptr") != NULL) { if(fieldType[0] == 'S' && fieldType[1] == 'F') // single field { readSFFieldContainerPtr(fc, mask, field); } else if(fieldType[0] == 'M' && fieldType[1] == 'F') // multi field { UInt32 noe; _in->getValue(noe); readMFFieldContainerPtr(fc, mask, field, noe); } } else if(!strcmp(fieldName.c_str(), "attachments")) { UInt32 noe; _in->getValue(noe); // old buggy format without binding info but we want to keep the // osb format backward and forward compatible! if(size == sizeof(UInt32) + sizeof(UInt32) * noe) readMFFieldContainerPtr(fc, mask, field, noe); else readSFAttachmentMap(fc, mask, field, noe); } else { beginEditCP(fc, mask); fc->copyFromBin(*_in, mask); endEditCP(fc, mask); } } return fieldName; }