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