Exemplo n.º 1
0
unsigned File::Read(void* dest, unsigned size)
{
    if (!IsOpen())
    {
        // If file not open, do not log the error further here to prevent spamming the stderr stream
        return 0;
    }

    if (mode_ == FILE_WRITE)
    {
        ATOMIC_LOGERROR("File not opened for reading");
        return 0;
    }

    if (size + position_ > size_)
        size = size_ - position_;
    if (!size)
        return 0;

#ifdef __ANDROID__
    if (assetHandle_ && !compressed_)
    {
        // If not using a compressed package file, buffer file reads on Android for better performance
        if (!readBuffer_)
        {
            readBuffer_ = new unsigned char[READ_BUFFER_SIZE];
            readBufferOffset_ = 0;
            readBufferSize_ = 0;
        }

        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (readBufferOffset_ >= readBufferSize_)
            {
                readBufferSize_ = Min(size_ - position_, READ_BUFFER_SIZE);
                readBufferOffset_ = 0;
                ReadInternal(readBuffer_.Get(), readBufferSize_);
            }

            unsigned copySize = Min((readBufferSize_ - readBufferOffset_), sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }
#endif

    if (compressed_)
    {
        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (!readBuffer_ || readBufferOffset_ >= readBufferSize_)
            {
                unsigned char blockHeaderBytes[4];
                ReadInternal(blockHeaderBytes, sizeof blockHeaderBytes);

                MemoryBuffer blockHeader(&blockHeaderBytes[0], sizeof blockHeaderBytes);
                unsigned unpackedSize = blockHeader.ReadUShort();
                unsigned packedSize = blockHeader.ReadUShort();

                if (!readBuffer_)
                {
                    readBuffer_ = new unsigned char[unpackedSize];
                    inputBuffer_ = new unsigned char[LZ4_compressBound(unpackedSize)];
                }

                /// \todo Handle errors
                ReadInternal(inputBuffer_.Get(), packedSize);
                LZ4_decompress_fast((const char*)inputBuffer_.Get(), (char*)readBuffer_.Get(), unpackedSize);

                readBufferSize_ = unpackedSize;
                readBufferOffset_ = 0;
            }

            unsigned copySize = Min((readBufferSize_ - readBufferOffset_), sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }

    // Need to reassign the position due to internal buffering when transitioning from writing to reading
    if (readSyncNeeded_)
    {
        SeekInternal(position_ + offset_);
        readSyncNeeded_ = false;
    }

    if (!ReadInternal(dest, size))
    {
        // Return to the position where the read began
        SeekInternal(position_ + offset_);
        ATOMIC_LOGERROR("Error while reading from file " + GetName());
        return 0;
    }

    writeSyncNeeded_ = true;
    position_ += size;
    return size;
}
Exemplo n.º 2
0
unsigned File::Read(void* dest, unsigned size)
{
    #ifdef ANDROID
    if (!handle_ && !assetHandle_)
    #else
    if (!handle_)
    #endif
    {
        // Do not log the error further here to prevent spamming the stderr stream
        return 0;
    }

    if (mode_ == FILE_WRITE)
    {
        LOGERROR("File not opened for reading");
        return 0;
    }

    if (size + position_ > size_)
        size = size_ - position_;
    if (!size)
        return 0;

    #ifdef ANDROID
    if (assetHandle_)
    {
        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (readBufferOffset_ >= readBufferSize_)
            {
                readBufferSize_ = Min((int)size_ - position_, (int)READ_BUFFER_SIZE);
                readBufferOffset_ = 0;
                SDL_RWread(assetHandle_, readBuffer_.Get(), readBufferSize_, 1);
            }

            unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }
    #endif
    if (compressed_)
    {
        unsigned sizeLeft = size;
        unsigned char* destPtr = (unsigned char*)dest;

        while (sizeLeft)
        {
            if (!readBuffer_ || readBufferOffset_ >= readBufferSize_)
            {
                unsigned char blockHeaderBytes[4];
                fread(blockHeaderBytes, sizeof blockHeaderBytes, 1, (FILE*)handle_);

                MemoryBuffer blockHeader(&blockHeaderBytes[0], sizeof blockHeaderBytes);
                unsigned unpackedSize = blockHeader.ReadUShort();
                unsigned packedSize = blockHeader.ReadUShort();

                if (!readBuffer_)
                {
                    readBuffer_ = new unsigned char[unpackedSize];
                    inputBuffer_ = new unsigned char[LZ4_compressBound(unpackedSize)];
                }

                /// \todo Handle errors
                fread(inputBuffer_.Get(), packedSize, 1, (FILE*)handle_);
                LZ4_decompress_fast((const char*)inputBuffer_.Get(), (char *)readBuffer_.Get(), unpackedSize);

                readBufferSize_ = unpackedSize;
                readBufferOffset_ = 0;
            }

            unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft);
            memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize);
            destPtr += copySize;
            sizeLeft -= copySize;
            readBufferOffset_ += copySize;
            position_ += copySize;
        }

        return size;
    }

    size_t ret = fread(dest, size, 1, (FILE*)handle_);
    if (ret != 1)
    {
        // Return to the position where the read began
        fseek((FILE*)handle_, position_ + offset_, SEEK_SET);
        LOGERROR("Error while reading from file " + GetName());
        return 0;
    }

    position_ += size;
    return size;
}
Exemplo n.º 3
0
void CADLayer::addHandle( long handle, CADObject::ObjectType type, long cadinserthandle )
{
#ifdef _DEBUG
    cout << "addHandle: " << handle << " type: " << type << endl;
#endif //_DEBUG
    if( type == CADObject::ATTRIB || type == CADObject::ATTDEF )
    {
        unique_ptr<CADAttdef> attdef( static_cast< CADAttdef *>( pCADFile->GetGeometry( this->getId() - 1, handle ) ) );

        attributesNames.insert( attdef->getTag() );
    }

    if( type == CADObject::INSERT )
    {
        // TODO: transform insert to block of objects (do we need to transform
        // coordinates according to insert point)?
        unique_ptr<CADObject> insert( pCADFile->GetObject( handle, false ) );
        CADInsertObject * pInsert = static_cast<CADInsertObject *>(insert.get());
        if( nullptr != pInsert )
        {
            unique_ptr<CADObject> blockHeader( pCADFile->GetObject( pInsert->hBlockHeader.getAsLong(), false ) );
            CADBlockHeaderObject * pBlockHeader = static_cast<CADBlockHeaderObject *>(blockHeader.get());
            if( nullptr != pBlockHeader )
            {
#ifdef _DEBUG
                if( pBlockHeader->bBlkisXRef )
                {
                    assert( 0 );
                }
#endif //_DEBUG
                auto dCurrentEntHandle = pBlockHeader->hEntities[0].getAsLong();
                auto dLastEntHandle    = pBlockHeader->hEntities[pBlockHeader->hEntities.size() -
                                                                 1].getAsLong(); // FIXME: in 2000+ entities probably has no links to each other.

                if( dCurrentEntHandle == dLastEntHandle ) // Blocks can be empty (contain no objects)
                    return;

                while( true )
                {
                    unique_ptr<CADEntityObject> entity( static_cast< CADEntityObject * >(
                                                                pCADFile->GetObject( dCurrentEntHandle, true ) ) );

                    if( dCurrentEntHandle == dLastEntHandle )
                    {
                        if( entity != nullptr )
                        {
                            addHandle( dCurrentEntHandle, entity->getType(), handle );
                            Matrix mat;
                            mat.translate( pInsert->vertInsertionPoint );
                            mat.scale( pInsert->vertScales );
                            mat.rotate( pInsert->dfRotation );
                            transformations[dCurrentEntHandle] = mat;
                            break;
                        } else
                        {
                            assert( 0 );
                        }
                    }

                    if( entity != nullptr )
                    {
                        addHandle( dCurrentEntHandle, entity->getType(), handle );
                        Matrix mat;
                        mat.translate( pInsert->vertInsertionPoint );
                        mat.scale( pInsert->vertScales );
                        mat.rotate( pInsert->dfRotation );
                        transformations[dCurrentEntHandle] = mat;

                        if( entity->stCed.bNoLinks )
                            ++dCurrentEntHandle;
                        else
                            dCurrentEntHandle = entity->stChed.hNextEntity.getAsLong( entity->stCed.hObjectHandle );
                    } else
                    {
                        assert ( 0 );
                    }
                }
            }
        }
        return;
    }

    if( isCommonEntityType( type ) )
    {
        if( type == CADObject::IMAGE )
            imageHandles.push_back( handle );
        else
        {
            if( pCADFile->isReadingUnsupportedGeometries() == false )
            {
                if( isSupportedGeometryType( type ) )
                {
                    if( geometryTypes.size() == 0 ) geometryTypes.push_back( type );

                    if( find( geometryTypes.begin(), geometryTypes.end(), type ) == geometryTypes.end() )
                    {
                        geometryTypes.push_back( type );
                    }
                    geometryHandles.push_back( make_pair( handle, cadinserthandle ) );
                }
            }
            else
            {
                if( geometryTypes.size() == 0 ) geometryTypes.push_back( type );

                if( find( geometryTypes.begin(), geometryTypes.end(), type ) == geometryTypes.end() )
                {
                    geometryTypes.push_back( type );
                }
                geometryHandles.push_back( make_pair( handle, cadinserthandle ) );
            }
        }
    }
}