MCPcopy Create free account
hub / github.com/SpartanJ/eepp / guessFileEncoding

Function guessFileEncoding

src/eepp/ui/doc/textformat.cpp:390–456  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

388}
389
390TextFormat guessFileEncoding( IOStream& ins ) {
391 auto start = ins.tell();
392 ScopedOp op( [] {}, [&start, &ins] { ins.seek( start ); } );
393 TextFileStats stats8;
394
395 // Try UTF8 first:
396 Uint32 numBytesRead =
397 scanTextFile( stats8, ins, TextEncoding::get<UTF8>(), NumBytesForAutodetect );
398 if ( numBytesRead == 0 )
399 return { TextFormat::Encoding::UTF8, stats8.getNewLineType(), false };
400
401 ins.seek( 0 );
402 if ( stats8.numInvalidPoints() == 0 && stats8.numControl == 0 ) {
403 // No UTF-8 encoding errors, and no weird control characters/nulls. Pick UTF-8.
404 return { TextFormat::Encoding::UTF8, stats8.getNewLineType(), false };
405 }
406
407 // If more than 20% of the high bytes in UTF-8 are encoding errors, reinterpret UTF-8 as just
408 // bytes.
409 TextFormat::Encoding encoding8 = TextFormat::Encoding::UTF8;
410 {
411 Uint32 numHighBytes = numBytesRead - stats8.numPlainAscii - stats8.numControl;
412 if ( stats8.numInvalidPoints() >= numHighBytes * 0.2f ) {
413 // Too many UTF-8 errors. Consider it bytes.
414 encoding8 = TextFormat::Encoding::Latin1;
415 stats8.numPoints = numBytesRead;
416 stats8.numValidPoints = numBytesRead;
417 }
418 }
419
420 // Examine both UTF16 endianness:
421 TextFileStats stats16_le;
422 scanTextFile( stats16_le, ins, TextEncoding::get<UTF16_LE>(), NumBytesForAutodetect );
423 ins.seek( 0 );
424
425 TextFileStats stats16_be;
426 scanTextFile( stats16_be, ins, TextEncoding::get<UTF16_BE>(), NumBytesForAutodetect );
427 ins.seek( 0 );
428
429 // Choose the better UTF16 candidate:
430 TextFileStats* stats = &stats16_le;
431 TextFormat::Encoding encoding = TextFormat::Encoding::UTF16LE;
432 if ( stats16_be.getScore() > stats16_le.getScore() ) {
433 stats = &stats16_be;
434 encoding = TextFormat::Encoding::UTF16BE;
435 }
436
437 TextFileStats statsShiftJIS;
438 statsShiftJIS.count16b = true;
439 scanTextFile( statsShiftJIS, ins, TextEncoding::get<ShiftJIS>(), NumBytesForAutodetect );
440 ins.seek( 0 );
441
442 if ( statsShiftJIS.allValidPoints() && statsShiftJIS.num16bytes &&
443 statsShiftJIS.getScore() > stats->getScore() ) {
444 stats = &statsShiftJIS;
445 encoding = TextFormat::Encoding::Shift_JIS;
446 }
447

Callers 1

autodetectMethod · 0.85

Calls 7

scanTextFileFunction · 0.85
getNewLineTypeMethod · 0.80
numInvalidPointsMethod · 0.80
getScoreMethod · 0.80
allValidPointsMethod · 0.80
tellMethod · 0.45
seekMethod · 0.45

Tested by

no test coverage detected