Initial checkin. Stolen from BFS and then touched up so no one will notice.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4152 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder
2003-07-31 06:56:12 +00:00
parent 9787066de4
commit e0c62c0f66
@@ -0,0 +1,152 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
// Based on the CachedBlock class from OpenBFS,
// Copyright (c) 2002 Axel Dörfler, [email protected]
//---------------------------------------------------------------------
#ifndef _UDF_CACHED_BLOCK_H
#define _UDF_CACHED_BLOCK_H
/*! \file CachedBlock.h
Based on the CachedBlock class from OpenBFS, written by
Axel Dörfler, [email protected]
*/
extern "C" {
#ifndef _IMPEXP_KERNEL
# define _IMPEXP_KERNEL
#endif
#include <fsproto.h>
#include "lock.h"
#include "cache.h"
}
#include "cpp.h"
#include "UdfDebug.h"
#include "DiskStructures.h"
#include "Volume.h"
namespace Udf {
class CachedBlock {
public:
CachedBlock(Volume *volume);
CachedBlock(Volume *volume, off_t block, bool empty = false);
CachedBlock(CachedBlock *cached);
~CachedBlock();
inline void Keep();
inline void Unset();
inline uint8 *SetTo(off_t block, bool empty = false);
inline uint8 *SetTo(udf_long_address address, bool empty = false);
template <class Accessor, class Descriptor>
inline uint8* SetTo(Accessor &accessor, Descriptor &descriptor,
bool empty = false);
uint8 *Block() const { return fBlock; }
off_t BlockNumber() const { return fBlockNumber; }
uint32 BlockSize() const { return fVolume->BlockSize(); }
uint32 BlockShift() const { return fVolume->BlockShift(); }
private:
CachedBlock(const CachedBlock &); // unimplemented
CachedBlock &operator=(const CachedBlock &); // unimplemented
protected:
Volume *fVolume;
off_t fBlockNumber;
uint8 *fBlock;
};
inline
CachedBlock::CachedBlock(Volume *volume)
:
fVolume(volume),
fBlock(NULL)
{
}
inline
CachedBlock::CachedBlock(Volume *volume, off_t block, bool empty = false)
:
fVolume(volume),
fBlock(NULL)
{
SetTo(block, empty);
}
inline
CachedBlock::CachedBlock(CachedBlock *cached)
: fVolume(cached->fVolume)
, fBlockNumber(cached->BlockNumber())
, fBlock(cached->fBlock)
{
cached->Keep();
}
inline
CachedBlock::~CachedBlock()
{
Unset();
}
inline void
CachedBlock::Keep()
{
fBlock = NULL;
}
inline void
CachedBlock::Unset()
{
DEBUG_INIT(CF_HIGH_VOLUME | CF_PUBLIC, "CachedBlock");
if (fBlock) {
PRINT(("releasing block #%lld\n", BlockNumber()));
release_block(fVolume->Device(), fBlockNumber);
} else {
PRINT(("no block to release\n"));
}
}
inline uint8 *
CachedBlock::SetTo(off_t block, bool empty = false)
{
DEBUG_INIT_ETC(CF_HIGH_VOLUME | CF_PUBLIC, "CachedBlock", ("block: %lld, empty: %s",
block, (empty ? "true" : "false")));
Unset();
fBlockNumber = block;
PRINT(("getting block #%lld\n", block));
return fBlock = empty ? (uint8 *)get_empty_block(fVolume->Device(), block, BlockSize())
: (uint8 *)get_block(fVolume->Device(), block, BlockSize());
}
inline uint8 *
CachedBlock::SetTo(udf_long_address address, bool empty = false)
{
off_t block;
if (fVolume->MapBlock(address, &block) == B_OK)
return SetTo(block, empty);
else
return NULL;
}
template <class Accessor, class Descriptor>
inline uint8*
CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor, bool empty = false)
{
// Make a udf_long_address out of the descriptor and call it a day
udf_long_address address;
address.set_to(accessor.GetBlock(descriptor),
accessor.GetPartition(descriptor));
return SetTo(address, empty);
}
}; // namespace Udf
#endif // _UDF_CACHED_BLOCK_H