1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 // -*- c++ -*- 19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 20 21 // O S C L _ B I N _ S T R E A M 22 23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 24 25 /* 26 ** Constants 27 */ 28 29 const static int16 NO_BITS_IN_BYTE = 8; 30 const static uint8 BYTE_MASK = 0xff; 31 32 #include "oscl_mem_basic_functions.h" 33 34 OSCL_INLINE bool OsclBinStream::good() 35 { 36 return state == GOOD_STATE; 37 } 38 39 OSCL_INLINE bool OsclBinStream::eof() 40 { 41 return state == EOF_STATE; 42 } 43 44 OSCL_INLINE bool OsclBinStream::fail() 45 { 46 return state == FAIL_STATE; 47 } 48 49 OSCL_INLINE void OsclBinStream::Attach(void * buffer, uint32 l_length) 50 { 51 fragsLeft = 0; 52 pBasePosition = (uint8 *)buffer; 53 pPosition = pBasePosition; 54 length = l_length; 55 state = GOOD_STATE; 56 specialFragBuffer.ptr = buffer; 57 specialFragBuffer.len = l_length; 58 numFrags = 1; 59 firstFragPtr = &specialFragBuffer; 60 } 61 62 OSCL_INLINE void OsclBinStream::Attach(const uint32 numFragments, const OsclMemoryFragment * fragPtr) 63 { 64 pBasePosition = (uint8 *)fragPtr->ptr; 65 pPosition = pBasePosition; 66 numFrags = numFragments; 67 firstFragPtr = fragPtr; 68 length = fragPtr->len; 69 if (numFragments > 1) 70 { 71 fragsLeft = numFragments - 1; 72 nextFragPtr = fragPtr + 1; 73 } 74 else 75 { 76 fragsLeft = 0; 77 } 78 state = GOOD_STATE; 79 } 80 81 OSCL_INLINE uint32 OsclBinStream::tellg() 82 { 83 uint32 pos = 0; 84 for (int ii = 0; ii < numFrags - fragsLeft - 1; ii++) 85 { 86 pos += firstFragPtr[ii].len; 87 } 88 pos += PositionInBlock(); 89 90 return pos; 91 } 92 93 OSCL_INLINE void OsclBinStream::Seek(uint32 absPosition) 94 { 95 uint32 pos = 0; 96 int fragIndex; 97 98 for (fragIndex = 0; 99 fragIndex < numFrags && absPosition >= pos + firstFragPtr[fragIndex].len; 100 fragIndex++) 101 { 102 pos += firstFragPtr[fragIndex].len; 103 } 104 105 if (fragIndex >= numFrags) 106 { 107 fragsLeft = 0; 108 pBasePosition = (uint8 *)firstFragPtr[numFrags-1].ptr; 109 length = firstFragPtr[numFrags-1].len; 110 pPosition = pBasePosition + length; 111 if (absPosition == pos) 112 { 113 state = EOF_STATE; 114 } 115 else 116 { 117 state = FAIL_STATE; 118 } 119 return; 120 } 121 122 // otherwise there is more data 123 nextFragPtr = &firstFragPtr[fragIndex + 1]; 124 fragsLeft = numFrags - fragIndex - 1; 125 pBasePosition = (uint8 *)firstFragPtr[fragIndex].ptr; 126 length = firstFragPtr[fragIndex].len; 127 uint32 reqBytes = absPosition - pos; 128 if (reqBytes <= length) 129 { 130 pPosition = pBasePosition + reqBytes; 131 } 132 else 133 { 134 pPosition = pBasePosition + length; 135 state = FAIL_STATE; 136 } 137 } 138 139 OSCL_INLINE uint32 OsclBinStream::PositionInBlock() 140 { 141 return pPosition - pBasePosition; 142 } 143 144 OSCL_INLINE void OsclBinStream::seekFromCurrentPosition(int32 offset) 145 { 146 Seek(tellg() + offset); 147 } 148 149 OSCL_INLINE bool OsclBinStream::ReserveSpace(uint32 size) 150 { 151 if (fail()) 152 { 153 return false; 154 } 155 uint32 newSize = PositionInBlock() + size; 156 if (newSize > length) 157 { 158 state = FAIL_STATE; 159 return false; 160 } 161 if (newSize == length) 162 { 163 state = EOF_STATE; 164 } 165 return true; 166 } 167 168 OSCL_INLINE bool OsclBinStream::HaveRoomInCurrentBlock(uint32 size) 169 { 170 uint32 pos = PositionInBlock() + size; 171 if (pos < length) 172 { 173 return true; 174 } 175 if (pos == length && fragsLeft == 0) 176 { 177 state = EOF_STATE; 178 } 179 return (pos <= length); 180 } 181 182 /* 183 ** Class OsclBinIStream 184 ** This class implements the basic stream functions for an input stream. 185 */ 186 OSCL_INLINE uint8 OsclBinIStream::Read_uint8() 187 { 188 if (HaveRoomInCurrentBlock(sizeof(uint8))) 189 { 190 return (*pPosition++); 191 } 192 if (fragsLeft) 193 { 194 pBasePosition = (uint8 *)nextFragPtr->ptr; 195 pPosition = pBasePosition; 196 length = nextFragPtr->len; 197 fragsLeft--; 198 nextFragPtr++; 199 return (*pPosition++); 200 } 201 state = FAIL_STATE; 202 return 0; 203 } 204 205 OSCL_INLINE OsclBinIStream & OsclBinIStream::get( 206 int8 * data, /* Pointer to the place to store the bytes read */ 207 int32 size /* Number of bytes to read */ 208 ) 209 { 210 if (HaveRoomInCurrentBlock(size)) 211 { 212 oscl_memcpy(data, pPosition, size); 213 pPosition += size; 214 } 215 else 216 { 217 uint32 pos = PositionInBlock(); 218 uint32 bytesToCopy = length - pos; 219 oscl_memcpy(data, pPosition, bytesToCopy); 220 data += bytesToCopy; 221 uint32 bytesLeft = size - bytesToCopy; 222 while (bytesLeft > 0 && fragsLeft) 223 { 224 pBasePosition = (uint8 *)nextFragPtr->ptr; 225 pPosition = pBasePosition; 226 length = nextFragPtr->len; 227 fragsLeft--; 228 nextFragPtr++; 229 230 if (bytesLeft <= length) 231 { 232 bytesToCopy = bytesLeft; 233 } 234 else 235 { 236 bytesToCopy = length; 237 } 238 239 oscl_memcpy(data, pPosition, bytesToCopy); 240 data += bytesToCopy; 241 pPosition += bytesToCopy; 242 bytesLeft -= bytesToCopy; 243 } 244 } 245 return *this; 246 } 247 248 /* 249 ** Class OsclBinIStreamLittleEndian 250 ** This class implements a binary input stream using little endian byte ordering 251 */ 252 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int8 & data) 253 { 254 data = int8(Read_uint8()); 255 return *this; 256 } 257 258 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint8 & data) 259 { 260 data = Read_uint8(); 261 return *this; 262 } 263 264 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int16 & data) 265 { 266 data = int16(Read_uint16()); 267 268 return *this; 269 } 270 271 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint16 & data) 272 { 273 data = Read_uint16(); 274 275 return *this; 276 } 277 278 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int32 & data) 279 { 280 data = int32(Read_uint32()); 281 return *this; 282 } 283 284 OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint32 & data) 285 { 286 data = Read_uint32(); 287 return *this; 288 } 289 290 OSCL_INLINE uint16 OsclBinIStreamLittleEndian::Read_uint16() 291 { 292 if (HaveRoomInCurrentBlock(sizeof(uint16))) 293 { 294 #if defined(BYTE_ORDER_LITTLE_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 295 uint16 *ptr = (uint16 *)pPosition; 296 pPosition += sizeof(uint16); 297 return *ptr; 298 #else 299 uint16 byteB = *pPosition++; 300 uint16 byteA = *pPosition++; 301 302 return ((byteA << NO_BITS_IN_BYTE) | byteB); 303 #endif 304 } 305 else 306 { 307 uint16 byteB = Read_uint8(); 308 uint16 byteA = Read_uint8(); 309 return ((byteA << NO_BITS_IN_BYTE) | byteB); 310 } 311 } 312 313 OSCL_INLINE uint32 OsclBinIStreamLittleEndian::Read_uint32() 314 { 315 if (HaveRoomInCurrentBlock(sizeof(uint32))) 316 { 317 #if defined(BYTE_ORDER_LITTLE_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 318 uint32 *ptr = (uint32 *)pPosition; 319 pPosition += sizeof(uint32); 320 return *ptr; 321 #else 322 uint32 result; 323 uint8 byteD = *pPosition++; 324 uint8 byteC = *pPosition++; 325 uint8 byteB = *pPosition++; 326 uint8 byteA = *pPosition++; 327 328 result = byteA; 329 result = (result << NO_BITS_IN_BYTE) | byteB; 330 result = (result << NO_BITS_IN_BYTE) | byteC; 331 result = (result << NO_BITS_IN_BYTE) | byteD; 332 333 return result; 334 #endif 335 } 336 else 337 { 338 uint32 result; 339 uint8 byteD = Read_uint8(); 340 uint8 byteC = Read_uint8(); 341 uint8 byteB = Read_uint8(); 342 uint8 byteA = Read_uint8(); 343 344 result = byteA; 345 result = (result << NO_BITS_IN_BYTE) | byteB; 346 result = (result << NO_BITS_IN_BYTE) | byteC; 347 result = (result << NO_BITS_IN_BYTE) | byteD; 348 349 return result; 350 } 351 } 352 353 354 355 /* 356 ** Class OsclBinIStreamBigEndian 357 ** This class implements a binary input stream using big endian byte ordering 358 */ 359 OSCL_INLINE void OsclBinIStreamBigEndian::Read(int8 & data) 360 { 361 data = int8(Read_uint8()); 362 } 363 364 OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint8 & data) 365 { 366 data = Read_uint8(); 367 } 368 369 OSCL_INLINE void OsclBinIStreamBigEndian::Read(int16 & data) 370 { 371 data = int16(Read_uint16()); 372 } 373 374 OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint16 & data) 375 { 376 data = Read_uint16(); 377 } 378 379 OSCL_INLINE void OsclBinIStreamBigEndian::Read(int32 & data) 380 { 381 data = int32(Read_uint32()); 382 } 383 384 OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint32 & data) 385 { 386 data = Read_uint32(); 387 } 388 389 OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int8 & data) 390 { 391 data = int8(Read_uint8()); 392 return *this; 393 } 394 395 OSCL_INLINE OsclBinIStream & OsclBinIStreamBigEndian::operator>>(uint8 & data) 396 { 397 data = Read_uint8(); 398 return *this; 399 } 400 401 OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int16 & data) 402 { 403 data = int16(Read_uint16()); 404 return *this; 405 } 406 407 OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(uint16 & data) 408 { 409 data = Read_uint16(); 410 return *this; 411 } 412 413 OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int32 & data) 414 { 415 data = int32(Read_uint32()); 416 return *this; 417 } 418 419 OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(uint32 & data) 420 { 421 data = Read_uint32(); 422 return *this; 423 } 424 425 OSCL_INLINE uint16 OsclBinIStreamBigEndian::Read_uint16() 426 { 427 if (HaveRoomInCurrentBlock(sizeof(uint16))) 428 { 429 #if defined(BYTE_ORDER_BIG_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 430 uint16 *ptr = (uint16 *)pPosition; 431 pPosition += sizeof(uint16); 432 return *ptr; 433 #else 434 uint16 byteA = *pPosition++; 435 uint16 byteB = *pPosition++; 436 437 return ((byteA << NO_BITS_IN_BYTE) | byteB); 438 #endif 439 } 440 else 441 { 442 uint16 byteA = Read_uint8(); 443 uint16 byteB = Read_uint8(); 444 445 return ((byteA << NO_BITS_IN_BYTE) | byteB); 446 } 447 } 448 449 OSCL_INLINE uint32 OsclBinIStreamBigEndian::Read_uint32() 450 { 451 if (HaveRoomInCurrentBlock(sizeof(uint32))) 452 { 453 #if defined(BYTE_ORDER_BIG_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 454 uint32 *ptr = (uint32 *)pPosition; 455 pPosition += sizeof(uint32); 456 return *ptr; 457 #else 458 uint32 result; 459 460 result = *pPosition++; 461 result = (result << NO_BITS_IN_BYTE) | *pPosition++; 462 result = (result << NO_BITS_IN_BYTE) | *pPosition++; 463 result = (result << NO_BITS_IN_BYTE) | *pPosition++; 464 465 return result; 466 #endif 467 } 468 else 469 { 470 uint32 result; 471 472 result = Read_uint8(); 473 result = (result << NO_BITS_IN_BYTE) | Read_uint8(); 474 result = (result << NO_BITS_IN_BYTE) | Read_uint8(); 475 result = (result << NO_BITS_IN_BYTE) | Read_uint8(); 476 477 return result; 478 } 479 } 480 481 482 /* 483 ** Class OsclBinOStream 484 ** This class implements the basic stream functions for an output stream. 485 */ 486 487 OSCL_INLINE OsclBinOStream & OsclBinOStream::write( 488 const int8 * data, /* data to store */ 489 int32 size /* length of data to store */ 490 ) 491 { 492 if (ReserveSpace(size)) 493 { 494 oscl_memcpy(pPosition, data, size); 495 pPosition += size; 496 } 497 return *this; 498 } 499 500 /* 501 ** Class OsclBinOStreamLittleEndian 502 ** This class implements a binary output stream using little endian byte ordering 503 */ 504 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const int8 & data) 505 { 506 if (ReserveSpace(sizeof(data))) 507 { 508 *((int8 *)pPosition) = data; 509 pPosition++; 510 } 511 return *this; 512 } 513 514 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint8 & data) 515 { 516 if (ReserveSpace(sizeof(data))) 517 { 518 *pPosition++ = data; 519 } 520 return *this; 521 } 522 523 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const int16 & data) 524 { 525 if (ReserveSpace(sizeof(data))) 526 { 527 WriteUnsignedShort((uint16)data); 528 } 529 530 return *this; 531 } 532 533 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint16 & data) 534 { 535 if (ReserveSpace(sizeof(data))) 536 { 537 WriteUnsignedShort(data); 538 } 539 return *this; 540 } 541 542 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const int32 & data) 543 { 544 if (ReserveSpace(sizeof(data))) 545 { 546 WriteUnsignedLong(uint32(data)); 547 } 548 549 return *this; 550 } 551 552 OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint32 & data) 553 { 554 if (ReserveSpace(sizeof(data))) 555 { 556 WriteUnsignedLong(data); 557 } 558 559 return *this; 560 } 561 562 OSCL_INLINE void OsclBinOStreamLittleEndian::WriteUnsignedShort(const uint16 data) 563 { 564 #if defined(BYTE_ORDER_LITTLE_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 565 uint16 *ptr = (uint16 *)pPosition; 566 pPosition += sizeof(uint16); 567 *ptr = data; 568 #else 569 uint8 byteB = (uint8)data; 570 uint8 byteA = data >> NO_BITS_IN_BYTE; 571 572 *pPosition++ = byteB; 573 *pPosition++ = byteA; 574 #endif 575 } 576 577 OSCL_INLINE void OsclBinOStreamLittleEndian::WriteUnsignedLong(const uint32 data) 578 { 579 #if defined(BYTE_ORDER_LITTLE_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 580 uint32 *ptr = (uint32 *)pPosition; 581 pPosition += sizeof(uint32); 582 *ptr = data; 583 #else 584 uint32 temp = data; 585 *pPosition++ = (uint8)temp; 586 temp >>= NO_BITS_IN_BYTE; 587 *pPosition++ = (uint8)temp; 588 temp >>= NO_BITS_IN_BYTE; 589 *pPosition++ = (uint8)temp; 590 temp >>= NO_BITS_IN_BYTE; 591 *pPosition++ = (uint8)temp; 592 #endif 593 } 594 595 596 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const int8 & data) 597 { 598 if (ReserveSpace(sizeof(data))) 599 { 600 *((int8 *)pPosition) = data; 601 pPosition++; 602 } 603 604 return *this; 605 } 606 607 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint8 & data) 608 { 609 if (ReserveSpace(sizeof(data))) 610 { 611 *pPosition++ = data; 612 } 613 return *this; 614 } 615 616 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const int16 & data) 617 { 618 if (ReserveSpace(sizeof(data))) 619 { 620 WriteUnsignedShort((uint16)data); 621 } 622 return *this; 623 } 624 625 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint16 & data) 626 { 627 if (ReserveSpace(sizeof(data))) 628 { 629 WriteUnsignedShort(data); 630 } 631 return *this; 632 } 633 634 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const int32 & data) 635 { 636 if (ReserveSpace(sizeof(data))) 637 { 638 WriteUnsignedLong(uint32(data)); 639 } 640 return *this; 641 } 642 643 OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint32 & data) 644 { 645 if (ReserveSpace(sizeof(data))) 646 { 647 WriteUnsignedLong(data); 648 } 649 650 return *this; 651 } 652 653 OSCL_INLINE void OsclBinOStreamBigEndian::WriteUnsignedShort(const uint16 data) 654 { 655 #if defined(BYTE_ORDER_BIG_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 656 uint16 *ptr = (uint16 *)pPosition; 657 pPosition += sizeof(uint16); 658 *ptr = data; 659 #else 660 uint8 byteB = (uint8)data; 661 uint8 byteA = data >> NO_BITS_IN_BYTE; 662 663 *pPosition++ = byteA; 664 *pPosition++ = byteB; 665 #endif 666 } 667 668 OSCL_INLINE void OsclBinOStreamBigEndian::WriteUnsignedLong(const uint32 data) 669 { 670 #if defined(BYTE_ORDER_BIG_ENDIAN) && !defined(INTEGERS_WORD_ALIGNED) 671 uint32 *ptr = (uint32 *)pPosition; 672 pPosition += sizeof(uint32); 673 *ptr = data; 674 #else 675 uint32 temp = data; 676 uint8 byteD = (uint8)temp; 677 temp >>= NO_BITS_IN_BYTE; 678 uint8 byteC = (uint8)temp; 679 temp >>= NO_BITS_IN_BYTE; 680 uint8 byteB = (uint8)temp; 681 temp >>= NO_BITS_IN_BYTE; 682 uint8 byteA = (uint8)temp; 683 684 *pPosition++ = byteA; 685 *pPosition++ = byteB; 686 *pPosition++ = byteC; 687 *pPosition++ = byteD; 688 #endif 689 } 690