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