Example #1
0
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;
}
Example #2
0
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);
                }
            }
        }
    }
}
Example #3
0
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();
    }
}
Example #4
0
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;
}