| 183 | } |
| 184 | |
| 185 | Stream::Stream(std::istream& input) |
| 186 | : m_input(input), |
| 187 | m_mark{}, |
| 188 | m_charSet{}, |
| 189 | m_readahead{}, |
| 190 | m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), |
| 191 | m_nPrefetchedAvailable(0), |
| 192 | m_nPrefetchedUsed(0) { |
| 193 | using char_traits = std::istream::traits_type; |
| 194 | |
| 195 | if (!input) |
| 196 | return; |
| 197 | |
| 198 | // Determine (or guess) the character-set by reading the BOM, if any. See |
| 199 | // the YAML specification for the determination algorithm. |
| 200 | char_traits::int_type intro[4]{}; |
| 201 | int nIntroUsed = 0; |
| 202 | UtfIntroState state = uis_start; |
| 203 | for (; !s_introFinalState[state];) { |
| 204 | std::istream::int_type ch = input.get(); |
| 205 | intro[nIntroUsed++] = ch; |
| 206 | UtfIntroCharType charType = IntroCharTypeOf(ch); |
| 207 | UtfIntroState newState = s_introTransitions[state][charType]; |
| 208 | int nUngets = s_introUngetCount[state][charType]; |
| 209 | if (nUngets > 0) { |
| 210 | input.clear(); |
| 211 | for (; nUngets > 0; --nUngets) { |
| 212 | if (char_traits::eof() != intro[--nIntroUsed]) |
| 213 | input.putback(char_traits::to_char_type(intro[nIntroUsed])); |
| 214 | } |
| 215 | } |
| 216 | state = newState; |
| 217 | } |
| 218 | |
| 219 | switch (state) { |
| 220 | case uis_utf8: |
| 221 | m_charSet = utf8; |
| 222 | break; |
| 223 | case uis_utf16le: |
| 224 | m_charSet = utf16le; |
| 225 | break; |
| 226 | case uis_utf16be: |
| 227 | m_charSet = utf16be; |
| 228 | break; |
| 229 | case uis_utf32le: |
| 230 | m_charSet = utf32le; |
| 231 | break; |
| 232 | case uis_utf32be: |
| 233 | m_charSet = utf32be; |
| 234 | break; |
| 235 | default: |
| 236 | m_charSet = utf8; |
| 237 | break; |
| 238 | } |
| 239 | |
| 240 | ReadAheadTo(0); |
| 241 | } |
| 242 |
nothing calls this directly
no test coverage detected