1/* 2 File: CBufferSegment.c 3 4 Contains: Implementation of the CBufferSegment class 5 6 7*/ 8 9 10#include "CBufferSegment.h" 11#include "IrDALog.h" 12 13#if (hasTracing > 0 && hasCBufferSegTracing > 0) 14 15enum 16{ 17 kLogNew = 1, 18 kLogNewWith, 19 kLogDelete, 20 kLogFree1, 21 kLogFree2, 22 kLogCBInit1, 23 kLogCBInit2, 24 25 kLogIOAllocBuf, 26 kLogIOAllocSize, 27 kLogIOFreeBuf, 28 kLogIOFreeSize 29}; 30 31static 32EventTraceCauseDesc TraceEvents[] = { 33 {kLogNew, "CBufferSegment: New, obj="}, 34 {kLogNewWith, "CBufferSegment: New hdr, obj=, buffer="}, 35 {kLogDelete, "CBufferSegment: Delete"}, 36 {kLogFree1, "CBufferSegment: Free, obj="}, 37 {kLogFree2, "CBufferSegment: Free, buffer="}, 38 {kLogCBInit1, "CBufferSegment: Init, length="}, 39 {kLogCBInit2, "CBufferSegment: Init, buffer="}, 40 41 {kLogIOAllocBuf, "CBufferSegment: ioalloc, buffer="}, 42 {kLogIOAllocSize, "CBufferSegment: ioalloc, size="}, 43 {kLogIOFreeBuf, "CBufferSegment: iofree, buffer="}, 44 {kLogIOFreeSize, "CBufferSegment: iofree, size="} 45}; 46#define XTRACE(x, y, z) IrDALogAdd( x, y, (uintptr_t)z & 0xffff, TraceEvents, true ) 47#else 48#define XTRACE(x, y, z) ((void) 0) 49#endif 50 51#define super CBuffer 52 OSDefineMetaClassAndStructors(CBufferSegment, CBuffer); 53 54 55//-------------------------------------------------------------------------------- 56// CBufferSegment::New 57// This is the preferred method (and easiest) of getting a statically 58// allocated CbufferSegment and its associated buffer. Initializes 59// the object also. 60// 61//-------------------------------------------------------------------------------- 62CBufferSegment * CBufferSegment::New(Size len) 63{ 64#pragma unused(len) 65 //int Fix_Unused_Length; 66 67 CBufferSegment *obj = new CBufferSegment; 68 69 XTRACE(kLogNew, 0, obj); 70 71 if (obj && !obj->Init(nil, kDefaultCBufferSize)) { // alloc a big buffer 72 obj->release(); 73 obj = nil; 74 } 75 76 return obj; 77} 78 79CBufferSegment * CBufferSegment::New(UByte *buffer, Size len) 80{ 81 CBufferSegment *obj = new CBufferSegment; 82 83 XTRACE(kLogNewWith, 0, obj); 84 XTRACE(kLogNewWith, 0, buffer); 85 86 if (obj && !obj->Init(buffer, len)) { 87 obj->release(); 88 obj = nil; 89 } 90 91 return obj; 92} 93 94//-------------------------------------------------------------------------------- 95// CBufferSegment::Delete 96// Old naming style, just calls release 97//-------------------------------------------------------------------------------- 98/*void 99CBufferSegment::Delete() 100{ 101 XTRACE( kLogDelete, (int)this >> 16, (int)this); 102 103 this->release(); 104}*/ 105 106//-------------------------------------------------------------------------------- 107// CBufferSegment::free 108//-------------------------------------------------------------------------------- 109void 110CBufferSegment::free(void) 111{ 112 XTRACE(kLogFree1, 0, this); 113 XTRACE(kLogFree2, (uintptr_t)fBufBase>>16, fBufBase); 114 115 if (fFreeMe && fBufBase) { 116 check(fSize); 117 XTRACE(kLogIOFreeBuf, 0, fBufBase); 118 XTRACE(kLogIOFreeSize, fSize >> 16, fSize); 119 IOFree(fBufBase, fSize); 120 fBufBase = nil; 121 fSize = 0; 122 } 123 124 super::free(); 125} 126 127 128//-------------------------------------------------------------------------------- 129// CBufferSegment::init 130//-------------------------------------------------------------------------------- 131Boolean CBufferSegment::Init(UByte *buffer, Size len) 132{ 133 XTRACE(kLogCBInit1, 0, len); 134 135 fBufBase = nil; 136 137 if (!super::init()) return false; 138 139 if (buffer == nil) { // callers wants us to alloc and free 140 fBufBase = (UByte*)IOMalloc(len); 141 XTRACE(kLogIOAllocBuf, 0, fBufBase); 142 XTRACE(kLogIOAllocSize, len >> 16, len); 143 require(fBufBase, Fail); 144 fFreeMe = true; 145 } else { 146 fBufBase = buffer; 147 fFreeMe = false; 148 } 149 150 XTRACE(kLogCBInit2, (uintptr_t)fBufBase>>16, fBufBase); 151 152 fSize = len; 153 fBufEnd = fBufBase + fSize; 154 155 // the whole buffer is available 156 157 fBase = fMark = fBufBase; 158 fEnd = fBufEnd; 159 160 return true; 161 162Fail: 163 return false; 164 165} // CBufferSegment::init 166 167 168//-------------------------------------------------------------------------------- 169// CBufferSegment::Peek 170//-------------------------------------------------------------------------------- 171int CBufferSegment::Peek() 172{ 173 return (fMark >= fEnd) ? EOF : *fMark; 174 175} // CBufferSegment::Peek 176 177 178//-------------------------------------------------------------------------------- 179// CBufferSegment::Next 180//-------------------------------------------------------------------------------- 181int CBufferSegment::Next() 182{ 183 return (fMark >= fEnd) ? EOF : *(++fMark); 184 185} // CBufferSegment::Next 186 187 188//-------------------------------------------------------------------------------- 189// CBufferSegment::Skip 190//-------------------------------------------------------------------------------- 191uintptr_t CBufferSegment::Skip() 192{ 193 return (fMark >= fEnd) ? EOF : (uintptr_t)fMark++; 194 195} // CBufferSegment::Skip 196 197 198//-------------------------------------------------------------------------------- 199// CBufferSegment::Get 200//-------------------------------------------------------------------------------- 201int CBufferSegment::Get() 202{ 203 return (fMark >= fEnd) ? EOF : *fMark++; 204 205} // CBufferSegment::Get 206 207 208//-------------------------------------------------------------------------------- 209// CBufferSegment::Getn 210//-------------------------------------------------------------------------------- 211Size CBufferSegment::Getn(UByte* p, Size n) 212{ 213 if (n > 0) 214 { 215 n = Min(n, fEnd - fMark); 216 if (n > 0) 217 { 218 BlockMove(fMark, p, n); 219 fMark += n; 220 } 221 } 222 223 return n; 224 225} // CBufferSegment::Getn 226 227 228//-------------------------------------------------------------------------------- 229// CBufferSegment::CopyOut 230//-------------------------------------------------------------------------------- 231int CBufferSegment::CopyOut(UByte* p, Size& n) 232{ 233 int result = 0; 234 235 if (n > 0) 236 { 237 n -= Getn(p, n); 238 if (fMark == fEnd) 239 result = EOF; 240 } 241 242 return result; 243 244} // CBufferSegment::CopyOut 245 246 247//-------------------------------------------------------------------------------- 248// CBufferSegment::Put 249//-------------------------------------------------------------------------------- 250int CBufferSegment::Put(int b) 251{ 252 return (fMark >= fEnd) ? EOF : (*fMark++ = b); 253 254} // CBufferSegment::Put 255 256 257//-------------------------------------------------------------------------------- 258// CBufferSegment::Putn 259//-------------------------------------------------------------------------------- 260Size CBufferSegment::Putn(const UByte* p, Size n) 261{ 262 if (n > 0) 263 { 264 n = Min(n, fEnd - fMark); 265 if (n > 0) 266 { 267 BlockMove(p, fMark, n); 268 fMark += n; 269 } 270 } 271 272 return n; 273 274} // CBufferSegment::Putn 275 276 277//-------------------------------------------------------------------------------- 278// CBufferSegment::CopyIn 279//-------------------------------------------------------------------------------- 280int CBufferSegment::CopyIn(const UByte* p, Size& n) 281{ 282 int result = 0; 283 284 if (n > 0) 285 { 286 n -= Putn(p, n); 287 if (fMark == fEnd) 288 return EOF; 289 } 290 291 return result; 292 293} // CBufferSegment::CopyIn 294 295 296//-------------------------------------------------------------------------------- 297// CBufferSegment::Reset 298//-------------------------------------------------------------------------------- 299void CBufferSegment::Reset() 300{ 301 fBase = fMark = fBufBase; 302 fEnd = fBufEnd; 303 304} // CBufferSegment::Reset 305 306 307//-------------------------------------------------------------------------------- 308// CBufferSegment::Hide 309//-------------------------------------------------------------------------------- 310Size CBufferSegment::Hide(Long count, int dir) 311{ 312 if (count == 0) 313 return 0; 314 315 switch (dir) 316 { 317 case kPosBeg: 318 fBase += count; 319 if (fBase < fBufBase) 320 { 321 count += (Long) (fBufBase - fBase); 322 fBase = fBufBase; 323 } 324 else if (fBase > fBufEnd) 325 { 326 count -= (Long) (fBase - fBufEnd); 327 fBase = fBufEnd; 328 } 329 fMark = fBase; 330 break; 331 332 case kPosEnd: 333 fEnd -= count; 334 if (fEnd < fBufBase) 335 { 336 count -= (Long) (fBufBase - fEnd); 337 fEnd = fBufBase; 338 } 339 else if (fEnd > fBufEnd) 340 { 341 count += (Long) (fEnd - fBufEnd); 342 fEnd = fBufEnd; 343 } 344 fMark = fEnd; 345 break; 346 347 default: 348 count = 0; 349 break; 350 } 351 352 return count; 353 354} // CBufferSegment::Hide 355 356 357//-------------------------------------------------------------------------------- 358// CBufferSegment::Seek 359//-------------------------------------------------------------------------------- 360Size CBufferSegment::Seek(Long off, int dir) 361{ 362 UByte* newPos; 363 364 // quick check for simple cases 365 366 if (off == 0) 367 { 368 if (dir == kPosBeg) 369 fMark = fBase; 370 371 else if (dir == kPosEnd) 372 fMark = fEnd; 373 374 else if (dir == kPosCur) 375 /* no change */; 376 } 377 378 else 379 { 380 switch (dir) 381 { 382 case kPosBeg: 383 newPos = fBase + off; 384 break; 385 386 case kPosCur: 387 newPos = fMark + off; 388 break; 389 390 case kPosEnd: 391 newPos = fEnd - off; 392 break; 393 394 default: 395 newPos = fMark; 396 break; 397 } 398 399 fMark = (UByte*) UMinMax((uintptr_t) fBase, (uintptr_t) newPos, (uintptr_t) fEnd); 400 } 401 402 return (Size) (fMark - fBase); 403 404} // CBufferSegment::Seek 405 406 407//-------------------------------------------------------------------------------- 408// CBufferSegment::Position 409//-------------------------------------------------------------------------------- 410Size CBufferSegment::Position() const 411{ 412 return (Size) (fMark ? (fMark - fBase) : 0); 413 414} // CBufferSegment::Position 415 416 417//-------------------------------------------------------------------------------- 418// CBufferSegment::GetSize 419//-------------------------------------------------------------------------------- 420Size CBufferSegment::GetSize() const 421{ 422 return (Size) (fEnd - fBase); 423 424} // CBufferSegment::GetSize 425 426 427//-------------------------------------------------------------------------------- 428// CBufferSegment::AtEOF 429//-------------------------------------------------------------------------------- 430Boolean CBufferSegment::AtEOF() const 431{ 432 return (fMark == fEnd); 433 434} // CBufferSegment::AtEOF 435 436