1//---------------------------------------------------------------------- 2// This software is part of the OpenBeOS distribution and is covered 3// by the OpenBeOS license. 4// 5// Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net 6// Based on the CachedBlock class from OpenBFS, 7// Copyright (c) 2002 Axel D��rfler, axeld@pinc-software.de 8//--------------------------------------------------------------------- 9#ifndef _UDF_CACHED_BLOCK_H 10#define _UDF_CACHED_BLOCK_H 11 12/*! \file CachedBlock.h 13 14 Based on the CachedBlock class from OpenBFS, written by 15 Axel D��rfler, axeld@pinc-software.de 16*/ 17 18#ifdef COMPILE_FOR_R5 19extern "C" { 20#endif 21 #include "fsproto.h" 22#ifdef COMPILE_FOR_R5 23} 24#endif 25 26extern "C" { 27 #ifndef _IMPEXP_KERNEL 28 # define _IMPEXP_KERNEL 29 #endif 30 31 #include "lock.h" 32 #include "cache.h" 33} 34 35#include "kernel_cpp.h" 36#include "UdfDebug.h" 37 38#include "UdfStructures.h" 39#include "Volume.h" 40 41namespace Udf { 42 43class CachedBlock { 44 public: 45 CachedBlock(Volume *volume); 46 CachedBlock(Volume *volume, off_t block, bool empty = false); 47 CachedBlock(CachedBlock *cached); 48 ~CachedBlock(); 49 50 inline void Keep(); 51 inline void Unset(); 52 inline uint8 *SetTo(off_t block, bool empty = false); 53 inline uint8 *SetTo(long_address address, bool empty = false); 54 template <class Accessor, class Descriptor> 55 inline uint8* SetTo(Accessor &accessor, Descriptor &descriptor, 56 bool empty = false); 57 58 uint8 *Block() const { return fBlock; } 59 off_t BlockNumber() const { return fBlockNumber; } 60 uint32 BlockSize() const { return fVolume->BlockSize(); } 61 uint32 BlockShift() const { return fVolume->BlockShift(); } 62 63 private: 64 CachedBlock(const CachedBlock &); // unimplemented 65 CachedBlock &operator=(const CachedBlock &); // unimplemented 66 67 protected: 68 Volume *fVolume; 69 off_t fBlockNumber; 70 uint8 *fBlock; 71}; 72 73inline 74CachedBlock::CachedBlock(Volume *volume) 75 : 76 fVolume(volume), 77 fBlock(NULL) 78{ 79} 80 81inline 82CachedBlock::CachedBlock(Volume *volume, off_t block, bool empty = false) 83 : 84 fVolume(volume), 85 fBlock(NULL) 86{ 87 SetTo(block, empty); 88} 89 90inline 91CachedBlock::CachedBlock(CachedBlock *cached) 92 : fVolume(cached->fVolume) 93 , fBlockNumber(cached->BlockNumber()) 94 , fBlock(cached->fBlock) 95{ 96 cached->Keep(); 97} 98 99inline 100CachedBlock::~CachedBlock() 101{ 102 Unset(); 103} 104 105inline void 106CachedBlock::Keep() 107{ 108 fBlock = NULL; 109} 110 111inline void 112CachedBlock::Unset() 113{ 114 DEBUG_INIT("CachedBlock"); 115 if (fBlock) { 116 PRINT(("releasing block #%Ld\n", BlockNumber())); 117 release_block(fVolume->Device(), fBlockNumber); 118 } else { 119 PRINT(("no block to release\n")); 120 } 121} 122 123inline uint8 * 124CachedBlock::SetTo(off_t block, bool empty = false) 125{ 126 DEBUG_INIT_ETC("CachedBlock", ("block: %Ld, empty: %s", 127 block, (empty ? "true" : "false"))); 128 Unset(); 129 fBlockNumber = block; 130 PRINT(("getting block #%Ld\n", block)); 131 return fBlock = empty ? (uint8 *)get_empty_block(fVolume->Device(), block, BlockSize()) 132 : (uint8 *)get_block(fVolume->Device(), block, BlockSize()); 133} 134 135inline uint8 * 136CachedBlock::SetTo(long_address address, bool empty = false) 137{ 138 off_t block; 139 if (fVolume->MapBlock(address, &block) == B_OK) 140 return SetTo(block, empty); 141 else 142 return NULL; 143} 144 145template <class Accessor, class Descriptor> 146inline uint8* 147CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor, bool empty = false) 148{ 149 // Make a long_address out of the descriptor and call it a day 150 long_address address; 151 address.set_to(accessor.GetBlock(descriptor), 152 accessor.GetPartition(descriptor)); 153 return SetTo(address, empty); 154} 155 156}; // namespace Udf 157 158#endif // _UDF_CACHED_BLOCK_H 159 160