Repository navigation
Expand file tree
/
Copy pathFasta.cpp
More file actions
129 lines (111 loc) · 3.83 KB
/
Copy pathFasta.cpp
File metadata and controls
129 lines (111 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <cstring>
#include <unordered_set>
#include <cstddef>
#include "Fasta.hpp"
#include "Arguments.hpp"
utils::Fasta::Fasta(std::istream &is)
{
_read(is);
}
void utils::Fasta::write_to(std::ostream &os, bool output_name) const
{
if (output_name)
write_to(os, sequences.cbegin(), sequences.cend(), names.cbegin());
else
write_to(os, sequences.cbegin(), sequences.cend());
}
void utils::Fasta::write_to(std::stringstream &ss, bool output_name) const
{
if (output_name)
write_to(ss, sequences.cbegin(), sequences.cend(), names.cbegin());
else
write_to(ss, sequences.cbegin(), sequences.cend());
}
void utils::Fasta::_read(std::istream &is)
{
std::unordered_set<std::string> names_of_current_file;
std::string tmp;
char * buffer = new char [arguments::buffer_size + 1];
int blocks = 0;
bool is_name = false, flag = false;
// read data as so many blocks
while(true)
{
is.read(buffer, arguments::buffer_size);
for(int bi = 0; bi < is.gcount(); ++ bi)
{
if(buffer[bi] == '\r') continue;
if(buffer[bi] == '\n')
{
if(! is_name) continue;
else
{
is_name = false;
if (arguments::check_duplicate)
{
// std::cerr << arguments::check_duplicate << std::endl;
if (names_of_current_file.contains(tmp))
duplicate_name();
names_of_current_file.insert(tmp);
}
names.emplace_back(std::move(tmp));
}
}
else if(buffer[bi] == '>')
{
// here, this string will become sequence name
is_name = true;
if(flag) sequences.emplace_back(std::move(tmp));
flag = true;
}
else tmp += buffer[bi];
}
if (! is) break;
}
sequences.emplace_back(std::move(tmp));
delete[] buffer;
}
void utils::Fasta::write_with_wrapping(std::stringstream &ss, const std::string &sequence)
{
const std::size_t sequence_length = sequence.size();
char *cut_sequence = new char[sequence_length + sequence_length / max_line_length + 1];
std::size_t des_index = 0;
for (std::size_t src_index = 0; src_index < sequence_length; src_index += max_line_length)
{
if (src_index) cut_sequence[des_index++] = '\n';
std::size_t write_length = sequence_length - src_index;
if (write_length > max_line_length) write_length = max_line_length;
memcpy(cut_sequence + des_index, sequence.data() + src_index, write_length);
des_index += write_length;
}
cut_sequence[des_index] = 0;
ss << cut_sequence;
delete[] cut_sequence;
}
void utils::Fasta::write_with_wrapping(std::ostream &os, const std::string &sequence)
{
const std::size_t sequence_length = sequence.size();
char *cut_sequence = new char[sequence_length + sequence_length / max_line_length + 1];
std::size_t des_index = 0;
for (std::size_t src_index = 0; src_index < sequence_length; src_index += max_line_length)
{
if (src_index) cut_sequence[des_index++] = '\n';
std::size_t write_length = sequence_length - src_index;
if (write_length > max_line_length) write_length = max_line_length;
memcpy(cut_sequence + des_index, sequence.data() + src_index, write_length);
des_index += write_length;
}
cut_sequence[des_index] = 0;
os << cut_sequence;
delete[] cut_sequence;
}
void utils::Fasta::duplicate_name()
{
std::cerr << "\033[31mError: duplicate sequence name found, please delete it and run again\033[0m\n";
exit(1);
}
void utils::Fasta::pre_length_error()
{
std::cerr << "\033[31msequence length is different\033[0m\n";
exit(1);
}