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