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(off_t block, off_t base, size_t length); 40 inline status_t SetTo(long_address address); 41 template <class Accessor, class Descriptor> 42 inline status_t SetTo(Accessor &accessor, 43 Descriptor &descriptor); 44 45 protected: 46 uint8 *fBlock; 47 off_t fBlockNumber; 48 Volume *fVolume; 49 }; 50 51 52 inline 53 CachedBlock::CachedBlock(Volume *volume) 54 : 55 fBlock(NULL), 56 fBlockNumber(0), 57 fVolume(volume) 58 { 59 } 60 61 62 inline 63 CachedBlock::CachedBlock(CachedBlock *cached) 64 : 65 fBlock(cached->fBlock), 66 fBlockNumber(cached->BlockNumber()), 67 fVolume(cached->fVolume) 68 { 69 cached->Keep(); 70 } 71 72 73 inline 74 CachedBlock::~CachedBlock() 75 { 76 Unset(); 77 } 78 79 80 inline void 81 CachedBlock::Keep() 82 { 83 fBlock = NULL; 84 } 85 86 87 inline void 88 CachedBlock::Unset() 89 { 90 if (fBlock != NULL) { 91 block_cache_put(fVolume->BlockCache(), fBlockNumber); 92 fBlock = NULL; 93 } 94 } 95 96 97 inline status_t 98 CachedBlock::SetTo(off_t block) 99 { 100 return SetTo(block, block, 1); 101 } 102 103 104 inline status_t 105 CachedBlock::SetTo(off_t block, off_t base, size_t length) 106 { 107 Unset(); 108 fBlockNumber = block; 109 return block_cache_get_etc(fVolume->BlockCache(), block, base, length, 110 (const void**)&fBlock); 111 } 112 113 114 inline status_t 115 CachedBlock::SetTo(long_address address) 116 { 117 off_t block; 118 if (fVolume->MapBlock(address, &block) == B_OK) 119 return SetTo(block, block, 1); 120 121 return B_BAD_VALUE; 122 } 123 124 125 template <class Accessor, class Descriptor> 126 inline status_t 127 CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor) 128 { 129 // Make a long_address out of the descriptor and call it a day 130 long_address address; 131 address.set_to(accessor.GetBlock(descriptor), 132 accessor.GetPartition(descriptor)); 133 return SetTo(address); 134 } 135 136 137 #endif // _UDF_CACHED_BLOCK_H 138