Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

CSeg.cpp

Go to the documentation of this file.
00001 
00034 #include "stdafx.h"
00035 
00036 namespace AxPipe {
00038     void
00039     CSeg::Init(size_t cbBuf, void *pvBuf, bool fReadOnly, int iType) {
00040         InitializeCriticalSection(&m_CritSect);
00041         m_iType = iType;
00042         m_pMom = NULL;
00043         m_fReadOnly = fReadOnly;
00044         if (m_cbLen = m_cbBuf = cbBuf) {
00045             if (!(m_fOwnPtr = (pvBuf == NULL))) {
00046                 m_pvBuf = pvBuf;
00047             } else {
00048                 m_pvBuf = new unsigned char[m_cbBuf];
00049             }
00050         } else {
00051             m_fOwnPtr = false;
00052             m_pvBuf = NULL;
00053         }
00054         m_cbOff = 0;
00055         m_iRefCnt = 1;
00056     }
00057 
00061     CSeg&
00062     CSeg::operator=(CSeg& rhs) {
00063 
00064         EnterCriticalSection(&m_CritSect);
00065 
00066         // Here we should have some check for assignment to non-empty lhs
00067         // and clear that. We don't implement that right now.
00068         m_pMom = &rhs;
00069         m_pvBuf = rhs.m_pvBuf;
00070         m_cbBuf = rhs.m_cbBuf;
00071         m_cbLen = rhs.m_cbLen;
00072         m_cbOff = rhs.m_cbOff;
00073         m_fReadOnly = rhs.m_fReadOnly;
00074         m_fOwnPtr = false;                  // A copy can never own the buffer.
00075 
00076         LeaveCriticalSection(&m_CritSect);
00077 
00078         rhs.AddRef();
00079         return *this;
00080     }
00081 
00085     CSeg::CSeg(size_t cbBuf, void *pvBuf, bool fReadOnly) {
00086         Init(cbBuf, pvBuf, fReadOnly, 0);
00087     }
00088 
00091     CSeg::CSeg(size_t cbBuf, const void *pvBuf) {
00092         Init(cbBuf, (void *)pvBuf, true, 0);
00093     }
00094 
00098     CSeg::CSeg(const void *pvBuf, size_t cbLen, size_t cbGrowBuf) {
00099         Init(cbLen + cbGrowBuf, NULL, false, 0);
00100         
00101         // Decrease length to the valid part.
00102         m_cbLen = cbLen;
00103         
00104         // Initialize the allocated buffer with the data provided
00105         CopyMemory(m_pvBuf, pvBuf, cbLen);
00106     }
00107 
00116     CSeg::~CSeg() {
00117         if (m_iRefCnt) {
00118             MessageBox(NULL, _T("CSeg::~CSeg() bad call or double-delete"), _T("http://www.axondata.se"), MB_OK);
00119         } else {
00120             if (m_pMom) {
00121                 m_pMom->Release();
00122             } else if (m_pvBuf && m_fOwnPtr) {
00123                 delete m_pvBuf;
00124                 m_pvBuf = NULL;
00125             }
00126         }
00127         DeleteCriticalSection(&m_CritSect);
00128     }
00129     
00133     unsigned char *
00134     CSeg::Ptr() {
00135         // m_pvBuf is only initialized in the constructor, so this is thread-safe
00136         return (unsigned char *)m_pvBuf;
00137     }
00138 
00141     const unsigned char *
00142     CSeg::PtrRd() {
00143         const unsigned char *r;
00144         EnterCriticalSection(&m_CritSect); {
00145             r = &((const unsigned char *)m_pvBuf)[m_cbOff];
00146         } LeaveCriticalSection(&m_CritSect);
00147         return r;
00148     }
00149 
00152     unsigned char *
00153     CSeg::PtrWr() {
00154         // m_fReadOnly is only initialized in the constructor, thus thread-safe
00155         return m_fReadOnly ? NULL : (unsigned char *)(PtrRd());
00156     }
00157 
00162     void *
00163     CSeg::PtrRelease() {
00164         // Return a buffer that is free to use. 
00165         void *p;
00166         EnterCriticalSection(&m_CritSect); {
00167             if (!m_fOwnPtr || (m_iRefCnt > 1) || m_pMom || m_cbOff) {
00168                 if (p = new unsigned char[Len()]) {
00169                     memcpy(p, PtrRd(), Len());
00170                 }
00171             } else {
00172                 p = &((char *)m_pvBuf)[m_cbOff];
00173                 m_pvBuf = NULL;
00174             }
00175         } LeaveCriticalSection(&m_CritSect);
00176 
00177         Release();
00178         return p;
00179     }
00180     
00184     size_t
00185     CSeg::Size(void) {
00186         size_t s;
00187         EnterCriticalSection(&m_CritSect); {
00188             s = m_cbBuf - m_cbOff;
00189         } LeaveCriticalSection(&m_CritSect);
00190         return s;
00191     }
00192     
00195     size_t
00196     CSeg::Len(void) {
00197         size_t l;
00198         EnterCriticalSection(&m_CritSect); {
00199             l = m_cbLen - m_cbOff;
00200         } LeaveCriticalSection(&m_CritSect);
00201         return l;
00202     }
00203     
00206     CSeg *
00207     CSeg::Len(size_t cbLen) {
00208         EnterCriticalSection(&m_CritSect); {
00209             m_cbLen = cbLen + m_cbOff;
00210         } LeaveCriticalSection(&m_CritSect);
00211         return this;
00212     }
00213 
00220     CSeg *
00221     CSeg::Writeable() {
00222         if (m_fReadOnly) {
00223             CSeg *pWriteable;
00224             EnterCriticalSection(&m_CritSect); {
00225                 pWriteable = new CSeg(Len());
00226                 memcpy(pWriteable->PtrWr(), PtrRd(), Len());
00227             } LeaveCriticalSection(&m_CritSect);
00228             return pWriteable;
00229         } else {
00230             return AddRef();
00231         }
00232     }
00233     
00237     CSeg *
00238     CSeg::Drop(size_t cbOff) {
00239         EnterCriticalSection(&m_CritSect); {
00240             m_cbOff += cbOff;
00241         } LeaveCriticalSection(&m_CritSect);
00242         return this;
00243     }
00244 
00247     CSeg *
00248     CSeg::AddRef() {
00249         // II makes it thread-safe
00250         InterlockedIncrement(&m_iRefCnt);
00251         return this;
00252     }
00253 
00262     int
00263     CSeg::Release() {
00264        LONG i = InterlockedDecrement(&m_iRefCnt);
00265         if (i == 0) {
00266             // This is why you must *never* reference a CSeg* after calling Release()
00267             // This is also why you must *never* delete  CSeg manually, nor allocate
00268             // one as auto or static.
00269             delete this;
00270         }
00271         return i;
00272     }
00273 
00280     int
00281     CSeg::Type() {
00282         // m_iType should only be set in construction, thus thread-safe
00283         return m_iType;
00284     }
00285     
00290     CSeg *
00291     CSeg::SetType(int iType) {
00292         m_iType = iType;
00293         return this;
00294     }
00295     
00298     bool
00299     CSeg::IsSeg(CSeg *pSeg) {
00300         return (pSeg != NULL && !pSeg->Type());
00301     }
00302 
00306     CSeg *
00307     CSeg::Clone() {
00308         // The operator= handles thread-issues
00309         return &(*new CSeg = *this);
00310     }
00311 
00329     void *
00330     CSeg::ClassId() {
00331         static int i;
00332         return &i;
00333     }
00334 
00337     void *
00338     CSeg::RTClassId() {
00339         return ClassId();
00340     }
00341 };

Generated on Mon Feb 2 13:19:18 2004 for AxPipe by doxygen 1.3.5