Example #1
0
int AL_PROTO ALCompressedObject::Insert( ALStorage AL_DLL_FAR &input_object )
{
    AL_ASSERT_OBJECT( this, ALCompressedObject, "Insert" );
    AL_ASSERT_OBJECT( &input_object, ALStorage, "Insert" );
    if ( mStatus < AL_SUCCESS )
        return mStatus;
//
// Here is where we open the input and the output.  
//
    ALOpenFiles files( input_object, *mpStorageObject );
//
// We first write out the uncompressed size, which we already know.  We
// then save the current position, and write placeholder longs out for
// what will become the compressed size and the CRC-32.
//
    mpStorageObject->WritePortableLong( input_object.GetSize() );
    long saved_pos = mpStorageObject->Tell();
    mpStorageObject->WritePortableLong( 0xfedcba98L ); //Temporary
    mpStorageObject->WritePortableLong( 0x01234567L );  //Temporary
//
// If a derived class has any header data to write out, this is where it
// will be performed.  The base class writes 0 bytes here.
//
    WriteHeaderData( &input_object );
    long start = mpStorageObject->Tell();
//
// Next, perform the compression.  Once that is done we can calculate
// the compressed size.  The CRC-32 will have been calculated on the fly
// as the compression was performed.
//
    mpCompressionEngine->Compress( input_object, *mpStorageObject );
    long compressed_size = mpStorageObject->Tell() - start;
    if ( mpCompressionEngine->mStatus < 0 )
        return mStatus = mpCompressionEngine->mStatus;
//
// Go back to the spot we remembered, and write out the compressed
// size and the CRC. At that point, the compressed object is complete.
//
    mpStorageObject->Seek( saved_pos );
    mpStorageObject->WritePortableLong( compressed_size );
    mpStorageObject->WritePortableLong( ~input_object.GetCrc32() );
    if ( mpStorageObject->mStatus < 0 )
        return mStatus = mpStorageObject->mStatus;
    return AL_SUCCESS;
}
Example #2
0
/* CheckpointHeader
   The header lives in its own file, so we can write it at any point we
   have a valid archive.
   This includes all the tables, as well as basic header info.
*/
bool trpgwArchive::CheckpointHeader()
{
    trpgMemWriteBuffer buf(ness);

    if (!isValid())
        return false;

    if (!header.isValid())
    {
        if(header.getErrMess())
            strcpy(errMess, header.getErrMess());
        return false;
    }

    // This will close the appendable files
    if (tileFile) {
        tileFile->Flush();
    }

    /* Build a Tile Table
       We need to build one from scratch here.  However,
       we have all the relevant information collected during
       the WriteTile calls.
    */


    if(header.GetIsLocal()) {
        int row = 0;
        int col = 0;
        header.GetBlocks(row,col);
        tileTable.SetCurrentBlock(row,col,true);
    }
    if (tileMode == TileExternal) {
        // External tiles are easy
        tileTable.SetMode(trpgTileTable::External);
    } else if( tileMode == TileExternalSaved) {
   
        if(!isRegenerate && firstHeaderWrite)
        {
            // Set up the sizes
            tileTable.SetMode(trpgTileTable::ExternalSaved);
            tileTable.SetNumLod(1);
            trpg2iPoint lodSize;
            header.GetLodSize(0,lodSize);
            tileTable.SetNumTiles(lodSize.x, lodSize.y, 0);
            firstHeaderWrite = false;
        }

        // Now set the individual tile locations
        for (unsigned int i=0;i<externalTiles.size();i++) {
            TileFileEntry &te = externalTiles[i];
            trpgwAppAddress addr;
            addr.file = -1;
            addr.offset = -1;
            tileTable.SetTile(te.x,te.y,te.lod,addr,te.zmin,te.zmax);
        }

        externalTiles.clear();

    } else {
        if (!isRegenerate && firstHeaderWrite) {

            // Local tiles require more work
            tileTable.SetMode(trpgTileTable::Local);

            if(majorVersion == 2 && minorVersion >= 1)
            {
                // Version 2.1, we store only lod 0 in the tile table

                // Set up the sizes
                tileTable.SetNumLod(1);
                trpg2iPoint lodSize;
                header.GetLodSize(0,lodSize);
                tileTable.SetNumTiles(lodSize.x, lodSize.y, 0);
             
            }
            else
            {

                // Set up the sizes
                int32 numLod;
                header.GetNumLods(numLod);
                tileTable.SetNumLod(numLod);
                for (int i=0;i<numLod;i++) {
                    trpg2iPoint lodSize;
                    header.GetLodSize(i,lodSize);
                    tileTable.SetNumTiles(lodSize.x,lodSize.y,i);
                }
			   
            }
            firstHeaderWrite = false;
        }
   

        // Now set the individual tile locations
        // Nothing special need to be done with version 2.1 since
        // only tile with lod 0 will be found in the tileFiles container
        for (unsigned int i=0;i<tileFiles.size();i++) {
            TileFile &tf = tileFiles[i];
            for (unsigned int j=0;j<tf.tiles.size();j++) {
                TileFileEntry &te = tf.tiles[j];
                trpgwAppAddress addr;
                addr.file = tf.id;
                addr.offset = te.offset;
                tileTable.SetTile(te.x,te.y,te.lod,addr,te.zmin,te.zmax);
            }

            tf.tiles.clear();
	         
         
        }
    }
   

    // Write all the headers into a buffer
    if (!header.Write(buf))
        return false;

    // Do the mat table and texture table
    // These can be different depending on the version
    switch (majorVersion) {
    case 1:
    {
        trpgMatTable1_0 matTable1_0(matTable);
        trpgTexTable1_0 texTable1_0(texTable);
        trpgTileTable1_0 tileTable1_0(tileTable);

        if (!matTable1_0.Write(buf) ||
            !texTable1_0.Write(buf) ||
            !modelTable.Write(buf) ||
            !tileTable1_0.Write(buf) ||
            !lightTable.Write(buf) ||
            !rangeTable.Write(buf))
            return false;
    }
    break;
    case 2:
        if(!header.GetIsMaster()||texTable.isValid()) {
            if(!texTable.Write(buf))
            {
                strcpy(errMess, "Error writing texture table");
                if(texTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, texTable.getErrMess());
                    return false;
                }
            }
        }
        //These tables will not be populated if this is the master table.
        if(!header.GetIsMaster()) {
            if (!matTable.Write(buf))
            {
                strcpy(errMess, "Error writing material table");
                if(matTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, matTable.getErrMess());
                    return false;
                }
            }
		
			
            if(!modelTable.Write(buf) )
            {
                strcpy(errMess, "Error writing model table");
                if(modelTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, modelTable.getErrMess());
                    return false;
                }
            }
        }
        //always write the tile table, even if we are a master
        if(!tileTable.Write(buf))
        {
            strcpy(errMess, "Error writing tile table");
            if(tileTable.getErrMess())
            {
                strcat(errMess, ": ");
                strcat(errMess, tileTable.getErrMess());
                return false;
            }
        }
        if(!header.GetIsMaster()) {
            if(!lightTable.Write(buf))
            {
                strcpy(errMess, "Error writing light table");
                if(lightTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, lightTable.getErrMess());
                    return false;
                }
            }
            if(!rangeTable.Write(buf))
            {
                strcpy(errMess, "Error writing range table");
                if(rangeTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, rangeTable.getErrMess());
                    return false;
                }
            }
            if (!textStyleTable.Write(buf))
            {
                strcpy(errMess,"Error writing text style table");
                if (textStyleTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, textStyleTable.getErrMess());
                    return false;
                }
            }
            if (!supportStyleTable.Write(buf))
            {
                strcpy(errMess,"Error writing support style table");
                if (supportStyleTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, supportStyleTable.getErrMess());
                    return false;
                }
            }
            if (!labelPropertyTable.Write(buf))
            {
                strcpy(errMess,"Error writing label property table");
                if (labelPropertyTable.getErrMess())
                {
                    strcat(errMess, ": ");
                    strcat(errMess, labelPropertyTable.getErrMess());
                    return false;
                }
            }
        }
	break;
    }

    // Write the disk header
    int32 magic = GetMagicNumber();
    if (ness != cpuNess)
        magic = trpg_byteswap_int(magic);
    if (fwrite(&magic,sizeof(int32),1,fp) != 1)
    {
        strcpy(errMess, "Could not write the magic number");
        return false;
    }

    // Write the header length
    int32 headerSize = buf.length();
    int headLen = headerSize;
    if (ness != cpuNess)
        headerSize = trpg_byteswap_int(headerSize);
    if (fwrite(&headerSize,1,sizeof(int32),fp) != sizeof(int32))
    {
        strcpy(errMess, "Could not write the header size");
        return false;
    }

    // Write the buffer
    const char *data = buf.getData();

    if (WriteHeaderData(data,headLen,fp) != headLen)
    {
        strcpy(errMess, "Could not write the buffer");
        return false;
    }

    // Note: Not sure what this is
    char space[40];
    if (fwrite(space,1,4,fp) != 4)
        return false;

    // Flush output
    fflush(fp);
    // Head back to the start of the file
    rewind(fp);

    return true;
}