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 *sBufferModule; 13 14 class NetBufferModuleGetter { 15 public: 16 static net_buffer_module_info *Get() { return sBufferModule; } 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 Type & 40 Data() 41 { 42 Type *data; 43 if (Module::Get()->direct_access(fBuffer, 0, sizeof(Type), 44 (void **)&data) == B_OK) 45 return *data; 46 47 Module::Get()->read(fBuffer, 0, &fDataBuffer, sizeof(Type)); 48 return fDataBuffer; 49 } 50 51 void 52 Remove() 53 { 54 if (fBuffer != NULL) { 55 Module::Get()->remove_header(fBuffer, sizeof(Type)); 56 fBuffer = NULL; 57 } 58 } 59 60 void 61 Remove(size_t bytes) 62 { 63 if (fBuffer != NULL) { 64 Module::Get()->remove_header(fBuffer, bytes); 65 fBuffer = NULL; 66 } 67 } 68 69 void 70 Detach() 71 { 72 fBuffer = NULL; 73 } 74 75 private: 76 net_buffer *fBuffer; 77 Type fDataBuffer; 78 }; 79 80 //! A class to add a header to a buffer 81 template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferPrepend { 82 public: 83 NetBufferPrepend(net_buffer *buffer) 84 : 85 fBuffer(buffer), 86 fData(NULL) 87 { 88 fStatus = Module::Get()->prepend_size(buffer, sizeof(Type), (void **)&fData); 89 } 90 91 ~NetBufferPrepend() 92 { 93 if (fBuffer != NULL) 94 Detach(); 95 } 96 97 status_t 98 Status() 99 { 100 return fStatus; 101 } 102 103 Type & 104 Data() 105 { 106 if (fData != NULL) 107 return *fData; 108 109 return fDataBuffer; 110 } 111 112 // TODO: I'm not sure it's a good idea to have Detach() routines 113 // in NetBufferHeader and here with such a different outcome... 114 void 115 Detach() 116 { 117 if (fData == NULL) 118 Module::Get()->write(fBuffer, 0, &fDataBuffer, sizeof(Type)); 119 fBuffer = NULL; 120 } 121 122 private: 123 net_buffer *fBuffer; 124 status_t fStatus; 125 Type *fData; 126 Type fDataBuffer; 127 }; 128 129 #endif // NET_BUFFER_UTILITIES_H 130