00001
00002
00003
00004
00005
00012 #ifndef HBUFFER_H
00013 #define HBUFFER_H
00014
00024 template <uint32 BUF_LEN>
00025 class HBuffer : public HObjNoCopy
00026 {
00027 typedef HObjNoCopy base_class;
00028 static StringPtr ClassName(void) { return "HBuffer"; }
00029
00030
00031
00032 protected:
00033 uint32 m_uBytes;
00034 uint32 m_uRead;
00035 uint32 m_uWrite;
00036 uint8 m_data[BUF_LEN];
00037
00038
00039
00040 public:
00041 HBuffer(void)
00042 { (void) Reset(); }
00043
00044 virtual
00045 ~HBuffer(void)
00046 {
00047 #if __DEBUG__
00048 if (m_uBytes)
00049 DEBUG_LOG("~HBuffer() => %lu bytes still in buffer\n", m_uBytes);
00050 #endif
00051 (void) Reset();
00052 }
00053
00054
00055
00056 public:
00064 ErrCode
00065 Find(uint8 xWanted, uint32 & uOffset) const
00066 {
00067 const uint32 uSize = GetDataBytes();
00068
00069 for (uOffset = 0; uOffset < uSize; ++uOffset)
00070 if (GetAt(uOffset) == xWanted)
00071 {
00072 DEBUG_LOG( "HBuffer::Find() => found 0x%02X at %lu\n",
00073 xWanted, uOffset);
00074 return HError::NoError();
00075 }
00076
00077 return HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00078 }
00086 ErrCode
00087 FindLast(const uint8 xWanted, uint32 & uOffset) const
00088 {
00089 ErrCode ec = HError::NoError();
00090
00091 uOffset = GetDataBytes();
00092
00093 while (uOffset > 0)
00094 if (GetAt(--uOffset) == xWanted)
00095 return ec;
00096
00097 return HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00098 }
00106 ErrCode
00107 Read(Ptr pBuf, const uint32 uBufLen)
00108 {
00109 ErrCode ec = HError::NoError();
00110
00111 DEBUG_CHECK(uBufLen > 0 && uBufLen < MB(16));
00112
00113 if (uBufLen <= GetDataBytes())
00114 {
00115 if ((m_uRead + uBufLen) <= BUF_LEN)
00116 {
00117 DEBUG_LOG( "HBuffer::Read() => copied %lu bytes from buffer, starting at %lu\n",
00118 uBufLen, m_uRead);
00119 ASSERT(m_uRead < BUF_LEN);
00120 MEM_COPY(pBuf, &m_data[m_uRead], uBufLen);
00121 m_uRead += uBufLen;
00122 }
00123 else
00124 {
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 const uint32 uBlockA = (m_uRead < BUF_LEN) ? BUF_LEN - m_uRead : 0;
00139 const uint32 uBlockB = uBufLen - uBlockA;
00140
00141 if (uBlockA > 0)
00142 {
00143 ASSERT(m_uRead < BUF_LEN);
00144 MEM_COPY(pBuf, &m_data[m_uRead], uBlockA);
00145 DEBUG_LOG( "HBuffer::Read(#1) => copied %lu bytes from buffer, starting at %lu\n",
00146 uBlockA, m_uRead);
00147 }
00148
00149 if (uBlockB > 0)
00150 {
00151 PtrData pc = reinterpret_cast<PtrData>( pBuf );
00152
00153 DEBUG_LOG( "HBuffer::Read(#2) => copied %lu bytes from buffer\n",
00154 uBlockB);
00155 ASSERT(uBlockA < BUF_LEN);
00156 MEM_COPY(&pc[uBlockA], m_data, uBlockB);
00157 }
00158
00159 m_uRead = uBlockB;
00160 ASSERT(m_uRead < BUF_LEN);
00161 ASSERT((uBlockA + uBlockB) == uBufLen);
00162 }
00163
00164 ASSERT(uBufLen <= m_uBytes);
00165 m_uBytes -= uBufLen;
00166 }
00167 else
00168 ec = HError::Set(ERR_BUFFER_UNDERFLOW, __FILE__, __LINE__);
00169
00170 return ec;
00171 }
00180 ErrCode
00181 ReadLine(TextPtr psz, const int32 nMaxLen, bool bChomp = true)
00182 {
00183 ErrCode ec = HError::NoError();
00184
00185 if (GOOD_PTR(psz) && nMaxLen > 0)
00186 {
00187 uint32 uOffset = 0;
00188
00189 if (Find('\n', uOffset) == NO_ERROR)
00190 {
00191 ASSERT(uOffset < GetDataBytes());
00192
00193 ec = Read(reinterpret_cast<PtrData>(psz), uOffset + 1);
00194 if (ec == NO_ERROR)
00195 {
00196 psz[uOffset] = '\0';
00197 if (bChomp && uOffset > 0)
00198 {
00199
00200
00201
00202
00203
00204
00205 for (uint32 uLast = uOffset; uLast <= uOffset; --uLast)
00206 {
00207 if (isspace(psz[uLast]))
00208 psz[uLast] = '\0';
00209 else
00210 break;
00211 }
00212 }
00213 }
00214 }
00215 else
00216 ec = HError::Set(ERR_BUFFER_UNDERFLOW, __FILE__, __LINE__);
00217 }
00218 else
00219 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00220
00221 return ec;
00222 }
00231 ErrCode
00232 Reset(void)
00233 {
00234 m_uBytes = m_uRead = m_uWrite = 0;
00235 return Zero();
00236 }
00244 ErrCode
00245 Write(PtrConst pBuf, uint32 uDataLen)
00246 {
00247 ErrCode ec = HError::NoError();
00248
00249 DEBUG_CHECK(uDataLen < MB(16));
00250
00251 if (uDataLen > GetFreeBytes())
00252 ec = HError::Set(ERR_BUFFER_OVERFLOW, __FILE__, __LINE__);
00253 else if (uDataLen > 0)
00254 {
00255 DEBUG_CHECK(uDataLen < MB(16));
00256 if ((m_uWrite + uDataLen) < BUF_LEN)
00257 {
00258 ASSERT(m_uWrite < BUF_LEN);
00259 DEBUG_LOG( "HBuffer::Write() => writing %lu bytes beginning at offset %lu\n",
00260 uDataLen, m_uWrite);
00261
00262 MEM_COPY(&m_data[m_uWrite], pBuf, uDataLen);
00263 m_uWrite += uDataLen;
00264 }
00265 else
00266 {
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 const uint32 uBlockA = (m_uWrite < BUF_LEN) ? BUF_LEN - m_uWrite : 0;
00281 const uint32 uBlockB = uDataLen - uBlockA;
00282
00283 if (uBlockA > 0)
00284 {
00285 ASSERT(m_uWrite < BUF_LEN);
00286 MEM_COPY(&m_data[m_uWrite], pBuf, uBlockA );
00287 DEBUG_LOG( "HBuffer::Write(#1) => copied %lu bytes to buffer, starting at %lu\n",
00288 uBlockA, m_uWrite);
00289 }
00290
00291 if (uBlockB > 0)
00292 {
00293 PtrDataConst pc = reinterpret_cast<PtrDataConst>( pBuf );
00294
00295 ASSERT(uBlockA < BUF_LEN);
00296 MEM_COPY(m_data, &pc[uBlockA], uBlockB );
00297 DEBUG_LOG("HBuffer::Write(#2) => copied %lu bytes to buffer\n", uBlockB);
00298 }
00299
00300 m_uWrite = uBlockB;
00301 ASSERT(m_uWrite < BUF_LEN);
00302 ASSERT((uBlockA + uBlockB) == uDataLen);
00303 }
00304
00305 m_uBytes += uDataLen;
00306 ASSERT(m_uBytes <= BUF_LEN);
00307 }
00308
00309 return ec;
00310 }
00318 ErrCode
00319 WriteLine(StringPtr pstr, int32 nMaxLen = -1)
00320 {
00321 ErrCode ec = HError::NoError();
00322 uint32 uBytes = (nMaxLen >= 0) ? uint32(nMaxLen) : STR_LEN(pstr);
00323
00324 if (uBytes <= GetFreeBytes())
00325 {
00326 if (GOOD_PTR(pstr) && uBytes > 0)
00327 {
00328 if ((ec = Write(pstr, uBytes)) == NO_ERROR)
00329 ec = Write("\n", 1);
00330 }
00331 else
00332 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00333 }
00334 else
00335 ec = HError::Set(ERR_BUFFER_OVERFLOW, __FILE__, __LINE__);
00336
00337 return ec;
00338 }
00339
00340
00341
00342 public:
00349 uint8
00350 GetAt(const uint32 uOffset) const
00351 {
00352 uint8 xVal = 0xFF;
00353
00354 if (uOffset < GetDataBytes())
00355 {
00356 ASSERT( m_uWrite != m_uRead );
00357
00358 if (m_uWrite > m_uRead)
00359 xVal = m_data[ m_uRead + uOffset ];
00360 else if (m_uWrite < m_uRead)
00361 {
00362 if ((m_uRead + uOffset) < BUF_LEN)
00363 xVal = m_data[ m_uRead + uOffset ];
00364 else
00365 xVal = m_data[ uOffset - (BUF_LEN - m_uRead) ];
00366 }
00367 }
00368
00369 return xVal;
00370 }
00376 uint32 GetSize(void) const
00377 { return BUF_LEN; }
00383 inline uint32 GetDataBytes(void) const
00384 { return m_uBytes; }
00390 inline uint32 GetFreeBytes(void) const
00391 { return BUF_LEN - m_uBytes; }
00392
00393
00394
00398 inline bool CanRead(uint32 uWanted = 1) const
00399 { return (m_uBytes >= uWanted); }
00402 inline bool IsEmpty(void) const
00403 { return (m_uBytes == 0); }
00406 inline ErrCode Zero(void)
00407 {
00408 (void) MEM_ZERO(m_data, sizeof(m_data));
00409 return HError::NoError();
00410 }
00411
00412
00413
00414 inline uint8 operator [] (uint32 udx) const
00415 { return GetAt(udx); }
00416 };
00417 #endif // HBASE_H
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445