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