OSDN Git Service

Fix a crash problem when the Diff algorithm is set to something other than default...
[winmerge-jp/winmerge-jp.git] / Src / DiffContext.h
1 /**
2  *  @file DiffContext.h
3  *
4  *  @brief Declarations of CDiffContext and diff structures
5  */
6 #pragma once
7
8 #define POCO_NO_UNWINDOWS 1
9 #include <Poco/Mutex.h>
10 #include <memory>
11 #include "PathContext.h"
12 #include "DiffItemList.h"
13 #include "FilterList.h"
14 #include "SubstitutionList.h"
15 #include "PropertySystem.h"
16
17 class PackingInfo;
18 class PrediffingInfo;
19 class IDiffFilter;
20 class CompareStats;
21 class IAbortable;
22 class CDiffWrapper;
23 class CompareOptions;
24 struct DIFFOPTIONS;
25
26 /** Interface to a provider of plugin info */
27 class IPluginInfos
28 {
29 public:
30         virtual void FetchPluginInfos(const String& filteredFilenames, 
31                                       PackingInfo ** infoUnpacker, 
32                                       PrediffingInfo ** infoPrediffer) = 0;
33 };
34
35 /** Information on the number of duplicate hash values */
36 struct DuplicateInfo
37 {
38         int groupid;
39         int count[3];
40         bool nonpaired;
41 };
42
43 /**
44  * The folder compare context.
45  * This class holds data of the current folder compare. There are paths
46  * to compare, filters used, compare options etc. And compare results list
47  * is also contained in this class. Many compare classes and functions have
48  * a pointer to instance of this class. 
49  *
50  * @note If you add new member variables, remember to copy values in
51  * CDiffContext::CDiffContext(..,CDiffContext) constructor!
52  */
53 class CDiffContext : public DiffItemList
54 {
55 public:
56         /** @brief Special values for difference counts. */
57         enum
58         {
59                 DIFFS_UNKNOWN = -1, /**< Difference count unknown (generally). */
60                 DIFFS_UNKNOWN_QUICKCOMPARE = -9, /**< Unknown because of quick-compare method. */
61         };
62
63         CDiffContext(const PathContext & paths, int compareMethod);
64         ~CDiffContext();
65
66         void UpdateVersion(DIFFITEM &di, int nIndex) const;
67
68         /**
69          * Get the main compare method used in this compare.
70          * @return Compare method used.
71          */
72         int GetCompareMethod(void) const { return m_nCompMethod; }
73
74         //@{
75         /**
76          * @name Path accessor functions.
77          *
78          * These functions return left/right path associated to DiffContext.
79          * There is no setter fuctions and path can be set only via constructor.
80          * Normalized paths are preferred to use - short paths are expanded
81          * and trailing slashes removed (except from root path).
82          */
83         /**
84          * Get left-side compare path.
85          * @return full path in left-side.
86          */
87         String GetLeftPath() const { return m_paths.GetLeft(false); }
88         String GetMiddlePath() const { return m_paths.GetMiddle(false); }
89         /**
90          * Get right-side compare path.
91          * @return full path in right-side.
92          */
93         String GetRightPath() const { return m_paths.GetRight(false); }
94         String GetPath(int nIndex) const { return m_paths.GetPath(nIndex, false); }
95         /**
96          * Get left-side compare path in normalized form.
97          * @return full path in left-side.
98          */
99         String GetNormalizedLeft() const { return m_paths.GetLeft(); }
100         String GetNormalizedMiddle() const { return m_paths.GetMiddle(); }
101         /**
102          * Get right-side compare path in normalized form.
103          * @return full path in left-side.
104          */
105         String GetNormalizedRight() const { return m_paths.GetRight(); }
106         String GetNormalizedPath(int nIndex) const { return m_paths.GetPath(nIndex, true); }
107         PathContext GetNormalizedPaths() const
108         {
109                 PathContext paths;
110                 for (int nIndex = 0; nIndex < m_paths.GetSize(); nIndex++)
111                         paths.SetPath(nIndex, m_paths.GetPath(nIndex, true));
112                 return paths;
113         }
114         //@}
115
116         // change an existing difference
117         bool UpdateInfoFromDiskHalf(DIFFITEM &di, int nIndex);
118         void UpdateStatusFromDisk(DIFFITEM *diffpos, int nIndex);
119
120         bool CreateCompareOptions(int compareMethod, const DIFFOPTIONS & options);
121         CompareOptions * GetCompareOptions(int compareMethod);
122
123         // retrieve or manufacture plugin info for specified file comparison
124         void FetchPluginInfos(const String& filteredFilenames,
125                 PackingInfo ** infoUnpacker, PrediffingInfo ** infoPrediffer);
126
127         //@{
128         /**
129          * @name Compare aborting interface.
130          * These functions handle compare aborting using IAbortable interface.
131          */
132         bool ShouldAbort() const;
133
134         /**
135          * Set pointer to IAbortable interface.
136          * This function sets pointer to interface used to abort the compare when
137          * user wants to.
138          * @param [in] piAbortable Pointer to interface.
139          */
140         void SetAbortable(IAbortable * piAbortable) { m_piAbortable = piAbortable; }
141
142         /**
143          * Returns a pointer to current IAbortable interface.
144          * This function returns a pointer to interface used to abort the compare.
145          * @return Pointer to current IAbortable interface.
146          */
147         const IAbortable * GetAbortable() const { return m_piAbortable; }
148         //@}
149
150         int GetCompareDirs() const { return m_paths.GetSize(); }
151
152         void Swap(int idx1, int idx2)
153         {
154                 String tmp;
155                 tmp = m_paths.GetPath(idx1);
156                 m_paths.SetPath(idx1, m_paths.GetPath(idx2));
157                 m_paths.SetPath(idx2, tmp);
158                 DiffItemList::Swap(idx1, idx2);
159         }
160
161         const DIFFOPTIONS *GetOptions() const { return m_pOptions.get(); }
162
163         void GetComparePaths(const DIFFITEM& di, PathContext& tFiles) const;
164         String GetFilteredFilenames(const DIFFITEM& di) const;
165         static String GetFilteredFilenames(const PathContext& paths) { return strutils::join(paths.begin(), paths.end(), _T("|")); }
166         void CreateDuplicateValueMap();
167
168         IDiffFilter * m_piFilterGlobal; /**< Interface for file filtering. */
169         IDiffFilter * m_pImgfileFilter; /**< Interface for image file filtering */
170         IPluginInfos * m_piPluginInfos;
171         int m_iGuessEncodingType;
172
173         bool m_bIgnoreSmallTimeDiff; /**< Ignore small timedifferences when comparing by date */
174         CompareStats *m_pCompareStats; /**< Pointer to compare statistics */
175
176         /**
177          * Optimize compare by stopping after first difference.
178          * In some compare methods (currently quick compare) we can stop the
179          * compare right after finding the first difference. This speeds up the
180          * compare, but also causes compare statistics to be inaccurate.
181          */
182         bool m_bStopAfterFirstDiff;
183
184         /**
185          * Threshold size for switching to quick compare.
186          * When diffutils compare is selected, files bigger (in bytes) than this
187          * value are compared using Quick compare. This is because diffutils simply
188          * cannot compare large files. And large files are usually binary files.
189          */
190         int m_nQuickCompareLimit;
191
192         int m_nBinaryCompareLimit;
193
194         /**
195          * Walk into unique folders and add contents.
196          * This enables/disables walking into unique folders. If we don't walk into
197          * unique folders, they are shown as such in folder compare results. If we
198          * walk into unique folders, we'll show all files in the unique folder and
199          * in possible subfolders.
200          *
201          * This value is true by default.
202          */
203         bool m_bWalkUniques;
204         bool m_bIgnoreReparsePoints;
205         bool m_bIgnoreCodepage;
206         bool m_bEnableImageCompare;
207         double m_dColorDistanceThreshold;
208
209         bool m_bRecursive; /**< Do we include subfolders to compare? */
210         bool m_bPluginsEnabled; /**< Are plugins enabled? */
211         std::shared_ptr<FilterList> m_pFilterList; /**< Filter list for line filters */
212         std::shared_ptr<SubstitutionList> m_pSubstitutionList; /// list for Substitution Filters
213         std::unique_ptr<PropertySystem> m_pPropertySystem; /**< pointer to Property System */
214         std::vector<std::map<std::vector<uint8_t>, DuplicateInfo>> m_duplicateValues; /**< Number of duplicate hash values */
215         std::vector<String> m_vCurrentlyHiddenItems; /**< The list of currently hidden items */
216
217 private:
218         /**
219          * The main compare method used.
220          * This is the main compare method set when compare is started. There
221          * can be temporary switches to other method (e.g. for large file) but
222          * this main method must be set back for next file.
223          */
224         int m_nCompMethod;
225
226         std::unique_ptr<DIFFOPTIONS> m_pOptions; /**< Generalized compare options. */
227         std::unique_ptr<CompareOptions> m_pContentCompareOptions; /**< Per compare method compare options. */
228         std::unique_ptr<CompareOptions> m_pQuickCompareOptions;   /**< Per compare method compare options. */
229         PathContext m_paths; /**< (root) paths for this context */
230         IAbortable *m_piAbortable; /**< Interface for aborting the compare. */
231         Poco::FastMutex m_mutex;
232 };