Example #1
0
void TextBuffer::setTextCodec (QTextCodec *codec)
{
  m_textCodec = codec;

  // enforce bom for some encodings
  int mib = m_textCodec->mibEnum ();
  if (mib == 1013 || mib == 1014 || mib == 1015) // utf16
    setGenerateByteOrderMark (true);
  if (mib == 1017 || mib == 1018 || mib == 1019) // utf32
    setGenerateByteOrderMark (true);
}
Example #2
0
bool TextBuffer::load (const QString &filename, bool &encodingErrors)
{
  // fallback codec must exist
  Q_ASSERT (m_fallbackTextCodec);

  // codec must be set!
  Q_ASSERT (m_textCodec);

  /**
   * first: clear buffer in any case!
   */
  clear ();

  /**
   * check if this is a normal file or not, else exit
   */
  KDE_struct_stat sbuf;
  if (KDE::stat(filename, &sbuf) != 0 || !S_ISREG(sbuf.st_mode))
    return false;

  /**
   * construct the file loader for the given file, with correct prober type
   */
  Kate::TextLoader file (filename, m_encodingProberType);

  /**
   * triple play, maximal three loading rounds
   * 0) use the given encoding, be done, if no encoding errors happen
   * 1) use BOM to decided if unicode or if that fails, use encoding prober, if no encoding errors happen, be done
   * 2) use fallback encoding, be done, if no encoding errors happen
   * 3) use again given encoding, be done in any case
   */
  for (int i = 0; i < 4;  ++i) {
    /**
     * kill all blocks beside first one
     */
    for (int b = 1; b < m_blocks.size(); ++b) {
      TextBlock* block = m_blocks.at(b);
      block->m_lines.clear ();
      delete block;
    }
    m_blocks.resize (1);

    /**
     * remove lines in first block
     */
    m_blocks.last()->m_lines.clear ();
    m_lines = 0;

    /**
     * try to open file, with given encoding
     * in round 0 + 3 use the given encoding from user
     * in round 1 use 0, to trigger detection
     * in round 2 use fallback
     */
    QTextCodec *codec = m_textCodec;
    if (i == 1)
      codec = 0;
    else if (i == 2)
      codec = m_fallbackTextCodec;

    if (!file.open (codec)) {
      // create one dummy textline, in any case
      m_blocks.last()->appendLine (TextLine (new TextLineData()));
      m_lines++;
      return false;
    }

    // read in all lines...
    encodingErrors = false;
    while ( !file.eof() )
    {
      // read line
      int offset = 0, length = 0;
      bool currentError = !file.readLine (offset, length);
      encodingErrors = encodingErrors || currentError;

      // bail out on encoding error, if not last round!
      if (encodingErrors && i < 3) {
        kDebug (13020) << "Failed try to load file" << filename << "with codec" <<
                          (file.textCodec() ? file.textCodec()->name() : "(null)");
        break;
      }

      // get unicode data for this line
      const QChar *unicodeData = file.unicode () + offset;

      // construct new text line with content from file
      TextLine textLine = TextLine (new TextLineData(QString (unicodeData, length)));

      // ensure blocks aren't too large
      if (m_blocks.last()->lines() >= m_blockSize)
        m_blocks.append (new TextBlock (this, m_blocks.last()->startLine() + m_blocks.last()->lines()));

      m_blocks.last()->appendLine (textLine);
      m_lines++;
    }

    // if no encoding error, break out of reading loop
    if (!encodingErrors) {
      // remember used codec
      m_textCodec = file.textCodec ();
      break;
    }
  }

  // remember if BOM was found
  if (file.byteOrderMarkFound ())
    setGenerateByteOrderMark (true);

  // remember eol mode, if any found in file
  if (file.eol() != eolUnknown)
    setEndOfLineMode (file.eol());

  // remember mime type for filter device
  m_mimeTypeForFilterDev = file.mimeTypeForFilterDev ();

  // assert that one line is there!
  Q_ASSERT (m_lines > 0);

  // report CODEC + ERRORS
  kDebug (13020) << "Loaded file " << filename << "with codec" << m_textCodec->name()
    << (encodingErrors ? "with" : "without") << "encoding errors";

  // report BOM
  kDebug (13020) << (file.byteOrderMarkFound () ? "Found" : "Didn't find") << "byte order mark";

  // report filter device mime-type
  kDebug (13020) << "used filter device for mime-type" << m_mimeTypeForFilterDev;

  // emit success
  emit loaded (filename, encodingErrors);

  // file loading worked, modulo encoding problems
  return true;
}