From 33ffe01bffad5a556f5a4f40d63456e3ddc4b715 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sat, 29 Aug 2015 14:41:12 +0000 Subject: [PATCH] - reworked HexDump class - unified array dumps and usage of standard java calls for hex format - fixed a few findbugs DM_DEFAULT_ENCODING issues - removed a few System.out/.err calls - instead the poilogger is used - closed a few left open resource instances git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1700040 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/ddf/EscherBitmapBlip.java | 27 +- .../poi/ddf/EscherClientAnchorRecord.java | 30 +- .../poi/ddf/EscherClientDataRecord.java | 30 +- src/java/org/apache/poi/ddf/EscherDump.java | 6 +- .../org/apache/poi/hssf/dev/BiffViewer.java | 181 ++++++++-- .../org/apache/poi/hssf/dev/EFBiffViewer.java | 6 +- .../apache/poi/hssf/dev/FormulaViewer.java | 14 +- .../org/apache/poi/hssf/dev/RecordLister.java | 7 +- .../poi/hssf/record/HyperlinkRecord.java | 28 +- .../poi/poifs/filesystem/NPOIFSDocument.java | 36 +- .../poi/poifs/filesystem/OPOIFSDocument.java | 27 +- .../apache/poi/poifs/storage/HeaderBlock.java | 13 +- src/java/org/apache/poi/util/HexDump.java | 264 +++++--------- .../org/apache/poi/ddf/TestEscherDump.java | 44 ++- .../apache/poi/hssf/dev/TestBiffViewer.java | 17 +- .../poi/hssf/record/TestHyperlinkRecord.java | 43 ++- .../crypto/TestBiff8DecryptingStream.java | 22 +- .../apache/poi/poifs/storage/RawDataUtil.java | 4 +- .../ss/formula/eval/TestMinusZeroResult.java | 2 +- .../NumberComparingSpreadsheetGenerator.java | 4 +- .../poi/ss/util/TestExpandedDouble.java | 19 +- .../poi/ss/util/TestNumberComparer.java | 27 +- .../org/apache/poi/util/TestHexDump.java | 337 ++++++------------ 23 files changed, 511 insertions(+), 677 deletions(-) diff --git a/src/java/org/apache/poi/ddf/EscherBitmapBlip.java b/src/java/org/apache/poi/ddf/EscherBitmapBlip.java index d81eebdcc..096e0c4a8 100644 --- a/src/java/org/apache/poi/ddf/EscherBitmapBlip.java +++ b/src/java/org/apache/poi/ddf/EscherBitmapBlip.java @@ -20,8 +20,6 @@ package org.apache.poi.ddf; import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; -import java.io.ByteArrayOutputStream; - /** * @author Glen Stampoultzis */ @@ -95,17 +93,8 @@ public class EscherBitmapBlip extends EscherBlipRecord { { String nl = System.getProperty( "line.separator" ); - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump( this.field_pictureData, 0, b, 0 ); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = e.toString(); - } + String extraData = HexDump.dump(this.field_pictureData, 0, 0); + return getClass().getName() + ":" + nl + " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl + " Version: 0x" + HexDump.toHex( getVersion() ) + nl + @@ -117,17 +106,7 @@ public class EscherBitmapBlip extends EscherBlipRecord { @Override public String toXml(String tab) { - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump( this.field_pictureData, 0, b, 0 ); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = e.toString(); - } + String extraData = HexDump.dump(this.field_pictureData, 0, 0); StringBuilder builder = new StringBuilder(); builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) .append(tab).append("\t").append("0x").append(HexDump.toHex(field_1_UID)).append("\n") diff --git a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java index ffc9170c4..665a091d7 100644 --- a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java +++ b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java @@ -20,8 +20,6 @@ package org.apache.poi.ddf; import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; -import java.io.ByteArrayOutputStream; - /** * The escher client anchor specifies which rows and cells the shape is bound to as well as * the offsets within those cells. Each cell is 1024 units wide by 256 units long regardless @@ -138,18 +136,7 @@ public class EscherClientAnchorRecord public String toString() { String nl = System.getProperty("line.separator"); - - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump(this.remainingData, 0, b, 0); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = "error\n"; - } + String extraData = HexDump.dump(this.remainingData, 0, 0); return getClass().getName() + ":" + nl + " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + " Version: 0x" + HexDump.toHex(getVersion()) + nl + @@ -169,20 +156,7 @@ public class EscherClientAnchorRecord @Override public String toXml(String tab) { - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump(this.remainingData, 0, b, 0); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = "error\n"; - } - if (extraData.contains("No Data")){ - extraData = "No Data"; - } + String extraData = HexDump.dump(this.remainingData, 0, 0).trim(); StringBuilder builder = new StringBuilder(); builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) .append(tab).append("\t").append("").append(field_1_flag).append("\n") diff --git a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java index 4c78e6760..8e519c555 100644 --- a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java +++ b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java @@ -21,8 +21,6 @@ package org.apache.poi.ddf; import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; -import java.io.ByteArrayOutputStream; - /** * The EscherClientDataRecord is used to store client specific data about the position of a * shape within a container. @@ -78,18 +76,7 @@ public class EscherClientDataRecord public String toString() { String nl = System.getProperty("line.separator"); - - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump(this.remainingData, 0, b, 0); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = "error\n"; - } + String extraData = HexDump.dump(this.remainingData, 0, 0); return getClass().getName() + ":" + nl + " RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl + " Version: 0x" + HexDump.toHex(getVersion()) + nl + @@ -101,20 +88,7 @@ public class EscherClientDataRecord @Override public String toXml(String tab) { - String extraData; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try - { - HexDump.dump(this.remainingData, 0, b, 0); - extraData = b.toString(); - } - catch ( Exception e ) - { - extraData = "error"; - } - if (extraData.contains("No Data")){ - extraData = "No Data"; - } + String extraData = HexDump.dump(this.remainingData, 0, 0).trim(); StringBuilder builder = new StringBuilder(); builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), HexDump.toHex(getInstance()))) diff --git a/src/java/org/apache/poi/ddf/EscherDump.java b/src/java/org/apache/poi/ddf/EscherDump.java index 5621806e6..4ed9519c9 100644 --- a/src/java/org/apache/poi/ddf/EscherDump.java +++ b/src/java/org/apache/poi/ddf/EscherDump.java @@ -777,6 +777,10 @@ public final class EscherDump { * A simple test stub. */ public static void main( String[] args ) { + main(args, System.out); + } + + public static void main( String[] args, PrintStream out ) { String dump = "0F 00 00 F0 89 07 00 00 00 00 06 F0 18 00 00 00 " + "05 04 00 00 02 00 00 00 05 00 00 00 01 00 00 00 " + @@ -907,7 +911,7 @@ public final class EscherDump { EscherDump dumper = new EscherDump(); // Dump the contents of scher to screen. // dumper.dumpOld( bytes.length, new ByteArrayInputStream( bytes ), System.out ); - dumper.dump(bytes, 0, bytes.length, System.out); + dumper.dump(bytes, 0, bytes.length, out); } diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index 3afd25a4a..33fb1912b 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -19,7 +19,6 @@ package org.apache.poi.hssf.dev; import java.io.DataInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -31,8 +30,119 @@ import java.io.Writer; import java.util.ArrayList; import java.util.List; -import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.record.ArrayRecord; +import org.apache.poi.hssf.record.AutoFilterInfoRecord; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.BackupRecord; +import org.apache.poi.hssf.record.BlankRecord; +import org.apache.poi.hssf.record.BookBoolRecord; +import org.apache.poi.hssf.record.BoolErrRecord; +import org.apache.poi.hssf.record.BottomMarginRecord; +import org.apache.poi.hssf.record.BoundSheetRecord; +import org.apache.poi.hssf.record.CFHeader12Record; +import org.apache.poi.hssf.record.CFHeaderRecord; +import org.apache.poi.hssf.record.CFRule12Record; +import org.apache.poi.hssf.record.CFRuleRecord; +import org.apache.poi.hssf.record.CalcCountRecord; +import org.apache.poi.hssf.record.CalcModeRecord; +import org.apache.poi.hssf.record.CodepageRecord; +import org.apache.poi.hssf.record.ColumnInfoRecord; +import org.apache.poi.hssf.record.ContinueRecord; +import org.apache.poi.hssf.record.CountryRecord; +import org.apache.poi.hssf.record.DBCellRecord; +import org.apache.poi.hssf.record.DConRefRecord; +import org.apache.poi.hssf.record.DSFRecord; +import org.apache.poi.hssf.record.DVALRecord; +import org.apache.poi.hssf.record.DVRecord; +import org.apache.poi.hssf.record.DateWindow1904Record; +import org.apache.poi.hssf.record.DefaultColWidthRecord; +import org.apache.poi.hssf.record.DefaultRowHeightRecord; +import org.apache.poi.hssf.record.DeltaRecord; +import org.apache.poi.hssf.record.DimensionsRecord; +import org.apache.poi.hssf.record.DrawingGroupRecord; +import org.apache.poi.hssf.record.DrawingRecordForBiffViewer; +import org.apache.poi.hssf.record.DrawingSelectionRecord; +import org.apache.poi.hssf.record.EOFRecord; +import org.apache.poi.hssf.record.ExtSSTRecord; +import org.apache.poi.hssf.record.ExtendedFormatRecord; +import org.apache.poi.hssf.record.ExternSheetRecord; +import org.apache.poi.hssf.record.ExternalNameRecord; +import org.apache.poi.hssf.record.FeatHdrRecord; +import org.apache.poi.hssf.record.FeatRecord; +import org.apache.poi.hssf.record.FilePassRecord; +import org.apache.poi.hssf.record.FileSharingRecord; +import org.apache.poi.hssf.record.FnGroupCountRecord; +import org.apache.poi.hssf.record.FontRecord; +import org.apache.poi.hssf.record.FooterRecord; +import org.apache.poi.hssf.record.FormatRecord; +import org.apache.poi.hssf.record.FormulaRecord; +import org.apache.poi.hssf.record.GridsetRecord; +import org.apache.poi.hssf.record.GutsRecord; +import org.apache.poi.hssf.record.HCenterRecord; +import org.apache.poi.hssf.record.HeaderRecord; +import org.apache.poi.hssf.record.HideObjRecord; +import org.apache.poi.hssf.record.HorizontalPageBreakRecord; +import org.apache.poi.hssf.record.HyperlinkRecord; +import org.apache.poi.hssf.record.IndexRecord; +import org.apache.poi.hssf.record.InterfaceEndRecord; +import org.apache.poi.hssf.record.InterfaceHdrRecord; +import org.apache.poi.hssf.record.IterationRecord; +import org.apache.poi.hssf.record.LabelRecord; +import org.apache.poi.hssf.record.LabelSSTRecord; +import org.apache.poi.hssf.record.LeftMarginRecord; +import org.apache.poi.hssf.record.MMSRecord; +import org.apache.poi.hssf.record.MergeCellsRecord; +import org.apache.poi.hssf.record.MulBlankRecord; +import org.apache.poi.hssf.record.MulRKRecord; +import org.apache.poi.hssf.record.NameCommentRecord; +import org.apache.poi.hssf.record.NameRecord; +import org.apache.poi.hssf.record.NoteRecord; +import org.apache.poi.hssf.record.NumberRecord; +import org.apache.poi.hssf.record.ObjRecord; +import org.apache.poi.hssf.record.PaletteRecord; +import org.apache.poi.hssf.record.PaneRecord; +import org.apache.poi.hssf.record.PasswordRecord; +import org.apache.poi.hssf.record.PasswordRev4Record; +import org.apache.poi.hssf.record.PrecisionRecord; +import org.apache.poi.hssf.record.PrintGridlinesRecord; +import org.apache.poi.hssf.record.PrintHeadersRecord; +import org.apache.poi.hssf.record.PrintSetupRecord; +import org.apache.poi.hssf.record.ProtectRecord; +import org.apache.poi.hssf.record.ProtectionRev4Record; +import org.apache.poi.hssf.record.RKRecord; +import org.apache.poi.hssf.record.RecalcIdRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RecordFormatException; +import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.RecordInputStream.LeftoverDataException; +import org.apache.poi.hssf.record.RefModeRecord; +import org.apache.poi.hssf.record.RefreshAllRecord; +import org.apache.poi.hssf.record.RightMarginRecord; +import org.apache.poi.hssf.record.RowRecord; +import org.apache.poi.hssf.record.SCLRecord; +import org.apache.poi.hssf.record.SSTRecord; +import org.apache.poi.hssf.record.SaveRecalcRecord; +import org.apache.poi.hssf.record.SelectionRecord; +import org.apache.poi.hssf.record.SharedFormulaRecord; +import org.apache.poi.hssf.record.StringRecord; +import org.apache.poi.hssf.record.StyleRecord; +import org.apache.poi.hssf.record.SupBookRecord; +import org.apache.poi.hssf.record.TabIdRecord; +import org.apache.poi.hssf.record.TableRecord; +import org.apache.poi.hssf.record.TableStylesRecord; +import org.apache.poi.hssf.record.TextObjectRecord; +import org.apache.poi.hssf.record.TopMarginRecord; +import org.apache.poi.hssf.record.UncalcedRecord; +import org.apache.poi.hssf.record.UnknownRecord; +import org.apache.poi.hssf.record.UseSelFSRecord; +import org.apache.poi.hssf.record.VCenterRecord; +import org.apache.poi.hssf.record.VerticalPageBreakRecord; +import org.apache.poi.hssf.record.WSBoolRecord; +import org.apache.poi.hssf.record.WindowOneRecord; +import org.apache.poi.hssf.record.WindowProtectRecord; +import org.apache.poi.hssf.record.WindowTwoRecord; +import org.apache.poi.hssf.record.WriteAccessRecord; +import org.apache.poi.hssf.record.WriteProtectRecord; import org.apache.poi.hssf.record.chart.AreaFormatRecord; import org.apache.poi.hssf.record.chart.AreaRecord; import org.apache.poi.hssf.record.chart.AxisLineFormatRecord; @@ -85,13 +195,16 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.util.HexDump; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; /** * Utillity for reading in BIFF8 records and displaying data from them. * @see #main */ public final class BiffViewer { - static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray(); + static final String NEW_LINE_CHARS = System.getProperty("line.separator"); + private static POILogger logger = POILogFactory.getLogger(BiffViewer.class); private BiffViewer() { // no instances of this class @@ -114,8 +227,7 @@ public final class BiffViewer { try { hasNext = recStream.hasNextRecord(); } catch (LeftoverDataException e) { - e.printStackTrace(); - System.err.println("Discarding " + recStream.remaining() + " bytes and continuing"); + logger.log(POILogger.ERROR, "Discarding " + recStream.remaining() + " bytes and continuing", e); recStream.readRemainder(); hasNext = recStream.hasNextRecord(); } @@ -427,7 +539,7 @@ public final class BiffViewer { * * */ - public static void main(String[] args) { + public static void main(String[] args) throws IOException { // args = new String[] { "--out", "", }; CommandArgs cmdArgs; try { @@ -437,40 +549,37 @@ public final class BiffViewer { return; } - try { - - PrintStream ps; - if (cmdArgs.shouldOutputToFile()) { - OutputStream os = new FileOutputStream(cmdArgs.getFile().getAbsolutePath() + ".out"); - ps = new PrintStream(os); - } else { - ps = System.out; - } - - InputStream is = getPOIFSInputStream(cmdArgs.getFile()); - - if (cmdArgs.shouldOutputRawHexOnly()) { - int size = is.available(); - byte[] data = new byte[size]; - - is.read(data); - HexDump.dump(data, 0, System.out, 0); - } else { - boolean dumpInterpretedRecords = cmdArgs.shouldDumpRecordInterpretations(); - boolean dumpHex = cmdArgs.shouldDumpBiffHex(); - boolean zeroAlignHexDump = dumpInterpretedRecords; // TODO - fix non-zeroAlign - runBiffViewer(ps, is, dumpInterpretedRecords, dumpHex, zeroAlignHexDump, - cmdArgs.suppressHeader()); - } - ps.close(); - } catch (Exception e) { - e.printStackTrace(); + PrintStream ps; + if (cmdArgs.shouldOutputToFile()) { + OutputStream os = new FileOutputStream(cmdArgs.getFile().getAbsolutePath() + ".out"); + ps = new PrintStream(os); + } else { + ps = System.out; } + + NPOIFSFileSystem fs = new NPOIFSFileSystem(cmdArgs.getFile(), true); + InputStream is = getPOIFSInputStream(fs); + + if (cmdArgs.shouldOutputRawHexOnly()) { + int size = is.available(); + byte[] data = new byte[size]; + + is.read(data); + HexDump.dump(data, 0, System.out, 0); + } else { + boolean dumpInterpretedRecords = cmdArgs.shouldDumpRecordInterpretations(); + boolean dumpHex = cmdArgs.shouldDumpBiffHex(); + boolean zeroAlignHexDump = dumpInterpretedRecords; // TODO - fix non-zeroAlign + runBiffViewer(ps, is, dumpInterpretedRecords, dumpHex, zeroAlignHexDump, + cmdArgs.suppressHeader()); + } + is.close(); + fs.close(); + ps.close(); } - protected static InputStream getPOIFSInputStream(File file) + protected static InputStream getPOIFSInputStream(NPOIFSFileSystem fs) throws IOException, FileNotFoundException { - NPOIFSFileSystem fs = new NPOIFSFileSystem(new FileInputStream(file)); String workbookName = HSSFWorkbook.getWorkbookDirEntryName(fs.getRoot()); return fs.createDocumentInputStream(workbookName); } diff --git a/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java b/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java index 2893f31ed..c87f5f73b 100644 --- a/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/EFBiffViewer.java @@ -25,6 +25,7 @@ import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; import org.apache.poi.hssf.eventusermodel.HSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFRequest; import org.apache.poi.hssf.record.Record; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; /** * @@ -42,7 +43,8 @@ public class EFBiffViewer } public void run() throws IOException { - InputStream din = BiffViewer.getPOIFSInputStream(new File(file)); + NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); + InputStream din = BiffViewer.getPOIFSInputStream(fs); HSSFRequest req = new HSSFRequest(); req.addListenerForAllRecords(new HSSFListener() @@ -55,6 +57,8 @@ public class EFBiffViewer HSSFEventFactory factory = new HSSFEventFactory(); factory.processEvents(req, din); + din.close(); + fs.close(); } public void setFile(String file) diff --git a/src/java/org/apache/poi/hssf/dev/FormulaViewer.java b/src/java/org/apache/poi/hssf/dev/FormulaViewer.java index 69e0c3005..eaa3fff0b 100644 --- a/src/java/org/apache/poi/hssf/dev/FormulaViewer.java +++ b/src/java/org/apache/poi/hssf/dev/FormulaViewer.java @@ -18,6 +18,7 @@ package org.apache.poi.hssf.dev; import java.io.File; +import java.io.InputStream; import java.util.List; import org.apache.poi.hssf.model.HSSFFormulaParser; @@ -25,6 +26,7 @@ import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.RecordFactory; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.ss.formula.ptg.ExpPtg; import org.apache.poi.ss.formula.ptg.FuncPtg; import org.apache.poi.ss.formula.ptg.OperationPtg; @@ -56,12 +58,10 @@ public class FormulaViewer * */ - public void run() - throws Exception - { - List records = - RecordFactory - .createRecords(BiffViewer.getPOIFSInputStream(new File(file))); + public void run() throws Exception { + NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); + InputStream is = BiffViewer.getPOIFSInputStream(fs); + List records = RecordFactory.createRecords(is); for (int k = 0; k < records.size(); k++) { @@ -76,6 +76,8 @@ public class FormulaViewer } } } + is.close(); + fs.close(); } private void listFormula(FormulaRecord record) { diff --git a/src/java/org/apache/poi/hssf/dev/RecordLister.java b/src/java/org/apache/poi/hssf/dev/RecordLister.java index 28896f2a1..7c626b8a1 100644 --- a/src/java/org/apache/poi/hssf/dev/RecordLister.java +++ b/src/java/org/apache/poi/hssf/dev/RecordLister.java @@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.ContinueRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.RecordFactory; import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; /** * This is a low-level debugging class, which simply prints @@ -49,7 +50,8 @@ public class RecordLister public void run() throws IOException { - InputStream din = BiffViewer.getPOIFSInputStream(new File(file)); + NPOIFSFileSystem fs = new NPOIFSFileSystem(new File(file), true); + InputStream din = BiffViewer.getPOIFSInputStream(fs); RecordInputStream rinp = new RecordInputStream(din); while(rinp.hasNextRecord()) { @@ -77,6 +79,9 @@ public class RecordLister System.out.println( formatData(data) ); } } + + din.close(); + fs.close(); } private static String formatSID(int sid) { diff --git a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java index 618a86b06..07466f06e 100644 --- a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java +++ b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java @@ -124,16 +124,16 @@ public final class HyperlinkRecord extends StandardRecord { StringBuilder sb = new StringBuilder(36); int PREFIX_LEN = "0x".length(); - sb.append(HexDump.intToHex(_d1), PREFIX_LEN, 8); + sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN)); sb.append("-"); - sb.append(HexDump.shortToHex(_d2), PREFIX_LEN, 4); + sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN)); sb.append("-"); - sb.append(HexDump.shortToHex(_d3), PREFIX_LEN, 4); + sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN)); sb.append("-"); - char[] d4Chars = HexDump.longToHex(getD4()); - sb.append(d4Chars, PREFIX_LEN, 4); + String d4Chars = HexDump.longToHex(getD4()); + sb.append(d4Chars.substring(PREFIX_LEN, PREFIX_LEN+4)); sb.append("-"); - sb.append(d4Chars, PREFIX_LEN + 4, 12); + sb.append(d4Chars.substring(PREFIX_LEN+4)); return sb.toString(); } @@ -643,14 +643,14 @@ public final class HyperlinkRecord extends StandardRecord { private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) { byte[] result = new byte[TAIL_SIZE]; in.readFully(result); - if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail - for (int i = 0; i < expectedTail.length; i++) { - if (expectedTail[i] != result[i]) { - logger.log( POILogger.ERROR, "Mismatch in tail byte [" + i + "]" - + "expected " + (expectedTail[i] & 0xFF) + " but got " + (result[i] & 0xFF)); - } - } - } +// if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail +// for (int i = 0; i < expectedTail.length; i++) { +// if (expectedTail[i] != result[i]) { +// logger.log( POILogger.ERROR, "Mismatch in tail byte [" + i + "]" +// + "expected " + (expectedTail[i] & 0xFF) + " but got " + (result[i] & 0xFF)); +// } +// } +// } return result; } private static void writeTail(byte[] tail, LittleEndianOutput out) { diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java index c94e427b9..7e7ca0780 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java @@ -18,7 +18,6 @@ package org.apache.poi.poifs.filesystem; import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -211,31 +210,22 @@ public final class NPOIFSDocument implements POIFSViewable { * @return an array of Object; may not be null, but may be empty */ public Object[] getViewableArray() { - Object[] results = new Object[1]; - String result; + String result = ""; - try { - if(getSize() > 0) { - // Get all the data into a single array - byte[] data = new byte[getSize()]; - int offset = 0; - for(ByteBuffer buffer : _stream) { - int length = Math.min(_block_size, data.length-offset); - buffer.get(data, offset, length); - offset += length; - } - - ByteArrayOutputStream output = new ByteArrayOutputStream(); - HexDump.dump(data, 0, output, 0); - result = output.toString(); - } else { - result = ""; + if(getSize() > 0) { + // Get all the data into a single array + byte[] data = new byte[getSize()]; + int offset = 0; + for(ByteBuffer buffer : _stream) { + int length = Math.min(_block_size, data.length-offset); + buffer.get(data, offset, length); + offset += length; } - } catch (IOException e) { - result = e.getMessage(); + + result = HexDump.dump(data, 0, 0); } - results[0] = result; - return results; + + return new String[]{ result }; } /** diff --git a/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java index 05b21baea..a7479f319 100644 --- a/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java +++ b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java @@ -332,11 +332,9 @@ public final class OPOIFSDocument implements BATManaged, BlockWritable, POIFSVie * @return an array of Object; may not be null, but may be empty */ public Object[] getViewableArray() { - Object[] results = new Object[1]; - String result; + String result = ""; try { - ByteArrayOutputStream output = new ByteArrayOutputStream(); BlockWritable[] blocks = null; if (_big_store.isValid()) { @@ -345,28 +343,17 @@ public final class OPOIFSDocument implements BATManaged, BlockWritable, POIFSVie blocks = _small_store.getBlocks(); } if (blocks != null) { - for (int k = 0; k < blocks.length; k++) { - blocks[k].writeBlocks(output); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + for (BlockWritable bw : blocks) { + bw.writeBlocks(output); } - byte[] data = output.toByteArray(); - - if (data.length > _property.getSize()) { - byte[] tmp = new byte[_property.getSize()]; - - System.arraycopy(data, 0, tmp, 0, tmp.length); - data = tmp; - } - output = new ByteArrayOutputStream(); - HexDump.dump(data, 0, output, 0); - result = output.toString(); - } else { - result = ""; + int length = Math.min(output.size(), _property.getSize()); + result = HexDump.dump(output.toByteArray(), 0, 0, length); } } catch (IOException e) { result = e.getMessage(); } - results[0] = result; - return results; + return new String[]{ result }; } /** diff --git a/src/java/org/apache/poi/poifs/storage/HeaderBlock.java b/src/java/org/apache/poi/poifs/storage/HeaderBlock.java index 06e9c4a1b..49e491c5a 100644 --- a/src/java/org/apache/poi/poifs/storage/HeaderBlock.java +++ b/src/java/org/apache/poi/poifs/storage/HeaderBlock.java @@ -34,17 +34,12 @@ import org.apache.poi.util.IntegerField; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; import org.apache.poi.util.LongField; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; import org.apache.poi.util.ShortField; /** * The block containing the archive header */ public final class HeaderBlock implements HeaderBlockConstants { - private static final POILogger _logger = - POILogFactory.getLogger(HeaderBlock.class); - /** * What big block size the file uses. Most files * use 512 bytes, but a few use 4096 @@ -165,8 +160,8 @@ public final class HeaderBlock implements HeaderBlockConstants { // Give a generic error if the OLE2 signature isn't found throw new NotOLE2FileException("Invalid header signature; read " - + longToHex(signature) + ", expected " - + longToHex(_signature) + " - Your file appears " + + HexDump.longToHex(signature) + ", expected " + + HexDump.longToHex(_signature) + " - Your file appears " + "not to be a valid OLE2 document"); } @@ -237,10 +232,6 @@ public final class HeaderBlock implements HeaderBlockConstants { return data; } - private static String longToHex(long value) { - return new String(HexDump.longToHex(value)); - } - private static IOException alertShortRead(int pRead, int expectedReadSize) { int read; if (pRead < 0) { diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java index b874e6c42..7fd9d11e1 100644 --- a/src/java/org/apache/poi/util/HexDump.java +++ b/src/java/org/apache/poi/util/HexDump.java @@ -24,6 +24,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PrintStream; import java.nio.charset.Charset; import java.text.DecimalFormat; @@ -31,20 +32,12 @@ import java.text.DecimalFormat; import org.apache.commons.codec.CharEncoding; /** - * dump data in hexadecimal format; derived from a HexDump utility I - * wrote in June 2001. - * - * @author Marc Johnson - * @author Glen Stampoultzis (glens at apache.org) + * dump data in hexadecimal format */ +@Internal public class HexDump { public static final String EOL = System.getProperty("line.separator"); - private static final Charset UTF8 = Charset.forName(CharEncoding.UTF_8); - private static final char _hexcodes[] = "0123456789ABCDEF".toCharArray(); - private static final int _shifts[] = - { - 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0 - }; + public static final Charset UTF8 = Charset.forName(CharEncoding.UTF_8); private HexDump() { // all static methods, so no need for a public constructor @@ -68,73 +61,15 @@ public class HexDump { * null */ public static void dump(final byte [] data, final long offset, - final OutputStream stream, final int index, final int length) - throws IOException, ArrayIndexOutOfBoundsException, - IllegalArgumentException - { - if (data.length == 0) - { - stream.write( ("No Data" + EOL).getBytes(UTF8) ); - stream.flush(); - return; - } - if ((index < 0) || (index >= data.length)) - { - throw new ArrayIndexOutOfBoundsException( - "illegal index: " + index + " into array of length " - + data.length); - } - if (stream == null) - { + final OutputStream stream, final int index, final int length) + throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { + if (stream == null) { throw new IllegalArgumentException("cannot write to nullstream"); } - long display_offset = offset + index; - StringBuffer buffer = new StringBuffer(74); - - - int data_length = Math.min(data.length,index+length); - for (int j = index; j < data_length; j += 16) - { - int chars_read = data_length - j; - - if (chars_read > 16) - { - chars_read = 16; - } - buffer.append( - dump(display_offset) - ).append(' '); - for (int k = 0; k < 16; k++) - { - if (k < chars_read) - { - buffer.append(dump(data[ k + j ])); - } - else - { - buffer.append(" "); - } - buffer.append(' '); - } - for (int k = 0; k < chars_read; k++) - { - if ((data[ k + j ] >= ' ') && (data[ k + j ] < 127)) - { - buffer.append(( char ) data[ k + j ]); - } - else - { - buffer.append('.'); - } - } - buffer.append(EOL); - stream.write(buffer.toString().getBytes(UTF8)); - stream.flush(); - buffer.setLength(0); - display_offset += chars_read; - } - + OutputStreamWriter osw = new OutputStreamWriter(stream, UTF8); + osw.write(dump(data, offset, index, length)); + osw.flush(); } /** @@ -155,11 +90,9 @@ public class HexDump { */ public synchronized static void dump(final byte [] data, final long offset, - final OutputStream stream, final int index) - throws IOException, ArrayIndexOutOfBoundsException, - IllegalArgumentException - { - dump(data, offset, stream, index, data.length-index); + final OutputStream stream, final int index) + throws IOException, ArrayIndexOutOfBoundsException, IllegalArgumentException { + dump(data, offset, stream, index, Integer.MAX_VALUE); } /** @@ -175,40 +108,57 @@ public class HexDump { */ public static String dump(final byte [] data, final long offset, final int index) { - if ((index < 0) || (index > data.length)) - { - throw new ArrayIndexOutOfBoundsException( - "illegal index: " + index + " into array of length " - + data.length); + return dump(data, offset, index, Integer.MAX_VALUE); + } + + /** + * dump an array of bytes to a String + * + * @param data the byte array to be dumped + * @param offset its offset, whatever that might mean + * @param index initial index into the byte array + * @param length number of characters to output + * + * @exception ArrayIndexOutOfBoundsException if the index is + * outside the data array's bounds + * @return output string + */ + + public static String dump(final byte [] data, final long offset, final int index, final int length) { + if (data == null || data.length == 0) { + return "No Data"+EOL; } + + int data_length = (length == Integer.MAX_VALUE || length < 0 || index+length < 0) + ? data.length + : Math.min(data.length,index+length); + + + if ((index < 0) || (index >= data.length)) { + String err = "illegal index: "+index+" into array of length "+data.length; + throw new ArrayIndexOutOfBoundsException(err); + } + long display_offset = offset + index; StringBuilder buffer = new StringBuilder(74); - - for (int j = index; j <= data.length; j += 16) { - int chars_read = data.length - j; + + for (int j = index; j < data_length; j += 16) { + int chars_read = data_length - j; if (chars_read > 16) { chars_read = 16; } - buffer.append(dump(display_offset)).append(' '); + buffer.append(String.format("%08X ", display_offset)); for (int k = 0; k < 16; k++) { - String hexDmp = (k < chars_read) ? dump(data[ k + j ]) : " "; - buffer.append(hexDmp); - buffer.append(' '); + if (k < chars_read) { + buffer.append(String.format("%02X ", data[ k + j ])); + } else { + buffer.append(" "); + } } for (int k = 0; k < chars_read; k++) { - byte dataB = data[ k + j ]; - char charB = (char)(dataB & 0xFF); - switch (charB) { - case 127: case 128: case 129: case 141: case 142: case 143: case 144: case 157: case 158: - charB = '.'; - break; - default: - if (charB < ' ') charB = '.'; - break; - } - buffer.append(charB); + buffer.append(toAscii(data[ k + j ])); } buffer.append(EOL); display_offset += chars_read; @@ -216,29 +166,18 @@ public class HexDump { return buffer.toString(); } - - private static String dump(final long value) - { - StringBuffer buf = new StringBuffer(); - buf.setLength(0); - for (int j = 0; j < 8; j++) - { - buf.append( _hexcodes[ (( int ) (value >> _shifts[ j + _shifts.length - 8 ])) & 15 ]); + public static char toAscii(int dataB) { + char charB = (char)(dataB & 0xFF); + if (Character.isISOControl(charB)) return '.'; + + switch (charB) { + case 0xFF: case 0xDD: // printable, but not compilable with current compiler encoding + charB = '.'; + break; } - return buf.toString(); + return charB; } - - private static String dump(final byte value) - { - StringBuffer buf = new StringBuffer(); - buf.setLength(0); - for (int j = 0; j < 2; j++) - { - buf.append(_hexcodes[ (value >> _shifts[ j + 6 ]) & 15 ]); - } - return buf.toString(); - } - + /** * Converts the parameter to a hex value. * @@ -326,9 +265,8 @@ public class HexDump { * @param value The value to convert * @return The result right padded with 0 */ - public static String toHex(final short value) - { - return toHex(value, 4); + public static String toHex(final short value) { + return String.format("%04X", value); } /** @@ -337,9 +275,8 @@ public class HexDump { * @param value The value to convert * @return The result right padded with 0 */ - public static String toHex(final byte value) - { - return toHex(value, 2); + public static String toHex(final byte value) { + return String.format("%02X", value); } /** @@ -348,9 +285,8 @@ public class HexDump { * @param value The value to convert * @return The result right padded with 0 */ - public static String toHex(final int value) - { - return toHex(value, 8); + public static String toHex(final int value) { + return String.format("%08X", value); } /** @@ -359,20 +295,8 @@ public class HexDump { * @param value The value to convert * @return The result right padded with 0 */ - public static String toHex(final long value) - { - return toHex(value, 16); - } - - - private static String toHex(final long value, final int digits) - { - StringBuffer result = new StringBuffer(digits); - for (int j = 0; j < digits; j++) - { - result.append( _hexcodes[ (int) ((value >> _shifts[ j + (16 - digits) ]) & 15)]); - } - return result.toString(); + public static String toHex(final long value) { + return String.format("%016X", value); } /** @@ -411,49 +335,33 @@ public class HexDump { byte[] data = buf.toByteArray(); dump(data, 0, out, start, data.length); } - /** - * @return char array of uppercase hex chars, zero padded and prefixed with '0x' - */ - private static char[] toHexChars(long pValue, int nBytes) { - int charPos = 2 + nBytes*2; - // The return type is char array because most callers will probably append the value to a - // StringBuffer, or write it to a Stream / Writer so there is no need to create a String; - char[] result = new char[charPos]; - long value = pValue; - do { - result[--charPos] = _hexcodes[(int) (value & 0x0F)]; - value >>>= 4; - } while (charPos > 1); - - // Prefix added to avoid ambiguity - result[0] = '0'; - result[1] = 'x'; - return result; - } /** - * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x' + * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x' */ - public static char[] longToHex(long value) { - return toHexChars(value, 8); + public static String longToHex(long value) { + return String.format("0x%016X", value); } + /** - * @return char array of 4 (zero padded) uppercase hex chars and prefixed with '0x' + * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x' */ - public static char[] intToHex(int value) { - return toHexChars(value, 4); + public static String intToHex(int value) { + return String.format("0x%08X", value & 0xFFFFFFFF); } + /** - * @return char array of 2 (zero padded) uppercase hex chars and prefixed with '0x' + * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x' */ - public static char[] shortToHex(int value) { - return toHexChars(value, 2); + public static String shortToHex(int value) { + return String.format("0x%04X", value & 0xFFFF); } + /** - * @return char array of 1 (zero padded) uppercase hex chars and prefixed with '0x' + * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x' */ - public static char[] byteToHex(int value) { - return toHexChars(value, 1); + public static String byteToHex(int value) { + return String.format("0x%02X", value & 0xFF); } public static void main(String[] args) throws Exception { diff --git a/src/testcases/org/apache/poi/ddf/TestEscherDump.java b/src/testcases/org/apache/poi/ddf/TestEscherDump.java index 276c15f41..718585592 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherDump.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherDump.java @@ -17,9 +17,12 @@ package org.apache.poi.ddf; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -30,23 +33,23 @@ public class TestEscherDump { @Test public void testSimple() throws Exception { // simple test to at least cover some parts of the class - EscherDump.main(new String[] {}); + EscherDump.main(new String[] {}, new NullPrinterStream()); - new EscherDump().dump(0, new byte[] {}, System.out); - new EscherDump().dump(new byte[] {}, 0, 0, System.out); - new EscherDump().dumpOld(0, new ByteArrayInputStream(new byte[] {}), System.out); + new EscherDump().dump(0, new byte[] {}, new NullPrinterStream()); + new EscherDump().dump(new byte[] {}, 0, 0, new NullPrinterStream()); + new EscherDump().dumpOld(0, new ByteArrayInputStream(new byte[] {}), new NullPrinterStream()); } @Test public void testWithData() throws Exception { - new EscherDump().dumpOld(8, new ByteArrayInputStream(new byte[] { 00, 00, 00, 00, 00, 00, 00, 00 }), System.out); + new EscherDump().dumpOld(8, new ByteArrayInputStream(new byte[] { 00, 00, 00, 00, 00, 00, 00, 00 }), new NullPrinterStream()); } @Test public void testWithSamplefile() throws Exception { //InputStream stream = HSSFTestDataSamples.openSampleFileStream(") byte[] data = POIDataSamples.getDDFInstance().readFile("Container.dat"); - new EscherDump().dump(data.length, data, System.out); + new EscherDump().dump(data.length, data, new NullPrinterStream()); //new EscherDump().dumpOld(data.length, new ByteArrayInputStream(data), System.out); data = new byte[2586114]; @@ -55,4 +58,31 @@ public class TestEscherDump { //new EscherDump().dump(bytes, data, System.out); //new EscherDump().dumpOld(bytes, new ByteArrayInputStream(data), System.out); } + + /** + * Implementation of an OutputStream which does nothing, used + * to redirect stdout to avoid spamming the console with output + */ + private static class NullPrinterStream extends PrintStream { + private NullPrinterStream() { + super(new NullOutputStream()); + } + /** + * Implementation of an OutputStream which does nothing, used + * to redirect stdout to avoid spamming the console with output + */ + private static class NullOutputStream extends OutputStream { + @Override + public void write(byte[] b, int off, int len) { + } + + @Override + public void write(int b) { + } + + @Override + public void write(byte[] b) throws IOException { + } + } + } } diff --git a/src/testcases/org/apache/poi/hssf/dev/TestBiffViewer.java b/src/testcases/org/apache/poi/hssf/dev/TestBiffViewer.java index a1d190ab5..776e27852 100644 --- a/src/testcases/org/apache/poi/hssf/dev/TestBiffViewer.java +++ b/src/testcases/org/apache/poi/hssf/dev/TestBiffViewer.java @@ -21,6 +21,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; +import org.apache.poi.POIDataSamples; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.junit.Ignore; +import org.junit.Test; + public class TestBiffViewer extends BaseXLSIteratingTest { static { // these are likely ok to fail @@ -43,21 +48,21 @@ public class TestBiffViewer extends BaseXLSIteratingTest { @Override void runOneFile(File file) throws IOException { - InputStream is = BiffViewer.getPOIFSInputStream(file); + NPOIFSFileSystem fs = new NPOIFSFileSystem(file, true); + InputStream is = BiffViewer.getPOIFSInputStream(fs); try { // use a NullOutputStream to not write the bytes anywhere for best runtime BiffViewer.runBiffViewer(new PrintStream(NULL_OUTPUT_STREAM), is, true, true, true, false); } finally { is.close(); + fs.close(); } } // @Test +// @Ignore("only used for manual tests") // public void testOneFile() throws Exception { -// List failed = new ArrayList(); -// runOneFile("test-data/spreadsheet", "WORKBOOK_in_capitals.xls", failed); -// -// assertTrue("Expected to have no failed except the ones excluded, but had: " + failed, -// failed.isEmpty()); +// POIDataSamples samples = POIDataSamples.getSpreadSheetInstance(); +// runOneFile(samples.getFile("43493.xls")); // } } diff --git a/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java b/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java index 8c7e71fb2..d1e5631b9 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java @@ -17,14 +17,16 @@ package org.apache.poi.hssf.record; import static org.junit.Assert.assertArrayEquals; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.fail; import org.apache.poi.hssf.record.HyperlinkRecord.GUID; import org.apache.poi.util.HexDump; import org.apache.poi.util.HexRead; import org.apache.poi.util.LittleEndianByteArrayInputStream; import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.junit.Test; /** * Test HyperlinkRecord @@ -32,7 +34,7 @@ import org.apache.poi.util.LittleEndianByteArrayOutputStream; * @author Nick Burch * @author Yegor Kozlov */ -public final class TestHyperlinkRecord extends TestCase { +public final class TestHyperlinkRecord { //link to http://www.lakings.com/ private static final byte[] data1 = { 0x02, 0x00, //First row of the hyperlink @@ -262,6 +264,8 @@ public final class TestHyperlinkRecord extends TestCase { private void confirmGUID(GUID expectedGuid, GUID actualGuid) { assertEquals(expectedGuid, actualGuid); } + + @Test public void testReadURLLink(){ RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data1); HyperlinkRecord link = new HyperlinkRecord(is); @@ -281,6 +285,7 @@ public final class TestHyperlinkRecord extends TestCase { assertEquals("http://www.lakings.com/", link.getAddress()); } + @Test public void testReadFileLink(){ RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data2); HyperlinkRecord link = new HyperlinkRecord(is); @@ -300,6 +305,7 @@ public final class TestHyperlinkRecord extends TestCase { assertEquals("link1.xls", link.getAddress()); } + @Test public void testReadEmailLink(){ RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data3); HyperlinkRecord link = new HyperlinkRecord(is); @@ -318,6 +324,7 @@ public final class TestHyperlinkRecord extends TestCase { assertEquals("mailto:ebgans@mail.ru?subject=Hello,%20Ebgans!", link.getAddress()); } + @Test public void testReadDocumentLink(){ RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data4); HyperlinkRecord link = new HyperlinkRecord(is); @@ -347,6 +354,7 @@ public final class TestHyperlinkRecord extends TestCase { assertArrayEquals(bytes1, bytes2); } + @Test public void testSerialize(){ serialize(data1); serialize(data2); @@ -354,6 +362,7 @@ public final class TestHyperlinkRecord extends TestCase { serialize(data4); } + @Test public void testCreateURLRecord() { HyperlinkRecord link = new HyperlinkRecord(); link.newUrlLink(); @@ -369,6 +378,7 @@ public final class TestHyperlinkRecord extends TestCase { assertArrayEquals(data1, ser); } + @Test public void testCreateFileRecord() { HyperlinkRecord link = new HyperlinkRecord(); link.newFileLink(); @@ -384,6 +394,7 @@ public final class TestHyperlinkRecord extends TestCase { assertArrayEquals(data2, ser); } + @Test public void testCreateDocumentRecord() { HyperlinkRecord link = new HyperlinkRecord(); link.newDocumentLink(); @@ -399,6 +410,7 @@ public final class TestHyperlinkRecord extends TestCase { assertArrayEquals(data4, ser); } + @Test public void testCreateEmailtRecord() { HyperlinkRecord link = new HyperlinkRecord(); link.newUrlLink(); @@ -414,6 +426,7 @@ public final class TestHyperlinkRecord extends TestCase { assertArrayEquals(data3, ser); } + @Test public void testClone() { byte[][] data = {data1, data2, data3, data4}; for (int i = 0; i < data.length; i++) { @@ -425,27 +438,27 @@ public final class TestHyperlinkRecord extends TestCase { } - public void testReserializeTargetFrame() { + @Test + public void testReserializeTargetFrame() { RecordInputStream in = TestcaseRecordInputStream.create(HyperlinkRecord.sid, dataTargetFrame); HyperlinkRecord hr = new HyperlinkRecord(in); byte[] ser = hr.serialize(); TestcaseRecordInputStream.confirmRecordEncoding(HyperlinkRecord.sid, dataTargetFrame, ser); } - + @Test public void testReserializeLinkToWorkbook() { RecordInputStream in = TestcaseRecordInputStream.create(HyperlinkRecord.sid, dataLinkToWorkbook); HyperlinkRecord hr = new HyperlinkRecord(in); byte[] ser = hr.serialize(); TestcaseRecordInputStream.confirmRecordEncoding(HyperlinkRecord.sid, dataLinkToWorkbook, ser); - if ("YEARFR~1.XLS".equals(hr.getAddress())) { - throw new AssertionFailedError("Identified bug in reading workbook link"); - } + assertNotEquals("Identified bug in reading workbook link", "YEARFR~1.XLS", hr.getAddress()); assertEquals("yearfracExamples.xls", hr.getAddress()); } - public void testReserializeUNC() { + @Test + public void testReserializeUNC() { RecordInputStream in = TestcaseRecordInputStream.create(HyperlinkRecord.sid, dataUNC); HyperlinkRecord hr = new HyperlinkRecord(in); @@ -454,10 +467,11 @@ public final class TestHyperlinkRecord extends TestCase { try { hr.toString(); } catch (NullPointerException e) { - throw new AssertionFailedError("Identified bug with option URL and UNC set at same time"); + fail("Identified bug with option URL and UNC set at same time"); } } + @Test public void testGUID() { GUID g; g = GUID.parse("3F2504E0-4F89-11D3-9A0C-0305E82C3301"); @@ -489,12 +503,13 @@ public final class TestHyperlinkRecord extends TestCase { } private void confirmGUID(GUID g, int d1, int d2, int d3, long d4) { - assertEquals(new String(HexDump.intToHex(d1)), new String(HexDump.intToHex(g.getD1()))); - assertEquals(new String(HexDump.shortToHex(d2)), new String(HexDump.shortToHex(g.getD2()))); - assertEquals(new String(HexDump.shortToHex(d3)), new String(HexDump.shortToHex(g.getD3()))); - assertEquals(new String(HexDump.longToHex(d4)), new String(HexDump.longToHex(g.getD4()))); + assertEquals(HexDump.intToHex(d1), HexDump.intToHex(g.getD1())); + assertEquals(HexDump.shortToHex(d2), HexDump.shortToHex(g.getD2())); + assertEquals(HexDump.shortToHex(d3), HexDump.shortToHex(g.getD3())); + assertEquals(HexDump.longToHex(d4), HexDump.longToHex(g.getD4())); } + @Test public void test47498(){ RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data_47498); HyperlinkRecord link = new HyperlinkRecord(is); diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java index 6c8cd0177..26eb16b2f 100644 --- a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java +++ b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java @@ -92,15 +92,15 @@ public final class TestBiff8DecryptingStream { } public void confirmByte(int expVal) { - cmp(HexDump.byteToHex(expVal), HexDump.byteToHex(_bds.readUByte())); + assertEquals(HexDump.byteToHex(expVal), HexDump.byteToHex(_bds.readUByte())); } public void confirmShort(int expVal) { - cmp(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readShort())); + assertEquals(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readShort())); } public void confirmUShort(int expVal) { - cmp(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readUShort())); + assertEquals(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readUShort())); } public short readShort() { @@ -112,25 +112,13 @@ public final class TestBiff8DecryptingStream { } public void confirmInt(int expVal) { - cmp(HexDump.intToHex(expVal), HexDump.intToHex(_bds.readInt())); + assertEquals(HexDump.intToHex(expVal), HexDump.intToHex(_bds.readInt())); } public void confirmLong(long expVal) { - cmp(HexDump.longToHex(expVal), HexDump.longToHex(_bds.readLong())); + assertEquals(HexDump.longToHex(expVal), HexDump.longToHex(_bds.readLong())); } - private void cmp(char[] exp, char[] act) { - if (Arrays.equals(exp, act)) { - return; - } - _errorsOccurred = true; - if (ONLY_LOG_ERRORS) { - logErr(3, "Value mismatch " + new String(exp) + " - " + new String(act)); - return; - } - throw new ComparisonFailure("Value mismatch", new String(exp), new String(act)); - } - public void confirmData(String expHexData) { byte[] expData = HexRead.readFromString(expHexData); diff --git a/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java b/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java index d69fd681c..dca549c88 100644 --- a/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java +++ b/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java @@ -50,9 +50,7 @@ public final class RawDataUtil { System.out.println("String[] hexDataLines = {"); System.out.print("\t\""); while(true) { - char[] cc = HexDump.byteToHex(data[i]); - System.out.print(cc[2]); - System.out.print(cc[3]); + System.out.print(HexDump.byteToHex(data[i]).substring(2)); i++; if (i>=data.length) { break; diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java b/src/testcases/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java index 1ee9b45a8..7500be57e 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java @@ -142,7 +142,7 @@ public final class TestMinusZeroResult extends TestCase { long bitsB = Double.doubleToLongBits(b); if (bitsA != bitsB) { throw new ComparisonFailure("value different to expected", - new String(HexDump.longToHex(bitsA)), new String(HexDump.longToHex(bitsB))); + HexDump.longToHex(bitsA), HexDump.longToHex(bitsB)); } } } diff --git a/src/testcases/org/apache/poi/ss/util/NumberComparingSpreadsheetGenerator.java b/src/testcases/org/apache/poi/ss/util/NumberComparingSpreadsheetGenerator.java index d04bf402e..d4f1ebb92 100644 --- a/src/testcases/org/apache/poi/ss/util/NumberComparingSpreadsheetGenerator.java +++ b/src/testcases/org/apache/poi/ss/util/NumberComparingSpreadsheetGenerator.java @@ -125,9 +125,7 @@ public class NumberComparingSpreadsheetGenerator { private static String formatDoubleAsHex(double d) { long l = Double.doubleToLongBits(d); - StringBuilder sb = new StringBuilder(20); - sb.append(HexDump.longToHex(l)).append('L'); - return sb.toString(); + return HexDump.longToHex(l)+'L'; } public static void main(String[] args) { diff --git a/src/testcases/org/apache/poi/ss/util/TestExpandedDouble.java b/src/testcases/org/apache/poi/ss/util/TestExpandedDouble.java index dd524fdb8..d4d63192d 100644 --- a/src/testcases/org/apache/poi/ss/util/TestExpandedDouble.java +++ b/src/testcases/org/apache/poi/ss/util/TestExpandedDouble.java @@ -17,21 +17,24 @@ package org.apache.poi.ss.util; +import static org.junit.Assert.assertEquals; + import java.math.BigDecimal; import java.math.BigInteger; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - import org.apache.poi.util.HexDump; +import org.junit.Test; + +import junit.framework.AssertionFailedError; /** * Tests for {@link ExpandedDouble} * * @author Josh Micich */ -public final class TestExpandedDouble extends TestCase { +public final class TestExpandedDouble { private static final BigInteger BIG_POW_10 = BigInteger.valueOf(1000000000); + @Test public void testNegative() { ExpandedDouble hd = new ExpandedDouble(0xC010000000000000L); @@ -44,6 +47,7 @@ public final class TestExpandedDouble extends TestCase { assertEquals(1, frac.bitCount()); } + @Test public void testSubnormal() { ExpandedDouble hd = new ExpandedDouble(0x0000000000000001L); @@ -59,6 +63,7 @@ public final class TestExpandedDouble extends TestCase { /** * Tests specific values for conversion from {@link ExpandedDouble} to {@link NormalisedDecimal} and back */ + @Test public void testRoundTripShifting() { long[] rawValues = { 0x4010000000000004L, @@ -87,6 +92,7 @@ public final class TestExpandedDouble extends TestCase { throw new AssertionFailedError("One or more test examples failed. See stderr."); } } + public static boolean confirmRoundTrip(int i, long rawBitsA) { double a = Double.longBitsToDouble(rawBitsA); if (a == 0.0) { @@ -150,6 +156,7 @@ public final class TestExpandedDouble extends TestCase { } return bd.unscaledValue().toString(); } + public static BigInteger getNearby(NormalisedDecimal md, int offset) { BigInteger frac = md.composeFrac(); int be = frac.bitLength() - 24 - 1; @@ -218,8 +225,6 @@ public final class TestExpandedDouble extends TestCase { private static String formatDoubleAsHex(double d) { long l = Double.doubleToLongBits(d); - StringBuilder sb = new StringBuilder(20); - sb.append(HexDump.longToHex(l)).append('L'); - return sb.toString(); + return HexDump.longToHex(l)+'L'; } } diff --git a/src/testcases/org/apache/poi/ss/util/TestNumberComparer.java b/src/testcases/org/apache/poi/ss/util/TestNumberComparer.java index 7c3d87e99..506df6749 100644 --- a/src/testcases/org/apache/poi/ss/util/TestNumberComparer.java +++ b/src/testcases/org/apache/poi/ss/util/TestNumberComparer.java @@ -17,18 +17,21 @@ package org.apache.poi.ss.util; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.apache.poi.ss.util.NumberComparisonExamples.ComparisonExample; import org.apache.poi.util.HexDump; +import org.junit.Test; /** * Tests for {@link NumberComparer} * * @author Josh Micich */ -public final class TestNumberComparer extends TestCase { +public final class TestNumberComparer { + @Test public void testAllComparisonExamples() { ComparisonExample[] examples = NumberComparisonExamples.getComparisonExamples(); boolean success = true; @@ -40,11 +43,11 @@ public final class TestNumberComparer extends TestCase { success &= confirm(i, ce.getNegA(), ce.getNegB(), -ce.getExpectedResult()); success &= confirm(i, ce.getNegB(), ce.getNegA(), +ce.getExpectedResult()); } - if (!success) { - throw new AssertionFailedError("One or more cases failed. See stderr"); - } + + assertTrue("One or more cases failed. See stderr", success); } + @Test public void testRoundTripOnComparisonExamples() { ComparisonExample[] examples = NumberComparisonExamples.getComparisonExamples(); boolean success = true; @@ -55,10 +58,8 @@ public final class TestNumberComparer extends TestCase { success &= confirmRoundTrip(i, ce.getB()); success &= confirmRoundTrip(i, ce.getNegB()); } - if (!success) { - throw new AssertionFailedError("One or more cases failed. See stderr"); - } - + + assertTrue("One or more cases failed. See stderr", success); } private boolean confirmRoundTrip(int i, double a) { @@ -68,6 +69,7 @@ public final class TestNumberComparer extends TestCase { /** * The actual example from bug 47598 */ + @Test public void testSpecificExampleA() { double a = 0.06-0.01; double b = 0.05; @@ -78,6 +80,7 @@ public final class TestNumberComparer extends TestCase { /** * The example from the nabble posting */ + @Test public void testSpecificExampleB() { double a = 1+1.0028-0.9973; double b = 1.0055; @@ -99,8 +102,6 @@ public final class TestNumberComparer extends TestCase { } private static String formatDoubleAsHex(double d) { long l = Double.doubleToLongBits(d); - StringBuilder sb = new StringBuilder(20); - sb.append(HexDump.longToHex(l)).append('L'); - return sb.toString(); + return HexDump.longToHex(l)+'L'; } } diff --git a/src/testcases/org/apache/poi/util/TestHexDump.java b/src/testcases/org/apache/poi/util/TestHexDump.java index 883cedd91..11cd4cb9a 100644 --- a/src/testcases/org/apache/poi/util/TestHexDump.java +++ b/src/testcases/org/apache/poi/util/TestHexDump.java @@ -17,6 +17,12 @@ package org.apache.poi.util; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -26,243 +32,116 @@ import java.io.InputStream; import java.io.PrintStream; import java.lang.reflect.Constructor; -import junit.framework.TestCase; - -/** - * @author Glen Stampoultzis (glens at apache.org) - * @author Marc Johnson (mjohnson at apache dot org) - */ -public final class TestHexDump extends TestCase { - - - private static char toHex(int n) { - return Character.toUpperCase(Character.forDigit(n & 0x0F, 16)); - } +import org.junit.Test; +public final class TestHexDump { + @Test public void testDump() throws IOException { byte[] testArray = new byte[ 256 ]; - for (int j = 0; j < 256; j++) - { + for (int j = 0; j < 256; j++) { testArray[ j ] = ( byte ) j; } - ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ByteArrayOutputStream streamAct = new ByteArrayOutputStream(); + HexDump.dump(testArray, 0, streamAct, 0); + byte bytesAct[] = streamAct.toByteArray(); + byte bytesExp[] = toHexDump(0,0); - HexDump.dump(testArray, 0, stream, 0); - byte[] outputArray = new byte[ 16 * (73 + HexDump.EOL.length()) ]; - - for (int j = 0; j < 16; j++) - { - int offset = (73 + HexDump.EOL.length()) * j; - - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) ' '; - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) toHex(k); - outputArray[ offset++ ] = ( byte ) ' '; - } - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toAscii((j * 16) + k); - } - System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset, - HexDump.EOL.getBytes().length); - } - byte[] actualOutput = stream.toByteArray(); - - assertEquals("array size mismatch", outputArray.length, - actualOutput.length); - for (int j = 0; j < outputArray.length; j++) - { - assertEquals("array[ " + j + "] mismatch", outputArray[ j ], - actualOutput[ j ]); - } + assertEquals("array size mismatch", bytesExp.length, bytesAct.length); + assertArrayEquals("array mismatch", bytesExp, bytesAct); // verify proper behavior with non-zero offset - stream = new ByteArrayOutputStream(); - HexDump.dump(testArray, 0x10000000, stream, 0); - outputArray = new byte[ 16 * (73 + HexDump.EOL.length()) ]; - for (int j = 0; j < 16; j++) - { - int offset = (73 + HexDump.EOL.length()) * j; - - outputArray[ offset++ ] = ( byte ) '1'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) ' '; - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) toHex(k); - outputArray[ offset++ ] = ( byte ) ' '; - } - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toAscii((j * 16) + k); - } - System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset, - HexDump.EOL.getBytes().length); - } - actualOutput = stream.toByteArray(); - assertEquals("array size mismatch", outputArray.length, - actualOutput.length); - for (int j = 0; j < outputArray.length; j++) - { - assertEquals("array[ " + j + "] mismatch", outputArray[ j ], - actualOutput[ j ]); - } + streamAct.reset(); + HexDump.dump(testArray, 0x10000000L, streamAct, 0); + bytesAct = streamAct.toByteArray(); + bytesExp = toHexDump(0x10000000L,0); + + assertEquals("array size mismatch", bytesExp.length, bytesAct.length); + assertArrayEquals("array mismatch", bytesExp, bytesAct); // verify proper behavior with negative offset - stream = new ByteArrayOutputStream(); - HexDump.dump(testArray, 0xFF000000, stream, 0); - outputArray = new byte[ 16 * (73 + HexDump.EOL.length()) ]; - for (int j = 0; j < 16; j++) - { - int offset = (73 + HexDump.EOL.length()) * j; + streamAct.reset(); + HexDump.dump(testArray, 0xFF000000L, streamAct, 0); + bytesAct = streamAct.toByteArray(); + bytesExp = toHexDump(0xFF000000L,0); - outputArray[ offset++ ] = ( byte ) 'F'; - outputArray[ offset++ ] = ( byte ) 'F'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) ' '; - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toHex(j); - outputArray[ offset++ ] = ( byte ) toHex(k); - outputArray[ offset++ ] = ( byte ) ' '; - } - for (int k = 0; k < 16; k++) - { - outputArray[ offset++ ] = ( byte ) toAscii((j * 16) + k); - } - System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset, - HexDump.EOL.getBytes().length); - } - actualOutput = stream.toByteArray(); - assertEquals("array size mismatch", outputArray.length, - actualOutput.length); - for (int j = 0; j < outputArray.length; j++) - { - assertEquals("array[ " + j + "] mismatch", outputArray[ j ], - actualOutput[ j ]); - } + assertEquals("array size mismatch", bytesExp.length, bytesAct.length); + assertArrayEquals("array mismatch", bytesExp, bytesAct); // verify proper behavior with non-zero index - stream = new ByteArrayOutputStream(); - HexDump.dump(testArray, 0x10000000, stream, 0x81); - outputArray = new byte[ (8 * (73 + HexDump.EOL.length())) - 1 ]; - for (int j = 0; j < 8; j++) - { - int offset = (73 + HexDump.EOL.length()) * j; + streamAct.reset(); + HexDump.dump(testArray, 0xFF000000L, streamAct, 0x81); + bytesAct = streamAct.toByteArray(); + bytesExp = toHexDump(0xFF000000L,0x81); - outputArray[ offset++ ] = ( byte ) '1'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) '0'; - outputArray[ offset++ ] = ( byte ) toHex(j + 8); - outputArray[ offset++ ] = ( byte ) '1'; - outputArray[ offset++ ] = ( byte ) ' '; - for (int k = 0; k < 16; k++) - { - int index = 0x81 + (j * 16) + k; + assertEquals("array size mismatch", bytesExp.length, bytesAct.length); + assertArrayEquals("array mismatch", bytesExp, bytesAct); - if (index < 0x100) - { - outputArray[ offset++ ] = ( byte ) toHex(index / 16); - outputArray[ offset++ ] = ( byte ) toHex(index); - } - else - { - outputArray[ offset++ ] = ( byte ) ' '; - outputArray[ offset++ ] = ( byte ) ' '; - } - outputArray[ offset++ ] = ( byte ) ' '; - } - for (int k = 0; k < 16; k++) - { - int index = 0x81 + (j * 16) + k; - - if (index < 0x100) - { - outputArray[ offset++ ] = ( byte ) toAscii(index); - } - } - System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset, - HexDump.EOL.getBytes().length); - } - actualOutput = stream.toByteArray(); - assertEquals("array size mismatch", outputArray.length, - actualOutput.length); - for (int j = 0; j < outputArray.length; j++) - { - assertEquals("array[ " + j + "] mismatch", outputArray[ j ], - actualOutput[ j ]); - } // verify proper behavior with negative index - try - { - HexDump.dump(testArray, 0x10000000, new ByteArrayOutputStream(), -1); + try { + streamAct.reset(); + HexDump.dump(testArray, 0x10000000L, streamAct, -1); fail("should have caught ArrayIndexOutOfBoundsException on negative index"); - } - catch (ArrayIndexOutOfBoundsException ignored_exception) - { - + } catch (ArrayIndexOutOfBoundsException ignored_exception) { // as expected } // verify proper behavior with index that is too large - try - { - HexDump.dump(testArray, 0x10000000, new ByteArrayOutputStream(), - testArray.length); + try { + streamAct.reset(); + HexDump.dump(testArray, 0x10000000L, streamAct, testArray.length); fail("should have caught ArrayIndexOutOfBoundsException on large index"); - } - catch (ArrayIndexOutOfBoundsException ignored_exception) - { - + } catch (ArrayIndexOutOfBoundsException ignored_exception) { // as expected } // verify proper behavior with null stream - try - { - HexDump.dump(testArray, 0x10000000, null, 0); + try { + HexDump.dump(testArray, 0x10000000L, null, 0); fail("should have caught IllegalArgumentException on negative index"); - } - catch (IllegalArgumentException ignored_exception) - { + } catch (IllegalArgumentException ignored_exception) { // as expected } // verify proper behaviour with empty byte array - ByteArrayOutputStream os = new ByteArrayOutputStream( ); - HexDump.dump( new byte[0], 0, os, 0 ); - assertEquals( "No Data" + System.getProperty( "line.separator"), os.toString() ); + streamAct.reset(); + HexDump.dump( new byte[0], 0, streamAct, 0 ); + assertEquals( "No Data" + System.getProperty( "line.separator"), streamAct.toString() ); } + + private byte[] toHexDump(long offset, int index) { + StringBuilder strExp = new StringBuilder(), chrs = new StringBuilder(); + Object obj[] = new Object[33]; + StringBuilder format = new StringBuilder(); + + for (int j = 0; j < 16 && (index + j*16) < 256; j++) { + obj[0] = offset+index+j*16; + chrs.setLength(0); + format.setLength(0); + format.append("%08X "); + for (int k = 0; k < 16; k++) { + if (index+j*16+k < 256){ + obj[k+1] = index+j*16+k; + chrs.append(HexDump.toAscii(index+j*16+k)); + format.append("%02X "); + } else { + format.append(" "); + } + } + obj[17] = chrs.toString(); + format.append("%18$s"+HexDump.EOL); + + String str = String.format(format.toString(), obj); + strExp.append(str); + } + byte bytesExp[] = strExp.toString().getBytes(HexDump.UTF8); + return bytesExp; + } + @Test public void testToHex() { assertEquals("000A", HexDump.toHex((short)0xA)); @@ -287,29 +166,17 @@ public final class TestHexDump extends TestCase { assertEquals("00000000000004D2", HexDump.toHex(1234l)); - confirmStr("0xFE", HexDump.byteToHex(-2)); - confirmStr("0x25", HexDump.byteToHex(37)); - confirmStr("0xFFFE", HexDump.shortToHex(-2)); - confirmStr("0x0005", HexDump.shortToHex(5)); - confirmStr("0xFFFFFF9C", HexDump.intToHex(-100)); - confirmStr("0x00001001", HexDump.intToHex(4097)); - confirmStr("0xFFFFFFFFFFFF0006", HexDump.longToHex(-65530)); - confirmStr("0x0000000000003FCD", HexDump.longToHex(16333)); + assertEquals("0xFE", HexDump.byteToHex(-2)); + assertEquals("0x25", HexDump.byteToHex(37)); + assertEquals("0xFFFE", HexDump.shortToHex(-2)); + assertEquals("0x0005", HexDump.shortToHex(5)); + assertEquals("0xFFFFFF9C", HexDump.intToHex(-100)); + assertEquals("0x00001001", HexDump.intToHex(4097)); + assertEquals("0xFFFFFFFFFFFF0006", HexDump.longToHex(-65530)); + assertEquals("0x0000000000003FCD", HexDump.longToHex(16333)); } - private static void confirmStr(String expected, char[] actualChars) { - assertEquals(expected, new String(actualChars)); - } - - private static char toAscii(int c) { - char rval = '.'; - - if (c >= 32 && c <= 126) { - rval = ( char ) c; - } - return rval; - } - + @Test public void testDumpToString() throws Exception { byte[] testArray = new byte[ 256 ]; @@ -328,24 +195,22 @@ public final class TestHexDump extends TestCase { dump.contains("123456789:;<=>?@")); } - public void testDumpToStringOutOfIndex() throws Exception { - byte[] testArray = new byte[ 0 ]; + @Test(expected=ArrayIndexOutOfBoundsException.class) + public void testDumpToStringOutOfIndex1() throws Exception { + HexDump.dump(new byte[ 1 ], 0, -1); + } - try { - HexDump.dump(testArray, 0, -1); - fail("Should throw an exception with invalid input"); - } catch (ArrayIndexOutOfBoundsException e) { - // expected - } + @Test(expected=ArrayIndexOutOfBoundsException.class) + public void testDumpToStringOutOfIndex2() throws Exception { + HexDump.dump(new byte[ 1 ], 0, 2); + } - try { - HexDump.dump(testArray, 0, 1); - fail("Should throw an exception with invalid input"); - } catch (ArrayIndexOutOfBoundsException e) { - // expected - } + public void testDumpToStringOutOfIndex3() throws Exception { + HexDump.dump(new byte[ 1 ], 0, 1); } + + @Test public void testDumpToPrintStream() throws IOException { byte[] testArray = new byte[ 256 ]; @@ -425,6 +290,7 @@ public final class TestHexDump extends TestCase { } } + @Test public void testConstruct() throws Exception { // to cover private constructor // get the default constructor @@ -437,6 +303,7 @@ public final class TestHexDump extends TestCase { assertNotNull(c.newInstance((Object[]) null)); } + @Test public void testMain() throws Exception { File file = TempFile.createTempFile("HexDump", ".dat"); try {