Buffer.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_BUFFER_H_
00014 #define _SUPPORT_BUFFER_H_
00015 
00016 #include <support/SupportDefs.h>
00017 #include <string.h>
00018 
00019 #if _SUPPORTS_NAMESPACE
00020 namespace palmos {
00021 namespace support {
00022 #endif
00023 
00024 class SBuffer
00025 {
00026     public: // members
00027         SBuffer *               next;   // next buffer in the chain, or NULL
00028 
00029     public: // methods
00030         inline                  SBuffer();
00031         inline                  SBuffer(void * data, size_t size);
00032         inline                  SBuffer(const SBuffer& clone);
00033         inline  SBuffer&        operator=(const SBuffer& clone);
00034 
00035         inline  void            MakeEmpty();
00036         inline  status_t        SetTo(void * data, size_t size);
00037 
00038         inline  bool            IsValid() const;
00039 
00040         // access just this buffer in the chain
00041         inline  void const *    Data() const;
00042         inline  void *          WriteData() const;
00043         inline  size_t          Size() const;
00044 
00045         // access entire chain starting with this buffer
00046         size_t          ChainSize() const
00047         {
00048             size_t s = 0;
00049             for (SBuffer const * i = this; i != 0; i = i->next)
00050             {
00051                 s += i->Size();
00052             }
00053             return s;
00054         }
00055         
00056         // copy data out of the chain starting with this buffer
00057         ssize_t         CopyTo(void * dest, size_t size, size_t fromOffset) const
00058         {
00059             if (dest == 0) return B_BAD_VALUE;
00060             ssize_t total = 0;
00061             SBuffer const * i = this;
00062             while (size && i)
00063             {
00064                 if (fromOffset >= i->Size())
00065                 {
00066                     fromOffset -= i->Size();
00067                     i = i->next;
00068                     continue;
00069                 }
00070                 size_t toCopy = i->Size() - fromOffset;
00071                 if (toCopy > size)
00072                 {
00073                     toCopy = size;
00074                 }
00075                 memcpy(dest, (int8_t*)i->Data() + fromOffset, toCopy);
00076                 size -= toCopy;
00077                 total += toCopy;
00078                 if (size)
00079                 {
00080                     fromOffset = 0;
00081                     dest = (int8_t*)dest + toCopy;
00082                     i = i->next;
00083                 }
00084             }
00085             return total;
00086         }
00087         
00088     protected:
00089                 size_t          m_size;
00090                 void *          m_data;
00091 };
00092 
00093 inline
00094 SBuffer::SBuffer()
00095     : next(0), m_size(0), m_data(0)
00096 {
00097 }
00098 
00099 inline
00100 SBuffer::SBuffer(void * data, size_t size)
00101     : next(0), m_size(size), m_data(data)
00102 {
00103 }
00104 
00105 inline
00106 SBuffer::SBuffer(const SBuffer& clone)
00107 {
00108     next = clone.next;
00109     m_size = clone.m_size;
00110     m_data = clone.m_data;
00111 }
00112 
00113 inline SBuffer&
00114 SBuffer::operator=(const SBuffer& clone)
00115 {
00116     next = clone.next;
00117     m_size = clone.m_size;
00118     m_data = clone.m_data;
00119     return *this;
00120 }
00121 
00122 inline void
00123 SBuffer::MakeEmpty()
00124 {
00125     next = 0;
00126     m_size = 0;
00127     m_data = 0;
00128 }
00129 
00130 inline status_t
00131 SBuffer::SetTo(void * data, size_t size)
00132 {
00133     m_size = size;
00134     m_data = data;
00135     return B_OK;
00136 }
00137 
00138 inline bool
00139 SBuffer::IsValid() const
00140 {
00141     return (m_data != 0);
00142 }
00143 
00144 inline void const *
00145 SBuffer::Data() const
00146 {
00147     return m_data;
00148 }
00149 
00150 inline void *
00151 SBuffer::WriteData() const
00152 {
00153     return m_data;
00154 }
00155 
00156 inline size_t
00157 SBuffer::Size() const
00158 {
00159     return m_size;
00160 }
00161 
00162 #if _SUPPORTS_NAMESPACE
00163 } } // palmos::support
00164 #endif
00165 
00166 #endif // _SUPPORT_BUFFER_H_
00167