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
00067
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;
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
00102 m_cbLen = cbLen;
00103
00104
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
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
00155 return m_fReadOnly ? NULL : (unsigned char *)(PtrRd());
00156 }
00157
00162 void *
00163 CSeg::PtrRelease() {
00164
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
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
00267
00268
00269 delete this;
00270 }
00271 return i;
00272 }
00273
00280 int
00281 CSeg::Type() {
00282
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
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 };