1 /**
2  * @copyright
3  * ====================================================================
4  *    Licensed to the Apache Software Foundation (ASF) under one
5  *    or more contributor license agreements.  See the NOTICE file
6  *    distributed with this work for additional information
7  *    regarding copyright ownership.  The ASF licenses this file
8  *    to you under the Apache License, Version 2.0 (the
9  *    "License"); you may not use this file except in compliance
10  *    with the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *    Unless required by applicable law or agreed to in writing,
15  *    software distributed under the License is distributed on an
16  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  *    KIND, either express or implied.  See the License for the
18  *    specific language governing permissions and limitations
19  *    under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file org_apache_subversion_javahl_util_DiffLib.cpp
24  * @brief Implementation of the native methods in the Java class DiffLib
25  */
26 
27 #include "../include/org_apache_subversion_javahl_util_DiffLib.h"
28 
29 #include "JNIStackElement.h"
30 #include "JNIStringHolder.h"
31 #include "JNIUtil.h"
32 #include "OutputStream.h"
33 #include "Path.h"
34 #include "Pool.h"
35 
36 #include "svn_diff.h"
37 
38 JNIEXPORT jboolean JNICALL
Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff(JNIEnv * env,jobject jthis,jstring joriginal_file,jstring jmodified_file,jint jignore_space_ordinal,jboolean jignore_eol_style,jboolean jshow_c_function,jint jcontext_size,jstring joriginal_header,jstring jmodified_header,jstring jheader_encoding,jstring jrelative_to_dir,jobject jresult_stream)39 Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff(
40     JNIEnv* env, jobject jthis,
41     jstring joriginal_file,
42     jstring jmodified_file,
43 
44     jint jignore_space_ordinal,
45     jboolean jignore_eol_style,
46     jboolean jshow_c_function,
47     jint jcontext_size,
48 
49     jstring joriginal_header,
50     jstring jmodified_header,
51     jstring jheader_encoding,
52     jstring jrelative_to_dir,
53 
54     jobject jresult_stream)
55 {
56   JNIEntry(DiffLib, nativeFileDiff);
57 
58   // Using a "global" request pool since we don't keep a context with
59   // its own pool around for these functions.
60   SVN::Pool pool;
61 
62   Path original(joriginal_file, pool);
63   if (JNIUtil::isJavaExceptionThrown())
64     return false;
65   SVN_JNI_ERR(original.error_occurred(), false);
66 
67   Path modified(jmodified_file, pool);
68   if (JNIUtil::isJavaExceptionThrown())
69     return false;
70   SVN_JNI_ERR(modified.error_occurred(), false);
71 
72   svn_diff_t* diff;
73   svn_diff_file_options_t* diff_options =
74     svn_diff_file_options_create(pool.getPool());
75   diff_options->ignore_space =
76     svn_diff_file_ignore_space_t(jignore_space_ordinal);
77   diff_options->ignore_eol_style = svn_boolean_t(jignore_eol_style);
78   diff_options->show_c_function = svn_boolean_t(jshow_c_function);
79   SVN_JNI_ERR(svn_diff_file_diff_2(&diff,
80                                    original.c_str(),
81                                    modified.c_str(),
82                                    diff_options,
83                                    pool.getPool()),
84               false);
85 
86   const jboolean diffs = svn_diff_contains_diffs(diff);
87 
88   JNIStringHolder original_header(joriginal_header);
89   if (JNIUtil::isJavaExceptionThrown())
90     return false;
91 
92   JNIStringHolder modified_header(jmodified_header);
93   if (JNIUtil::isJavaExceptionThrown())
94     return false;
95 
96   JNIStringHolder header_encoding(jheader_encoding);
97   if (JNIUtil::isJavaExceptionThrown())
98     return false;
99 
100   JNIStringHolder relative_to_dir(jrelative_to_dir);
101   if (JNIUtil::isJavaExceptionThrown())
102     return false;
103 
104   OutputStream result_stream(jresult_stream);
105 
106   SVN_JNI_ERR(svn_diff_file_output_unified4(
107                   result_stream.getStream(pool), diff,
108                   original.c_str(), modified.c_str(),
109                   original_header.c_str(), modified_header.c_str(),
110                   header_encoding.c_str(), relative_to_dir.c_str(),
111                   diff_options->show_c_function, int(jcontext_size),
112                   NULL, NULL, pool.getPool()),
113               false);
114 
115   return diffs;
116 }
117 
118 JNIEXPORT jboolean JNICALL
Java_org_apache_subversion_javahl_util_DiffLib_nativeFileMerge(JNIEnv * env,jobject jthis,jstring joriginal_file,jstring jmodified_file,jstring jlatest_file,jint jignore_space_ordinal,jboolean jignore_eol_style,jboolean jshow_c_function,jstring jconflict_original,jstring jconflict_modified,jstring jconflict_latest,jstring jconflict_separator,jint jconflict_style_ordinal,jobject jresult_stream)119 Java_org_apache_subversion_javahl_util_DiffLib_nativeFileMerge(
120     JNIEnv* env, jobject jthis,
121     jstring joriginal_file,
122     jstring jmodified_file,
123     jstring jlatest_file,
124 
125     jint jignore_space_ordinal,
126     jboolean jignore_eol_style,
127     jboolean jshow_c_function,
128 
129     jstring jconflict_original,
130     jstring jconflict_modified,
131     jstring jconflict_latest,
132     jstring jconflict_separator,
133     jint jconflict_style_ordinal,
134 
135     jobject jresult_stream)
136 {
137   JNIEntry(DiffLib, nativeFileMerge);
138 
139   // Using a "global" request pool since we don't keep a context with
140   // its own pool around for these functions.
141   SVN::Pool pool;
142 
143   Path original(joriginal_file, pool);
144   if (JNIUtil::isJavaExceptionThrown())
145     return false;
146   SVN_JNI_ERR(original.error_occurred(), false);
147 
148   Path modified(jmodified_file, pool);
149   if (JNIUtil::isJavaExceptionThrown())
150     return false;
151   SVN_JNI_ERR(modified.error_occurred(), false);
152 
153   Path latest(jlatest_file, pool);
154   if (JNIUtil::isJavaExceptionThrown())
155     return false;
156   SVN_JNI_ERR(latest.error_occurred(), false);
157 
158   svn_diff_t* diff;
159   svn_diff_file_options_t* diff_options =
160     svn_diff_file_options_create(pool.getPool());
161   diff_options->ignore_space =
162     svn_diff_file_ignore_space_t(jignore_space_ordinal);
163   diff_options->ignore_eol_style = svn_boolean_t(jignore_eol_style);
164   diff_options->show_c_function = svn_boolean_t(jshow_c_function);
165   SVN_JNI_ERR(svn_diff_file_diff3_2(&diff,
166                                     original.c_str(),
167                                     modified.c_str(),
168                                     latest.c_str(),
169                                     diff_options,
170                                     pool.getPool()),
171               false);
172 
173   const jboolean conflicts = svn_diff_contains_conflicts(diff);
174 
175   JNIStringHolder conflict_original(jconflict_original);
176   if (JNIUtil::isJavaExceptionThrown())
177     return false;
178 
179   JNIStringHolder conflict_modified(jconflict_modified);
180   if (JNIUtil::isJavaExceptionThrown())
181     return false;
182 
183   JNIStringHolder conflict_latest(jconflict_latest);
184   if (JNIUtil::isJavaExceptionThrown())
185     return false;
186 
187   JNIStringHolder conflict_separator(jconflict_separator);
188   if (JNIUtil::isJavaExceptionThrown())
189     return false;
190 
191   OutputStream result_stream(jresult_stream);
192 
193   SVN_JNI_ERR(svn_diff_file_output_merge3(
194                   result_stream.getStream(pool), diff,
195                   original.c_str(), modified.c_str(), latest.c_str(),
196                   conflict_original.c_str(),
197                   conflict_modified.c_str(),
198                   conflict_latest.c_str(),
199                   conflict_separator.c_str(),
200                   svn_diff_conflict_display_style_t(jconflict_style_ordinal),
201                   NULL, NULL,
202                   pool.getPool()),
203               false);
204 
205   return conflicts;
206 }
207