fileio.hpp
Go to the documentation of this file.
1// $Id: fileio.hpp 1077 2012-09-24 12:56:09Z perroe $
2
3// Copyright (c) 2011, Norwegian Computing Center
4// All rights reserved.
5// Redistribution and use in source and binary forms, with or without modification,
6// are permitted provided that the following conditions are met:
7// • Redistributions of source code must retain the above copyright notice, this
8// list of conditions and the following disclaimer.
9// • Redistributions in binary form must reproduce the above copyright notice, this list of
10// conditions and the following disclaimer in the documentation and/or other materials
11// provided with the distribution.
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
13// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
15// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
16// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
17// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
19// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
20// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22#ifndef NRLIB_FILEIO_HPP
23#define NRLIB_FILEIO_HPP
24
25#include <string>
26#include <vector>
27#include <iostream>
28
29#include <stdio.h>
30#include <stdlib.h>
31
32#include "stringtools.hpp"
33#include "../exception/exception.hpp"
34
35namespace NRLib {
43 SGRI = 4,
44 SEGY = 5,
46
48 void OpenRead(std::ifstream& stream,
49 const std::string& filename,
50 std::ios_base::openmode mode = std::ios_base::in);
51 void OpenRead(std::fstream& stream,
52 const std::string& filename,
53 std::ios_base::openmode mode = std::ios_base::in);
54
57 void OpenWrite(std::ofstream& stream,
58 const std::string& filename,
59 std::ios_base::openmode mode = std::ios_base::out,
60 bool create_dir = true);
61 void OpenWrite(std::fstream& stream,
62 const std::string& filename ,
63 std::ios_base::openmode mode= std::ios_base::out ,
64 bool create_dir = true);
65
66 void CopyFile(const std::string & from_path,
67 const std::string & to_path,
68 bool allow_overwrite);
69
70 bool FileExists(const std::string& filename);
71
72 void CreateDirIfNotExists(const std::string & filename);
73
74 void RemoveFile(const std::string & filename);
75
78 unsigned long long FindFileSize(const std::string & filename);
79
82 int FindGridFileType(const std::string& filename);
83
84 // ---------------------------------
85 // ASCII read and write
86 // ---------------------------------
87
92 void DiscardRestOfLine(std::istream& stream,
93 int& line_num,
94 bool throw_if_non_whitespace);
95
98 std::istream& GetNextNonEmptyLine(std::istream & stream,
99 int & line_num,
100 std::string & line);
101
105 std::string FindLastNonEmptyLine(std::istream & stream,
106 const std::ios::pos_type & max_line_len = 1000);
107
111 void SkipComments(std::istream & stream,
112 char comment_token,
113 int & line_num);
114
118 bool CheckEndOfFile(std::istream& stream);
119
125 std::istream& ReadNextToken(std::istream& stream, std::string& s, int& line);
126
132 template <typename T>
133 T ReadNext(std::istream& stream, int& line);
134
136 void ReadNextQuoted(std::istream& stream, char quote, std::string& s, int& line);
137
139 template <typename I>
140 void WriteAsciiArray(std::ostream& stream,
141 I begin,
142 I end,
143 int n_per_line = 6);
144
150 template <typename I>
151 I ReadAsciiArray(std::istream& stream, I begin, size_t n, int& line);
152
157 template <typename I>
158 I ReadAsciiArrayFast(std::istream& stream, I begin, size_t n);
159
169 template <typename I>
170 I ReadAsciiArrayFastRestOfFile(std::istream& stream, I begin, size_t n);
171
172 // ---------------------------------
173 // Binary read and write
174 //
175 // 2-byte integer
176 // ---------------------------------
177
179 void WriteBinaryShort(std::ostream& stream,
180 short s,
181 Endianess number_representation = END_BIG_ENDIAN);
182
184 short ReadBinaryShort(std::istream& stream,
185 Endianess number_representation = END_BIG_ENDIAN);
186
188 template<typename I>
189 void WriteBinaryShortArray(std::ostream& stream,
190 I begin,
191 I end,
192 Endianess number_representation = END_BIG_ENDIAN);
193
197 template<typename I>
198 I ReadBinaryShortArray(std::istream& stream,
199 I begin,
200 size_t n,
201 Endianess number_representation = END_BIG_ENDIAN);
202
203 // ---------------------------------
204 // 4-byte integer
205 // ---------------------------------
206
208 void WriteBinaryInt(std::ostream& stream,
209 int i,
210 Endianess number_representation = END_BIG_ENDIAN);
211
213 int ReadBinaryInt(std::istream& stream,
214 Endianess number_representation = END_BIG_ENDIAN);
215
217 template<typename I>
218 void WriteBinaryIntArray(std::ostream& stream,
219 I begin,
220 I end,
221 Endianess number_representation = END_BIG_ENDIAN);
222
226 template<typename I>
227 I ReadBinaryIntArray(std::istream& stream,
228 I begin,
229 size_t n,
230 Endianess number_representation = END_BIG_ENDIAN);
231
232 // ---------------------------------
233 // 4-byte IEEE floating point number
234 // ---------------------------------
235
237 void WriteBinaryFloat(std::ostream& stream,
238 float f,
239 Endianess number_representation = END_BIG_ENDIAN);
240
242 float ReadBinaryFloat(std::istream& stream,
243 Endianess number_representation = END_BIG_ENDIAN);
244
246 template<typename I>
247 void WriteBinaryFloatArray(std::ostream& stream,
248 I begin,
249 I end,
250 Endianess number_representation = END_BIG_ENDIAN);
251
255 template<typename I>
256 I ReadBinaryFloatArray(std::istream& stream,
257 I begin,
258 size_t n,
259 Endianess number_representation = END_BIG_ENDIAN);
260
261 // ---------------------------------
262 // 8-byte IEEE floating point number
263 // ---------------------------------
264
266 void WriteBinaryDouble(std::ostream& stream,
267 double d,
268 Endianess number_representation = END_BIG_ENDIAN);
269
271 double ReadBinaryDouble(std::istream& stream,
272 Endianess number_representation = END_BIG_ENDIAN);
273
275 template<typename I>
276 void WriteBinaryDoubleArray(std::ostream& stream,
277 I begin,
278 I end,
279 Endianess number_representation = END_BIG_ENDIAN);
280
284 template<typename I>
285 I ReadBinaryDoubleArray(std::istream& stream,
286 I begin,
287 size_t n,
288 Endianess number_representation = END_BIG_ENDIAN);
289
290 // ---------------------------------
291 // 4-byte IBM floating point number
292 // ---------------------------------
293
295 void WriteBinaryIbmFloat(std::ostream& stream,
296 float f,
297 Endianess number_representation = END_BIG_ENDIAN);
298
300 float ReadBinaryIbmFloat(std::istream& stream,
301 Endianess number_representation = END_BIG_ENDIAN);
302
304 template<typename I>
305 void WriteBinaryIbmFloatArray(std::ostream& stream,
306 I begin,
307 I end,
308 Endianess number_representation = END_BIG_ENDIAN);
309
313 template<typename I>
314 I ReadBinaryIbmFloatArray(std::istream& stream,
315 I begin,
316 size_t n,
317 Endianess number_representation = END_BIG_ENDIAN);
318
319bool IgnoreComment(std::ifstream& file,
320 char chin);
321
322
323 // ----------------------------------------------------------
324 // Generic seek-function.
325 // Requires FILE *, since streams fail after 2G on windows.
326 // ----------------------------------------------------------
327
329 int Seek(FILE * file, long long offset, int origin);
330
331
332 // ---------------------------------
333 // Parsing of read data
334 // ---------------------------------
335 // The four ParseBE-functions here are needed by the SegY reader in a special case.
336
338 inline void ParseInt16BE(const char* buffer, /*uint16_t*/ short& ui);
339
341 inline void ParseInt32BE(const char* buffer, /*uint32_t*/ int& ui);
342
344 inline void ParseUInt16BE(const char* buffer, /*uint16_t*/ unsigned short& ui);
345
347 inline void ParseUInt32BE(const char* buffer, /*uint32_t*/ unsigned int& ui);
348
350 inline void ParseIEEEFloatBE(const char* buffer, float& f);
351
353 inline void ParseIBMFloatBE(const char* buffer, float& f);
354
355namespace NRLibPrivate {
357 // typedef unsigned int uint32_t;
358 // typedef unsigned long long uint64_t;
359
361 /*uint32_t*/ unsigned int ui;
362 float f;
363 };
364
366 /*uint64_t*/ unsigned long long ull;
367 double d;
368 };
369
370
372 inline void ParseUInt16LE(const char* buffer, /*uint16_t*/ unsigned short& ui);
373
375 inline void WriteUInt16BE(char* buffer, /*uint16_t*/ unsigned short us);
376
378 inline void WriteUInt16LE(char* buffer, /*uint16_t*/ unsigned short us);
379
381 inline void ParseUInt32LE(const char* buffer, /*uint32_t*/ unsigned int& ui);
382
384 inline void WriteUInt32BE(char* buffer, /*uint32_t*/ unsigned int ui);
385
387 inline void WriteUInt32LE(char* buffer, /*uint32_t*/ unsigned int ui);
388
390 inline void ParseIEEEFloatLE(const char* buffer, float& f);
391
393 inline void WriteIEEEFloatBE(char* buffer, float f);
394
396 inline void WriteIEEEFloatLE(char* buffer, float f);
397
399 inline void ParseIEEEDoubleBE(const char* buffer, double& d);
400
402 inline void ParseIEEEDoubleLE(const char* buffer, double& d);
403
405 inline void WriteIEEEDoubleBE(char* buffer, double d);
406
408 inline void WriteIEEEDoubleLE(char* buffer, double d);
409
411 inline void ParseIBMFloatLE(const char* buffer, float& f);
412
414 inline void WriteIBMFloatBE(char* buffer, float f);
415
417 inline void WriteIBMFloatLE(char* buffer, float f);
418} // namespace NRLibPrivate
419
420} // namespace NRLib
421
422
423// ========== INLINE AND TEMPLATE FUNCTION DEFINITIONS =========
424
425namespace NRLib { // Needed to prevent gcc compilation error.
426
427template <>
428inline std::string ReadNext<std::string>(std::istream& stream, int& line)
429{
430 std::string s;
431 ReadNextToken(stream, s, line);
432 if (s == "")
433 throw EndOfFile();
434 return s;
435}
436
437
438template <typename T>
439T ReadNext(std::istream& stream, int& line)
440{
441 std::string s;
442 ReadNextToken(stream, s, line);
443 if (s == "")
444 throw EndOfFile();
445 return ParseType<T>(s);
446}
447
448
449} // namespace NRLib
450
451
452template <typename I>
453void NRLib::WriteAsciiArray(std::ostream& stream,
454 I begin,
455 I end,
456 int n_per_line)
457{
458 int count = 1;
459 for (I it = begin; it != end; ++it, ++count) {
460 stream << *it << ' ';
461 if (count % n_per_line == 0) {
462 stream << '\n';
463 }
464 }
465}
466
467
468template <typename I>
469I NRLib::ReadAsciiArray(std::istream& stream, I begin, size_t n, int& line)
470{
471 typedef typename std::iterator_traits<I>::value_type T;
472 for (size_t i = 0; i < n; ++i) {
473 *begin = ReadNext<T>(stream, line);
474 ++begin;
475 }
476 return begin;
477}
478
479
480template <typename I>
481I NRLib::ReadAsciiArrayFast(std::istream& stream, I begin, size_t n)
482{
483 for (size_t i = 0; i < n; ++i) {
484 stream >> *begin;
485 ++begin;
486 if ( stream.eof() ) {
487 throw EndOfFile();
488 }
489 if ( stream.fail() ) {
490 stream.clear();
491 std::string nextToken;
492 stream >> nextToken;
493 throw Exception("Failure during reading element " + ToString(static_cast<unsigned int>(i)) + " of array. "
494 + "Next token is " + nextToken + "\n");
495 }
496 }
497 return begin;
498}
499
500
501template <typename I>
502I NRLib::ReadAsciiArrayFastRestOfFile(std::istream& stream, I begin, size_t n)
503{
504 std::streampos pos = stream.tellg();
505 stream.seekg(0, std::ios_base::end);
506 std::streampos end = stream.tellg();
507 stream.seekg(pos);
508 size_t len = static_cast<size_t>(end - pos);
509 std::string buffer(len, ' ');
510 stream.read(&buffer[0], len);
511
512 return ParseAsciiArrayFast(buffer, begin, n);
513}
514
515
516template <typename I>
517void NRLib::WriteBinaryShortArray(std::ostream& stream,
518 I begin,
519 I end,
520 NRLib::Endianess number_representation)
521{
522 using namespace NRLib::NRLibPrivate;
523
524 typename I::difference_type n_char = 2*std::distance(begin, end);
525 std::vector<char> buffer(n_char);
526
527 switch (number_representation) {
528 case END_BIG_ENDIAN:
529 for (int i = 0; begin != end; ++begin, ++i) {
530 WriteUInt16BE(&buffer[2*i], static_cast<unsigned short>(*begin));
531 }
532 break;
534 for (int i = 0; begin != end; ++begin, ++i) {
535 WriteUInt16LE(&buffer[2*i], static_cast<unsigned short>(*begin));
536 }
537 break;
538 default:
539 throw Exception("Invalid number representation.");
540 }
541
542 if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) {
543 throw Exception("Error writing to stream.");
544 }
545}
546
547
548template <typename I>
549I NRLib::ReadBinaryShortArray(std::istream& stream,
550 I begin,
551 size_t n,
552 NRLib::Endianess number_representation)
553{
554 using namespace NRLib::NRLibPrivate;
555
556 std::vector<char> buffer(2*n);
557 unsigned short us;
558
559 if (!stream.read(&buffer[0], static_cast<std::streamsize>(2*n))) {
560 throw Exception("Error reading from stream (f).");
561 }
562
563 switch (number_representation) {
564 case END_BIG_ENDIAN:
565 for (size_t i = 0; i < n; ++i) {
566 ParseUInt16BE(&buffer[2*i], us);
567 *begin = static_cast<typename std::iterator_traits<I>::value_type>(us);
568 ++begin;
569 }
570 break;
572 for (size_t i = 0; i < n; ++i) {
573 ParseUInt16LE(&buffer[2*i], us);
574 *begin = static_cast<typename std::iterator_traits<I>::value_type>(us);
575 ++begin;
576 }
577 break;
578 default:
579 throw Exception("Invalid number representation.");
580 }
581
582 return begin;
583}
584
585
586template <typename I>
587void NRLib::WriteBinaryIntArray(std::ostream& stream,
588 I begin,
589 I end,
590 NRLib::Endianess number_representation)
591{
592 using namespace NRLib::NRLibPrivate;
593
594 typename I::difference_type n_char = 4*std::distance(begin, end);
595 std::vector<char> buffer(n_char);
596
597 switch (number_representation) {
598 case END_BIG_ENDIAN:
599 for (int i = 0; begin != end; ++begin, ++i) {
600 WriteUInt32BE(&buffer[4*i], static_cast<unsigned int>(*begin));
601 }
602 break;
604 for (int i = 0; begin != end; ++begin, ++i) {
605 WriteUInt32LE(&buffer[4*i], static_cast<unsigned int>(*begin));
606 }
607 break;
608 default:
609 throw Exception("Invalid number representation.");
610 }
611
612 if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) {
613 throw Exception("Error writing to stream.");
614 }
615}
616
617
618template <typename I>
619I NRLib::ReadBinaryIntArray(std::istream& stream,
620 I begin,
621 size_t n,
622 NRLib::Endianess number_representation)
623{
624 using namespace NRLib::NRLibPrivate;
625
626 std::vector<char> buffer(4*n);
627 unsigned int ui;
628
629 if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) {
630 throw Exception("Error reading from stream (g).");
631 }
632
633 switch (number_representation) {
634 case END_BIG_ENDIAN:
635 for (size_t i = 0; i < n; ++i) {
636 ParseUInt32BE(&buffer[4*i], ui);
637 *begin = static_cast<typename std::iterator_traits<I>::value_type>(ui);
638 ++begin;
639 }
640 break;
642 for (size_t i = 0; i < n; ++i) {
643 ParseUInt32LE(&buffer[4*i], ui);
644 *begin = static_cast<typename std::iterator_traits<I>::value_type>(ui);
645 ++begin;
646 }
647 break;
648 default:
649 throw Exception("Invalid number representation.");
650 }
651
652 return begin;
653}
654
655
656template <typename I>
657void NRLib::WriteBinaryFloatArray(std::ostream& stream,
658 I begin,
659 I end,
660 NRLib::Endianess number_representation)
661{
662 using namespace NRLib::NRLibPrivate;
663
664 typename I::difference_type n_char = 4*std::distance(begin, end);
665 std::vector<char> buffer(n_char);
666
667 switch (number_representation) {
668 case END_BIG_ENDIAN:
669 for (int i = 0; begin != end; ++begin, ++i) {
671 }
672 break;
674 for (int i = 0; begin != end; ++begin, ++i) {
676 }
677 break;
678 default:
679 throw Exception("Invalid number representation.");
680 }
681
682 if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) {
683 throw Exception("Error writing to stream.");
684 }
685}
686
687template <typename I>
688I NRLib::ReadBinaryFloatArray(std::istream& stream,
689 I begin,
690 size_t n,
691 NRLib::Endianess number_representation)
692{
693 using namespace NRLib::NRLibPrivate;
694
695 std::vector<char> buffer(4*n);
696 float f;
697
698 if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) {
699 throw Exception("Error reading from stream (h).");
700 }
701
702 switch (number_representation) {
703 case END_BIG_ENDIAN:
704 for (size_t i = 0; i < n; ++i) {
705 ParseIEEEFloatBE(&buffer[4*i], f);
706 *begin = static_cast<typename std::iterator_traits<I>::value_type>(f);
707 ++begin;
708 }
709 break;
711 for (size_t i = 0; i < n; ++i) {
712 ParseIEEEFloatLE(&buffer[4*i], f);
713 *begin = static_cast<typename std::iterator_traits<I>::value_type>(f);
714 ++begin;
715 }
716 break;
717 default:
718 throw Exception("Invalid number representation.");
719 }
720
721 return begin;
722}
723
724
725template <typename I>
726void NRLib::WriteBinaryDoubleArray(std::ostream& stream,
727 I begin,
728 I end,
729 NRLib::Endianess number_representation)
730{
731 using namespace NRLib::NRLibPrivate;
732
733 typename I::difference_type n_char = 8*std::distance(begin, end);
734 std::vector<char> buffer(n_char);
735
736 switch (number_representation) {
737 case END_BIG_ENDIAN:
738 for (int i = 0; begin != end; ++begin, ++i) {
740 }
741 break;
743 for (int i = 0; begin != end; ++begin, ++i) {
745 }
746 break;
747 default:
748 throw Exception("Invalid number representation.");
749 }
750
751 if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) {
752 throw Exception("Error writing to stream.");
753 }
754}
755
756
757template <typename I>
758I NRLib::ReadBinaryDoubleArray(std::istream& stream,
759 I begin,
760 size_t n,
761 NRLib::Endianess number_representation)
762{
763 using namespace NRLib::NRLibPrivate;
764
765 std::vector<char> buffer(8*n);
766 double d;
767
768 if (!stream.read(&buffer[0], static_cast<std::streamsize>(8*n))) {
769 throw Exception("Error reading from stream (i).");
770 }
771
772 switch (number_representation) {
773 case END_BIG_ENDIAN:
774 for (size_t i = 0; i < n; ++i) {
775 ParseIEEEDoubleBE(&buffer[8*i], d);
776 *begin = static_cast<typename std::iterator_traits<I>::value_type>(d);
777 ++begin;
778 }
779 break;
781 for (size_t i = 0; i < n; ++i) {
782 ParseIEEEDoubleLE(&buffer[8*i], d);
783 *begin = static_cast<typename std::iterator_traits<I>::value_type>(d);
784 ++begin;
785 }
786 break;
787 default:
788 throw Exception("Invalid number representation.");
789 }
790
791 return begin;
792}
793
794
795template <typename I>
796void NRLib::WriteBinaryIbmFloatArray(std::ostream& stream,
797 I begin,
798 I end,
799 NRLib::Endianess number_representation)
800{
801 using namespace NRLib::NRLibPrivate;
802
803 typename I::difference_type n_char = 4*std::distance(begin, end);
804 std::vector<char> buffer(n_char);
805
806 switch (number_representation) {
807 case END_BIG_ENDIAN:
808 for (int i = 0; begin != end; ++begin, ++i) {
810 }
811 break;
813 for (int i = 0; begin != end; ++begin, ++i) {
815 }
816 break;
817 default:
818 throw Exception("Invalid number representation.");
819 }
820
821 if (!stream.write(&buffer[0], static_cast<std::streamsize>(n_char))) {
822 throw Exception("Error writing to stream.");
823 }
824}
825
826
827template <typename I>
828I NRLib::ReadBinaryIbmFloatArray(std::istream& stream,
829 I begin,
830 size_t n,
831 NRLib::Endianess number_representation)
832{
833 using namespace NRLib::NRLibPrivate;
834
835 std::vector<char> buffer(4*n);
836 float f;
837
839 if (!stream.read(&buffer[0], static_cast<std::streamsize>(4*n))) {
840 if (stream.eof())
841 error = "Error reading binary IBM float array. Trying to read 4*" + NRLib::ToString(n) + " elements when end-of-file was reached.\n";
842 else {
843 error = "Error reading binary IBM float array. Hardware error? Full disk?\n";
844 }
845 }
846
847 switch (number_representation) {
848 case END_BIG_ENDIAN:
849 for (size_t i = 0; i < n; ++i) {
850 ParseIBMFloatBE(&buffer[4*i], f);
851 *begin = f;
852 ++begin;
853 }
854 break;
856 for (size_t i = 0; i < n; ++i) {
857 ParseIBMFloatLE(&buffer[4*i], f);
858 *begin = f;
859 ++begin;
860 }
861 break;
862 default:
863 error += "Invalid number representation. Cannot interpret bit stream as numbers";
864 }
865
866 if (error != "") {
867 throw Exception(error);
868 }
869
870 return begin;
871}
872
873
874static const unsigned short smasks[2] = {0x00ff, 0xff00};
875
876static const unsigned int masks[4] =
877{0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000};
878
879static const unsigned long long lmasks[8] =
880{0x00000000000000ffULL, 0x000000000000ff00ULL,
881 0x0000000000ff0000ULL, 0x00000000ff000000ULL,
882 0x000000ff00000000ULL, 0x0000ff0000000000ULL,
883 0x00ff000000000000ULL, 0xff00000000000000ULL};
884
885
886// ----------------- 16 bit integer ---------------------
887
889 /*uint16_t*/ short& us)
890{
891 us = static_cast<unsigned char>(buffer[0]);
892 us <<= 8;
893 us |= static_cast<unsigned char>(buffer[1]);
894}
895
896
897// ----------------- 16 bit integer ---------------------
898
900 /*uint16_t*/ unsigned short& us)
901{
902 us = static_cast<unsigned char>(buffer[0]);
903 us <<= 8;
904 us |= static_cast<unsigned char>(buffer[1]);
905}
906
907
909 /*uint32_t*/ unsigned short& us)
910{
911 us = static_cast<unsigned char>(buffer[1]);
912 us <<= 8;
913 us |= static_cast<unsigned char>(buffer[0]);
914}
915
916
918 /*uint32_t*/ unsigned short us)
919{
920 buffer[0] = static_cast<char>( (us & smasks[1]) >> 8 );
921 buffer[1] = static_cast<char>( us & smasks[0] );
922}
923
924
926 /*uint32_t*/ unsigned short us)
927{
928 buffer[0] = static_cast<char>(us & smasks[0]);
929 buffer[1] = static_cast<char>( (us & smasks[1]) >> 8 );
930}
931
932
933// ----------------- 32 bit integer ---------------------
934
935
937 /*int32_t*/ int& ui)
938{
939 ui = static_cast<unsigned char>(buffer[0]);
940 for (int i = 1; i < 4; ++i) {
941 ui <<= 8;
942 ui |= static_cast<unsigned char>(buffer[i]);
943 }
944}
945
946// -------------- 32 bit unsigned integer -----------------
947
948
950 /*uint32_t*/ unsigned int& ui)
951{
952 ui = static_cast<unsigned char>(buffer[0]);
953 for (int i = 1; i < 4; ++i) {
954 ui <<= 8;
955 ui |= static_cast<unsigned char>(buffer[i]);
956 }
957}
958
959
961 /*uint32_t*/ unsigned int& ui)
962{
963 ui = static_cast<unsigned char>(buffer[3]);
964 for (int i = 1; i < 4; ++i) {
965 ui <<= 8;
966 ui |= static_cast<unsigned char>(buffer[3-i]);
967 }
968}
969
970
972 /*uint32_t*/ unsigned int ui)
973{
974 buffer[0] = static_cast<char>( (ui & masks[3]) >> 24);
975 buffer[1] = static_cast<char>( (ui & masks[2]) >> 16 );
976 buffer[2] = static_cast<char>( (ui & masks[1]) >> 8 );
977 buffer[3] = static_cast<char>( ui & masks[0] );
978}
979
980
982 /*uint32_t*/ unsigned int ui)
983{
984 buffer[0] = static_cast<char>(ui & masks[0]);
985 buffer[1] = static_cast<char>( (ui & masks[1]) >> 8 );
986 buffer[2] = static_cast<char>( (ui & masks[2]) >> 16 );
987 buffer[3] = static_cast<char>( (ui & masks[3]) >> 24 );
988}
989
990
991// ----------------- 32 bit IEEE floating point -------------------
992
993
994// Big endian number representation.
995void NRLib::ParseIEEEFloatBE(const char* buffer, float& f)
996{
998 tmp.ui = static_cast<unsigned char>(buffer[0]);
999 for (int i = 1; i < 4; ++i) {
1000 tmp.ui <<= 8;
1001 tmp.ui |= static_cast<unsigned char>(buffer[i]);
1002 }
1003 f = tmp.f;
1004}
1005
1006// Little endian number representation.
1008{
1009 FloatAsInt tmp;
1010 tmp.ui = static_cast<unsigned char>(buffer[3]);
1011 for (int i = 1; i < 4; ++i) {
1012 tmp.ui <<= 8;
1013 tmp.ui |= static_cast<unsigned char>(buffer[3-i]);
1014 }
1015 f = tmp.f;
1016}
1017
1018
1019// Big endian number representation.
1021{
1022 FloatAsInt tmp;
1023 tmp.f = f;
1024 buffer[0] = static_cast<char>( (tmp.ui & masks[3]) >> 24);
1025 buffer[1] = static_cast<char>( (tmp.ui & masks[2]) >> 16 );
1026 buffer[2] = static_cast<char>( (tmp.ui & masks[1]) >> 8 );
1027 buffer[3] = static_cast<char>( tmp.ui & masks[0] );
1028}
1029
1030// Little endian number representation.
1032{
1033 FloatAsInt tmp;
1034 tmp.f = f;
1035 buffer[0] = static_cast<char>(tmp.ui & masks[0]);
1036 buffer[1] = static_cast<char>( (tmp.ui & masks[1]) >> 8 );
1037 buffer[2] = static_cast<char>( (tmp.ui & masks[2]) >> 16 );
1038 buffer[3] = static_cast<char>( (tmp.ui & masks[3]) >> 24 );
1039}
1040
1041
1042// ----------------- 64 bit IEEE floating point --------------------
1043
1044
1045// Big endian number representation.
1047{
1048 DoubleAsLongLong tmp;
1049 tmp.ull = static_cast<unsigned char>(buffer[0]);
1050 for (int i = 1; i < 8; ++i) {
1051 tmp.ull <<= 8;
1052 tmp.ull |= static_cast<unsigned char>(buffer[i]);
1053 }
1054 d = tmp.d;
1055}
1056
1057// Little endian number representation.
1059{
1060 DoubleAsLongLong tmp;
1061 tmp.ull = static_cast<unsigned char>(buffer[7]);
1062 for (int i = 1; i < 8; ++i) {
1063 tmp.ull <<= 8;
1064 tmp.ull |= static_cast<unsigned char>(buffer[7-i]);
1065 }
1066 d = tmp.d;
1067}
1068
1069
1070// Big endian number representation.
1072{
1073 DoubleAsLongLong tmp;
1074 tmp.d = d;
1075 buffer[0] = static_cast<char>( (tmp.ull & lmasks[7]) >> 56);
1076 buffer[1] = static_cast<char>( (tmp.ull & lmasks[6]) >> 48);
1077 buffer[2] = static_cast<char>( (tmp.ull & lmasks[5]) >> 40);
1078 buffer[3] = static_cast<char>( (tmp.ull & lmasks[4]) >> 32);
1079 buffer[4] = static_cast<char>( (tmp.ull & lmasks[3]) >> 24);
1080 buffer[5] = static_cast<char>( (tmp.ull & lmasks[2]) >> 16);
1081 buffer[6] = static_cast<char>( (tmp.ull & lmasks[1]) >> 8 );
1082 buffer[7] = static_cast<char>( tmp.ull & lmasks[0] );
1083}
1084
1085// Little endian number representation.
1087{
1088 DoubleAsLongLong tmp;
1089 tmp.d = d;
1090 buffer[0] = static_cast<char>( tmp.ull & lmasks[0]);
1091 buffer[1] = static_cast<char>( (tmp.ull & lmasks[1]) >> 8 );
1092 buffer[2] = static_cast<char>( (tmp.ull & lmasks[2]) >> 16);
1093 buffer[3] = static_cast<char>( (tmp.ull & lmasks[3]) >> 24);
1094 buffer[4] = static_cast<char>( (tmp.ull & lmasks[4]) >> 32);
1095 buffer[5] = static_cast<char>( (tmp.ull & lmasks[5]) >> 40);
1096 buffer[6] = static_cast<char>( (tmp.ull & lmasks[6]) >> 48);
1097 buffer[7] = static_cast<char>( (tmp.ull & lmasks[7]) >> 56);
1098}
1099
1100
1101// ----------------- 32 bit IBM floating point -------------------
1102
1103static unsigned int IEEEMAX = 0x7FFFFFFF;
1104static unsigned int IEMAXIB = 0x611FFFFF;
1105static unsigned int IEMINIB = 0x21200000;
1106
1107
1109static inline void Ibm2Ieee(/*uint32_t*/ unsigned int& in)
1110{
1111 static int it[8] = { 0x21800000, 0x21400000, 0x21000000, 0x21000000,
1112 0x20c00000, 0x20c00000, 0x20c00000, 0x20c00000 };
1113 static int mt[8] = { 8, 4, 2, 2, 1, 1, 1, 1 };
1114 /*uint32_t*/ unsigned int manthi, iexp, inabs;
1115 int ix;
1116
1117 manthi = in & 0x00ffffff;
1118 ix = manthi >> 21;
1119 iexp = ( ( in & 0x7f000000 ) - it[ix] ) << 1;
1120 manthi = manthi * mt[ix] + iexp;
1121 inabs = in & 0x7fffffff;
1122 if ( inabs > IEMAXIB ) manthi = IEEEMAX;
1123 manthi = manthi | ( in & 0x80000000 );
1124 in = ( inabs < IEMINIB ) ? 0 : manthi;
1125}
1126
1127
1129static inline void Ieee2Ibm ( /*uint32_t*/ unsigned int& in)
1130{
1131 static int it[4] = { 0x21200000, 0x21400000, 0x21800000, 0x22100000 };
1132 static int mt[4] = { 2, 4, 8, 1 };
1133 /*uint32_t*/ unsigned int manthi, iexp, ix;
1134
1135 ix = ( in & 0x01800000 ) >> 23;
1136 iexp = ( ( in & 0x7e000000 ) >> 1 ) + it[ix];
1137 manthi = ( mt[ix] * ( in & 0x007fffff) ) >> 3;
1138 manthi = (manthi + iexp) | ( in & 0x80000000 );
1139 in = ( in & 0x7fffffff ) ? manthi : 0;
1140}
1141
1142
1143// Big endian number representation.
1144void NRLib::ParseIBMFloatBE(const char* buffer, float& f)
1145{
1147 tmp.ui = static_cast<unsigned char>(buffer[0]);
1148 for (int i = 1; i < 4; ++i) {
1149 tmp.ui <<= 8;
1150 tmp.ui |= static_cast<unsigned char>(buffer[i]);
1151 }
1152
1153 Ibm2Ieee(tmp.ui);
1154 f = tmp.f;
1155}
1156
1157
1158// Little endian number representation.
1160{
1161 FloatAsInt tmp;
1162 tmp.ui = static_cast<unsigned char>(buffer[3]);
1163 for (int i = 1; i < 4; ++i) {
1164 tmp.ui <<= 8;
1165 tmp.ui |= static_cast<unsigned char>(buffer[3-i]);
1166 }
1167
1168 Ibm2Ieee(tmp.ui);
1169 f = tmp.f;
1170}
1171
1172
1173// Big endian number representation.
1175{
1176 FloatAsInt tmp;
1177 tmp.f = f;
1178 Ieee2Ibm(tmp.ui);
1179 buffer[0] = static_cast<char>( (tmp.ui & masks[3]) >> 24);
1180 buffer[1] = static_cast<char>( (tmp.ui & masks[2]) >> 16 );
1181 buffer[2] = static_cast<char>( (tmp.ui & masks[1]) >> 8 );
1182 buffer[3] = static_cast<char>( tmp.ui & masks[0] );
1183}
1184
1185
1186// Little endian number representation.
1188{
1189 FloatAsInt tmp;
1190 tmp.f = f;
1191 Ieee2Ibm(tmp.ui);
1192 buffer[0] = static_cast<char>(tmp.ui & masks[0]);
1193 buffer[1] = static_cast<char>( (tmp.ui & masks[1]) >> 8 );
1194 buffer[2] = static_cast<char>( (tmp.ui & masks[2]) >> 16 );
1195 buffer[3] = static_cast<char>( (tmp.ui & masks[3]) >> 24 );
1196}
1197
1198#endif // NRLIB_FILEIO_HPP
int count
Definition: cJSON.h:212
const char *const string
Definition: cJSON.h:170
char * buffer
Definition: cJSON.h:161
Definition: exception.hpp:80
Definition: exception.hpp:34
static unsigned int IEMAXIB
Definition: fileio.hpp:1104
static void Ieee2Ibm(unsigned int &in)
Converts Ieee float (represented as 32-bit int) to IBM float.
Definition: fileio.hpp:1129
static const unsigned short smasks[2]
Definition: fileio.hpp:874
static const unsigned int masks[4]
Definition: fileio.hpp:876
static void Ibm2Ieee(unsigned int &in)
Converts Ieee float (represented as 32-bit int) to IBM float.
Definition: fileio.hpp:1109
static const unsigned long long lmasks[8]
Definition: fileio.hpp:879
static unsigned int IEEEMAX
Definition: fileio.hpp:1103
static unsigned int IEMINIB
Definition: fileio.hpp:1105
not_this_one begin(...)
Definition: fileio.hpp:355
void WriteIBMFloatBE(char *buffer, float f)
Write IEEE double-precision float to big-endian buffer.
Definition: fileio.hpp:1174
void ParseIEEEDoubleBE(const char *buffer, double &d)
Parse IEEE double-precision float from big-endian buffer.
Definition: fileio.hpp:1046
void WriteIBMFloatLE(char *buffer, float f)
Write IEEE double-precision float to little-endian buffer.
Definition: fileio.hpp:1187
void WriteUInt16BE(char *buffer, unsigned short us)
Write unsigned 32-bit integer to big-endian buffer.
Definition: fileio.hpp:917
void WriteUInt16LE(char *buffer, unsigned short us)
Write unsigned 32-bit integer to little-endian buffer.
Definition: fileio.hpp:925
void WriteIEEEFloatLE(char *buffer, float f)
Write IEEE single-precision float to little-endian buffer.
Definition: fileio.hpp:1031
void ParseIBMFloatLE(const char *buffer, float &f)
Parse IEEE double-precision float from little-endian buffer.
Definition: fileio.hpp:1159
void WriteIEEEFloatBE(char *buffer, float f)
Write IEEE single-precision float to big-endian buffer.
Definition: fileio.hpp:1020
void ParseIEEEFloatLE(const char *buffer, float &f)
Parse IEEE single-precision float from little-endian buffer.
Definition: fileio.hpp:1007
void ParseUInt16LE(const char *buffer, unsigned short &ui)
Parse unsigned 32-bit integer from little-endian buffer.
Definition: fileio.hpp:908
void ParseUInt32LE(const char *buffer, unsigned int &ui)
Parse unsigned 32-bit integer from little-endian buffer.
Definition: fileio.hpp:960
void WriteIEEEDoubleLE(char *buffer, double d)
Write IEEE double-precision float to little-endian buffer.
Definition: fileio.hpp:1086
void WriteIEEEDoubleBE(char *buffer, double d)
Write IEEE double-precision float to big-endian buffer.
Definition: fileio.hpp:1071
void ParseIEEEDoubleLE(const char *buffer, double &d)
Parse IEEE double-precision float from little-endian buffer.
Definition: fileio.hpp:1058
void WriteUInt32LE(char *buffer, unsigned int ui)
Write unsigned 32-bit integer to little-endian buffer.
Definition: fileio.hpp:981
void WriteUInt32BE(char *buffer, unsigned int ui)
Write unsigned 32-bit integer to big-endian buffer.
Definition: fileio.hpp:971
Definition: exception.hpp:31
void WriteBinaryShort(std::ostream &stream, short s, Endianess number_representation=END_BIG_ENDIAN)
Write a 2-byte integer to a binary file.
void WriteBinaryDouble(std::ostream &stream, double d, Endianess number_representation=END_BIG_ENDIAN)
Write a 8-byte float on standard IEEE format.
void RemoveFile(const std::string &filename)
void WriteBinaryIbmFloatArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of 4-byte floats on standard IEEE format.
Definition: fileio.hpp:796
I ReadBinaryIbmFloatArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of 4-byte floats on standard IEEE format.
Definition: fileio.hpp:828
void ParseUInt32BE(const char *buffer, unsigned int &ui)
Parse unsigned 32-bit integer from big-endian buffer.
Definition: fileio.hpp:949
std::istream & GetNextNonEmptyLine(std::istream &stream, int &line_num, std::string &line)
Gets the next line that not only contains whitespace. Returns the stream. Stream will be bad if end-o...
I ReadBinaryFloatArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of 4-byte floats on standard IEEE format.
Definition: fileio.hpp:688
I ReadAsciiArrayFast(std::istream &stream, I begin, size_t n)
Gets sequence with elements of type T from input stream. Does no type checking, and does not count li...
Definition: fileio.hpp:481
void ParseUInt16BE(const char *buffer, unsigned short &ui)
Parse unsigned 32-bit integer from big-endian buffer.
Definition: fileio.hpp:899
I ParseAsciiArrayFast(std::string &s, I begin, size_t n)
Not safe. Replaces whitespace in s with \0.
Definition: stringtools.hpp:191
void WriteBinaryFloatArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of 4-byte floats on standard IEEE format.
Definition: fileio.hpp:657
void WriteBinaryIntArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of binary 4-byte integers.
Definition: fileio.hpp:587
void WriteBinaryFloat(std::ostream &stream, float f, Endianess number_representation=END_BIG_ENDIAN)
Write a 4-byte float on standard IEEE format.
T ReadNext(std::istream &stream, int &line)
Gets next token from file, and parses it as type T Might be relatively slow, due to typechecking,...
Definition: fileio.hpp:439
bool FileExists(const std::string &filename)
void ReadNextQuoted(std::istream &stream, char quote, std::string &s, int &line)
Reads the next, possibly quoted, string.
I ReadBinaryDoubleArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of 8-byte floats on standard IEEE format.
Definition: fileio.hpp:758
void CreateDirIfNotExists(const std::string &filename)
void ParseIEEEFloatBE(const char *buffer, float &f)
Parse IEEE single-precision float from big-endian buffer.
Definition: fileio.hpp:995
void ParseInt16BE(const char *buffer, short &ui)
Parse unsigned 32-bit integer from big-endian buffer.
Definition: fileio.hpp:888
void WriteBinaryInt(std::ostream &stream, int i, Endianess number_representation=END_BIG_ENDIAN)
Write a 4-byte integer to a binary file.
void ParseInt32BE(const char *buffer, int &ui)
Parse unsigned 32-bit integer from big-endian buffer.
Definition: fileio.hpp:936
void ParseIBMFloatBE(const char *buffer, float &f)
Parse IEEE double-precision float from big-endian buffer.
Definition: fileio.hpp:1144
bool IgnoreComment(std::ifstream &file, char chin)
float ReadBinaryFloat(std::istream &stream, Endianess number_representation=END_BIG_ENDIAN)
Read a 4-byte float on standard IEEE format.
short ReadBinaryShort(std::istream &stream, Endianess number_representation=END_BIG_ENDIAN)
Read a 2-byte integer from a binary file.
void DiscardRestOfLine(std::istream &stream, int &line_num, bool throw_if_non_whitespace)
Reads and discard all characters until and including next newline.
void CopyFile(const std::string &from_path, const std::string &to_path, bool allow_overwrite)
void WriteBinaryShortArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of binary 2-byte integers.
Definition: fileio.hpp:517
GridFileFormat
Definition: fileio.hpp:38
@ PLAIN_ASCII
Definition: fileio.hpp:45
@ STORM_PETRO_BINARY
Definition: fileio.hpp:39
@ UNKNOWN
Definition: fileio.hpp:38
@ STORM_PETRO_ASCII
Definition: fileio.hpp:40
@ SGRI
Definition: fileio.hpp:43
@ SEGY
Definition: fileio.hpp:44
@ STORM_FACIES_BINARY
Definition: fileio.hpp:41
@ STORM_FACIES_ASCII
Definition: fileio.hpp:42
Endianess
Definition: fileio.hpp:36
@ END_LITTLE_ENDIAN
Definition: fileio.hpp:36
@ END_BIG_ENDIAN
Definition: fileio.hpp:37
I ReadBinaryShortArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of binary 2-byte integers.
Definition: fileio.hpp:549
int ReadBinaryInt(std::istream &stream, Endianess number_representation=END_BIG_ENDIAN)
Read a 4-byte integer from a binary file.
I ReadAsciiArrayFastRestOfFile(std::istream &stream, I begin, size_t n)
Gets sequence with elements of type T from input stream. Does no type checking, and does not count li...
Definition: fileio.hpp:502
int FindGridFileType(const std::string &filename)
Find type of file, for 3D grid files.
std::istream & ReadNextToken(std::istream &stream, std::string &s, int &line)
Read next white-space seperated token from file. Updates line number when new line is read in....
I ReadAsciiArray(std::istream &stream, I begin, size_t n, int &line)
Gets sequence with elements of type T from input stream. Might be relatively slow,...
Definition: fileio.hpp:469
float ReadBinaryIbmFloat(std::istream &stream, Endianess number_representation=END_BIG_ENDIAN)
Read a 4-byte float on standard IEEE format.
std::string FindLastNonEmptyLine(std::istream &stream, const std::ios::pos_type &max_line_len=1000)
Returns last non-empty line in file. Stream will be at end of file.
int Seek(FILE *file, long long offset, int origin)
Seek to given position in file, works for large files.
void WriteBinaryIbmFloat(std::ostream &stream, float f, Endianess number_representation=END_BIG_ENDIAN)
Write a 4-byte float on standard IEEE format.
double ReadBinaryDouble(std::istream &stream, Endianess number_representation=END_BIG_ENDIAN)
Read a 8-byte float on standard IEEE format.
bool CheckEndOfFile(std::istream &stream)
Check if end of file is reached. Discards all whitespace before end of file or next token.
void WriteBinaryDoubleArray(std::ostream &stream, I begin, I end, Endianess number_representation=END_BIG_ENDIAN)
Write an array of 8-byte floats on standard IEEE format.
Definition: fileio.hpp:726
void SkipComments(std::istream &stream, char comment_token, int &line_num)
Returns next line that not only contains whitespace, or starts with the given comment token.
void OpenWrite(std::ofstream &stream, const std::string &filename, std::ios_base::openmode mode=std::ios_base::out, bool create_dir=true)
Open file for writing.
void WriteAsciiArray(std::ostream &stream, I begin, I end, int n_per_line=6)
Writes array.
Definition: fileio.hpp:453
unsigned long long FindFileSize(const std::string &filename)
Finds the size of a file. Throws IOError if file not found.
void OpenRead(std::ifstream &stream, const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Open file for reading.
std::string ToString(const T obj, int precision=-99999)
Definition: stringtools.hpp:177
I ReadBinaryIntArray(std::istream &stream, I begin, size_t n, Endianess number_representation=END_BIG_ENDIAN)
Read an array of binary 4-byte integers.
Definition: fileio.hpp:619
const char quote
Definition: RawConsts.hpp:30
@ error
Definition: ActionValue.hpp:21
@ end
Definition: ActionValue.hpp:20
Definition: fileio.hpp:365
unsigned long long ull
Definition: fileio.hpp:366
double d
Definition: fileio.hpp:367
Definition: fileio.hpp:360
float f
Definition: fileio.hpp:362
unsigned int ui
Definition: fileio.hpp:361