Multi-view edit I
[TortoiseGit.git] / src / TortoiseMerge / FileTextLines.h
blob32f31a1e04ff0d3d2e87beab575e7331355aab02
1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2006-2007, 2012-2013 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #pragma once
20 #include "EOL.h"
21 #include <deque>
23 // A template class to make an array which looks like a CStringArray or CDWORDArray but
24 // is in fact based on a STL vector, which is much faster at large sizes
25 template <typename T> class CStdArrayV
27 public:
28 int GetCount() const { return (int)m_vec.size(); }
29 const T& GetAt(int index) const { return m_vec[index]; }
30 void RemoveAt(int index) { m_vec.erase(m_vec.begin()+index); }
31 void InsertAt(int index, const T& strVal) { m_vec.insert(m_vec.begin()+index, strVal); }
32 void InsertAt(int index, const T& strVal, int nCopies) { m_vec.insert(m_vec.begin()+index, nCopies, strVal); }
33 void SetAt(int index, const T& strVal) { m_vec[index] = strVal; }
34 void Add(const T& strVal)
36 if (m_vec.size()==m_vec.capacity()) {
37 m_vec.reserve(m_vec.capacity() ? m_vec.capacity()*2 : 256);
39 m_vec.push_back(strVal);
41 void RemoveAll() { m_vec.clear(); }
42 void Reserve(int nHintSize) { m_vec.reserve(nHintSize); }
44 private:
45 std::vector<T> m_vec;
48 // A template class to make an array which looks like a CStringArray or CDWORDArray but
49 // is in fact based on a STL deque, which is much faster at large sizes
50 template <typename T> class CStdArrayD
52 public:
53 int GetCount() const { return (int)m_vec.size(); }
54 const T& GetAt(int index) const { return m_vec[index]; }
55 void RemoveAt(int index) { m_vec.erase(m_vec.begin()+index); }
56 void InsertAt(int index, const T& strVal) { m_vec.insert(m_vec.begin()+index, strVal); }
57 void InsertAt(int index, const T& strVal, int nCopies) { m_vec.insert(m_vec.begin()+index, nCopies, strVal); }
58 void SetAt(int index, const T& strVal) { m_vec[index] = strVal; }
59 void Add(const T& strVal) { m_vec.push_back(strVal); }
60 void RemoveAll() { m_vec.clear(); }
61 void Reserve(int ) { }
63 private:
64 std::deque<T> m_vec;
67 typedef CStdArrayV<DWORD> CStdDWORDArray;
69 struct CFileTextLine {
70 CString sLine;
71 EOL eEnding;
73 typedef CStdArrayD<CFileTextLine> CStdFileLineArray;
74 /**
75 * \ingroup TortoiseMerge
77 * Represents an array of text lines which are read from a file.
78 * This class is also responsible for determining the encoding of
79 * the file (e.g. UNICODE(UTF16), UTF8, ASCII, ...).
81 class CFileTextLines : public CStdFileLineArray
83 public:
84 CFileTextLines(void);
85 ~CFileTextLines(void);
87 enum UnicodeType
89 AUTOTYPE,
90 BINARY,
91 ASCII,
92 UTF16_LE, //=1200,
93 UTF16_BE, //=1201,
94 UTF32_LE, //=12000,
95 UTF32_BE, //=12001,
96 UTF8, //=65001,
97 UTF8BOM, //=UTF8+65536,
100 struct SaveParams {
101 UnicodeType m_UnicodeType;
102 EOL m_LineEndings;
106 * Loads the text file and adds each line to the array
107 * \param sFilePath the path to the file
108 * \param lengthHint hint to create line array
110 BOOL Load(const CString& sFilePath, int lengthHint = 0);
112 * Saves the whole array of text lines to a file, preserving
113 * the line endings detected at Load()
114 * \param sFilePath the path to save the file to
115 * \param bSaveAsUTF8 enforce encoding for save
116 * \param bUseSVNCompatibleEOLs limit EOLs to CRLF, CR and LF, last one is used instead of all others
117 * \param dwIgnoreWhitespaces "enum" mode of removing whitespaces
118 * \param bIgnoreCase converts whole file to lower case
119 * \param bBlame limit line len
121 BOOL Save(const CString& sFilePath
122 , bool bSaveAsUTF8 = false
123 , bool bUseSVNCompatibleEOLs = false
124 , DWORD dwIgnoreWhitespaces = 0
125 , BOOL bIgnoreCase = FALSE
126 , bool bBlame = false) const;
128 * Returns an error string of the last failed operation
130 CString GetErrorString() const {return m_sErrorString;}
132 * Copies the settings of a file like the line ending styles
133 * to another CFileTextLines object.
135 void CopySettings(CFileTextLines * pFileToCopySettingsTo);
137 bool NeedsConversion() const { return m_bNeedsConversion; }
138 UnicodeType GetUnicodeType() const {return m_SaveParams.m_UnicodeType;}
139 EOL GetLineEndings() const {return m_SaveParams.m_LineEndings;}
141 using CStdFileLineArray::Add;
142 void Add(const CString& sLine, EOL ending) { CFileTextLine temp={sLine, ending}; CStdFileLineArray::Add(temp); }
143 using CStdFileLineArray::RemoveAt;
144 using CStdFileLineArray::InsertAt;
145 void InsertAt(int index, const CString& strVal, EOL ending) { CFileTextLine temp={strVal, ending}; CStdFileLineArray::InsertAt(index, temp); }
147 const CString& GetAt(int index) const { return CStdFileLineArray::GetAt(index).sLine; }
148 EOL GetLineEnding(int index) const { return CStdFileLineArray::GetAt(index).eEnding; }
149 //void SetLineEnding(int index, EOL ending) { CStdFileLineArray::GetAt(index).eEnding = ending; }
151 using CStdFileLineArray::RemoveAll;
154 * Checks the Unicode type in a text buffer
155 * Must be public for TortoiseGitBlame
156 * \param pBuffer pointer to the buffer containing text
157 * \param cb size of the text buffer in bytes
159 UnicodeType CheckUnicodeType(LPVOID pBuffer, int cb);
161 private:
162 void SetErrorString();
164 static void StripWhiteSpace(CString& sLine, DWORD dwIgnoreWhitespaces, bool blame);
167 private:
168 CString m_sErrorString;
169 bool m_bNeedsConversion;
170 SaveParams m_SaveParams;
175 class CBuffer
177 public:
178 CBuffer() {Init(); }
179 CBuffer(const CBuffer & Src) {Init(); Copy(Src); }
180 CBuffer(const CBuffer * const Src) {Init(); Copy(*Src); }
181 ~CBuffer() {Free(); }
183 CBuffer & operator =(const CBuffer & Src) { Copy(Src); return *this; }
184 operator bool () { return !IsEmpty(); }
185 template<typename T>
186 operator T () const { return (T)m_pBuffer; }
188 void Clear() { m_nUsed=0; }
189 void ExpandToAtLeast(int nNewSize);
190 int GetLength() const { return m_nUsed; }
191 bool IsEmpty() const { return GetLength()==0; }
192 void SetLength(int nUsed);
193 void Swap(CBuffer & Src);
195 private:
196 void Copy(const CBuffer & Src);
197 void Free() { delete [] m_pBuffer; }
198 void Init() { m_pBuffer=NULL; m_nUsed=0; m_nAllocated=0; }
200 BYTE * m_pBuffer;
201 int m_nUsed;
202 int m_nAllocated;
206 class CBaseFilter
208 public:
209 CBaseFilter(CStdioFile * p_File) { m_pFile=p_File; m_nCodePage=0; }
210 virtual ~CBaseFilter() {}
212 virtual bool Decode(/*in out*/ CBuffer & s);
213 virtual const CBuffer & Encode(const CString data);
214 const CBuffer & GetBuffer() {return m_oBuffer; }
215 void Write(const CString s) { Write(Encode(s)); } ///< encode into buffer and write
216 void Write() { Write(m_oBuffer); } ///< write preencoded internal buffer
217 void Write(const CBuffer & buffer) { if (buffer.GetLength()) m_pFile->Write((void*)buffer, buffer.GetLength()); } ///< write preencoded buffer
219 protected:
220 CBuffer m_oBuffer;
222 Code page for WideCharToMultiByte.
224 UINT m_nCodePage;
226 private:
227 CStdioFile * m_pFile;
231 class CAsciiFilter : public CBaseFilter
233 public:
234 CAsciiFilter(CStdioFile *pFile) : CBaseFilter(pFile){ m_nCodePage=CP_ACP; }
235 virtual ~CAsciiFilter() {}
239 class CUtf8Filter : public CBaseFilter
241 public:
242 CUtf8Filter(CStdioFile *pFile) : CBaseFilter(pFile){ m_nCodePage=CP_UTF8;}
243 virtual ~CUtf8Filter() {}
247 class CUtf16leFilter : public CBaseFilter
249 public:
250 CUtf16leFilter(CStdioFile *pFile) : CBaseFilter(pFile){}
251 virtual ~CUtf16leFilter() {}
253 virtual bool Decode(/*in out*/ CBuffer & data);
254 virtual const CBuffer & Encode(const CString s);
258 class CUtf16beFilter : public CUtf16leFilter
260 public:
261 CUtf16beFilter(CStdioFile *pFile) : CUtf16leFilter(pFile){}
262 virtual ~CUtf16beFilter() {}
264 virtual bool Decode(/*in out*/ CBuffer & data);
265 virtual const CBuffer & Encode(const CString s);
269 class CUtf32leFilter : public CBaseFilter
271 public:
272 CUtf32leFilter(CStdioFile *pFile) : CBaseFilter(pFile){}
273 virtual ~CUtf32leFilter() {}
275 virtual bool Decode(/*in out*/ CBuffer & data);
276 virtual const CBuffer & Encode(const CString s);
280 class CUtf32beFilter : public CUtf32leFilter
282 public:
283 CUtf32beFilter(CStdioFile *pFile) : CUtf32leFilter(pFile){}
284 virtual ~CUtf32beFilter() {}
286 virtual bool Decode(/*in out*/ CBuffer & data);
287 virtual const CBuffer & Encode(const CString s);