예제 #1
0
	void Scene::save(stream::OutputStream<stream::SerializationEndian> &strm) const
	{
		PROFILE;
		strm.write(ENGINE_VERSION_MAJOR);
		strm.write(ENGINE_VERSION_MINOR);
		strm.write(ENGINE_VERSION_PATCH);

		strm.write(entities.size());

		for (unsigned i = 0; i < entities.size(); ++i)
		{
			entities[i]->save(strm);
		}
	}
예제 #2
0
    /** Continuous decompression process.
        Not all compressor support this (in that case, it's probably emulated or might return false).

        @param outStream        The output stream to write to.
        @param inStream         The input stream to read from.
        @param amountToProcess  The number of decompressed bytes to reach. Set to 0 to process the whole stream.
        @return true on success, false if not supported or an error occurred on the input stream */
    bool BSCLib::decompressStream(Stream::OutputStream & outStream, const Stream::InputStream & inStream, const uint32 amountToProcess)
    {
        // We need to first read the number of blocks
        if (!memBuffer || !outBuffer) return setError(NotEnoughMemory);

        const size_t minBlockHeaderSize = (sizeof(dataSize) + sizeof(decHeader.recordSize) + sizeof(decHeader.sortingContext) + BSC::HeaderSize);
        if (memBuffer->total <= outBuffer->total)
        {
            // If we were compressing, let's enlarge that
            resizeBuffer(minBlockHeaderSize);
            decHeader.curBlock = 0;
        }

        uint32 nBlocks = (uint32)dataSize;

#define POP(X, S) if (inStream.read(X, (uint64)S) != (uint64)S) return setError(Success); // No more data to read
        if (dataSize <= 0)
        {
            POP(&nBlocks, sizeof(nBlocks));
            dataSize = nBlocks; // Crude off estimation
            memBuffer->empty();
        }
        if (!nBlocks) return setError(BadFormat);

        // Check if we have enough data in our memory block to answer directly
        uint64 outSize = amountToProcess ? min((uint64)amountToProcess, outStream.fullSize()) : outStream.fullSize();
        if (outSize > 0xFFFFFFFF) outSize = 0xFFFFFFFF; // We can only deal with 4GB at a time

        // If we reach here, we have not enough data in the memory block (we need to refill it),
        int64 inPos = 0;

        do
        {
            // Check if we have a valid header
            if (!decHeader.valid && decHeader.curBlock < nBlocks)
            {
                if (memBuffer->available() < minBlockHeaderSize
                    && (memBuffer->refill(inStream, minBlockHeaderSize - memBuffer->available()) == (size_t)-1 || memBuffer->available() < minBlockHeaderSize))
                    return setError(UnexpectedEOD);

                // The decode the header
#define POPM(X, S) memcpy(X, *memBuffer, S); memBuffer->use(S);

    #ifndef BreakCompatibility
                POPM(&inPos, sizeof(inPos));
                POPM(&decHeader.recordSize, sizeof(decHeader.recordSize));
                POPM(&decHeader.sortingContext, sizeof(decHeader.sortingContext));
    #endif
                // Unsupported features ?
                if (decHeader.recordSize < 1 || decHeader.sortingContext < 1 || decHeader.sortingContext > 2) return setError(BadFormat);

                // Figure out the block informations
                if (opaque->getBlockInfo(*memBuffer, BSC::HeaderSize, decHeader.blockSize, decHeader.dataSize) != BSC::Success)
                    return setError(BadFormat);

                //memBuffer->empty();
                decHeader.valid = true;
            }
            // Check if we have decompressed data ready for output stream direct write
            if (outBuffer->available())
            {
                // Data is ready in the buffer, let's extract it
                size_t doneSize = min(outBuffer->available(), (size_t)outSize);
                if (outStream.write(*outBuffer, doneSize) != (uint64)doneSize) return setError(UnexpectedEOD);
                outBuffer->use(doneSize);

                if (doneSize == outSize) break; // Success
                outSize -= doneSize;
                // If we reach here, then the outBuffer is empty anyway, let's mark as is
                outBuffer->empty();

                // Need to refill a header now
                continue;
            }

            // We need to fetch a complete buffer from the input stream
            size_t need = decHeader.blockSize - memBuffer->available();
            if (memBuffer->refill(inStream, need) != need)
            {
                // Could not read enough from the input stream to fill a block.
                // Let's output the amount we succeed to write from it.
                if (amountToProcess - outSize > 0) return setError(Success);
                return setError(UnexpectedEOD);
            }

            if (decHeader.dataSize != 0 && decHeader.curBlock < dataSize)
            {
                // Now decompress the cruft
                BSC::Error err = opaque->decompress(*memBuffer, decHeader.blockSize, *outBuffer, decHeader.dataSize);
                if (err != BSC::Success)
                    return err == BSC::NotEnoughMemory ? setError(NotEnoughMemory) : setError(DataCorrupt);

                // Depending on the sorting context, we might need to reverse the blocks
                err = opaque->postProcess(*outBuffer, decHeader.dataSize, decHeader.sortingContext, decHeader.recordSize);
                if (err != BSC::Success)
                    return err == BSC::NotEnoughMemory ? setError(NotEnoughMemory) : setError(DataCorrupt);

                outBuffer->setFill(decHeader.dataSize);
                memBuffer->empty(); // Done with this data buffer
                decHeader.valid = false; // The block header is now invalid too
                decHeader.curBlock++;
            }
            else break; // No more data to decompress
        } while (true);
#undef POP
        // Check if we've finished sending the complete decompressed input stream
        if (decHeader.curBlock == dataSize && outBuffer->available() == 0)
        {
            // We can reset the decompression stream if it needs to be re-used
            decHeader.curBlock = 0;
            dataSize = 0;
        }
        if (outBuffer->available() == 0) outBuffer->empty();
        return setError(Success);
    }
예제 #3
0
	void Handle::save(stream::OutputStream<stream::SerializationEndian> &strm) const
	{
		strm.write(id);
	}