Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost serialization throws "input stream error" after a certain file size

I am using Boost::serialization to read/write to a file which contains 3d models.

After a certain size of the file (around 8-12kb+), serialization throws an "Input Stream Error" exception every time I try to read the file. It works fine every single time untill then - for example I can read/write a 1kb model 12 times successfully, then on the 13th time and onwards it will throw exception!

Here's the code to serialize/deserialize:

    JonsPackagePtr ReadJonsPkg(const std::string& jonsPkgName)
    {
        std::ifstream jonsPkgStream(jonsPkgName.c_str(), std::fstream::binary || std::fstream::in);
        JonsPackagePtr pkg(new JonsPackage());   // "JonsPackagePtr" is a boost_shared_ptr typedef

        if (jonsPkgStream && jonsPkgStream.good() && jonsPkgStream.is_open())
        {
            boost::archive::binary_iarchive iar(jonsPkgStream);

            iar >> (*pkg.get());
        }

        return pkg;
    }

    bool WriteJonsPkg(const std::string& jonsPkgName, const JonsPackagePtr pkg)
    {
        std::ofstream outStream(jonsPkgName.c_str(), std::fstream::out | std::fstream::binary);
        bool ret = false;

        if (outStream.is_open())
        {
            boost::archive::binary_oarchive oar(outStream);
            oar << (*pkg.get());

            ret = true;
        }

        return ret;
    }

Here's the contents that I archive:

/* PackageHeader definition */
    struct PackageHeader
    {
        std::string mSignature;
        uint8_t mMajorVersion;
        uint8_t mMinorVersion;


        PackageHeader();
    };

    /* PackageMesh definition */
    struct PackageMesh
    {
        std::vector<float> mVertexData;
        std::vector<uint32_t> mIndiceData;


        PackageMesh();
    };

    /* PackageModel definition */
    struct PackageModel
    {
        std::string mName;
        std::vector<PackageModel> mChildren;
        std::vector<PackageMesh> mMeshes;
        Mat4 mTransform;


        PackageModel();
    };

    /* JonsPackage definition */
    struct JonsPackage
    {
        PackageHeader mHeader;
        std::vector<PackageModel> mModels;


        JonsPackage();
    };


    typedef boost::shared_ptr<JonsPackage> JonsPackagePtr;
    JonsPackagePtr ReadJonsPkg(const std::string& jonsPkgName);
    bool WriteJonsPkg(const std::string& jonsPkgName, const JonsPackagePtr pkg);


    /* PackageHeader inlines */
    inline PackageHeader::PackageHeader() : mSignature("jons"), mMajorVersion(LatestMajorVersion), mMinorVersion(LatestMinorVersion)
    {
    }

    /* PackageModel inlines */
    inline PackageModel::PackageModel() : mName(""), mTransform(1.0f)
    {
    }

    /* PackageMesh inlines */
    inline PackageMesh::PackageMesh()
    {
    }

    /* JonsPackage inlines */
    inline JonsPackage::JonsPackage()
    {
    }

Finally here's my non-intrusive serialization definitions:

namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize(Archive & ar, JonsEngine::PackageHeader& header, const unsigned int version)
        {
            ar & header.mMajorVersion;
            ar & header.mMinorVersion;
            ar & header.mSignature;
        }

        template<class Archive>
        void serialize(Archive & ar, JonsEngine::PackageModel& model, const unsigned int version)
        {
            ar & model.mName;
            ar & model.mChildren;
            ar & model.mMeshes;
            ar & model.mTransform;
        }

        template<class Archive>
        void serialize(Archive & ar, JonsEngine::PackageMesh& mesh, const unsigned int version)
        {
            ar & mesh.mVertexData;
            ar & mesh.mIndiceData;
        }

        template<class Archive>
        void serialize(Archive & ar, JonsEngine::JonsPackage& pkg, const unsigned int version)
        {
            ar & pkg.mHeader;
            ar & pkg.mModels;
        }

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tmat4x4<glm::mediump_float> transform, const unsigned int version)
        {
            ar & transform[0];
            ar & transform[1];
            ar & transform[2];
            ar & transform[3];
        }

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec4<glm::mediump_float> vec, const unsigned int version)
        {
            ar & vec.x;
            ar & vec.y;
            ar & vec.z;
            ar & vec.w;
        }
    } // namespace serialization
} // namespace boost

As I mentioned above, it is only after a certain file size (8-12kb+) that it starts throwing the exceptions when I try to read it. Why on earth is this and what could possibly cause it? It goes fine up untill this point...

Thanks

like image 220
KaiserJohaan Avatar asked Sep 10 '25 15:09

KaiserJohaan


1 Answers

in ReadJonsPkg you should use bitwise or: std::fstream::binary | std::fstream::in

like image 107
Maciek B Avatar answered Sep 13 '25 05:09

Maciek B