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