mirror of https://github.com/apache/poi.git
should have been submitted with c682225 - Extensive fixes for data validation (bug 44953)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@682227 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9b67bb83a4
commit
5025e4909a
|
@ -0,0 +1,131 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to help test code verify that generated files do not differ from proof copies in
|
||||||
|
* any significant detail. Normally this task would be simple except for the presence of artifacts
|
||||||
|
* in the file that change every time it is generated. Usually these volatile artifacts are
|
||||||
|
* time-stamps, user names, or other machine dependent parameters.
|
||||||
|
*
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
|
public final class StreamUtility {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two streams with expected differences in specified regions. The streams are
|
||||||
|
* expected to be of equal length and comparison is always byte for byte. That is -
|
||||||
|
* differences can only involve exchanging each individual byte for another single byte.<br>
|
||||||
|
* Both input streams are closed.
|
||||||
|
*
|
||||||
|
* @param allowableDifferenceRegions array of integer pairs: (offset, length).
|
||||||
|
* Any differences encountered in these regions of the streams will be ignored
|
||||||
|
* @return <code>null</code> if streams are identical, else the
|
||||||
|
* byte indexes of differing data. If streams were different lengths,
|
||||||
|
* the returned indexes will be -1 and the length of the shorter stream
|
||||||
|
*/
|
||||||
|
public static int[] diffStreams(InputStream isA, InputStream isB, int[] allowableDifferenceRegions) {
|
||||||
|
|
||||||
|
if((allowableDifferenceRegions.length % 2) != 0) {
|
||||||
|
throw new RuntimeException("allowableDifferenceRegions length is odd");
|
||||||
|
}
|
||||||
|
boolean success = false;
|
||||||
|
int[] result;
|
||||||
|
try {
|
||||||
|
result = diffInternal(isA, isB, allowableDifferenceRegions);
|
||||||
|
success = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
close(isA, success);
|
||||||
|
close(isB, success);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param success <code>false</code> if the outer method is throwing an exception.
|
||||||
|
*/
|
||||||
|
private static void close(InputStream is, boolean success) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
if(success) {
|
||||||
|
// this is a new error. ok to throw
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// else don't subvert original exception. just print stack trace for this one
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] diffInternal(InputStream isA, InputStream isB, int[] allowableDifferenceRegions)
|
||||||
|
throws IOException {
|
||||||
|
int offset = 0;
|
||||||
|
List temp = new ArrayList();
|
||||||
|
while (true) {
|
||||||
|
int b = isA.read();
|
||||||
|
int b2 = isB.read();
|
||||||
|
if (b == -1) {
|
||||||
|
// EOF
|
||||||
|
if (b2 == -1) {
|
||||||
|
return toPrimitiveIntArray(temp);
|
||||||
|
}
|
||||||
|
return new int[] { -1, offset, };
|
||||||
|
}
|
||||||
|
if (b2 == -1) {
|
||||||
|
return new int[] { -1, offset, };
|
||||||
|
}
|
||||||
|
if (b != b2 && !isIgnoredRegion(allowableDifferenceRegions, offset)) {
|
||||||
|
temp.add(new Integer(offset));
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIgnoredRegion(int[] allowableDifferenceRegions, int offset) {
|
||||||
|
for (int i = 0; i < allowableDifferenceRegions.length; i+=2) {
|
||||||
|
int start = allowableDifferenceRegions[i];
|
||||||
|
int end = start + allowableDifferenceRegions[i+1];
|
||||||
|
if(start <= offset && offset < end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] toPrimitiveIntArray(List temp) {
|
||||||
|
int nItems = temp.size();
|
||||||
|
if(nItems < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Integer[] boxInts = new Integer[nItems];
|
||||||
|
temp.toArray(boxInts);
|
||||||
|
|
||||||
|
int[] result = new int[nItems];
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
result[i] = boxInts[i].intValue();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue