vfs: check userland buffers before reading them.
[haiku.git] / headers / private / shared / AutoDeleter.h
bloba508fefd9bf6554bf58679332544555014ec2407
1 /*
2 * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _AUTO_DELETER_H
6 #define _AUTO_DELETER_H
9 /*! Scope-based automatic deletion of objects/arrays.
10 ObjectDeleter - deletes an object
11 ArrayDeleter - deletes an array
12 MemoryDeleter - free()s malloc()ed memory
13 CObjectDeleter - calls an arbitrary specified destructor function
14 FileDescriptorCloser - closes a file descriptor
18 #include <stdlib.h>
19 #include <unistd.h>
22 namespace BPrivate {
25 // AutoDeleter
27 template<typename C, typename DeleteFunc>
28 class AutoDeleter {
29 public:
30 inline AutoDeleter()
31 : fObject(NULL)
35 inline AutoDeleter(C *object)
36 : fObject(object)
40 inline ~AutoDeleter()
42 fDelete(fObject);
45 inline void SetTo(C *object)
47 if (object != fObject) {
48 fDelete(fObject);
49 fObject = object;
53 inline void Unset()
55 SetTo(NULL);
58 inline void Delete()
60 SetTo(NULL);
63 inline C *Get() const
65 return fObject;
68 inline C *Detach()
70 C *object = fObject;
71 fObject = NULL;
72 return object;
75 inline C *operator->() const
77 return fObject;
80 protected:
81 C *fObject;
82 DeleteFunc fDelete;
86 // ObjectDeleter
88 template<typename C>
89 struct ObjectDelete
91 inline void operator()(C *object)
93 delete object;
97 template<typename C>
98 struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> >
100 ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {}
101 ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {}
105 // ArrayDeleter
107 template<typename C>
108 struct ArrayDelete
110 inline void operator()(C *array)
112 delete[] array;
116 template<typename C>
117 struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> >
119 ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {}
120 ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {}
124 // MemoryDeleter
126 struct MemoryDelete
128 inline void operator()(void *memory)
130 free(memory);
134 struct MemoryDeleter : AutoDeleter<void, MemoryDelete >
136 MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {}
137 MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {}
141 // CObjectDeleter
143 template<typename Type, typename DestructorReturnType>
144 struct CObjectDelete
146 inline void operator()(Type *object)
148 if (fDestructor != NULL && object != NULL)
149 fDestructor(object);
152 template<typename Destructor>
153 inline void operator=(Destructor destructor)
155 fDestructor = destructor;
158 private:
159 DestructorReturnType (*fDestructor)(Type*);
162 template<typename Type, typename DestructorReturnType = void>
163 struct CObjectDeleter
164 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> >
166 typedef AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > Base;
168 template<typename Destructor>
169 CObjectDeleter(Destructor destructor) : Base()
171 Base::fDelete = destructor;
174 template<typename Destructor>
175 CObjectDeleter(Type *object, Destructor destructor) : Base(object)
177 Base::fDelete = destructor;
182 // MethodDeleter
184 template<typename Type, typename DestructorReturnType>
185 struct MethodDelete
187 inline void operator()(Type *object)
189 if (fDestructor && object != NULL)
190 (object->*fDestructor)();
193 template<typename Destructor>
194 inline void operator=(Destructor destructor)
196 fDestructor = destructor;
199 private:
200 DestructorReturnType (Type::*fDestructor)();
204 template<typename Type, typename DestructorReturnType = void>
205 struct MethodDeleter
206 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> >
208 typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base;
210 template<typename Destructor>
211 MethodDeleter(Destructor destructor) : Base()
213 Base::fDelete = destructor;
216 template<typename Destructor>
217 MethodDeleter(Type *object, Destructor destructor) : Base(object)
219 Base::fDelete = destructor;
224 // FileDescriptorCloser
226 struct FileDescriptorCloser {
227 inline FileDescriptorCloser()
229 fDescriptor(-1)
233 inline FileDescriptorCloser(int descriptor)
235 fDescriptor(descriptor)
239 inline ~FileDescriptorCloser()
241 SetTo(-1);
244 inline void SetTo(int descriptor)
246 if (fDescriptor >= 0)
247 close(fDescriptor);
249 fDescriptor = descriptor;
252 inline void Unset()
254 SetTo(-1);
257 inline int Detach()
259 int descriptor = fDescriptor;
260 fDescriptor = -1;
261 return descriptor;
264 private:
265 int fDescriptor;
269 } // namespace BPrivate
272 using ::BPrivate::ObjectDeleter;
273 using ::BPrivate::ArrayDeleter;
274 using ::BPrivate::MemoryDeleter;
275 using ::BPrivate::CObjectDeleter;
276 using ::BPrivate::MethodDeleter;
277 using ::BPrivate::FileDescriptorCloser;
280 #endif // _AUTO_DELETER_H