* Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com
* Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net
* Copyright 2002-2020, Axel DΓΆrfler, axeld@pinc-software.de
* Distributed under the terms of the MIT License.
*/
#ifndef _UDF_CACHED_BLOCK_H
#define _UDF_CACHED_BLOCK_H
Based on the CachedBlock class from BFS, written by
Axel DΓΆrfler, axeld@pinc-software.de
*/
#include <fs_cache.h>
#include <util/kernel_cpp.h>
#include "UdfDebug.h"
#include "UdfStructures.h"
#include "Volume.h"
class CachedBlock {
public:
CachedBlock(Volume *volume);
CachedBlock(CachedBlock *cached);
~CachedBlock();
uint8 *Block() const { return fBlock; }
off_t BlockNumber() const { return fBlockNumber; }
uint32 BlockSize() const { return fVolume->BlockSize(); }
uint32 BlockShift() const { return fVolume->BlockShift(); }
inline void Keep();
inline void Unset();
inline status_t SetTo(off_t block);
inline status_t SetTo(long_address address);
template <class Accessor, class Descriptor>
inline status_t SetTo(Accessor &accessor,
Descriptor &descriptor);
protected:
uint8 *fBlock;
off_t fBlockNumber;
Volume *fVolume;
};
inline
CachedBlock::CachedBlock(Volume *volume)
:
fBlock(NULL),
fBlockNumber(0),
fVolume(volume)
{
}
inline
CachedBlock::CachedBlock(CachedBlock *cached)
:
fBlock(cached->fBlock),
fBlockNumber(cached->BlockNumber()),
fVolume(cached->fVolume)
{
cached->Keep();
}
inline
CachedBlock::~CachedBlock()
{
Unset();
}
inline void
CachedBlock::Keep()
{
fBlock = NULL;
}
inline void
CachedBlock::Unset()
{
if (fBlock != NULL) {
block_cache_put(fVolume->BlockCache(), fBlockNumber);
fBlock = NULL;
}
}
inline status_t
CachedBlock::SetTo(off_t block)
{
Unset();
fBlockNumber = block;
return block_cache_get_etc(fVolume->BlockCache(), block,
(const void**)&fBlock);
}
inline status_t
CachedBlock::SetTo(long_address address)
{
off_t block;
if (fVolume->MapBlock(address, &block) == B_OK)
return SetTo(block);
return B_BAD_VALUE;
}
template <class Accessor, class Descriptor>
inline status_t
CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor)
{
long_address address;
address.set_to(accessor.GetBlock(descriptor),
accessor.GetPartition(descriptor));
return SetTo(address);
}
#endif