SharedBuffer.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_SHARED_BUFFER_H_
00014 #define _SUPPORT_SHARED_BUFFER_H_
00015 
00022 #include <support/Atom.h>
00023 #include <support/SupportDefs.h>
00024 #include <support/atomic.h>
00025 
00026 #if _SUPPORTS_NAMESPACE
00027 namespace palmos {
00028 namespace support {
00029 #endif
00030 
00035 
00036 
00039 enum {
00040 
00041     B_BUFFER_USERS_SHIFT    = 4,        
00042     B_BUFFER_LENGTH_SHIFT   = 1,        
00043 
00045 
00046     B_STATIC_USERS          = 0x00000001,
00047 
00049 
00050     B_POOLED_USERS          = 0x00000002,
00051 
00053 
00054     B_EXTENDED_BUFFER   = 0x00000001
00055 };
00056 
00057 // *************************************************************************
00059 
00073 class SSharedBuffer
00074 {
00075 public:
00077 
00078     static  SSharedBuffer*  Alloc(size_t length);
00079             
00081     inline  const void*     Data() const;
00083 
00087     inline  void*           Data();
00089     inline  size_t          Length() const;
00090             
00092 
00099     static inline   const SSharedBuffer* BufferFromData(const void *data);
00100 
00102             void            IncUsers() const;
00104 
00105             void            DecUsers() const;
00107 
00111     inline  int32_t         Users() const;
00112             
00114 
00117             SSharedBuffer*  Edit(size_t newLength) const;
00118 
00120             SSharedBuffer*  Edit() const;
00121 
00123 
00128     const   SSharedBuffer*  Pool() const;
00129 
00131 
00134             int32_t         Compare(const SSharedBuffer* other) const;
00135 
00137 
00140             SSharedBuffer*  BeginBuffering();
00142             SSharedBuffer*  EndBuffering();
00143 
00145             bool            Buffering() const;
00147             size_t          BufferSize() const;
00148 
00150             void            IncStrong(const void* ) const   { IncUsers(); }
00152             void            DecStrong(const void* ) const   { DecUsers(); }
00154             void            IncStrongFast() const           { IncUsers(); }
00156             void            DecStrongFast() const           { DecUsers(); }
00157 
00158             // These are used for static values.  See StaticValue.h.
00159     typedef void            (*inc_ref_func)();
00160     typedef void            (*dec_ref_func)();
00161 
00162 private:
00163     inline                  SSharedBuffer() { }
00164     inline                  ~SSharedBuffer() { }
00165     
00166     struct  extended_info;
00167             extended_info*  get_extended_info() const;
00168             bool            unpool() const;
00169             void            do_delete() const;
00170 
00171                             SSharedBuffer(const SSharedBuffer& o);
00172 
00173     static  SSharedBuffer*  AllocExtended(extended_info* prototype, size_t length);
00174             SSharedBuffer*  Extend(size_t length) const;
00175 
00176             void            SetBufferSize(size_t size);
00177             void            SetLength(size_t len);
00178 
00179     /* *******************************************************
00180      * WARNING
00181      *
00182      * The size or layout of SSharedBuffer cannot be changed.
00183      * In order to do some important optimizations, some code
00184      * assumes this layout. For eg, see support/StaticValue.h.
00185      *
00186      * *******************************************************/
00187 
00188     mutable int32_t         m_users;
00189             size_t          m_length;
00190 #if defined(_MSC_VER)
00191             char            m_data[0];
00192 #endif
00193 };
00194 
00197 /*-------------------------------------------------------------*/
00198 /*---- No user serviceable parts after this -------------------*/
00199 
00200 inline const void* SSharedBuffer::Data() const
00201 {
00202     return this+1;
00203 }
00204 
00205 inline void* SSharedBuffer::Data()
00206 {
00207     return this+1;
00208 }
00209 
00210 inline const SSharedBuffer* SSharedBuffer::BufferFromData(const void *data)
00211 {
00212     return ((static_cast<const SSharedBuffer *>(data)) - 1);
00213 }
00214 
00215 inline size_t SSharedBuffer::Length() const
00216 {
00217     return m_length>>B_BUFFER_LENGTH_SHIFT;
00218 }
00219 
00220 inline int32_t SSharedBuffer::Users() const
00221 {
00222     return m_users>>B_BUFFER_USERS_SHIFT;
00223 }
00224 
00225 /*-------------------------------------------------------------*/
00226 // We need to specialize SSharedBuffer, because
00227 // raw SSharedBuffer alread have a count of 1
00228 
00229 template<> inline
00230 sptr<SSharedBuffer>::sptr(SSharedBuffer* p)
00231 {
00232     m_ptr = p;
00233 }
00234 
00235 template<> inline
00236 sptr<SSharedBuffer>& sptr<SSharedBuffer>::operator = (SSharedBuffer* p)
00237 {
00238     if (m_ptr) B_DEC_STRONG(m_ptr, this);
00239     m_ptr = p;
00240     return *this;
00241 }
00242 
00243 
00244 #if _SUPPORTS_NAMESPACE
00245 } } // namespace palmos::support
00246 #endif
00247 
00248 #endif  /* _SUPPORT_SHARED_BUFFER_H_ */