File indexing completed on 2024-12-08 05:07:39
0001 // clang-format off 0002 /* 0003 * This file is part of KDiff3. 0004 * 0005 * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de 0006 * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 // clang-format on 0010 0011 #ifndef SOURCEDATA_H 0012 #define SOURCEDATA_H 0013 0014 #include "diff.h" 0015 #include "fileaccess.h" 0016 #include "LineRef.h" 0017 #include "options.h" 0018 0019 #include <memory> 0020 #include <optional> 0021 0022 #include <QTemporaryFile> 0023 #include <QSharedPointer> 0024 #include <QString> 0025 #include <QStringList> 0026 0027 class SourceData 0028 { 0029 public: 0030 [[nodiscard]] LineType getSizeLines() const; 0031 [[nodiscard]] qint64 getSizeBytes() const; 0032 [[nodiscard]] const char* getBuf() const; 0033 [[nodiscard]] const QString& getText() const; 0034 [[nodiscard]] const std::shared_ptr<LineDataVector>& getLineDataForDisplay() const; 0035 [[nodiscard]] const std::shared_ptr<LineDataVector>& getLineDataForDiff() const; 0036 0037 void setFilename(const QString& filename); 0038 void setFileAccess(const FileAccess& fileAccess); 0039 [[nodiscard]] QString getFilename() const; 0040 void setAliasName(const QString& name); 0041 [[nodiscard]] QString getAliasName() const; 0042 [[nodiscard]] bool isEmpty() const; // File was set 0043 [[nodiscard]] bool hasData() const; // Data was readable 0044 [[nodiscard]] bool isText() const; // is it pure text (vs. binary data) 0045 [[nodiscard]] bool isIncompleteConversion() const; // true if some replacement characters were found 0046 [[nodiscard]] bool isFromBuffer() const; // was it set via setData() (vs. setFileAccess() or setFilename()) 0047 void setData(const QString& data); 0048 [[nodiscard]] bool isValid() const; // Either no file is specified or reading was successful 0049 0050 // Returns a list of error messages if anything went wrong 0051 void readAndPreprocess(const char* encoding, bool bAutoDetectUnicode); 0052 bool saveNormalDataAs(const QString& fileName); 0053 0054 [[nodiscard]] bool isBinaryEqualWith(const QSharedPointer<SourceData>& other) const; 0055 0056 void reset(); 0057 0058 [[nodiscard]] bool isDir() const { return m_fileAccess.isDir(); } 0059 0060 [[nodiscard]] const char* getEncoding() const { return mEncoding; } 0061 [[nodiscard]] e_LineEndStyle getLineEndStyle() const { return m_normalData.m_eLineEndStyle; } 0062 [[nodiscard]] inline bool hasEOLTermiantion() { return m_normalData.hasEOLTermiantion(); } 0063 [[nodiscard]] inline bool hasBOM() const { return m_normalData.hasBOM(); } 0064 [[nodiscard]] const QStringList& getErrors() const { return mErrors; } 0065 0066 void setEncoding(const char* encoding); 0067 0068 protected: 0069 bool convertFileEncoding(const QString& fileNameIn, const QByteArray& pCodecIn, 0070 const QString& fileNameOut, const QByteArray& pCodecOut); 0071 0072 [[nodiscard]] static std::optional<const char*> detectUTF8(const QByteArray& data); 0073 [[nodiscard]] static std::optional<const char*> detectEncoding(const char* buf, qint64 size, FileOffset& skipBytes); 0074 [[nodiscard]] static std::optional<const char*> getEncodingFromTag(const QByteArray& s, const QByteArray& encodingTag); 0075 0076 std::optional<const char*> detectEncoding(const QString& fileName); 0077 QString m_aliasName; 0078 FileAccess m_fileAccess; 0079 QString m_tempInputFileName; 0080 QTemporaryFile m_tempFile; //Created from clipboard content. 0081 0082 QStringList mErrors; 0083 0084 bool mFromClipBoard = false; 0085 0086 class FileData 0087 { 0088 private: 0089 friend SourceData; 0090 bool mHasBOM = false; 0091 0092 std::unique_ptr<char[]> m_pBuf; //TODO: Phase out needlessly wastes memory and time by keeping second copy of file data. 0093 quint64 mDataSize = 0; 0094 qint64 mLineCount = 0; // Number of lines in m_pBuf1 and size of m_v1, m_dv12 and m_dv13 0095 QSharedPointer<QString> m_unicodeBuf=QSharedPointer<QString>::create(); 0096 std::shared_ptr<LineDataVector> m_v=std::make_shared<LineDataVector>(); 0097 bool m_bIsText = false; 0098 bool m_bIncompleteConversion = false; 0099 e_LineEndStyle m_eLineEndStyle = eLineEndStyleUndefined; 0100 bool mHasEOLTermination = false; 0101 0102 public: 0103 bool readFile(FileAccess& file); 0104 bool readFile(const QString& filename); 0105 bool writeFile(const QString& filename); 0106 0107 bool preprocess(const QByteArray& encoding, bool removeComments); 0108 void reset(); 0109 void copyBufFrom(const FileData& src); 0110 0111 [[nodiscard]] bool isEmpty() const { return mDataSize == 0; } 0112 0113 [[nodiscard]] bool isText() const { return m_bIsText || isEmpty(); } 0114 [[nodiscard]] inline bool hasEOLTermiantion() const { return m_bIsText && mHasEOLTermination; } 0115 [[nodiscard]] inline bool hasBOM() const { return mHasBOM; } 0116 0117 [[nodiscard]] inline qint64 lineCount() const { return mLineCount; } 0118 [[nodiscard]] inline qint64 byteCount() const { return mDataSize; } 0119 }; 0120 FileData m_normalData; 0121 FileData m_lmppData; 0122 const char* mEncoding = u8"UTF-8"; 0123 }; 0124 0125 #endif // !SOURCEDATA_H