Add class to handle volume bitmap

git-svn-id: https://profuse.googlecode.com/svn/trunk@58 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
ksherlock 2009-09-04 22:16:00 +00:00
parent d296abe203
commit 4360263a1a
2 changed files with 123 additions and 0 deletions

66
Bitmap.cpp Normal file
View File

@ -0,0 +1,66 @@
#include "Bitmap.h"
#include <cstring>
namespace ProDOS {
/*
*
*
*
*/
Bitmap::Bitmap(unsigned blocks) :
_bitmap(NULL), _blocks(blocks),
_bitmapSize((blocks + 4096 - 1) >> 12)
{
// 1 block = 512 bytes = 4096 bits
_bitmap = new uint8_t[_bitmapSize];
// mark every requested block as free.
unsigned bytes = blocks >> 3;
std::memset(_bitmap, 0xff, bytes);
// all trailing blocks are marked as used.
std::memset(_bitmap + bytes, 0x00, _bitmapSize - bytes);
// and handle the edge case...
/*
* 0 -> 0 0 0 0 0 0 0 0
* 1 -> 1 0 0 0 0 0 0 0
* 2 -> 1 1 0 0 0 0 0 0
* 3 -> 1 1 1 0 0 0 0 0
* ...
* 7 -> 1 1 1 1 1 1 1 0
*/
//unsigned tmp = (1 << (8 - (blocks & 0x07))) - 1;
//_bitmap[bytes] = ~tmp & 0xff;
_bitmap[bytes] = 0 - (1 << (8 - (blocks & 0x07)));
//_bitmap[bytes] = (0xff00 >> (blocks & 0x07)) & 0xff;
}
Bitmap::~Bitmap()
{
delete[] _bitmap;
}
bool Bitmap::markBlock(unsigned block, bool inUse)
{
if (block >= _blocks) return false;
unsigned index = BlockIndex(block);
unsigned mask = BlockMask(block);
uint8_t data = _bitmap[index];
if (inUse) data &= ~mask;
else data |= mask;
_bitmap[index] = data;
return true;
}
} // namespace

57
Bitmap.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef __PRODOS_BITMAP_H__
#define __PRODOS_BITMAP_H__
#include <stdint.h>
namespace ProDOS {
class Bitmap {
public:
Bitmap(unsigned blocks);
~Bitmap();
bool blockFree(unsigned block) const;
bool markBlock(unsigned block, bool inUse);
unsigned blocks() const;
unsigned bitmapBlocks() const;
private:
static unsigned BlockMask(unsigned block);
static unsigned BlockIndex(unsigned block);
uint8_t *_bitmap;
unsigned _blocks;
unsigned _bitmapSize;
};
inline unsigned Bitmap::blocks() const
{
return _blocks;
}
inline unsigned Bitmap::bitmapBlocks() const
{
return _bitmapSize >> 12;
}
inline unsigned Bitmap::BlockMask(unsigned block)
{
return 0x80 >> (block & 0x07);
}
inline unsigned Bitmap::BlockIndex(unsigned block)
{
return block >> 3;
}
inline bool Bitmap::blockFree(unsigned block) const
{
if (block >= _blocks) return false;
return (_bitmap[BlockIndex(block)] & BlockMask(block)) != 0;
}
} // namespace
#endif