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