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.
tdeutils/khexedit/lib/kbigbuffer.cpp

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;
}