You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.1 KiB
217 lines
5.1 KiB
/***************************************************************************
|
|
kbigbuffer.cpp - description
|
|
-------------------
|
|
begin : Mit Jun 02 2003
|
|
copyright : (C) 2003 by Friedrich W. H. Kossebau
|
|
email : Friedrich.W.H@Kossebau.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License version 2 as published by the Free Software Foundation. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
// c specific
|
|
#include <stdlib.h>
|
|
// lib specific
|
|
#include "kbigbuffer.h"
|
|
|
|
using namespace KHE;
|
|
|
|
KBigBuffer::KBigBuffer( int NP, int PS )
|
|
: NoOfUsedPages( NP ),
|
|
NoOfFreePages( NP ),
|
|
PageSize( PS ),
|
|
FirstPage( -1 ),
|
|
LastPage( -1 ),
|
|
Size( 0 )
|
|
{
|
|
IsOpen = false;
|
|
|
|
// if( !filename.empty() )
|
|
// open(filename);
|
|
}
|
|
|
|
|
|
KBigBuffer::~KBigBuffer()
|
|
{
|
|
if( File.isOpen() )
|
|
close();
|
|
}
|
|
|
|
|
|
|
|
bool KBigBuffer::prepareRange( KSection /*Range*/ ) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
const char *KBigBuffer::dataSet( KSection /*Section*/ ) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
char KBigBuffer::datum( unsigned int DatumOffset ) const
|
|
{
|
|
// std::cout << "reading datum " << DatumOffset << std::endl;
|
|
int OffsetInPage = DatumOffset - OffsetOfActualPage;
|
|
// there shouldn't be any need to check l
|
|
if( OffsetInPage >= 0 && OffsetInPage < (int)PageSize )
|
|
return ActualPage[OffsetInPage];
|
|
|
|
// load the page
|
|
unsigned int PageIndex = DatumOffset / PageSize;
|
|
ensurePageLoaded( PageIndex );
|
|
return ActualPage[DatumOffset-OffsetOfActualPage];
|
|
}
|
|
|
|
|
|
|
|
|
|
int KBigBuffer::insert( int /*Pos*/, const char*, int /*Length*/ )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int KBigBuffer::remove( KSection /*Section*/ )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
unsigned int KBigBuffer::replace( KSection /*Section*/, const char*, unsigned int /*Length*/ )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int KBigBuffer::fill( char /*FillChar*/, int /*Length*/, unsigned int /*Pos*/ )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
int KBigBuffer::move( int /*DestPos*/, KSection /*SourceSection*/ ) { return 0; }
|
|
//int KBigBuffer::find( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
|
|
int KBigBuffer::find( const char*/*KeyData*/, int /*Length*/, KSection /*Section*/ ) const { return 0; }
|
|
|
|
int KBigBuffer::rfind( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
|
|
|
|
|
|
|
|
bool KBigBuffer::open( const TQString& FileName )
|
|
{
|
|
// clear old data
|
|
if( isOpen() && !close() ) // only occurs if close somehow fails.
|
|
return false;
|
|
|
|
File.setName( FileName );
|
|
if( !File.open(IO_ReadOnly|IO_Raw) )
|
|
return false;
|
|
|
|
// std::cout << "loading file " << FileName << std::endl;
|
|
|
|
int FileSize = File.size();
|
|
Size = FileSize;
|
|
|
|
// calculate necessary number of pages
|
|
int NoOfPages = FileSize/PageSize + 1;
|
|
|
|
// initialize Page pointers
|
|
Data.resize( NoOfPages );
|
|
for( KPageOfChar::iterator D=Data.begin(); D!=Data.end(); ++D )
|
|
*D = 0;
|
|
|
|
FirstPage = LastPage = 0;
|
|
|
|
return ensurePageLoaded( 0 );
|
|
}
|
|
|
|
|
|
bool KBigBuffer::close()
|
|
{
|
|
if( !isOpen() )
|
|
return false;
|
|
|
|
File.close();
|
|
|
|
if( File.status() == IO_UnspecifiedError )
|
|
return false;
|
|
|
|
// std::cout << "closing file " << std::endl;
|
|
|
|
// free pages
|
|
for( KPageOfChar::iterator D=Data.begin(); D!=Data.end(); ++D )
|
|
delete [] *D;
|
|
|
|
FirstPage = LastPage = -1;
|
|
NoOfFreePages = NoOfUsedPages;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool KBigBuffer::ensurePageLoaded( unsigned int PageIndex ) const
|
|
{
|
|
if( !isOpen() )
|
|
return false;
|
|
// page loaded?
|
|
if( Data[PageIndex] != 0 )
|
|
{
|
|
ActualPage = Data[PageIndex];
|
|
OffsetOfActualPage = PageIndex * PageSize;
|
|
return true;
|
|
}
|
|
|
|
// no page available?
|
|
if( NoOfFreePages < 1 )
|
|
{
|
|
// free the page which is the furthest away from the page we are loading
|
|
if( labs(FirstPage-PageIndex) > labs(LastPage-PageIndex) )
|
|
while( !freePage(FirstPage++) );
|
|
else
|
|
while( !freePage(LastPage--) );
|
|
}
|
|
|
|
// std::cout << "loading page " << PageIndex << std::endl;
|
|
// create Page
|
|
Data[PageIndex] = new char[PageSize];
|
|
--NoOfFreePages;
|
|
|
|
// jump to position and read the page's data in
|
|
bool Success = File.at( (unsigned long)(PageIndex*PageSize) );
|
|
if( Success )
|
|
Success = File.readBlock( Data[PageIndex], PageSize ) > 0;
|
|
|
|
if( Success )
|
|
{
|
|
// correct bounds
|
|
if( (int)PageIndex < FirstPage )
|
|
FirstPage = PageIndex;
|
|
|
|
if( (int)PageIndex > LastPage )
|
|
LastPage = PageIndex;
|
|
|
|
ActualPage = Data[PageIndex];
|
|
OffsetOfActualPage = PageIndex * PageSize;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
|
|
bool KBigBuffer::freePage( unsigned int PageIndex ) const
|
|
{
|
|
// check range and if is loaded at all
|
|
if( (unsigned int)PageIndex >= Data.size() || !Data[PageIndex] )
|
|
return false;
|
|
// std::cout << "freeing page " << PageIndex << std::endl;
|
|
delete [] Data[PageIndex];
|
|
Data[PageIndex] = 0;
|
|
++NoOfFreePages;
|
|
return true;
|
|
}
|