xref: /haiku/src/add-ons/kernel/file_systems/udf/CachedBlock.h (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
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 extern "C" {
19 	#ifndef _IMPEXP_KERNEL
20 	#	define _IMPEXP_KERNEL
21 	#endif
22 
23 	#include <fsproto.h>
24 	#include "lock.h"
25 	#include "cache.h"
26 }
27 
28 #include "kernel_cpp.h"
29 #include "UdfDebug.h"
30 
31 #include "UdfStructures.h"
32 #include "Volume.h"
33 
34 namespace Udf {
35 
36 class CachedBlock {
37 	public:
38 		CachedBlock(Volume *volume);
39 		CachedBlock(Volume *volume, off_t block, bool empty = false);
40 		CachedBlock(CachedBlock *cached);
41 		~CachedBlock();
42 
43 		inline void Keep();
44 		inline void Unset();
45 		inline uint8 *SetTo(off_t block, bool empty = false);
46 		inline uint8 *SetTo(long_address address, bool empty = false);
47 		template <class Accessor, class Descriptor>
48 			inline uint8* SetTo(Accessor &accessor, Descriptor &descriptor,
49 			bool empty = false);
50 
51 		uint8 *Block() const { return fBlock; }
52 		off_t BlockNumber() const { return fBlockNumber; }
53 		uint32 BlockSize() const { return fVolume->BlockSize(); }
54 		uint32 BlockShift() const { return fVolume->BlockShift(); }
55 
56 	private:
57 		CachedBlock(const CachedBlock &);				// unimplemented
58 		CachedBlock &operator=(const CachedBlock &);	// unimplemented
59 
60 	protected:
61 		Volume	*fVolume;
62 		off_t	fBlockNumber;
63 		uint8	*fBlock;
64 };
65 
66 inline
67 CachedBlock::CachedBlock(Volume *volume)
68 	:
69 	fVolume(volume),
70 	fBlock(NULL)
71 {
72 }
73 
74 inline
75 CachedBlock::CachedBlock(Volume *volume, off_t block, bool empty = false)
76 	:
77 	fVolume(volume),
78 	fBlock(NULL)
79 {
80 	SetTo(block, empty);
81 }
82 
83 inline
84 CachedBlock::CachedBlock(CachedBlock *cached)
85 	: fVolume(cached->fVolume)
86 	, fBlockNumber(cached->BlockNumber())
87 	, fBlock(cached->fBlock)
88 {
89 	cached->Keep();
90 }
91 
92 inline
93 CachedBlock::~CachedBlock()
94 {
95 	Unset();
96 }
97 
98 inline void
99 CachedBlock::Keep()
100 {
101 	fBlock = NULL;
102 }
103 
104 inline void
105 CachedBlock::Unset()
106 {
107 	DEBUG_INIT("CachedBlock");
108 	if (fBlock) {
109 		PRINT(("releasing block #%Ld\n", BlockNumber()));
110 		release_block(fVolume->Device(), fBlockNumber);
111 	} else {
112 		PRINT(("no block to release\n"));
113 	}
114 }
115 
116 inline uint8 *
117 CachedBlock::SetTo(off_t block, bool empty = false)
118 {
119 	DEBUG_INIT_ETC("CachedBlock", ("block: %Ld, empty: %s",
120 	               block, (empty ? "true" : "false")));
121 	Unset();
122 	fBlockNumber = block;
123 	PRINT(("getting block #%Ld\n", block));
124 	return fBlock = empty ? (uint8 *)get_empty_block(fVolume->Device(), block, BlockSize())
125 						  : (uint8 *)get_block(fVolume->Device(), block, BlockSize());
126 }
127 
128 inline uint8 *
129 CachedBlock::SetTo(long_address address, bool empty = false)
130 {
131 	off_t block;
132 	if (fVolume->MapBlock(address, &block) == B_OK)
133 		return SetTo(block, empty);
134 	else
135 		return NULL;
136 }
137 
138 template <class Accessor, class Descriptor>
139 inline uint8*
140 CachedBlock::SetTo(Accessor &accessor, Descriptor &descriptor, bool empty = false)
141 {
142 	// Make a long_address out of the descriptor and call it a day
143 	long_address address;
144 	address.set_to(accessor.GetBlock(descriptor),
145                              accessor.GetPartition(descriptor));
146     return SetTo(address, empty);
147 }
148 
149 };	// namespace Udf
150 
151 #endif	// _UDF_CACHED_BLOCK_H
152 
153