Fix for core.autocrlf=input resulting in modified file
This version does not attempt to unsmudge, unlike the first attempt in Idafad150553df14827eccfde2e3b95760e16a8b6. Bug: 372834 Change-Id: I9300e735cb16d6208e1df963abb1ff69f688155d Also-by: Robin Stocker <robin@nibor.org> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Robin Stocker <robin@nibor.org>
This commit is contained in:
parent
8352d1729c
commit
5404e70dc6
|
@ -68,9 +68,11 @@
|
||||||
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
|
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
|
||||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||||
|
import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
|
||||||
import org.eclipse.jgit.lib.IndexDiff.StageState;
|
import org.eclipse.jgit.lib.IndexDiff.StageState;
|
||||||
import org.eclipse.jgit.merge.MergeStrategy;
|
import org.eclipse.jgit.merge.MergeStrategy;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||||
import org.eclipse.jgit.util.IO;
|
import org.eclipse.jgit.util.IO;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -576,6 +578,35 @@ public void testStageState() throws IOException {
|
||||||
assertTrue(StageState.BOTH_ADDED.hasTheirs());
|
assertTrue(StageState.BOTH_ADDED.hasTheirs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAutoCRLFInput() throws Exception {
|
||||||
|
Git git = new Git(db);
|
||||||
|
FileBasedConfig config = db.getConfig();
|
||||||
|
|
||||||
|
// Make sure core.autocrlf is false before adding
|
||||||
|
config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
|
||||||
|
ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.FALSE);
|
||||||
|
config.save();
|
||||||
|
|
||||||
|
// File is already in repository with CRLF
|
||||||
|
writeTrashFile("crlf.txt", "this\r\ncontains\r\ncrlf\r\n");
|
||||||
|
git.add().addFilepattern("crlf.txt").call();
|
||||||
|
git.commit().setMessage("Add crlf.txt").call();
|
||||||
|
|
||||||
|
// Now set core.autocrlf to input
|
||||||
|
config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
|
||||||
|
ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.INPUT);
|
||||||
|
config.save();
|
||||||
|
|
||||||
|
FileTreeIterator iterator = new FileTreeIterator(db);
|
||||||
|
IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator);
|
||||||
|
diff.diff();
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
"Expected no modified files, but there were: "
|
||||||
|
+ diff.getModified(), diff.getModified().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyStageState(StageState expected, int... stages)
|
private void verifyStageState(StageState expected, int... stages)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
DirCacheBuilder builder = db.lockDirCache().builder();
|
DirCacheBuilder builder = db.lockDirCache().builder();
|
||||||
|
|
|
@ -223,7 +223,9 @@ public void testDirCacheMatchingId() throws Exception {
|
||||||
ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset());
|
ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset());
|
||||||
assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
|
assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
|
||||||
fromRaw.getName());
|
fromRaw.getName());
|
||||||
assertFalse(fti.isModified(dce, false));
|
ObjectReader objectReader = db.newObjectReader();
|
||||||
|
assertFalse(fti.isModified(dce, false, objectReader));
|
||||||
|
objectReader.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -242,7 +244,9 @@ public void testIsModifiedSymlink() throws Exception {
|
||||||
.getConfig().get(WorkingTreeOptions.KEY));
|
.getConfig().get(WorkingTreeOptions.KEY));
|
||||||
while (!fti.getEntryPathString().equals("symlink"))
|
while (!fti.getEntryPathString().equals("symlink"))
|
||||||
fti.next(1);
|
fti.next(1);
|
||||||
assertFalse(fti.isModified(dce, false));
|
ObjectReader objectReader = db.newObjectReader();
|
||||||
|
assertFalse(fti.isModified(dce, false, objectReader));
|
||||||
|
objectReader.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -265,7 +269,9 @@ public void testIsModifiedFileSmudged() throws Exception {
|
||||||
// If the rounding trick does not work we could skip the compareMetaData
|
// If the rounding trick does not work we could skip the compareMetaData
|
||||||
// test and hope that we are usually testing the intended code path.
|
// test and hope that we are usually testing the intended code path.
|
||||||
assertEquals(MetadataDiff.SMUDGED, fti.compareMetadata(dce));
|
assertEquals(MetadataDiff.SMUDGED, fti.compareMetadata(dce));
|
||||||
assertTrue(fti.isModified(dce, false));
|
ObjectReader objectReader = db.newObjectReader();
|
||||||
|
assertTrue(fti.isModified(dce, false, objectReader));
|
||||||
|
objectReader.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -326,7 +326,8 @@ void processEntry(CanonicalTreeParser m, DirCacheBuildIterator i,
|
||||||
m.getEntryFileMode());
|
m.getEntryFileMode());
|
||||||
} else if (i.getDirCacheEntry() != null) {
|
} else if (i.getDirCacheEntry() != null) {
|
||||||
// The index contains a file (and not a folder)
|
// The index contains a file (and not a folder)
|
||||||
if (f.isModified(i.getDirCacheEntry(), true)
|
if (f.isModified(i.getDirCacheEntry(), true,
|
||||||
|
this.walk.getObjectReader())
|
||||||
|| i.getDirCacheEntry().getStage() != 0)
|
|| i.getDirCacheEntry().getStage() != 0)
|
||||||
// The working tree file is dirty or the index contains a
|
// The working tree file is dirty or the index contains a
|
||||||
// conflict
|
// conflict
|
||||||
|
@ -660,7 +661,9 @@ void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
|
||||||
break;
|
break;
|
||||||
case 0xFFD: // 12 13 14
|
case 0xFFD: // 12 13 14
|
||||||
if (equalIdAndMode(hId, hMode, iId, iMode))
|
if (equalIdAndMode(hId, hMode, iId, iMode))
|
||||||
if (f == null || f.isModified(dce, true))
|
if (f == null
|
||||||
|
|| f.isModified(dce, true,
|
||||||
|
this.walk.getObjectReader()))
|
||||||
conflict(name, dce, h, m);
|
conflict(name, dce, h, m);
|
||||||
else
|
else
|
||||||
remove(name);
|
remove(name);
|
||||||
|
@ -774,7 +777,8 @@ else if (m == null)
|
||||||
// Nothing in Head
|
// Nothing in Head
|
||||||
// Something in Index
|
// Something in Index
|
||||||
if (dce != null
|
if (dce != null
|
||||||
&& (f == null || f.isModified(dce, true)))
|
&& (f == null || f.isModified(dce, true,
|
||||||
|
this.walk.getObjectReader())))
|
||||||
// No file or file is dirty
|
// No file or file is dirty
|
||||||
// Nothing in Merge and current path is part of
|
// Nothing in Merge and current path is part of
|
||||||
// File/Folder conflict
|
// File/Folder conflict
|
||||||
|
@ -841,7 +845,9 @@ else if (m == null)
|
||||||
// Something different from a submodule in Index
|
// Something different from a submodule in Index
|
||||||
// Nothing in Merge
|
// Nothing in Merge
|
||||||
// Something in Head
|
// Something in Head
|
||||||
if (f == null || f.isModified(dce, true))
|
if (f == null
|
||||||
|
|| f.isModified(dce, true,
|
||||||
|
this.walk.getObjectReader()))
|
||||||
// file is dirty
|
// file is dirty
|
||||||
// Index contains the same as Head
|
// Index contains the same as Head
|
||||||
// Something different from a submodule in Index
|
// Something different from a submodule in Index
|
||||||
|
@ -904,7 +910,8 @@ else if (m == null)
|
||||||
// file content
|
// file content
|
||||||
update(name, mId, mMode);
|
update(name, mId, mMode);
|
||||||
} else if (dce != null
|
} else if (dce != null
|
||||||
&& (f == null || f.isModified(dce, true))) {
|
&& (f == null || f.isModified(dce, true,
|
||||||
|
this.walk.getObjectReader()))) {
|
||||||
// File doesn't exist or is dirty
|
// File doesn't exist or is dirty
|
||||||
// Head and Index don't contain a submodule
|
// Head and Index don't contain a submodule
|
||||||
// Head contains the same as Index. Merge differs
|
// Head contains the same as Index. Merge differs
|
||||||
|
@ -1041,7 +1048,8 @@ private boolean isModified(String path) throws CorruptObjectException, IOExcepti
|
||||||
wtIt = tw.getTree(1, WorkingTreeIterator.class);
|
wtIt = tw.getTree(1, WorkingTreeIterator.class);
|
||||||
if (dcIt == null || wtIt == null)
|
if (dcIt == null || wtIt == null)
|
||||||
return true;
|
return true;
|
||||||
if (wtIt.isModified(dcIt.getDirCacheEntry(), true)) {
|
if (wtIt.isModified(dcIt.getDirCacheEntry(), true,
|
||||||
|
this.walk.getObjectReader())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,8 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize,
|
||||||
missing.add(treeWalk.getPathString());
|
missing.add(treeWalk.getPathString());
|
||||||
} else {
|
} else {
|
||||||
if (workingTreeIterator.isModified(
|
if (workingTreeIterator.isModified(
|
||||||
dirCacheIterator.getDirCacheEntry(), true)) {
|
dirCacheIterator.getDirCacheEntry(), true,
|
||||||
|
treeWalk.getObjectReader())) {
|
||||||
// in index, in workdir, content differs => modified
|
// in index, in workdir, content differs => modified
|
||||||
modified.add(treeWalk.getPathString());
|
modified.add(treeWalk.getPathString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,12 @@
|
||||||
import org.eclipse.jgit.internal.JGitText;
|
import org.eclipse.jgit.internal.JGitText;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.CoreConfig;
|
import org.eclipse.jgit.lib.CoreConfig;
|
||||||
|
import org.eclipse.jgit.lib.CoreConfig.CheckStat;
|
||||||
import org.eclipse.jgit.lib.FileMode;
|
import org.eclipse.jgit.lib.FileMode;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.eclipse.jgit.lib.ObjectLoader;
|
||||||
|
import org.eclipse.jgit.lib.ObjectReader;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.lib.CoreConfig.CheckStat;
|
|
||||||
import org.eclipse.jgit.submodule.SubmoduleWalk;
|
import org.eclipse.jgit.submodule.SubmoduleWalk;
|
||||||
import org.eclipse.jgit.util.FS;
|
import org.eclipse.jgit.util.FS;
|
||||||
import org.eclipse.jgit.util.IO;
|
import org.eclipse.jgit.util.IO;
|
||||||
|
@ -796,22 +798,46 @@ else if (!entry.isSmudged())
|
||||||
* True if the actual file content should be checked if
|
* True if the actual file content should be checked if
|
||||||
* modification time differs.
|
* modification time differs.
|
||||||
* @return true if content is most likely different.
|
* @return true if content is most likely different.
|
||||||
|
* @deprecated Use {@link #isModified(DirCacheEntry, boolean, ObjectReader)}
|
||||||
*/
|
*/
|
||||||
public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
|
public boolean isModified(DirCacheEntry entry, boolean forceContentCheck) {
|
||||||
|
return isModified(entry, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this entry differs from a given entry from the
|
||||||
|
* {@link DirCache}.
|
||||||
|
*
|
||||||
|
* File status information is used and if status is same we consider the
|
||||||
|
* file identical to the state in the working directory. Native git uses
|
||||||
|
* more stat fields than we have accessible in Java.
|
||||||
|
*
|
||||||
|
* @param entry
|
||||||
|
* the entry from the dircache we want to compare against
|
||||||
|
* @param forceContentCheck
|
||||||
|
* True if the actual file content should be checked if
|
||||||
|
* modification time differs.
|
||||||
|
* @param reader
|
||||||
|
* access to repository objects if necessary. Should not be null.
|
||||||
|
* @return true if content is most likely different.
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public boolean isModified(DirCacheEntry entry, boolean forceContentCheck,
|
||||||
|
ObjectReader reader) {
|
||||||
MetadataDiff diff = compareMetadata(entry);
|
MetadataDiff diff = compareMetadata(entry);
|
||||||
switch (diff) {
|
switch (diff) {
|
||||||
case DIFFER_BY_TIMESTAMP:
|
case DIFFER_BY_TIMESTAMP:
|
||||||
if (forceContentCheck)
|
if (forceContentCheck)
|
||||||
// But we are told to look at content even though timestamps
|
// But we are told to look at content even though timestamps
|
||||||
// tell us about modification
|
// tell us about modification
|
||||||
return contentCheck(entry);
|
return contentCheck(entry, reader);
|
||||||
else
|
else
|
||||||
// We are told to assume a modification if timestamps differs
|
// We are told to assume a modification if timestamps differs
|
||||||
return true;
|
return true;
|
||||||
case SMUDGED:
|
case SMUDGED:
|
||||||
// The file is clean by timestamps but the entry was smudged.
|
// The file is clean by timestamps but the entry was smudged.
|
||||||
// Lets do a content check
|
// Lets do a content check
|
||||||
return contentCheck(entry);
|
return contentCheck(entry, reader);
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
return false;
|
return false;
|
||||||
case DIFFER_BY_METADATA:
|
case DIFFER_BY_METADATA:
|
||||||
|
@ -854,10 +880,12 @@ public FileMode getIndexFileMode(final DirCacheIterator indexIter) {
|
||||||
*
|
*
|
||||||
* @param entry
|
* @param entry
|
||||||
* the entry to be checked
|
* the entry to be checked
|
||||||
* @return <code>true</code> if the content matches, <code>false</code>
|
* @param reader
|
||||||
* otherwise
|
* acccess to repository data if necessary
|
||||||
|
* @return <code>true</code> if the content doesn't match,
|
||||||
|
* <code>false</code> if it matches
|
||||||
*/
|
*/
|
||||||
private boolean contentCheck(DirCacheEntry entry) {
|
private boolean contentCheck(DirCacheEntry entry, ObjectReader reader) {
|
||||||
if (getEntryObjectId().equals(entry.getObjectId())) {
|
if (getEntryObjectId().equals(entry.getObjectId())) {
|
||||||
// Content has not changed
|
// Content has not changed
|
||||||
|
|
||||||
|
@ -873,7 +901,50 @@ private boolean contentCheck(DirCacheEntry entry) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Content differs: that's a real change!
|
// Content differs: that's a real change, perhaps
|
||||||
|
if (reader == null) // deprecated use, do no further checks
|
||||||
|
return true;
|
||||||
|
switch (getOptions().getAutoCRLF()) {
|
||||||
|
case INPUT:
|
||||||
|
case TRUE:
|
||||||
|
InputStream dcIn = null;
|
||||||
|
try {
|
||||||
|
ObjectLoader loader = reader.open(entry.getObjectId());
|
||||||
|
if (loader == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// We need to compute the length, but only if it is not
|
||||||
|
// a binary stream.
|
||||||
|
dcIn = new EolCanonicalizingInputStream(
|
||||||
|
loader.openStream(), true, true /* abort if binary */);
|
||||||
|
long dcInLen;
|
||||||
|
try {
|
||||||
|
dcInLen = computeLength(dcIn);
|
||||||
|
} catch (EolCanonicalizingInputStream.IsBinaryException e) {
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
dcIn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
dcIn = new EolCanonicalizingInputStream(
|
||||||
|
loader.openStream(), true);
|
||||||
|
byte[] autoCrLfHash = computeHash(dcIn, dcInLen);
|
||||||
|
boolean changed = getEntryObjectId().compareTo(
|
||||||
|
autoCrLfHash, 0) != 0;
|
||||||
|
return changed;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
if (dcIn != null)
|
||||||
|
try {
|
||||||
|
dcIn.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case FALSE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
import org.eclipse.jgit.errors.MissingObjectException;
|
import org.eclipse.jgit.errors.MissingObjectException;
|
||||||
import org.eclipse.jgit.lib.FileMode;
|
import org.eclipse.jgit.lib.FileMode;
|
||||||
|
import org.eclipse.jgit.lib.ObjectReader;
|
||||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||||
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
|
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
* <p>
|
* <p>
|
||||||
* If no difference is found then we have to compare index and working-tree as
|
* If no difference is found then we have to compare index and working-tree as
|
||||||
* the last step. By making use of
|
* the last step. By making use of
|
||||||
* {@link WorkingTreeIterator#isModified(org.eclipse.jgit.dircache.DirCacheEntry, boolean)}
|
* {@link WorkingTreeIterator#isModified(org.eclipse.jgit.dircache.DirCacheEntry, boolean, ObjectReader)}
|
||||||
* we can avoid the computation of the content id if the file is not dirty.
|
* we can avoid the computation of the content id if the file is not dirty.
|
||||||
* <p>
|
* <p>
|
||||||
* Instances of this filter should not be used for multiple {@link TreeWalk}s.
|
* Instances of this filter should not be used for multiple {@link TreeWalk}s.
|
||||||
|
@ -219,7 +220,7 @@ public boolean include(TreeWalk tw) throws MissingObjectException,
|
||||||
// Only one chance left to detect a diff: between index and working
|
// Only one chance left to detect a diff: between index and working
|
||||||
// tree. Make use of the WorkingTreeIterator#isModified() method to
|
// tree. Make use of the WorkingTreeIterator#isModified() method to
|
||||||
// avoid computing SHA1 on filesystem content if not really needed.
|
// avoid computing SHA1 on filesystem content if not really needed.
|
||||||
return wi.isModified(di.getDirCacheEntry(), true);
|
return wi.isModified(di.getDirCacheEntry(), true, tw.getObjectReader());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -70,6 +70,23 @@ public class EolCanonicalizingInputStream extends InputStream {
|
||||||
|
|
||||||
private boolean detectBinary;
|
private boolean detectBinary;
|
||||||
|
|
||||||
|
private boolean abortIfBinary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special exception thrown when {@link EolCanonicalizingInputStream} is
|
||||||
|
* told to throw an exception when attempting to read a binary file. The
|
||||||
|
* exception may be thrown at any stage during reading.
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public static class IsBinaryException extends IOException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
IsBinaryException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new InputStream, wrapping the specified stream
|
* Creates a new InputStream, wrapping the specified stream
|
||||||
*
|
*
|
||||||
|
@ -80,8 +97,25 @@ public class EolCanonicalizingInputStream extends InputStream {
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public EolCanonicalizingInputStream(InputStream in, boolean detectBinary) {
|
public EolCanonicalizingInputStream(InputStream in, boolean detectBinary) {
|
||||||
|
this(in, detectBinary, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new InputStream, wrapping the specified stream
|
||||||
|
*
|
||||||
|
* @param in
|
||||||
|
* raw input stream
|
||||||
|
* @param detectBinary
|
||||||
|
* whether binaries should be detected
|
||||||
|
* @param abortIfBinary
|
||||||
|
* throw an IOException if the file is binary
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public EolCanonicalizingInputStream(InputStream in, boolean detectBinary,
|
||||||
|
boolean abortIfBinary) {
|
||||||
this.in = in;
|
this.in = in;
|
||||||
this.detectBinary = detectBinary;
|
this.detectBinary = detectBinary;
|
||||||
|
this.abortIfBinary = abortIfBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -128,6 +162,14 @@ public int read(byte[] bs, final int off, final int len) throws IOException {
|
||||||
return i == off ? -1 : i - off;
|
return i == off ? -1 : i - off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the stream has detected as a binary so far
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public boolean isBinary() {
|
||||||
|
return isBinary;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
in.close();
|
in.close();
|
||||||
|
@ -140,6 +182,8 @@ private boolean fillBuffer() throws IOException {
|
||||||
if (detectBinary) {
|
if (detectBinary) {
|
||||||
isBinary = RawText.isBinary(buf, cnt);
|
isBinary = RawText.isBinary(buf, cnt);
|
||||||
detectBinary = false;
|
detectBinary = false;
|
||||||
|
if (isBinary && abortIfBinary)
|
||||||
|
throw new IsBinaryException();
|
||||||
}
|
}
|
||||||
ptr = 0;
|
ptr = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue