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 29const static int16 NO_BITS_IN_BYTE = 8; 30const static uint8 BYTE_MASK = 0xff; 31 32#include "oscl_mem_basic_functions.h" 33 34OSCL_INLINE bool OsclBinStream::good() 35{ 36 return state == GOOD_STATE; 37} 38 39OSCL_INLINE bool OsclBinStream::eof() 40{ 41 return state == EOF_STATE; 42} 43 44OSCL_INLINE bool OsclBinStream::fail() 45{ 46 return state == FAIL_STATE; 47} 48 49OSCL_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 62OSCL_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 81OSCL_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 93OSCL_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 139OSCL_INLINE uint32 OsclBinStream::PositionInBlock() 140{ 141 return pPosition - pBasePosition; 142} 143 144OSCL_INLINE void OsclBinStream::seekFromCurrentPosition(int32 offset) 145{ 146 Seek(tellg() + offset); 147} 148 149OSCL_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 168OSCL_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*/ 186OSCL_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 205OSCL_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*/ 252OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int8 & data) 253{ 254 data = int8(Read_uint8()); 255 return *this; 256} 257 258OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint8 & data) 259{ 260 data = Read_uint8(); 261 return *this; 262} 263 264OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int16 & data) 265{ 266 data = int16(Read_uint16()); 267 268 return *this; 269} 270 271OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint16 & data) 272{ 273 data = Read_uint16(); 274 275 return *this; 276} 277 278OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(int32 & data) 279{ 280 data = int32(Read_uint32()); 281 return *this; 282} 283 284OSCL_INLINE OsclBinIStreamLittleEndian & OsclBinIStreamLittleEndian::operator>>(uint32 & data) 285{ 286 data = Read_uint32(); 287 return *this; 288} 289 290OSCL_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 313OSCL_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*/ 359OSCL_INLINE void OsclBinIStreamBigEndian::Read(int8 & data) 360{ 361 data = int8(Read_uint8()); 362} 363 364OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint8 & data) 365{ 366 data = Read_uint8(); 367} 368 369OSCL_INLINE void OsclBinIStreamBigEndian::Read(int16 & data) 370{ 371 data = int16(Read_uint16()); 372} 373 374OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint16 & data) 375{ 376 data = Read_uint16(); 377} 378 379OSCL_INLINE void OsclBinIStreamBigEndian::Read(int32 & data) 380{ 381 data = int32(Read_uint32()); 382} 383 384OSCL_INLINE void OsclBinIStreamBigEndian::Read(uint32 & data) 385{ 386 data = Read_uint32(); 387} 388 389OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int8 & data) 390{ 391 data = int8(Read_uint8()); 392 return *this; 393} 394 395OSCL_INLINE OsclBinIStream & OsclBinIStreamBigEndian::operator>>(uint8 & data) 396{ 397 data = Read_uint8(); 398 return *this; 399} 400 401OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int16 & data) 402{ 403 data = int16(Read_uint16()); 404 return *this; 405} 406 407OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(uint16 & data) 408{ 409 data = Read_uint16(); 410 return *this; 411} 412 413OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(int32 & data) 414{ 415 data = int32(Read_uint32()); 416 return *this; 417} 418 419OSCL_INLINE OsclBinIStreamBigEndian & OsclBinIStreamBigEndian::operator>>(uint32 & data) 420{ 421 data = Read_uint32(); 422 return *this; 423} 424 425OSCL_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 449OSCL_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 487OSCL_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*/ 504OSCL_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 514OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint8 & data) 515{ 516 if (ReserveSpace(sizeof(data))) 517 { 518 *pPosition++ = data; 519 } 520 return *this; 521} 522 523OSCL_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 533OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint16 & data) 534{ 535 if (ReserveSpace(sizeof(data))) 536 { 537 WriteUnsignedShort(data); 538 } 539 return *this; 540} 541 542OSCL_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 552OSCL_INLINE OsclBinOStreamLittleEndian & OsclBinOStreamLittleEndian::operator<<(const uint32 & data) 553{ 554 if (ReserveSpace(sizeof(data))) 555 { 556 WriteUnsignedLong(data); 557 } 558 559 return *this; 560} 561 562OSCL_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 577OSCL_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 596OSCL_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 607OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint8 & data) 608{ 609 if (ReserveSpace(sizeof(data))) 610 { 611 *pPosition++ = data; 612 } 613 return *this; 614} 615 616OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const int16 & data) 617{ 618 if (ReserveSpace(sizeof(data))) 619 { 620 WriteUnsignedShort((uint16)data); 621 } 622 return *this; 623} 624 625OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint16 & data) 626{ 627 if (ReserveSpace(sizeof(data))) 628 { 629 WriteUnsignedShort(data); 630 } 631 return *this; 632} 633 634OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const int32 & data) 635{ 636 if (ReserveSpace(sizeof(data))) 637 { 638 WriteUnsignedLong(uint32(data)); 639 } 640 return *this; 641} 642 643OSCL_INLINE OsclBinOStreamBigEndian & OsclBinOStreamBigEndian::operator<<(const uint32 & data) 644{ 645 if (ReserveSpace(sizeof(data))) 646 { 647 WriteUnsignedLong(data); 648 } 649 650 return *this; 651} 652 653OSCL_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 668OSCL_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