STIR 6.4.0
InputStreamWithRecords.inl
Go to the documentation of this file.
1
8/*
9 Copyright (C) 2003-2011, Hammersmith Imanet Ltd
10 Copyright (C) 2012-2013, Kris Thielemans
11 This file is part of STIR.
12
13 SPDX-License-Identifier: Apache-2.0
14
15 See STIR/LICENSE.txt for details
16*/
17
18#include "stir/utilities.h"
19#include "stir/Succeeded.h"
20#include "stir/is_null_ptr.h"
21#include "stir/shared_ptr.h"
22#include "boost/shared_array.hpp"
23#include "stir/warning.h"
24#include "stir/error.h"
25#include <fstream>
26
27START_NAMESPACE_STIR
28template <class RecordT, class OptionsT>
30 const std::size_t size_of_record_signature,
31 const std::size_t max_size_of_record,
32 const OptionsT& options)
33 : stream_ptr(stream_ptr),
34 size_of_record_signature(size_of_record_signature),
35 max_size_of_record(max_size_of_record),
36 options(options)
37{
38 assert(size_of_record_signature <= max_size_of_record);
39 if (is_null_ptr(stream_ptr))
40 return;
41 starting_stream_position = stream_ptr->tellg();
42 if (!stream_ptr->good())
43 error("InputStreamWithRecords: error in tellg()\n");
44}
45
46template <class RecordT, class OptionsT>
48 const std::size_t size_of_record_signature,
49 const std::size_t max_size_of_record,
50 const OptionsT& options,
51 const std::streampos start_of_data)
52 : filename(filename),
53 starting_stream_position(start_of_data),
54 size_of_record_signature(size_of_record_signature),
55 max_size_of_record(max_size_of_record),
56 options(options)
57{
58 assert(size_of_record_signature <= max_size_of_record);
59 std::fstream* s_ptr = new std::fstream;
60 open_read_binary(*s_ptr, filename.c_str());
61 stream_ptr.reset(s_ptr);
62 if (reset() == Succeeded::no)
63 error("InputStreamWithRecords: error in reset() for filename %s\n", filename.c_str());
64}
65
66template <class RecordT, class OptionsT>
68InputStreamWithRecords<RecordT, OptionsT>::get_next_record(RecordT& record) const
69{
70 if (is_null_ptr(stream_ptr))
71 return Succeeded::no;
72
73 Succeeded ret = Succeeded::yes;
74
75#ifdef STIR_OPENMP
76# pragma omp critical(LISTMODEIO)
77#endif
78 {
79 // rely on file caching by the C++ library or the OS
80 assert(this->size_of_record_signature <= this->max_size_of_record);
81 boost::shared_array<char> data_sptr(new char[this->max_size_of_record]);
82
83 stream_ptr->read(data_sptr.get(), this->size_of_record_signature);
84 if (stream_ptr->gcount() < static_cast<std::streamsize>(this->size_of_record_signature))
85 {
86 ret = Succeeded::no;
87 }
88 const std::size_t size_of_record = record.size_of_record_at_ptr(data_sptr.get(), this->size_of_record_signature, options);
89 assert(size_of_record <= this->max_size_of_record);
90 if (size_of_record > this->size_of_record_signature)
91 stream_ptr->read(data_sptr.get() + this->size_of_record_signature, size_of_record - this->size_of_record_signature);
92 if (stream_ptr->eof())
93 {
94 ret = Succeeded::no;
95 }
96 else if (stream_ptr->bad())
97 {
98 warning("Error after reading from list mode stream in get_next_record");
99 ret = Succeeded::no;
100 }
101 if (ret == Succeeded::yes)
102 ret = record.init_from_data_ptr(data_sptr.get(), size_of_record, options);
103 }
104
105 return ret;
106}
107
108template <class RecordT, class OptionsT>
111{
112 if (is_null_ptr(stream_ptr))
113 return Succeeded::no;
114
115 // Strangely enough, once you read past EOF, even seekg(0) doesn't reset the eof flag
116 if (stream_ptr->eof())
117 stream_ptr->clear();
118 stream_ptr->seekg(starting_stream_position, std::ios::beg);
119 if (stream_ptr->bad())
120 return Succeeded::no;
121 else
122 return Succeeded::yes;
123}
124
125template <class RecordT, class OptionsT>
126typename InputStreamWithRecords<RecordT, OptionsT>::SavedPosition
128{
129 assert(!is_null_ptr(stream_ptr));
130 // TODO should somehow check if tellg() worked and return an error if it didn't
131 std::streampos pos;
132 if (!stream_ptr->eof())
133 {
134 pos = stream_ptr->tellg();
135 if (!stream_ptr->good())
136 error("InputStreamWithRecords<RecordT, OptionsT>::save_get_position\n"
137 "Error after getting position in file");
138 }
139 else
140 {
141 // use -1 to signify eof
142 // (this is probably the behaviour of tellg anyway, but this way we're sure).
143 pos = std::streampos(-1);
144 }
145 saved_get_positions.push_back(pos);
146 return saved_get_positions.size() - 1;
147}
148
149template <class RecordT, class OptionsT>
152 const typename InputStreamWithRecords<RecordT, OptionsT>::SavedPosition& pos)
153{
154 if (is_null_ptr(stream_ptr))
155 return Succeeded::no;
156
157 assert(pos < saved_get_positions.size());
158 stream_ptr->clear();
159 if (saved_get_positions[pos] == std::streampos(-1))
160 stream_ptr->seekg(0, std::ios::end); // go to eof
161 else
162 stream_ptr->seekg(saved_get_positions[pos]);
163
164 if (!stream_ptr->good())
165 return Succeeded::no;
166 else
167 return Succeeded::yes;
168}
169
170template <class RecordT, class OptionsT>
171std::vector<std::streampos>
173{
174 return saved_get_positions;
175}
176
177template <class RecordT, class OptionsT>
178void
180{
181 saved_get_positions = poss;
182}
183
184END_NAMESPACE_STIR
Declaration of class stir::Succeeded.
Succeeded reset()
go back to starting position
Definition InputStreamWithRecords.inl:110
std::vector< std::streampos > get_saved_get_positions() const
Function that enables the user to store the saved get_positions.
Definition InputStreamWithRecords.inl:172
void set_saved_get_positions(const std::vector< std::streampos > &)
Function that sets the saved get_positions.
Definition InputStreamWithRecords.inl:179
InputStreamWithRecords(const shared_ptr< std::istream > &stream_ptr, const std::size_t size_of_record_signature, const std::size_t max_size_of_record, const OptionsT &options)
Constructor taking a stream.
Definition InputStreamWithRecords.inl:29
SavedPosition save_get_position()
save current "get" position in an internal array
Definition InputStreamWithRecords.inl:127
Succeeded set_get_position(const SavedPosition &)
set current "get" position to previously saved value
Definition InputStreamWithRecords.inl:151
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
Declaration of stir::error()
void error(const char *const s,...)
Print error with format string a la printf and throw exception.
Definition error.cxx:42
void warning(const char *const s,...)
Print warning with format string a la printf.
Definition warning.cxx:41
FILE *& open_read_binary(FILE *&fptr, const string &name)
opens a FILE for reading binary data. Calls error() when it does not succeed.
Definition utilities.cxx:79
Definition of stir::is_null_ptr functions.
Import of std::shared_ptr, std::dynamic_pointer_cast and std::static_pointer_cast into the stir names...
This file declares various utility functions.
Declaration of stir::warning()