| 99 | } |
| 100 | |
| 101 | FileType::type IdentifyFile(const std::wstring& filename) |
| 102 | { |
| 103 | { |
| 104 | // Encoding detection is very complex, see #107 |
| 105 | std::ifstream fs(filename, std::ios::binary); |
| 106 | std::vector<unsigned char> buffer(3); |
| 107 | fs.read((char*)buffer.data(), buffer.size()); |
| 108 | if (buffer[0] == 0xfe && buffer[1] == 0xff) |
| 109 | { |
| 110 | return FileType::UTF16BE; |
| 111 | } |
| 112 | if (buffer[0] == 0xff && buffer[1] == 0xfe) |
| 113 | { |
| 114 | return FileType::UTF16LE; |
| 115 | } |
| 116 | if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) |
| 117 | { |
| 118 | return FileType::UTF8; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | std::ifstream is(filename); |
| 123 | std::string line; |
| 124 | if (!std::getline(is, line)) |
| 125 | return FileType::Unknown; |
| 126 | |
| 127 | // first we check for our own header |
| 128 | auto trimmed = boost::trim_copy_if(line, boost::is_any_of(" \r\n\t")); |
| 129 | if (boost::ends_with(trimmed, g_debugViewPPIdentification1)) |
| 130 | { |
| 131 | return FileType::DebugViewPP1; |
| 132 | } |
| 133 | if (boost::ends_with(trimmed, g_debugViewPPIdentification2)) |
| 134 | { |
| 135 | return FileType::DebugViewPP2; |
| 136 | } |
| 137 | |
| 138 | // if the extension is .txt (and we did not find our own header) |
| 139 | // we say it is an ascii-file. |
| 140 | if (boost::iends_with(filename, ".txt")) |
| 141 | return FileType::AsciiText; |
| 142 | |
| 143 | // .log files are potentially sysinternals dbgview files |
| 144 | if (boost::iends_with(filename, ".log")) |
| 145 | { |
| 146 | // to test for sysinternals debugview-logfiles, we need to check the second line |
| 147 | // since the first line contains the computer-name in some cases (depending on how it was saved) |
| 148 | // logfiles with only one line are not that interesting anyway. |
| 149 | if (!std::getline(is, line)) |
| 150 | return FileType::AsciiText; |
| 151 | |
| 152 | // if the second line contains 2 or 3 tabs characters, we say it's a sysinternals debugview-logfile |
| 153 | // two kinds of lines are logged, kernel message lines and process message lines, the latter have an extra PID Columnn |
| 154 | auto tabs = std::count(line.begin(), line.end(), '\t'); |
| 155 | if (tabs == 2 || tabs == 3) |
| 156 | return FileType::Sysinternals; |
| 157 | } |
| 158 | return FileType::AsciiText; |
no test coverage detected