Read a single record. */
| 128 | |
| 129 | /** Read a single record. */ |
| 130 | Sequence FastaReader::read(string& id, string& comment, |
| 131 | char& anchor, string& q) |
| 132 | { |
| 133 | next_record: |
| 134 | id.clear(); |
| 135 | comment.clear(); |
| 136 | anchor = 0; |
| 137 | q.clear(); |
| 138 | |
| 139 | // Discard comments. |
| 140 | while (m_in.peek() == '#') |
| 141 | ignoreLines(1); |
| 142 | |
| 143 | signed char recordType = m_in.peek(); |
| 144 | Sequence s; |
| 145 | |
| 146 | unsigned qualityOffset = 0; |
| 147 | if (recordType == EOF || m_in.tellg() >= m_end) { |
| 148 | m_in.seekg(0, ios::end); |
| 149 | m_in.clear(std::ios::eofbit | std::ios::failbit); |
| 150 | return s; |
| 151 | } else if (recordType == '>' || recordType == '@') { |
| 152 | // Read the header. |
| 153 | string header; |
| 154 | getline(header); |
| 155 | istringstream headerStream(header); |
| 156 | |
| 157 | // Ignore SAM headers. |
| 158 | if (header[0] == '@' && isalpha(header[1]) |
| 159 | && isalpha(header[2]) && header[3] == '\t') |
| 160 | goto next_record; |
| 161 | |
| 162 | headerStream >> recordType >> id >> ws; |
| 163 | std::getline(headerStream, comment); |
| 164 | |
| 165 | // Casava FASTQ format |
| 166 | if (comment.size() > 3 |
| 167 | && comment[1] == ':' && comment[3] == ':') { |
| 168 | // read, chastity, flags, index: 1:Y:0:AAAAAA |
| 169 | if (opt::chastityFilter && comment[2] == 'Y') { |
| 170 | m_unchaste++; |
| 171 | if (recordType == '@') { |
| 172 | ignoreLines(3); |
| 173 | } else { |
| 174 | while (m_in.peek() != '>' && m_in.peek() != '#' |
| 175 | && ignoreLines(1)) |
| 176 | ; |
| 177 | } |
| 178 | goto next_record; |
| 179 | } |
| 180 | if (id.size() > 2 && id.rbegin()[1] != '/') { |
| 181 | // Add the read number to the ID. |
| 182 | id += '/'; |
| 183 | id += comment[0]; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | getline(s); |
no test coverage detected