xref: /haiku/headers/private/net/NetBufferUtilities.h (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
1 /*
2  * Copyright 2006, 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 *sBufferModule;
13 
14 class NetBufferModuleGetter {
15 	public:
16 		static net_buffer_module_info *Get() { return sBufferModule; }
17 };
18 
19 //! A class to retrieve and remove a header from a buffer
20 template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferHeader {
21 	public:
22 		NetBufferHeader(net_buffer *buffer)
23 			:
24 			fBuffer(buffer)
25 		{
26 		}
27 
28 		~NetBufferHeader()
29 		{
30 			Remove();
31 		}
32 
33 		status_t
34 		Status()
35 		{
36 			return fBuffer->size < sizeof(Type) ? B_BAD_VALUE : B_OK;
37 		}
38 
39 		Type &
40 		Data()
41 		{
42 			Type *data;
43 			if (Module::Get()->direct_access(fBuffer, 0, sizeof(Type),
44 					(void **)&data) == B_OK)
45 				return *data;
46 
47 			Module::Get()->read(fBuffer, 0, &fDataBuffer, sizeof(Type));
48 			return fDataBuffer;
49 		}
50 
51 		void
52 		Remove()
53 		{
54 			if (fBuffer != NULL) {
55 				Module::Get()->remove_header(fBuffer, sizeof(Type));
56 				fBuffer = NULL;
57 			}
58 		}
59 
60 		void
61 		Remove(size_t bytes)
62 		{
63 			if (fBuffer != NULL) {
64 				Module::Get()->remove_header(fBuffer, bytes);
65 				fBuffer = NULL;
66 			}
67 		}
68 
69 		void
70 		Detach()
71 		{
72 			fBuffer = NULL;
73 		}
74 
75 	private:
76 		net_buffer	*fBuffer;
77 		Type		fDataBuffer;
78 };
79 
80 //! A class to add a header to a buffer
81 template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferPrepend {
82 	public:
83 		NetBufferPrepend(net_buffer *buffer)
84 			:
85 			fBuffer(buffer),
86 			fData(NULL)
87 		{
88 			fStatus = Module::Get()->prepend_size(buffer, sizeof(Type), (void **)&fData);
89 		}
90 
91 		~NetBufferPrepend()
92 		{
93 			if (fBuffer != NULL)
94 				Detach();
95 		}
96 
97 		status_t
98 		Status()
99 		{
100 			return fStatus;
101 		}
102 
103 		Type &
104 		Data()
105 		{
106 			if (fData != NULL)
107 				return *fData;
108 
109 			return fDataBuffer;
110 		}
111 
112 		// TODO: I'm not sure it's a good idea to have Detach() routines
113 		//	in NetBufferHeader and here with such a different outcome...
114 		void
115 		Detach()
116 		{
117 			if (fData == NULL)
118 				Module::Get()->write(fBuffer, 0, &fDataBuffer, sizeof(Type));
119 			fBuffer = NULL;
120 		}
121 
122 	private:
123 		net_buffer	*fBuffer;
124 		status_t	fStatus;
125 		Type		*fData;
126 		Type		fDataBuffer;
127 };
128 
129 #endif	// NET_BUFFER_UTILITIES_H
130