00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "pandaFileStreamBuf.h"
00016 #include "memoryHook.h"
00017 #include "filename.h"
00018 #include "textEncoder.h"
00019
00020 #ifdef USE_PANDAFILESTREAM
00021
00022 #ifndef _WIN32
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <fcntl.h>
00026 #include <errno.h>
00027 #endif // _WIN32
00028
00029 PandaFileStreamBuf::NewlineMode PandaFileStreamBuf::_newline_mode = NM_native;
00030
00031 static const size_t file_buffer_size = 4096;
00032
00033
00034
00035
00036
00037
00038 PandaFileStreamBuf::
00039 PandaFileStreamBuf() {
00040 _is_open = false;
00041 _open_mode = (ios::openmode)0;
00042
00043 _last_read_nl = 0;
00044
00045 #ifdef _WIN32
00046
00047 _handle = NULL;
00048 #else
00049 _fd = -1;
00050 #endif // _WIN32
00051
00052 #ifdef PHAVE_IOSTREAM
00053 _buffer = (char *)PANDA_MALLOC_ARRAY(file_buffer_size * 2);
00054 char *ebuf = _buffer + file_buffer_size * 2;
00055 char *mbuf = _buffer + file_buffer_size;
00056 setg(_buffer, mbuf, mbuf);
00057 setp(mbuf, ebuf);
00058
00059 #else
00060 allocate();
00061
00062
00063 char *b = base();
00064 char *t = ebuf();
00065 char *m = b + (t - b) / 2;
00066 setg(b, m, m);
00067 setp(b, m);
00068 #endif
00069
00070 _gpos = 0;
00071 _ppos = 0;
00072 }
00073
00074
00075
00076
00077
00078
00079 PandaFileStreamBuf::
00080 ~PandaFileStreamBuf() {
00081 close();
00082 #ifdef PHAVE_IOSTREAM
00083 PANDA_FREE_ARRAY(_buffer);
00084 #endif
00085 }
00086
00087
00088
00089
00090
00091
00092 void PandaFileStreamBuf::
00093 open(const char *filename, ios::openmode mode) {
00094 close();
00095
00096 _filename = filename;
00097 _open_mode = mode;
00098 _is_open = false;
00099
00100 if (_open_mode & ios::app) {
00101
00102 _open_mode |= ios::out;
00103 }
00104
00105 #ifdef _WIN32
00106
00107 DWORD access = 0;
00108 if (_open_mode & ios::in) {
00109 access |= GENERIC_READ;
00110 }
00111 if (_open_mode & ios::out) {
00112 access |= GENERIC_WRITE;
00113 }
00114
00115 DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
00116
00117 DWORD creation_disposition = 0;
00118 if ((_open_mode & (ios::trunc | ios::out)) == (ios::trunc | ios::out)) {
00119 creation_disposition = CREATE_ALWAYS;
00120 } else if (_open_mode & ios::out) {
00121 creation_disposition = OPEN_ALWAYS;
00122 } else {
00123 creation_disposition = OPEN_EXISTING;
00124 }
00125
00126 DWORD flags = 0;
00127
00128 if (!(_open_mode & ios::out)) {
00129 flags |= FILE_ATTRIBUTE_READONLY;
00130 }
00131
00132 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
00133
00134 flags |= FILE_FLAG_OVERLAPPED;
00135 #endif
00136
00137 TextEncoder encoder;
00138 encoder.set_encoding(Filename::get_filesystem_encoding());
00139 encoder.set_text(_filename);
00140 wstring wfilename = encoder.get_wtext();
00141 _handle = CreateFileW(wfilename.c_str(), access, share_mode,
00142 NULL, creation_disposition, flags, NULL);
00143 if (_handle != INVALID_HANDLE_VALUE) {
00144
00145 _is_open = true;
00146 }
00147
00148 #else
00149
00150 int flags = 0;
00151
00152 if ((_open_mode & (ios::in | ios::out)) == (ios::in | ios::out)) {
00153 flags |= O_RDWR | O_CREAT;
00154 } else if (_open_mode & ios::in) {
00155 flags |= O_RDONLY;
00156 } else if (_open_mode & ios::out) {
00157 flags |= O_WRONLY | O_CREAT;
00158 }
00159
00160 if (_open_mode & ios::app) {
00161 flags |= O_APPEND;
00162 }
00163
00164 if ((_open_mode & (ios::trunc | ios::out)) == (ios::trunc | ios::out)) {
00165 flags |= O_TRUNC;
00166 }
00167
00168 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
00169
00170 flags |= O_NONBLOCK;
00171 #endif
00172
00173 _fd = ::open(_filename.c_str(), flags, 0666);
00174 while (_fd == -1 && errno == EAGAIN) {
00175 thread_yield();
00176 _fd = ::open(_filename.c_str(), flags, 0666);
00177 }
00178
00179 if (_fd != -1) {
00180 _is_open = true;
00181 }
00182 #endif // _WIN32
00183
00184 }
00185
00186 #ifdef _WIN32
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 void PandaFileStreamBuf::
00199 attach(const char *filename, HANDLE handle, ios::openmode mode) {
00200 close();
00201
00202 _filename = filename;
00203 _open_mode = mode;
00204 _is_open = false;
00205
00206 if (_open_mode & ios::app) {
00207
00208 _open_mode |= ios::out;
00209 }
00210
00211 _handle = handle;
00212 if (_handle != INVALID_HANDLE_VALUE) {
00213
00214 _is_open = true;
00215 }
00216 }
00217 #endif // _WIN32
00218
00219 #ifndef _WIN32
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 void PandaFileStreamBuf::
00232 attach(const char *filename, int fd, ios::openmode mode) {
00233 close();
00234
00235 _filename = filename;
00236 _open_mode = mode;
00237 _is_open = false;
00238
00239 if (_open_mode & ios::app) {
00240
00241 _open_mode |= ios::out;
00242 }
00243
00244 _fd = fd;
00245 if (_fd != -1) {
00246
00247 _is_open = true;
00248 }
00249 }
00250 #endif // _WIN32
00251
00252
00253
00254
00255
00256
00257 bool PandaFileStreamBuf::
00258 is_open() const {
00259 return _is_open;
00260 }
00261
00262
00263
00264
00265
00266
00267 void PandaFileStreamBuf::
00268 close() {
00269
00270 sync();
00271
00272 #ifdef _WIN32
00273 if (_handle != NULL) {
00274 CloseHandle(_handle);
00275 }
00276 _handle = NULL;
00277 #else
00278 if (_fd != -1) {
00279 ::close(_fd);
00280 }
00281 _fd = -1;
00282 #endif // _WIN32
00283
00284 _is_open = false;
00285 _open_mode = (ios::openmode)0;
00286
00287 _gpos = 0;
00288 _ppos = 0;
00289
00290 pbump(pbase() - pptr());
00291 gbump(egptr() - gptr());
00292 }
00293
00294
00295
00296
00297
00298
00299 streampos PandaFileStreamBuf::
00300 seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
00301 streampos result = -1;
00302
00303 if (!(_open_mode & ios::binary)) {
00304
00305
00306 if (off != 0 || dir != ios::beg) {
00307 return -1;
00308 }
00309
00310 _last_read_nl = 0;
00311 }
00312
00313
00314 sync();
00315
00316 if (which & ios::in) {
00317
00318 size_t n = egptr() - gptr();
00319 gbump(n);
00320 _gpos -= n;
00321 assert(_gpos >= 0);
00322 size_t cur_pos = _gpos;
00323 size_t new_pos = cur_pos;
00324
00325
00326 switch (dir) {
00327 case ios::beg:
00328 new_pos = (size_t)off;
00329 break;
00330
00331 case ios::cur:
00332 new_pos = (size_t)((int)cur_pos + off);
00333 break;
00334
00335 case ios::end:
00336 #ifdef _WIN32
00337
00338 {
00339 LARGE_INTEGER li;
00340 GetFileSizeEx(_handle, &li);
00341 new_pos = (streampos)li.QuadPart + off;
00342 }
00343 #else
00344
00345 {
00346 off_t li = lseek(_fd, off, SEEK_END);
00347 if (li == (size_t)-1) {
00348 return -1;
00349 }
00350 new_pos = (size_t)li;
00351 }
00352 #endif // _WIN32
00353 break;
00354
00355 default:
00356
00357 break;
00358 }
00359
00360 _gpos = new_pos;
00361 assert(_gpos >= 0);
00362 result = new_pos;
00363 }
00364
00365 if (which & ios::out) {
00366
00367 size_t n = pptr() - pbase();
00368 streampos cur_pos = _ppos + (streamoff)n;
00369 streampos new_pos = cur_pos;
00370
00371
00372 switch (dir) {
00373 case ios::beg:
00374 new_pos = (streampos)off;
00375 break;
00376
00377 case ios::cur:
00378 new_pos = (streampos)((int)cur_pos + off);
00379 break;
00380
00381 case ios::end:
00382 #ifdef _WIN32
00383
00384 {
00385 LARGE_INTEGER li;
00386 GetFileSizeEx(_handle, &li);
00387 new_pos = (streampos)li.QuadPart + off;
00388 }
00389 #else
00390
00391 new_pos = lseek(_fd, off, SEEK_END);
00392 if (new_pos == (streampos)-1) {
00393 return -1;
00394 }
00395 #endif // _WIN32
00396 break;
00397
00398 default:
00399
00400 break;
00401 }
00402
00403 _ppos = new_pos;
00404 assert(_ppos >= 0);
00405 result = new_pos;
00406 }
00407
00408 return result;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 streampos PandaFileStreamBuf::
00426 seekpos(streampos pos, ios_openmode which) {
00427 return seekoff(pos, ios::beg, which);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 int PandaFileStreamBuf::
00437 overflow(int ch) {
00438 bool okflag = true;
00439
00440 size_t n = pptr() - pbase();
00441 if (n != 0) {
00442 size_t wrote = write_chars(pbase(), n);
00443 pbump(-(int)wrote);
00444 if (wrote != n) {
00445 okflag = false;
00446 }
00447 }
00448
00449 if (okflag && ch != EOF) {
00450 if (pptr() != epptr()) {
00451
00452 *(pptr()) = ch;
00453 pbump(1);
00454 } else {
00455
00456 okflag = false;
00457 }
00458 }
00459
00460 if (!okflag) {
00461 return EOF;
00462 }
00463 return 0;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472 int PandaFileStreamBuf::
00473 sync() {
00474 size_t n = pptr() - pbase();
00475
00476 size_t wrote = write_chars(pbase(), n);
00477 pbump(-(int)wrote);
00478
00479 if (n != wrote) {
00480 return EOF;
00481 }
00482 return 0;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 int PandaFileStreamBuf::
00492 underflow() {
00493
00494 if (gptr() >= egptr()) {
00495 sync();
00496
00497
00498 size_t buffer_size = egptr() - eback();
00499 gbump(-(int)buffer_size);
00500
00501 size_t num_bytes = buffer_size;
00502 size_t read_count = read_chars(gptr(), buffer_size);
00503
00504 if (read_count != num_bytes) {
00505
00506 if (read_count == 0) {
00507 gbump(num_bytes);
00508 return EOF;
00509 }
00510
00511
00512 assert(read_count < num_bytes);
00513 size_t delta = num_bytes - read_count;
00514 memmove(gptr() + delta, gptr(), read_count);
00515 gbump(delta);
00516 }
00517 }
00518
00519 return (unsigned char)*gptr();
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 size_t PandaFileStreamBuf::
00530 read_chars(char *start, size_t length) {
00531 if (length == 0 || !_is_open) {
00532
00533 return 0;
00534 }
00535
00536
00537 sync();
00538
00539 if (_open_mode & ios::binary) {
00540
00541
00542 return read_chars_raw(start, length);
00543 }
00544
00545
00546
00547 if (_newline_mode == NM_binary) {
00548
00549 return read_chars_raw(start, length);
00550 }
00551
00552 char *buffer = (char *)alloca(length);
00553
00554 size_t read_length;
00555 size_t final_length;
00556 do {
00557 read_length = length - 1;
00558 if (_last_read_nl != 0) {
00559
00560
00561
00562
00563
00564 --read_length;
00565 }
00566 read_length = read_chars_raw(buffer, read_length);
00567 final_length = decode_newlines(start, length, buffer, read_length);
00568
00569
00570
00571 } while (read_length != 0 && final_length == 0);
00572
00573 return final_length;
00574 }
00575
00576
00577
00578
00579
00580
00581
00582 size_t PandaFileStreamBuf::
00583 write_chars(const char *start, size_t length) {
00584 if (length == 0) {
00585
00586 return 0;
00587 }
00588
00589
00590 size_t n = egptr() - gptr();
00591 gbump(n);
00592 _gpos -= n;
00593 assert(_gpos >= 0);
00594
00595
00596 if (_open_mode & ios::binary) {
00597
00598
00599 return write_chars_raw(start, length);
00600 }
00601
00602
00603
00604
00605 NewlineMode this_newline_mode = _newline_mode;
00606 if (this_newline_mode == NM_native) {
00607 #ifdef _WIN32
00608 this_newline_mode = NM_msdos;
00609 #else
00610
00611 this_newline_mode = NM_unix;
00612 #endif
00613 }
00614
00615 if (this_newline_mode == NM_binary) {
00616 return write_chars_raw(start, length);
00617 }
00618
00619 size_t buffer_length = length;
00620 if (this_newline_mode == NM_msdos) {
00621
00622
00623 buffer_length *= 2;
00624 }
00625 char *buffer = (char *)alloca(buffer_length);
00626
00627 size_t write_length;
00628 switch (this_newline_mode) {
00629 case NM_msdos:
00630 write_length = encode_newlines_msdos(buffer, buffer_length, start, length);
00631 break;
00632
00633 case NM_mac:
00634 write_length = encode_newlines_mac(buffer, buffer_length, start, length);
00635 break;
00636
00637 default:
00638 write_length = encode_newlines_unix(buffer, buffer_length, start, length);
00639 break;
00640 }
00641
00642 if (write_length == write_chars_raw(buffer, write_length)) {
00643
00644 return length;
00645 }
00646
00647
00648 return 0;
00649 }
00650
00651
00652
00653
00654
00655
00656
00657
00658 size_t PandaFileStreamBuf::
00659 read_chars_raw(char *start, size_t length) {
00660 if (length == 0) {
00661 return 0;
00662 }
00663
00664 #ifdef _WIN32
00665
00666 OVERLAPPED overlapped;
00667 memset(&overlapped, 0, sizeof(overlapped));
00668 LARGE_INTEGER gpos;
00669 gpos.QuadPart = _gpos;
00670 overlapped.Offset = gpos.LowPart;
00671 overlapped.OffsetHigh = gpos.HighPart;
00672
00673 DWORD bytes_read = 0;
00674 BOOL success = ReadFile(_handle, start, length, &bytes_read, &overlapped);
00675 int pass = 0;
00676 while (!success) {
00677 DWORD error = GetLastError();
00678 if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) {
00679
00680
00681
00682
00683 if (pass > 0) {
00684 thread_yield();
00685 }
00686 } else if (error == ERROR_HANDLE_EOF || error == ERROR_BROKEN_PIPE) {
00687
00688 break;
00689 } else {
00690 cerr
00691 << "Error reading " << length
00692 << " bytes from " << _filename << ", windows error code 0x" << hex
00693 << error << dec << ".\n";
00694 return 0;
00695 }
00696 ++pass;
00697 success = GetOverlappedResult(_handle, &overlapped, &bytes_read, false);
00698 }
00699
00700 length = bytes_read;
00701
00702 #else
00703
00704 if (lseek(_fd, _gpos, SEEK_SET) == -1) {
00705 cerr
00706 << "Error seeking to position " << _gpos << " in " << _filename << "\n";
00707 return 0;
00708 }
00709
00710 ssize_t result = ::read(_fd, start, length);
00711 while (result < 0) {
00712 if (errno == EAGAIN) {
00713 thread_yield();
00714 } else {
00715 cerr
00716 << "Error reading " << length << " bytes from " << _filename << "\n";
00717 return 0;
00718 }
00719 result = ::read(_fd, start, length);
00720 }
00721
00722 length = result;
00723 #endif // _WIN32
00724
00725 _gpos += length;
00726 assert(_gpos >= 0);
00727 return length;
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 size_t PandaFileStreamBuf::
00737 write_chars_raw(const char *start, size_t length) {
00738 if (length == 0 || !_is_open) {
00739 return 0;
00740 }
00741
00742 #ifdef _WIN32
00743
00744 OVERLAPPED overlapped;
00745 memset(&overlapped, 0, sizeof(overlapped));
00746 LARGE_INTEGER ppos;
00747 ppos.QuadPart = _ppos;
00748 overlapped.Offset = ppos.LowPart;
00749 overlapped.OffsetHigh = ppos.HighPart;
00750
00751 if (_open_mode & ios::app) {
00752 overlapped.Offset = -1;
00753 overlapped.OffsetHigh = -1;
00754 }
00755
00756 DWORD bytes_written = 0;
00757 BOOL success = WriteFile(_handle, start, length, &bytes_written, &overlapped);
00758 int pass = 0;
00759 while (!success) {
00760 DWORD error = GetLastError();
00761 if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) {
00762
00763
00764
00765
00766 if (pass > 0) {
00767 thread_yield();
00768 }
00769 } else if (error == ERROR_BROKEN_PIPE) {
00770
00771 cerr << "Pipe closed on " << _filename << "\n";
00772 return bytes_written;
00773 } else {
00774 cerr
00775 << "Error writing " << length
00776 << " bytes to " << _filename << ", windows error code 0x" << hex
00777 << error << dec << ". Disk full?\n";
00778 return bytes_written;
00779 }
00780 ++pass;
00781 success = GetOverlappedResult(_handle, &overlapped, &bytes_written, false);
00782 }
00783 assert(bytes_written == length);
00784 _ppos += bytes_written;
00785 assert(_ppos >= 0);
00786
00787 #else
00788
00789 if (!(_open_mode & ios::app)) {
00790 if (lseek(_fd, _ppos, SEEK_SET) == -1) {
00791 cerr
00792 << "Error seeking to position " << _ppos << " in " << _filename << "\n";
00793 return 0;
00794 }
00795 }
00796
00797 size_t remaining = length;
00798 while (remaining > 0) {
00799 ssize_t result = ::write(_fd, start, remaining);
00800 if (result < 0) {
00801 if (errno == EAGAIN) {
00802 thread_yield();
00803 } else {
00804 cerr
00805 << "Error writing " << remaining << " bytes to " << _filename << "\n";
00806 return length - remaining;
00807 }
00808 continue;
00809 }
00810
00811 start += result;
00812 remaining -= result;
00813 _ppos += result;
00814 assert(_ppos >= 0);
00815 }
00816 #endif // _WIN32
00817
00818 return length;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 size_t PandaFileStreamBuf::
00833 decode_newlines(char *dest, size_t dest_length,
00834 const char *source, size_t source_length) {
00835 const char *p = source;
00836 char *q = dest;
00837
00838 if (source_length == 0) {
00839
00840
00841 switch (_last_read_nl) {
00842 case '\n':
00843 case '\r':
00844
00845 assert(q < dest + dest_length);
00846 *q++ = '\n';
00847 _last_read_nl = 0;
00848 break;
00849 default:
00850 break;
00851 }
00852 }
00853
00854 while (p < source + source_length) {
00855 assert(q < dest + dest_length);
00856 switch (*p) {
00857 case '\n':
00858 switch (_last_read_nl) {
00859 case '\r':
00860
00861 *q++ = '\n';
00862 _last_read_nl = 0;
00863 break;
00864 case '\n':
00865
00866 *q++ = '\n';
00867 _last_read_nl = '\n';
00868 break;
00869 default:
00870
00871 _last_read_nl = '\n';
00872 break;
00873 }
00874 break;
00875
00876 case '\r':
00877 switch (_last_read_nl) {
00878 case '\n':
00879
00880 *q++ = '\n';
00881 _last_read_nl = 0;
00882 break;
00883 case '\r':
00884
00885 *q++ = '\n';
00886 _last_read_nl = '\r';
00887 break;
00888 default:
00889
00890 _last_read_nl = '\r';
00891 break;
00892 }
00893 break;
00894
00895 default:
00896 switch (_last_read_nl) {
00897 case '\n':
00898 case '\r':
00899
00900 *q++ = '\n';
00901 _last_read_nl = 0;
00902 break;
00903 default:
00904 break;
00905 }
00906 assert(q < dest + dest_length);
00907 *q++ = *p;
00908 }
00909 ++p;
00910 }
00911
00912 return q - dest;
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 size_t PandaFileStreamBuf::
00926 encode_newlines_msdos(char *dest, size_t dest_length,
00927 const char *source, size_t source_length) {
00928 const char *p = source;
00929 char *q = dest;
00930
00931 while (p < source + source_length) {
00932 assert(q < dest + dest_length);
00933 switch (*p) {
00934 case '\n':
00935 *q++ = '\r';
00936 assert(q < dest + dest_length);
00937 *q++ = '\n';
00938 break;
00939
00940 case '\r':
00941
00942 break;
00943
00944 default:
00945 *q++ = *p;
00946 break;
00947 }
00948
00949 ++p;
00950 }
00951
00952 return q - dest;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 size_t PandaFileStreamBuf::
00969 encode_newlines_unix(char *dest, size_t dest_length,
00970 const char *source, size_t source_length) {
00971 const char *p = source;
00972 char *q = dest;
00973
00974 while (p < source + source_length) {
00975 assert(q < dest + dest_length);
00976 switch (*p) {
00977 case '\r':
00978 break;
00979
00980 default:
00981 *q++ = *p;
00982 break;
00983 }
00984
00985 ++p;
00986 }
00987
00988 return q - dest;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998 size_t PandaFileStreamBuf::
00999 encode_newlines_mac(char *dest, size_t dest_length,
01000 const char *source, size_t source_length) {
01001 const char *p = source;
01002 char *q = dest;
01003
01004 while (p < source + source_length) {
01005 assert(q < dest + dest_length);
01006 switch (*p) {
01007 case '\n':
01008 *q++ = '\r';
01009 break;
01010
01011 case '\r':
01012 break;
01013
01014 default:
01015 *q++ = *p;
01016 break;
01017 }
01018
01019 ++p;
01020 }
01021
01022 return q - dest;
01023 }
01024
01025 ostream &
01026 operator << (ostream &out, PandaFileStreamBuf::NewlineMode newline_mode) {
01027 switch (newline_mode) {
01028 case PandaFileStreamBuf::NM_native:
01029 return out << "native";
01030
01031 case PandaFileStreamBuf::NM_binary:
01032 return out << "binary";
01033
01034 case PandaFileStreamBuf::NM_msdos:
01035 return out << "msdos";
01036
01037 case PandaFileStreamBuf::NM_unix:
01038 return out << "unix";
01039
01040 case PandaFileStreamBuf::NM_mac:
01041 return out << "mac";
01042 }
01043
01044 cerr
01045 << "Invalid NewlineMode value: " << (int)newline_mode << "\n";
01046 return out;
01047 }
01048
01049 istream &
01050 operator >> (istream &in, PandaFileStreamBuf::NewlineMode &newline_mode) {
01051 string word;
01052 in >> word;
01053
01054 if (word == "native") {
01055 newline_mode = PandaFileStreamBuf::NM_native;
01056 } else if (word == "binary") {
01057 newline_mode = PandaFileStreamBuf::NM_binary;
01058 } else if (word == "msdos") {
01059 newline_mode = PandaFileStreamBuf::NM_msdos;
01060 } else if (word == "unix") {
01061 newline_mode = PandaFileStreamBuf::NM_unix;
01062 } else if (word == "mac") {
01063 newline_mode = PandaFileStreamBuf::NM_mac;
01064 } else {
01065 cerr
01066 << "Invalid NewlineMode value: " << word << "\n";
01067 newline_mode = PandaFileStreamBuf::NM_native;
01068 }
01069
01070 return in;
01071 }
01072
01073 #endif // USE_PANDAFILESTREAM