1///////////////////////////////////////////////////////////////////////////// 2// Name: src/common/datstrm.cpp 3// Purpose: Data stream classes 4// Author: Guilhem Lavaux 5// Modified by: Mickael Gilabert 6// Created: 28/06/98 7// RCS-ID: $Id: datstrm.cpp 53028 2008-04-05 17:28:32Z VZ $ 8// Copyright: (c) Guilhem Lavaux 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16 #pragma hdrstop 17#endif 18 19#if wxUSE_STREAMS 20 21#include "wx/datstrm.h" 22 23#ifndef WX_PRECOMP 24 #include "wx/math.h" 25#endif //WX_PRECOMP 26 27// --------------------------------------------------------------------------- 28// wxDataInputStream 29// --------------------------------------------------------------------------- 30 31#if wxUSE_UNICODE 32wxDataInputStream::wxDataInputStream(wxInputStream& s, const wxMBConv& conv) 33 : m_input(&s), m_be_order(false), m_conv(conv.Clone()) 34#else 35wxDataInputStream::wxDataInputStream(wxInputStream& s) 36 : m_input(&s), m_be_order(false) 37#endif 38{ 39} 40 41wxDataInputStream::~wxDataInputStream() 42{ 43#if wxUSE_UNICODE 44 delete m_conv; 45#endif // wxUSE_UNICODE 46} 47 48#if wxHAS_INT64 49wxUint64 wxDataInputStream::Read64() 50{ 51 wxUint64 tmp; 52 Read64(&tmp, 1); 53 return tmp; 54} 55#endif // wxHAS_INT64 56 57wxUint32 wxDataInputStream::Read32() 58{ 59 wxUint32 i32; 60 61 m_input->Read(&i32, 4); 62 63 if (m_be_order) 64 return wxUINT32_SWAP_ON_LE(i32); 65 else 66 return wxUINT32_SWAP_ON_BE(i32); 67} 68 69wxUint16 wxDataInputStream::Read16() 70{ 71 wxUint16 i16; 72 73 m_input->Read(&i16, 2); 74 75 if (m_be_order) 76 return wxUINT16_SWAP_ON_LE(i16); 77 else 78 return wxUINT16_SWAP_ON_BE(i16); 79} 80 81wxUint8 wxDataInputStream::Read8() 82{ 83 wxUint8 buf; 84 85 m_input->Read(&buf, 1); 86 return (wxUint8)buf; 87} 88 89double wxDataInputStream::ReadDouble() 90{ 91#if wxUSE_APPLE_IEEE 92 char buf[10]; 93 94 m_input->Read(buf, 10); 95 return ConvertFromIeeeExtended((const wxInt8 *)buf); 96#else 97 return 0.0; 98#endif 99} 100 101wxString wxDataInputStream::ReadString() 102{ 103 wxString ret; 104 105 const size_t len = Read32(); 106 if ( len > 0 ) 107 { 108#if wxUSE_UNICODE 109 wxCharBuffer tmp(len + 1); 110 if ( tmp ) 111 { 112 m_input->Read(tmp.data(), len); 113 tmp.data()[len] = '\0'; 114 ret = m_conv->cMB2WX(tmp.data()); 115 } 116#else 117 wxStringBuffer buf(ret, len); 118 if ( buf ) 119 m_input->Read(buf, len); 120#endif 121 } 122 123 return ret; 124} 125 126#if wxUSE_LONGLONG 127 128template <class T> 129static 130void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order) 131{ 132 typedef T DataType; 133 unsigned char *pchBuffer = new unsigned char[size * 8]; 134 // TODO: Check for overflow when size is of type uint and is > than 512m 135 input->Read(pchBuffer, size * 8); 136 size_t idx_base = 0; 137 if ( be_order ) 138 { 139 for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex ) 140 { 141 buffer[uiIndex] = 0l; 142 for ( unsigned ui = 0; ui != 8; ++ui ) 143 { 144 buffer[uiIndex] = buffer[uiIndex] * 256l + 145 DataType((unsigned long) pchBuffer[idx_base + ui]); 146 } 147 148 idx_base += 8; 149 } 150 } 151 else // little endian 152 { 153 for ( size_t uiIndex=0; uiIndex!=size; ++uiIndex ) 154 { 155 buffer[uiIndex] = 0l; 156 for ( unsigned ui=0; ui!=8; ++ui ) 157 buffer[uiIndex] = buffer[uiIndex] * 256l + 158 DataType((unsigned long) pchBuffer[idx_base + 7 - ui]); 159 idx_base += 8; 160 } 161 } 162 delete[] pchBuffer; 163} 164 165template <class T> 166static void DoWriteLL(const T *buffer, size_t size, wxOutputStream *output, bool be_order) 167{ 168 typedef T DataType; 169 unsigned char *pchBuffer = new unsigned char[size * 8]; 170 size_t idx_base = 0; 171 if ( be_order ) 172 { 173 for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex ) 174 { 175 DataType i64 = buffer[uiIndex]; 176 for ( unsigned ui = 0; ui != 8; ++ui ) 177 { 178 pchBuffer[idx_base + 7 - ui] = 179 (unsigned char) (i64.GetLo() & 255l); 180 i64 >>= 8l; 181 } 182 183 idx_base += 8; 184 } 185 } 186 else // little endian 187 { 188 for ( size_t uiIndex=0; uiIndex != size; ++uiIndex ) 189 { 190 DataType i64 = buffer[uiIndex]; 191 for (unsigned ui=0; ui!=8; ++ui) 192 { 193 pchBuffer[idx_base + ui] = 194 (unsigned char) (i64.GetLo() & 255l); 195 i64 >>= 8l; 196 } 197 198 idx_base += 8; 199 } 200 } 201 202 // TODO: Check for overflow when size is of type uint and is > than 512m 203 output->Write(pchBuffer, size * 8); 204 delete[] pchBuffer; 205} 206 207#endif // wxUSE_LONGLONG 208 209#ifdef wxLongLong_t 210 211template <class T> 212static 213void DoReadI64(T *buffer, size_t size, wxInputStream *input, bool be_order) 214{ 215 typedef T DataType; 216 unsigned char *pchBuffer = (unsigned char*) buffer; 217 // TODO: Check for overflow when size is of type uint and is > than 512m 218 input->Read(pchBuffer, size * 8); 219 if ( be_order ) 220 { 221 for ( wxUint32 i = 0; i < size; i++ ) 222 { 223 DataType v = wxUINT64_SWAP_ON_LE(*buffer); 224 *(buffer++) = v; 225 } 226 } 227 else // little endian 228 { 229 for ( wxUint32 i=0; i<size; i++ ) 230 { 231 DataType v = wxUINT64_SWAP_ON_BE(*buffer); 232 *(buffer++) = v; 233 } 234 } 235} 236 237template <class T> 238static 239void DoWriteI64(const T *buffer, size_t size, wxOutputStream *output, bool be_order) 240{ 241 typedef T DataType; 242 if ( be_order ) 243 { 244 for ( size_t i = 0; i < size; i++ ) 245 { 246 DataType i64 = wxUINT64_SWAP_ON_LE(*buffer); 247 buffer++; 248 output->Write(&i64, 8); 249 } 250 } 251 else // little endian 252 { 253 for ( size_t i=0; i < size; i++ ) 254 { 255 DataType i64 = wxUINT64_SWAP_ON_BE(*buffer); 256 buffer++; 257 output->Write(&i64, 8); 258 } 259 } 260} 261 262#endif // wxLongLong_t 263 264 265#if wxHAS_INT64 266void wxDataInputStream::Read64(wxUint64 *buffer, size_t size) 267{ 268#ifndef wxLongLong_t 269 DoReadLL(buffer, size, m_input, m_be_order); 270#else 271 DoReadI64(buffer, size, m_input, m_be_order); 272#endif 273} 274 275void wxDataInputStream::Read64(wxInt64 *buffer, size_t size) 276{ 277#ifndef wxLongLong_t 278 DoReadLL(buffer, size, m_input, m_be_order); 279#else 280 DoReadI64(buffer, size, m_input, m_be_order); 281#endif 282} 283#endif // wxHAS_INT64 284 285#if defined(wxLongLong_t) && wxUSE_LONGLONG 286void wxDataInputStream::Read64(wxULongLong *buffer, size_t size) 287{ 288 DoReadLL(buffer, size, m_input, m_be_order); 289} 290 291void wxDataInputStream::Read64(wxLongLong *buffer, size_t size) 292{ 293 DoReadLL(buffer, size, m_input, m_be_order); 294} 295#endif // wxLongLong_t 296 297#if wxUSE_LONGLONG 298void wxDataInputStream::ReadLL(wxULongLong *buffer, size_t size) 299{ 300 DoReadLL(buffer, size, m_input, m_be_order); 301} 302 303void wxDataInputStream::ReadLL(wxLongLong *buffer, size_t size) 304{ 305 DoReadLL(buffer, size, m_input, m_be_order); 306} 307 308wxLongLong wxDataInputStream::ReadLL(void) 309{ 310 wxLongLong ll; 311 DoReadLL(&ll, (size_t)1, m_input, m_be_order); 312 return ll; 313} 314#endif // wxUSE_LONGLONG 315 316void wxDataInputStream::Read32(wxUint32 *buffer, size_t size) 317{ 318 m_input->Read(buffer, size * 4); 319 320 if (m_be_order) 321 { 322 for (wxUint32 i=0; i<size; i++) 323 { 324 wxUint32 v = wxUINT32_SWAP_ON_LE(*buffer); 325 *(buffer++) = v; 326 } 327 } 328 else 329 { 330 for (wxUint32 i=0; i<size; i++) 331 { 332 wxUint32 v = wxUINT32_SWAP_ON_BE(*buffer); 333 *(buffer++) = v; 334 } 335 } 336} 337 338void wxDataInputStream::Read16(wxUint16 *buffer, size_t size) 339{ 340 m_input->Read(buffer, size * 2); 341 342 if (m_be_order) 343 { 344 for (wxUint32 i=0; i<size; i++) 345 { 346 wxUint16 v = wxUINT16_SWAP_ON_LE(*buffer); 347 *(buffer++) = v; 348 } 349 } 350 else 351 { 352 for (wxUint32 i=0; i<size; i++) 353 { 354 wxUint16 v = wxUINT16_SWAP_ON_BE(*buffer); 355 *(buffer++) = v; 356 } 357 } 358} 359 360void wxDataInputStream::Read8(wxUint8 *buffer, size_t size) 361{ 362 m_input->Read(buffer, size); 363} 364 365void wxDataInputStream::ReadDouble(double *buffer, size_t size) 366{ 367 for (wxUint32 i=0; i<size; i++) 368 { 369 *(buffer++) = ReadDouble(); 370 } 371} 372 373wxDataInputStream& wxDataInputStream::operator>>(wxString& s) 374{ 375 s = ReadString(); 376 return *this; 377} 378 379wxDataInputStream& wxDataInputStream::operator>>(wxInt8& c) 380{ 381 c = (wxInt8)Read8(); 382 return *this; 383} 384 385wxDataInputStream& wxDataInputStream::operator>>(wxInt16& i) 386{ 387 i = (wxInt16)Read16(); 388 return *this; 389} 390 391wxDataInputStream& wxDataInputStream::operator>>(wxInt32& i) 392{ 393 i = (wxInt32)Read32(); 394 return *this; 395} 396 397wxDataInputStream& wxDataInputStream::operator>>(wxUint8& c) 398{ 399 c = Read8(); 400 return *this; 401} 402 403wxDataInputStream& wxDataInputStream::operator>>(wxUint16& i) 404{ 405 i = Read16(); 406 return *this; 407} 408 409wxDataInputStream& wxDataInputStream::operator>>(wxUint32& i) 410{ 411 i = Read32(); 412 return *this; 413} 414 415#if wxHAS_INT64 416wxDataInputStream& wxDataInputStream::operator>>(wxUint64& i) 417{ 418 i = Read64(); 419 return *this; 420} 421 422wxDataInputStream& wxDataInputStream::operator>>(wxInt64& i) 423{ 424 i = Read64(); 425 return *this; 426} 427#endif // wxHAS_INT64 428 429#if defined(wxLongLong_t) && wxUSE_LONGLONG 430wxDataInputStream& wxDataInputStream::operator>>(wxULongLong& i) 431{ 432 i = ReadLL(); 433 return *this; 434} 435 436wxDataInputStream& wxDataInputStream::operator>>(wxLongLong& i) 437{ 438 i = ReadLL(); 439 return *this; 440} 441#endif // wxLongLong_t 442 443wxDataInputStream& wxDataInputStream::operator>>(double& i) 444{ 445 i = ReadDouble(); 446 return *this; 447} 448 449wxDataInputStream& wxDataInputStream::operator>>(float& f) 450{ 451 f = (float)ReadDouble(); 452 return *this; 453} 454 455// --------------------------------------------------------------------------- 456// wxDataOutputStream 457// --------------------------------------------------------------------------- 458 459#if wxUSE_UNICODE 460wxDataOutputStream::wxDataOutputStream(wxOutputStream& s, const wxMBConv& conv) 461 : m_output(&s), m_be_order(false), m_conv(conv.Clone()) 462#else 463wxDataOutputStream::wxDataOutputStream(wxOutputStream& s) 464 : m_output(&s), m_be_order(false) 465#endif 466{ 467} 468 469wxDataOutputStream::~wxDataOutputStream() 470{ 471#if wxUSE_UNICODE 472 delete m_conv; 473#endif // wxUSE_UNICODE 474} 475 476#if wxHAS_INT64 477void wxDataOutputStream::Write64(wxUint64 i) 478{ 479 Write64(&i, 1); 480} 481 482void wxDataOutputStream::Write64(wxInt64 i) 483{ 484 Write64(&i, 1); 485} 486#endif // wxHAS_INT64 487 488void wxDataOutputStream::Write32(wxUint32 i) 489{ 490 wxUint32 i32; 491 492 if (m_be_order) 493 i32 = wxUINT32_SWAP_ON_LE(i); 494 else 495 i32 = wxUINT32_SWAP_ON_BE(i); 496 m_output->Write(&i32, 4); 497} 498 499void wxDataOutputStream::Write16(wxUint16 i) 500{ 501 wxUint16 i16; 502 503 if (m_be_order) 504 i16 = wxUINT16_SWAP_ON_LE(i); 505 else 506 i16 = wxUINT16_SWAP_ON_BE(i); 507 508 m_output->Write(&i16, 2); 509} 510 511void wxDataOutputStream::Write8(wxUint8 i) 512{ 513 m_output->Write(&i, 1); 514} 515 516void wxDataOutputStream::WriteString(const wxString& string) 517{ 518#if wxUSE_UNICODE 519 const wxWX2MBbuf buf = string.mb_str(*m_conv); 520#else 521 const wxWX2MBbuf buf = string.mb_str(); 522#endif 523 size_t len = strlen(buf); 524 Write32(len); 525 if (len > 0) 526 m_output->Write(buf, len); 527} 528 529void wxDataOutputStream::WriteDouble(double d) 530{ 531 char buf[10]; 532 533#if wxUSE_APPLE_IEEE 534 ConvertToIeeeExtended(d, (wxInt8 *)buf); 535#else 536#if !defined(__VMS__) && !defined(__GNUG__) 537# pragma warning "wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!" 538#endif 539 buf[0] = '\0'; 540#endif 541 m_output->Write(buf, 10); 542} 543 544#if wxHAS_INT64 545void wxDataOutputStream::Write64(const wxUint64 *buffer, size_t size) 546{ 547#ifndef wxLongLong_t 548 DoWriteLL(buffer, size, m_output, m_be_order); 549#else 550 DoWriteI64(buffer, size, m_output, m_be_order); 551#endif 552} 553 554void wxDataOutputStream::Write64(const wxInt64 *buffer, size_t size) 555{ 556#ifndef wxLongLong_t 557 DoWriteLL(buffer, size, m_output, m_be_order); 558#else 559 DoWriteI64(buffer, size, m_output, m_be_order); 560#endif 561} 562#endif // wxHAS_INT64 563 564#if defined(wxLongLong_t) && wxUSE_LONGLONG 565void wxDataOutputStream::Write64(const wxULongLong *buffer, size_t size) 566{ 567 DoWriteLL(buffer, size, m_output, m_be_order); 568} 569 570void wxDataOutputStream::Write64(const wxLongLong *buffer, size_t size) 571{ 572 DoWriteLL(buffer, size, m_output, m_be_order); 573} 574#endif // wxLongLong_t 575 576#if wxUSE_LONGLONG 577void wxDataOutputStream::WriteLL(const wxULongLong *buffer, size_t size) 578{ 579 DoWriteLL(buffer, size, m_output, m_be_order); 580} 581 582void wxDataOutputStream::WriteLL(const wxLongLong *buffer, size_t size) 583{ 584 DoWriteLL(buffer, size, m_output, m_be_order); 585} 586 587void wxDataOutputStream::WriteLL(const wxLongLong &ll) 588{ 589 WriteLL(&ll, 1); 590} 591 592void wxDataOutputStream::WriteLL(const wxULongLong &ll) 593{ 594 WriteLL(&ll, 1); 595} 596#endif // wxUSE_LONGLONG 597 598void wxDataOutputStream::Write32(const wxUint32 *buffer, size_t size) 599{ 600 if (m_be_order) 601 { 602 for (wxUint32 i=0; i<size ;i++) 603 { 604 wxUint32 i32 = wxUINT32_SWAP_ON_LE(*buffer); 605 buffer++; 606 m_output->Write(&i32, 4); 607 } 608 } 609 else 610 { 611 for (wxUint32 i=0; i<size ;i++) 612 { 613 wxUint32 i32 = wxUINT32_SWAP_ON_BE(*buffer); 614 buffer++; 615 m_output->Write(&i32, 4); 616 } 617 } 618} 619 620void wxDataOutputStream::Write16(const wxUint16 *buffer, size_t size) 621{ 622 if (m_be_order) 623 { 624 for (wxUint32 i=0; i<size ;i++) 625 { 626 wxUint16 i16 = wxUINT16_SWAP_ON_LE(*buffer); 627 buffer++; 628 m_output->Write(&i16, 2); 629 } 630 } 631 else 632 { 633 for (wxUint32 i=0; i<size ;i++) 634 { 635 wxUint16 i16 = wxUINT16_SWAP_ON_BE(*buffer); 636 buffer++; 637 m_output->Write(&i16, 2); 638 } 639 } 640} 641 642void wxDataOutputStream::Write8(const wxUint8 *buffer, size_t size) 643{ 644 m_output->Write(buffer, size); 645} 646 647void wxDataOutputStream::WriteDouble(const double *buffer, size_t size) 648{ 649 for (wxUint32 i=0; i<size; i++) 650 { 651 WriteDouble(*(buffer++)); 652 } 653} 654 655wxDataOutputStream& wxDataOutputStream::operator<<(const wxChar *string) 656{ 657 Write32(wxStrlen(string)); 658 m_output->Write((const char *)string, wxStrlen(string)*sizeof(wxChar)); 659 return *this; 660} 661 662wxDataOutputStream& wxDataOutputStream::operator<<(const wxString& string) 663{ 664 WriteString(string); 665 return *this; 666} 667 668wxDataOutputStream& wxDataOutputStream::operator<<(wxInt8 c) 669{ 670 Write8((wxUint8)c); 671 return *this; 672} 673 674wxDataOutputStream& wxDataOutputStream::operator<<(wxInt16 i) 675{ 676 Write16((wxUint16)i); 677 return *this; 678} 679 680wxDataOutputStream& wxDataOutputStream::operator<<(wxInt32 i) 681{ 682 Write32((wxUint32)i); 683 return *this; 684} 685 686wxDataOutputStream& wxDataOutputStream::operator<<(wxUint8 c) 687{ 688 Write8(c); 689 return *this; 690} 691 692wxDataOutputStream& wxDataOutputStream::operator<<(wxUint16 i) 693{ 694 Write16(i); 695 return *this; 696} 697 698wxDataOutputStream& wxDataOutputStream::operator<<(wxUint32 i) 699{ 700 Write32(i); 701 return *this; 702} 703 704#if wxHAS_INT64 705wxDataOutputStream& wxDataOutputStream::operator<<(wxUint64 i) 706{ 707 Write64(i); 708 return *this; 709} 710 711wxDataOutputStream& wxDataOutputStream::operator<<(wxInt64 i) 712{ 713 Write64(i); 714 return *this; 715} 716#endif // wxHAS_INT64 717 718#if defined(wxLongLong_t) && wxUSE_LONGLONG 719wxDataOutputStream& wxDataOutputStream::operator<<(const wxULongLong &i) 720{ 721 WriteLL(i); 722 return *this; 723} 724 725wxDataOutputStream& wxDataOutputStream::operator<<(const wxLongLong &i) 726{ 727 WriteLL(i); 728 return *this; 729} 730#endif // wxLongLong_t 731 732wxDataOutputStream& wxDataOutputStream::operator<<(double f) 733{ 734 WriteDouble(f); 735 return *this; 736} 737 738wxDataOutputStream& wxDataOutputStream::operator<<(float f) 739{ 740 WriteDouble((double)f); 741 return *this; 742} 743 744#endif 745 // wxUSE_STREAMS 746