xref: /haiku/src/add-ons/kernel/file_systems/udf/CachedBlock.h (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
1 /*
2  * 	Copyright 2008, Salvatore Benedetto, salvatore.benedetto@gmail.com
3  * 	Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net
4  * 	Copyright 2002, 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 OpenBFS, 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 class CachedBlock {
24 public:
25 								CachedBlock(Volume *volume);
26 								CachedBlock(Volume *volume, off_t block);
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 uint8				*SetTo(off_t block);
39 	inline uint8				*SetTo(off_t block, off_t base, size_t length);
40 	inline uint8				*SetTo(long_address address);
41 	template <class Accessor, class Descriptor>
42 	inline uint8*				SetTo(Accessor &accessor, 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(Volume *volume, off_t block)
63 	:
64 	fBlock(NULL),
65 	fBlockNumber(0),
66 	fVolume(volume)
67 {
68 	SetTo(block);
69 }
70 
71 
72 inline
73 CachedBlock::CachedBlock(CachedBlock *cached)
74 	:
75 	fBlock(cached->fBlock),
76 	fBlockNumber(cached->BlockNumber()),
77 	fVolume(cached->fVolume)
78 {
79 	cached->Keep();
80 }
81 
82 
83 inline
84 CachedBlock::~CachedBlock()
85 {
86 	Unset();
87 }
88 
89 
90 inline void
91 CachedBlock::Keep()
92 {
93 	fBlock = NULL;
94 }
95 
96 
97 inline void
98 CachedBlock::Unset()
99 {
100 	if (fBlock) {
101 		block_cache_put(fVolume->BlockCache(), fBlockNumber);
102 		fBlock = NULL;
103 	}
104 }
105 
106 
107 inline uint8*
108 CachedBlock::SetTo(off_t block)
109 {
110 	return SetTo(block, block, 1);
111 }
112 
113 
114 inline uint8*
115 CachedBlock::SetTo(off_t block, off_t base, size_t length)
116 {
117 	Unset();
118 	fBlockNumber = block;
119 	return fBlock = (uint8 *)block_cache_get_etc(fVolume->BlockCache(),
120 		block, base, length);
121 }
122 
123 
124 inline uint8 *
125 CachedBlock::SetTo(long_address address)
126 {
127 	off_t block;
128 	if (fVolume->MapBlock(address, &block) == B_OK)
129 		return SetTo(block, block, 1);
130 	else
131 		return NULL;
132 }
133 
134 
135 template <class Accessor, class Descriptor>
136 inline uint8*
137 CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor)
138 {
139 	// Make a long_address out of the descriptor and call it a day
140 	long_address address;
141 	address.set_to(accessor.GetBlock(descriptor),
142 		accessor.GetPartition(descriptor));
143     return SetTo(address);
144 }
145 
146 #endif	// _UDF_CACHED_BLOCK_H
147