rubidium@6751: /* $Id$ */ richk@6739: richk@6739: /** @file FSMblockmap.h Definition of FSMblockmap class for use in state machines*/ richk@6739: richk@6739: #ifndef FSMBLOCKMAP_H richk@6739: #define FSMBLOCKMAP_H richk@6739: richk@6739: #include "stdafx.h" richk@6739: rubidium@6751: uint64 inline GetBlockAsBits(byte blocknumber) richk@6739: { richk@6739: if (blocknumber == 0) return 0ULL; richk@6739: if (blocknumber > 63) blocknumber -= 64; richk@6739: uint64 result = 1ULL << blocknumber; richk@6739: return result; richk@6739: } richk@6739: richk@6739: /** richk@6739: * This class provides functions and internal storage for blockmaps used in Finite State Machine richk@6739: * richk@6739: */ richk@6739: struct FSMblockmap { richk@6739: public: rubidium@6751: void inline ResetAll() richk@6739: { richk@6739: block_lower = 0x0000000000000000; richk@6739: block_upper = 0x0000000000000000; richk@6739: }; richk@6739: rubidium@6751: void Initialise(const byte *blocklist, int num_bytes) richk@6739: { richk@6739: ResetAll(); richk@6739: for (int i = 0; i < num_bytes; i++) richk@6739: { richk@6739: if (blocklist[i] < 64) { richk@6739: block_lower |= GetBlockAsBits(blocklist[i]); richk@6739: } else { richk@6739: block_upper |= GetBlockAsBits(blocklist[i]); richk@6739: } richk@6739: } richk@6739: } richk@6739: rubidium@6751: uint64 inline GetLower() const richk@6739: { richk@6739: return block_lower; richk@6739: } richk@6739: rubidium@6751: uint64 inline GetUpper() const richk@6739: { richk@6739: return block_upper; richk@6739: } rubidium@6751: rubidium@6751: void inline ReserveBlocks(const FSMblockmap *blockmap) richk@6739: { richk@6739: /* OR with blockmap to reserve blocks */ richk@6739: block_lower |= blockmap->GetLower(); richk@6739: block_upper |= blockmap->GetUpper(); richk@6739: } richk@6739: rubidium@6751: void inline ReleaseBlocks(const FSMblockmap *blockmap) richk@6739: { richk@6739: /* AND with ones-complement to clear set bits in blockmap from block_lower and block_upper */ richk@6739: block_lower &= ~blockmap->GetLower(); richk@6739: block_upper &= ~blockmap->GetUpper(); richk@6739: } richk@6739: rubidium@6751: bool inline BlocksAreFree(const FSMblockmap *blockmap) const richk@6739: { richk@6739: uint64 test_lower = blockmap->GetLower(); richk@6739: uint64 test_upper = blockmap->GetUpper(); richk@6739: richk@6739: if ((~block_lower & test_lower) != test_lower) return false; richk@6739: if ((~block_upper & test_upper) != test_upper) return false; richk@6739: richk@6739: return true; richk@6739: } richk@6739: rubidium@6751: bool inline HasBlocks(const FSMblockmap *blockmap) const richk@6739: { richk@6739: uint64 test_lower = blockmap->GetLower(); richk@6739: uint64 test_upper = blockmap->GetUpper(); richk@6739: richk@6739: if ((block_lower & test_lower) != test_lower) return false; richk@6739: if ((block_upper & test_upper) != test_upper) return false; richk@6739: richk@6739: return true; richk@6739: } richk@6739: rubidium@6751: bool inline HasBlock(byte blocknumber) const richk@6739: { rubidium@6751: FSMblockmap test_blockmap; rubidium@6751: test_blockmap.Initialise(&blocknumber, 1); rubidium@6751: return HasBlocks(&test_blockmap); richk@6739: } richk@6739: richk@6739: //bool inline HasBlock(byte blocknumber) richk@6739: //{ richk@6739: // uint64 test_block = GetBlockAsBits(blocknumber); richk@6739: // if (blocknumber < 64) return ((block_lower & test_block) == test_block); richk@6739: // return ((block_upper & test_block) == test_block); richk@6739: //} richk@6739: rubidium@6751: bool inline IsNotZero(void) const richk@6739: { richk@6739: return ((block_lower != 0) || (block_upper != 0)); richk@6739: } richk@6739: rubidium@6751: void PrintBlock(bool newline = true) const; rubidium@6751: richk@6739: private: richk@6739: uint64 block_lower; richk@6739: uint64 block_upper; richk@6739: }; richk@6739: rubidium@6751: FSMblockmap* SetFSMSingleBlock(const byte *blocklist); richk@6739: richk@6739: #endif /* FSMBLOCKMAP_H */