while (!in.eof()) {
if (m->control_pressed) { in.close(); outFasta.close(); m->mothurRemove(outFastaFile); return 0; }
- streampos seq_start = in.tellg();
+ streampos seq_start = reliable_tellg(in);
Sequence seq(in);
if (seq.getName() != "") {
in_fasta_from_hash_map(multimap<size_t,std::pair<std::streampos,string>>& seq_strings,
Sequence& seq,
ifstream& fasta_file) {
- streampos cur_pos = fasta_file.tellg();
const std::hash<std::string> hash_fn;
auto it_range = seq_strings.equal_range(hash_fn(seq.getAligned()));
// If the hash of the aligned sequence is not in the map, it can't
if (it_range.first == seq_strings.end()) {
return seq_strings.end();
}
+ pair<bool,streampos> file_pos = store_filepos(fasta_file);
// If it is, it might be a hash collision. Read the file to
// determine if that's the case
for (auto it = it_range.first; it != it_range.second; it++) {
// read in sequence
Sequence old_seq(fasta_file);
if (old_seq.getAligned() == seq.getAligned()) {
- fasta_file.seekg(cur_pos);
+ restore_filepos(fasta_file,file_pos);
return it;
}
}
- fasta_file.seekg(cur_pos);
+ restore_filepos(fasta_file,file_pos);
return seq_strings.end();
}
+streampos reliable_tellg(ifstream& file) {
+ bool was_eof = file.eof();
+ if (was_eof) { // we're at EOF: clear the bit so tellg works properly
+ file.clear(file.rdstate() & ~ios::eofbit);
+ }
+ streampos pos = file.tellg();
+ if (was_eof) { // we're at EOF: reset eofbit
+ file.clear(file.rdstate() | ios::eofbit);
+ }
+ return pos;
+}
+
+
+pair<bool,streampos> store_filepos(ifstream& file) {
+ bool was_eof = file.eof();
+ if (was_eof) { // we're at EOF: clear the bit so tellg works properly
+ file.clear(file.rdstate() & ~ios::eofbit);
+ }
+ streampos cur_pos = file.tellg();
+ return make_pair(was_eof,cur_pos);
+}
+
+void restore_filepos(ifstream& file, pair<bool,streampos>& pos_info) {
+ file.seekg(pos_info.second);
+ if (pos_info.first) { // at eof?
+ file.clear(file.rdstate() | ios::eofbit); // restore the eof bit if it was set
+ }
+}
string primary_seqname(string name) {
int pos = name.find_first_of(',');