/* * Copyright 2006, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef NET_BUFFER_UTILITIES_H #define NET_BUFFER_UTILITIES_H #include extern net_buffer_module_info *gBufferModule; class NetBufferModuleGetter { public: static net_buffer_module_info *Get() { return gBufferModule; } }; //! A class to retrieve and remove a header from a buffer template class NetBufferHeader { public: NetBufferHeader(net_buffer *buffer) : fBuffer(buffer) { } ~NetBufferHeader() { Remove(); } status_t Status() { return fBuffer->size < sizeof(Type) ? B_BAD_VALUE : B_OK; } status_t SetTo(net_buffer *buffer) { fBuffer = buffer; return Status(); } Type & Data() { Type *data; if (Module::Get()->direct_access(fBuffer, 0, sizeof(Type), (void **)&data) == B_OK) return *data; Module::Get()->read(fBuffer, 0, &fDataBuffer, sizeof(Type)); return fDataBuffer; } void Remove() { Remove(sizeof(Type)); } void Remove(size_t bytes) { if (fBuffer != NULL) { Module::Get()->remove_header(fBuffer, bytes); fBuffer = NULL; } } void Detach() { fBuffer = NULL; } private: net_buffer *fBuffer; Type fDataBuffer; }; //! A class to add a header to a buffer template class NetBufferPrepend { public: NetBufferPrepend(net_buffer *buffer, size_t size = 0) : fBuffer(buffer), fData(NULL) { if (size == 0) size = sizeof(Type); fStatus = Module::Get()->prepend_size(buffer, size, (void **)&fData); } ~NetBufferPrepend() { if (fBuffer != NULL) Detach(); } status_t Status() { return fStatus; } Type & Data() { if (fData != NULL) return *fData; return fDataBuffer; } // TODO: I'm not sure it's a good idea to have Detach() routines // in NetBufferHeader and here with such a different outcome... void Detach() { if (fData == NULL) Module::Get()->write(fBuffer, 0, &fDataBuffer, sizeof(Type)); fBuffer = NULL; } private: net_buffer *fBuffer; status_t fStatus; Type *fData; Type fDataBuffer; }; #endif // NET_BUFFER_UTILITIES_H