1 /* 2 * Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com 3 * Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net 4 * Copyright 2002-2020, Axel Dörfler, axeld@pinc-software.de 5 * Distributed under the terms of the MIT License. 6 */ 7 #ifndef _UDF_CACHED_BLOCK_H 8 #define _UDF_CACHED_BLOCK_H 9 10 /*! \file CachedBlock.h 11 12 Based on the CachedBlock class from BFS, written by 13 Axel Dörfler, axeld@pinc-software.de 14 */ 15 16 #include <fs_cache.h> 17 #include <util/kernel_cpp.h> 18 19 #include "UdfDebug.h" 20 #include "UdfStructures.h" 21 #include "Volume.h" 22 23 24 class CachedBlock { 25 public: 26 CachedBlock(Volume *volume); 27 CachedBlock(CachedBlock *cached); 28 ~CachedBlock(); 29 30 uint8 *Block() const { return fBlock; } 31 off_t BlockNumber() const { return fBlockNumber; } 32 uint32 BlockSize() const { return fVolume->BlockSize(); } 33 uint32 BlockShift() const { return fVolume->BlockShift(); } 34 35 inline void Keep(); 36 inline void Unset(); 37 38 inline status_t SetTo(off_t block); 39 inline status_t SetTo(long_address address); 40 template <class Accessor, class Descriptor> 41 inline status_t SetTo(Accessor &accessor, 42 Descriptor &descriptor); 43 44 protected: 45 uint8 *fBlock; 46 off_t fBlockNumber; 47 Volume *fVolume; 48 }; 49 50 51 inline 52 CachedBlock::CachedBlock(Volume *volume) 53 : 54 fBlock(NULL), 55 fBlockNumber(0), 56 fVolume(volume) 57 { 58 } 59 60 61 inline 62 CachedBlock::CachedBlock(CachedBlock *cached) 63 : 64 fBlock(cached->fBlock), 65 fBlockNumber(cached->BlockNumber()), 66 fVolume(cached->fVolume) 67 { 68 cached->Keep(); 69 } 70 71 72 inline 73 CachedBlock::~CachedBlock() 74 { 75 Unset(); 76 } 77 78 79 inline void 80 CachedBlock::Keep() 81 { 82 fBlock = NULL; 83 } 84 85 86 inline void 87 CachedBlock::Unset() 88 { 89 if (fBlock != NULL) { 90 block_cache_put(fVolume->BlockCache(), fBlockNumber); 91 fBlock = NULL; 92 } 93 } 94 95 96 inline status_t 97 CachedBlock::SetTo(off_t block) 98 { 99 Unset(); 100 fBlockNumber = block; 101 return block_cache_get_etc(fVolume->BlockCache(), block, 102 (const void**)&fBlock); 103 } 104 105 106 inline status_t 107 CachedBlock::SetTo(long_address address) 108 { 109 off_t block; 110 if (fVolume->MapBlock(address, &block) == B_OK) 111 return SetTo(block); 112 113 return B_BAD_VALUE; 114 } 115 116 117 template <class Accessor, class Descriptor> 118 inline status_t 119 CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor) 120 { 121 // Make a long_address out of the descriptor and call it a day 122 long_address address; 123 address.set_to(accessor.GetBlock(descriptor), 124 accessor.GetPartition(descriptor)); 125 return SetTo(address); 126 } 127 128 129 #endif // _UDF_CACHED_BLOCK_H 130