1 // TortoiseGitMerge - a Diff/Patch program
3 // Copyright (C) 2006-2007, 2012-2014 - 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.
24 // A template class to make an array which looks like a CStringArray or CDWORDArray but
25 // is in fact based on a STL vector, which is much faster at large sizes
26 template <typename T
> class CStdArrayV
29 int GetCount() const { return (int)m_vec
.size(); }
30 const T
& GetAt(int index
) const { return m_vec
[index
]; }
31 void RemoveAt(int index
) { m_vec
.erase(m_vec
.begin()+index
); }
32 void InsertAt(int index
, const T
& strVal
) { m_vec
.insert(m_vec
.begin()+index
, strVal
); }
33 void InsertAt(int index
, const T
& strVal
, int nCopies
) { m_vec
.insert(m_vec
.begin()+index
, nCopies
, strVal
); }
34 void SetAt(int index
, const T
& strVal
) { m_vec
[index
] = strVal
; }
35 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
); }
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
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 ) { }
67 typedef CStdArrayV
<DWORD
> CStdDWORDArray
;
69 struct CFileTextLine
{
73 typedef CStdArrayD
<CFileTextLine
> CStdFileLineArray
;
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
85 ~CFileTextLines(void);
99 UTF8BOM
, //=UTF8+65536,
103 UnicodeType m_UnicodeType
;
108 * Loads the text file and adds each line to the array
109 * \param sFilePath the path to the file
110 * \param lengthHint hint to create line array
112 BOOL
Load(const CString
& sFilePath
, int lengthHint
= 0);
114 * Saves the whole array of text lines to a file, preserving
115 * the line endings detected at Load()
116 * \param sFilePath the path to save the file to
117 * \param bSaveAsUTF8 enforce encoding for save
118 * \param bUseSVNCompatibleEOLs limit EOLs to CRLF, CR and LF, last one is used instead of all others
119 * \param dwIgnoreWhitespaces "enum" mode of removing whitespaces
120 * \param bIgnoreCase converts whole file to lower case
121 * \param bBlame limit line len
123 BOOL
Save(const CString
& sFilePath
124 , bool bSaveAsUTF8
= false
125 , bool bUseSVNCompatibleEOLs
= false
126 , DWORD dwIgnoreWhitespaces
= 0
127 , BOOL bIgnoreCase
= FALSE
128 , bool bBlame
= false
129 , bool bIgnoreComments
= false
130 , const CString
& linestart
= CString()
131 , const CString
& blockstart
= CString()
132 , const CString
& blockend
= CString()
133 , const std::wregex
& rx
= std::wregex(L
"")
134 , const std::wstring
& replacement
= L
"");
136 * Returns an error string of the last failed operation
138 CString
GetErrorString() const {return m_sErrorString
;}
140 * Copies the settings of a file like the line ending styles
141 * to another CFileTextLines object.
143 void CopySettings(CFileTextLines
* pFileToCopySettingsTo
) const;
145 void SetCommentTokens();
147 bool NeedsConversion() const { return m_bNeedsConversion
; }
148 UnicodeType
GetUnicodeType() const {return m_SaveParams
.m_UnicodeType
;}
149 EOL
GetLineEndings() const {return m_SaveParams
.m_LineEndings
;}
151 void Add(const CString
& sLine
, EOL ending
) { CFileTextLine temp
={sLine
, ending
}; CStdFileLineArray::Add(temp
); }
152 void InsertAt(int index
, const CString
& strVal
, EOL ending
) { CFileTextLine temp
={strVal
, ending
}; CStdFileLineArray::InsertAt(index
, temp
); }
154 const CString
& GetAt(int index
) const { return CStdFileLineArray::GetAt(index
).sLine
; }
155 EOL
GetLineEnding(int index
) const { return CStdFileLineArray::GetAt(index
).eEnding
; }
156 void SetSaveParams(const SaveParams
& sp
) { m_SaveParams
= sp
; }
157 //void SetLineEnding(int index, EOL ending) { CStdFileLineArray::GetAt(index).eEnding = ending; }
159 static const wchar_t * GetEncodingName(UnicodeType
);
162 * Checks the Unicode type in a text buffer
163 * Must be public for TortoiseGitBlame
164 * \param pBuffer pointer to the buffer containing text
165 * \param cb size of the text buffer in bytes
167 UnicodeType
CheckUnicodeType(LPVOID pBuffer
, int cb
);
170 void SetErrorString();
172 static void StripWhiteSpace(CString
& sLine
, DWORD dwIgnoreWhitespaces
, bool blame
);
173 bool StripComments(CString
& sLine
, bool bInBlockComment
);
174 void LineRegex(CString
& sLine
, const std::wregex
& rx
, const std::wstring
& replacement
) const;
178 CString m_sErrorString
;
179 bool m_bNeedsConversion
;
180 SaveParams m_SaveParams
;
181 CString m_sCommentLine
;
182 CString m_sCommentBlockStart
;
183 CString m_sCommentBlockEnd
;
192 CBuffer(const CBuffer
& Src
) {Init(); Copy(Src
); }
193 CBuffer(const CBuffer
* const Src
) {Init(); Copy(*Src
); }
194 ~CBuffer() {Free(); }
196 CBuffer
& operator =(const CBuffer
& Src
) { Copy(Src
); return *this; }
197 operator bool () const { return !IsEmpty(); }
199 operator T () const { return (T
)m_pBuffer
; }
201 void Clear() { m_nUsed
=0; }
202 void ExpandToAtLeast(int nNewSize
);
203 int GetLength() const { return m_nUsed
; }
204 bool IsEmpty() const { return GetLength()==0; }
205 void SetLength(int nUsed
);
206 void Swap(CBuffer
& Src
);
209 void Copy(const CBuffer
& Src
);
210 void Free() { delete [] m_pBuffer
; }
211 void Init() { m_pBuffer
=NULL
; m_nUsed
=0; m_nAllocated
=0; }
222 CBaseFilter(CStdioFile
* p_File
) { m_pFile
=p_File
; m_nCodePage
=0; }
223 virtual ~CBaseFilter() {}
225 virtual bool Decode(/*in out*/ CBuffer
& s
);
226 virtual const CBuffer
& Encode(const CString data
);
227 const CBuffer
& GetBuffer() const {return m_oBuffer
; }
228 void Write(const CString s
) { Write(Encode(s
)); } ///< encode into buffer and write
229 void Write() { Write(m_oBuffer
); } ///< write preencoded internal buffer
230 void Write(const CBuffer
& buffer
) { if (buffer
.GetLength()) m_pFile
->Write((void*)buffer
, buffer
.GetLength()); } ///< write preencoded buffer
235 Code page for WideCharToMultiByte.
240 CStdioFile
* m_pFile
;
244 class CAsciiFilter
: public CBaseFilter
247 CAsciiFilter(CStdioFile
*pFile
) : CBaseFilter(pFile
){ m_nCodePage
=CP_ACP
; }
248 virtual ~CAsciiFilter() {}
252 class CUtf8Filter
: public CBaseFilter
255 CUtf8Filter(CStdioFile
*pFile
) : CBaseFilter(pFile
){ m_nCodePage
=CP_UTF8
;}
256 virtual ~CUtf8Filter() {}
260 class CUtf16leFilter
: public CBaseFilter
263 CUtf16leFilter(CStdioFile
*pFile
) : CBaseFilter(pFile
){}
264 virtual ~CUtf16leFilter() {}
266 virtual bool Decode(/*in out*/ CBuffer
& data
);
267 virtual const CBuffer
& Encode(const CString s
);
271 class CUtf16beFilter
: public CUtf16leFilter
274 CUtf16beFilter(CStdioFile
*pFile
) : CUtf16leFilter(pFile
){}
275 virtual ~CUtf16beFilter() {}
277 virtual bool Decode(/*in out*/ CBuffer
& data
);
278 virtual const CBuffer
& Encode(const CString s
);
282 class CUtf32leFilter
: public CBaseFilter
285 CUtf32leFilter(CStdioFile
*pFile
) : CBaseFilter(pFile
){}
286 virtual ~CUtf32leFilter() {}
288 virtual bool Decode(/*in out*/ CBuffer
& data
);
289 virtual const CBuffer
& Encode(const CString s
);
293 class CUtf32beFilter
: public CUtf32leFilter
296 CUtf32beFilter(CStdioFile
*pFile
) : CUtf32leFilter(pFile
){}
297 virtual ~CUtf32beFilter() {}
299 virtual bool Decode(/*in out*/ CBuffer
& data
);
300 virtual const CBuffer
& Encode(const CString s
);