xref: /haiku/headers/private/net/NetBufferUtilities.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
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 
11 
12 extern net_buffer_module_info* gBufferModule;
13 
14 
15 class NetBufferModuleGetter {
16 	public:
17 		static net_buffer_module_info *Get() { return gBufferModule; }
18 };
19 
20 
21 //! A class to access a field safely across node boundaries
22 template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
23 class NetBufferFieldReader {
24 public:
25 	NetBufferFieldReader(net_buffer* buffer)
26 		:
27 		fBuffer(buffer)
28 	{
29 		fStatus = Module::Get()->direct_access(fBuffer, Offset, sizeof(Type),
30 			(void**)&fData);
31 		if (fStatus != B_OK) {
32 			fStatus = Module::Get()->read(fBuffer, Offset, &fDataBuffer,
33 				sizeof(Type));
34 			fData = &fDataBuffer;
35 		}
36 	}
37 
38 	status_t Status() const
39 	{
40 		return fStatus;
41 	}
42 
43 	Type& Data() const
44 	{
45 		return *fData;
46 	}
47 
48 	Type* operator->() const
49 	{
50 		return fData;
51 	}
52 
53 	Type& operator*() const
54 	{
55 		return *fData;
56 	}
57 
58 	void Sync()
59 	{
60 		if (fBuffer == NULL || fStatus < B_OK)
61 			return;
62 
63 		if (fData == &fDataBuffer)
64 			Module::Get()->write(fBuffer, Offset, fData, sizeof(Type));
65 
66 		fBuffer = NULL;
67 	}
68 
69 protected:
70 	NetBufferFieldReader()
71 	{
72 	}
73 
74 	net_buffer*	fBuffer;
75 	status_t	fStatus;
76 	Type*		fData;
77 	Type		fDataBuffer;
78 };
79 
80 
81 //! Writes back any changed data on destruction
82 template<typename Type, int Offset, typename Module = NetBufferModuleGetter>
83 class NetBufferField : public NetBufferFieldReader<Type, Offset, Module> {
84 public:
85 	NetBufferField(net_buffer* buffer)
86 		:
87 		NetBufferFieldReader<Type, Offset, Module>(buffer)
88 	{
89 	}
90 
91 	~NetBufferField()
92 	{
93 		// Note, "this->" is needed here for GCC4
94 		this->Sync();
95 	}
96 };
97 
98 
99 //! Can remove the header from the buffer
100 template<typename Type, typename Module = NetBufferModuleGetter>
101 class NetBufferHeaderReader : public NetBufferFieldReader<Type, 0, Module> {
102 public:
103 	NetBufferHeaderReader(net_buffer* buffer)
104 		:
105 		NetBufferFieldReader<Type, 0, Module>(buffer)
106 	{
107 	}
108 
109 	void Remove()
110 	{
111 		Remove(sizeof(Type));
112 	}
113 
114 	void Remove(size_t bytes)
115 	{
116 		if (this->fBuffer != NULL) {
117 			Module::Get()->remove_header(this->fBuffer, bytes);
118 			this->fBuffer = NULL;
119 		}
120 	}
121 };
122 
123 
124 //!	Removes the header on destruction
125 template<typename Type, typename Module = NetBufferModuleGetter>
126 class NetBufferHeaderRemover : public NetBufferHeaderReader<Type, Module> {
127 public:
128 	NetBufferHeaderRemover(net_buffer* buffer)
129 		:
130 		NetBufferHeaderReader<Type, Module>(buffer)
131 	{
132 	}
133 
134 	~NetBufferHeaderRemover()
135 	{
136 		this->Remove();
137 	}
138 };
139 
140 
141 //! A class to add a header to a buffer, syncs itself on destruction
142 template<typename Type, typename Module = NetBufferModuleGetter>
143 class NetBufferPrepend : public NetBufferFieldReader<Type, 0, Module> {
144 public:
145 	NetBufferPrepend(net_buffer* buffer, size_t size = sizeof(Type))
146 	{
147 		this->fBuffer = buffer;
148 
149 		this->fStatus = Module::Get()->prepend_size(buffer, size,
150 			(void**)&this->fData);
151 		if (this->fStatus == B_OK && this->fData == NULL)
152 			this->fData = &this->fDataBuffer;
153 	}
154 
155 	~NetBufferPrepend()
156 	{
157 		this->Sync();
158 	}
159 };
160 
161 
162 #endif	// NET_BUFFER_UTILITIES_H
163