xref: /haiku/headers/private/net/NetBufferUtilities.h (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
1 /*
2  * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef NET_BUFFER_UTILITIES_H
6 #define NET_BUFFER_UTILITIES_H
7 
8 
9 #include <net_buffer.h>
10 #include <AutoDeleter.h>
11 
12 
13 extern net_buffer_module_info* gBufferModule;
14 
15 
16 class NetBufferModuleGetter {
17 	public:
18 		static net_buffer_module_info *Get() { return gBufferModule; }
19 };
20 
21 
22 //! A class to access a field safely across node boundaries
23 template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
24 class NetBufferFieldReader {
25 public:
26 	NetBufferFieldReader(net_buffer* buffer)
27 		:
28 		fBuffer(buffer)
29 	{
30 		fStatus = Module::Get()->direct_access(fBuffer, Offset, sizeof(Type),
31 			(void**)&fData);
32 		if (fStatus != B_OK) {
33 			fStatus = Module::Get()->read(fBuffer, Offset, &fDataBuffer,
34 				sizeof(Type));
35 			fData = &fDataBuffer;
36 		}
37 	}
38 
39 	status_t Status() const
40 	{
41 		return fStatus;
42 	}
43 
44 	Type& Data() const
45 	{
46 		return *fData;
47 	}
48 
49 	Type* operator->() const
50 	{
51 		return fData;
52 	}
53 
54 	Type& operator*() const
55 	{
56 		return *fData;
57 	}
58 
59 	void Sync()
60 	{
61 		if (fBuffer == NULL || fStatus < B_OK)
62 			return;
63 
64 		if (fData == &fDataBuffer)
65 			Module::Get()->write(fBuffer, Offset, fData, sizeof(Type));
66 
67 		fBuffer = NULL;
68 	}
69 
70 protected:
71 	NetBufferFieldReader()
72 	{
73 	}
74 
75 	net_buffer*	fBuffer;
76 	status_t	fStatus;
77 	Type*		fData;
78 	Type		fDataBuffer;
79 };
80 
81 
82 //! Writes back any changed data on destruction
83 template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
84 class NetBufferField : public NetBufferFieldReader<Type, Offset, Module> {
85 public:
86 	NetBufferField(net_buffer* buffer)
87 		:
88 		NetBufferFieldReader<Type, Offset, Module>(buffer)
89 	{
90 	}
91 
92 	~NetBufferField()
93 	{
94 		// Note, "this->" is needed here for GCC4
95 		this->Sync();
96 	}
97 };
98 
99 
100 //! Can remove the header from the buffer
101 template<typename Type, typename Module = NetBufferModuleGetter>
102 class NetBufferHeaderReader : public NetBufferFieldReader<Type, 0, Module> {
103 public:
104 	NetBufferHeaderReader(net_buffer* buffer)
105 		:
106 		NetBufferFieldReader<Type, 0, Module>(buffer)
107 	{
108 	}
109 
110 	void Remove()
111 	{
112 		Remove(sizeof(Type));
113 	}
114 
115 	void Remove(size_t bytes)
116 	{
117 		if (this->fBuffer != NULL) {
118 			Module::Get()->remove_header(this->fBuffer, bytes);
119 			this->fBuffer = NULL;
120 		}
121 	}
122 };
123 
124 
125 //!	Removes the header on destruction
126 template<typename Type, typename Module = NetBufferModuleGetter>
127 class NetBufferHeaderRemover : public NetBufferHeaderReader<Type, Module> {
128 public:
129 	NetBufferHeaderRemover(net_buffer* buffer)
130 		:
131 		NetBufferHeaderReader<Type, Module>(buffer)
132 	{
133 	}
134 
135 	~NetBufferHeaderRemover()
136 	{
137 		this->Remove();
138 	}
139 };
140 
141 
142 //! A class to add a header to a buffer, syncs itself on destruction
143 template<typename Type, typename Module = NetBufferModuleGetter>
144 class NetBufferPrepend : public NetBufferFieldReader<Type, 0, Module> {
145 public:
146 	NetBufferPrepend(net_buffer* buffer, size_t size = sizeof(Type))
147 	{
148 		this->fBuffer = buffer;
149 
150 		this->fStatus = Module::Get()->prepend_size(buffer, size,
151 			(void**)&this->fData);
152 		if (this->fStatus == B_OK && this->fData == NULL)
153 			this->fData = &this->fDataBuffer;
154 	}
155 
156 	~NetBufferPrepend()
157 	{
158 		this->Sync();
159 	}
160 };
161 
162 
163 //! A class to automatically delete buffers on scope exit
164 template<typename Module>
165 struct NetBufferDelete
166 {
167 	inline void operator()(net_buffer* buffer)
168 	{
169 		if (buffer != NULL)
170 			Module::Get()->free(buffer);
171 	}
172 };
173 
174 
175 template<typename Module = NetBufferModuleGetter>
176 struct NetBufferDeleter
177 	: BPrivate::AutoDeleter<net_buffer, NetBufferDelete<Module> >
178 {
179 	NetBufferDeleter(net_buffer* buffer)
180 		: BPrivate::AutoDeleter<net_buffer, NetBufferDelete<Module> >(buffer)
181 	{}
182 };
183 
184 
185 
186 #endif	// NET_BUFFER_UTILITIES_H
187