/**
* JHOVE2 - Next-generation architecture for format-aware characterization
*
* Copyright (c) 2009 by The Regents of the University of California,
* Ithaka Harbors, Inc., and The Board of Trustees of the Leland Stanford
* Junior University.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of the University of California/California Digital
* Library, Ithaka Harbors/Portico, or Stanford University, nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jhove2.core.io;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.Buffer;
import java.nio.ByteOrder;
import javax.annotation.Resource;
import org.jhove2.ConfigTestBase;
import org.jhove2.app.util.FeatureConfigurationUtil;
import org.jhove2.core.Invocation;
import org.jhove2.core.JHOVE2;
import org.jhove2.core.JHOVE2Exception;
import org.jhove2.core.io.Input.Type;
import org.jhove2.core.source.Source;
import org.jhove2.core.source.SourceFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author mstrong
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
"classpath*:**/persist-test-config.xml",
"classpath*:**/core/test-config.xml",
"classpath*:**/module/**/test-config.xml",
"classpath*:**/abstractdisplayer-config.xml",
"classpath*:**/filepaths-config.xml"})
public class MappedInputTest extends ConfigTestBase{
int bufferSize;
static MappedInput abstractInput = null;
private String utf8DirBasePath;
private String testFile01;
private File testFile;
PrintWriter out;
ByteOrder nativeOrder = ByteOrder.nativeOrder();
private JHOVE2 jhove2;
@Resource
public void setJHOVE2(JHOVE2 jhove2) {
this.jhove2 = jhove2;
}
@Before
public void setUp() throws Exception {
bufferSize = 100;
String utf8DirPath = null;
try {
utf8DirPath =
FeatureConfigurationUtil.getFilePathFromClasspath(utf8DirBasePath, "utf8 dir");
} catch (JHOVE2Exception e1) {
fail("Could not create base directory");
}
String filePath = utf8DirPath.concat(testFile01);
testFile = new File(filePath);
out = new PrintWriter(System.out, true);
}
@After
public void tearDown() throws Exception {
}
@Test
public void testGetInput() {
try {
Invocation inv = jhove2.getInvocation();
inv.setBufferType(Type.Mapped);
SourceFactory factory = jhove2.getSourceFactory();
Source source = factory.getSource(jhove2, testFile);
/* Buffers are always created big-endian, not native-endian, so this test
* isn't operative.
*/
/*
abstractInput = (MappedInput) source.getInput(bufferSize, Type.Mapped);
out.printf("Native ByteOrder is %s \n", nativeOrder);
out.printf("AbstractInput buffer order is %s\n", abstractInput.getBuffer().order());
String assertString = "MemoryMapped AbstractInput byte order "+ abstractInput.getBuffer().order()+
" matches with native ByteOrder" + nativeOrder;
assertTrue(assertString, abstractInput.getBuffer().order() != nativeOrder);
abstractInput.close();
*/
abstractInput = (MappedInput) InputFactory.getInput(jhove2, testFile,
source.isTemp());
assertTrue("AbstractInput Scope is MemoryMapped", abstractInput.getClass()
.getName().equalsIgnoreCase(MappedInput.class.getName()));
out.printf("AbstractInput buffer order is %s\n", abstractInput.getBuffer().order());
out.printf("Setting AbstractInput buffer order to %s\n", ByteOrder.LITTLE_ENDIAN);
abstractInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
assertTrue("AbstractInput is MemoryMapped with LITTLE_ENDIAN",
abstractInput.getBuffer().order() != ByteOrder.BIG_ENDIAN);
out.printf("AbstractInput buffer order is %s\n", abstractInput.getBuffer().order());
} catch (FileNotFoundException e) {
fail(e.getMessage());
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
} catch (JHOVE2Exception e) {
fail(e.getMessage());
e.printStackTrace();
}
}
@Test
public void testGetBuffer() {
Buffer buffer = abstractInput.getBuffer();
assertTrue("Buffer returned is null", buffer != null);
}
/**
* Test method for {@link org.jhove2.core.io.MappedInput#getMaxBufferSize()}.
*/
@Test
public void testGetMaxBufferSize() {
long fileLength = testFile.length();
assertTrue("Mapped Buffersize does not match filesize",
(abstractInput.getBufferSize() == fileLength));
}
/**
* Test method for {@link org.jhove2.core.io.AbstractInput#getByteArray()}.
*/
@Test
public void testGetByteArray() {
byte [] byteArray = null;
byteArray = abstractInput.getByteArray();
String byteString = new String(byteArray);
assertTrue("ByteArray is null", byteArray != null);
}
/**
* Test method for {@link org.jhove2.core.io.AbstractInput#readSignedByte()}.
*/
@Test
public void testReadByte() {
short testValue = 0;
try {
abstractInput.setPosition(0);
// read unsigned byte
testValue = abstractInput.readUnsignedByte();
// check if high order bit is set
assertTrue("High Order bit not set",
(testValue > 128 && testValue < 255));
out.println(testValue);
out.printf("0x%X\n", testValue);
// read signed byte
abstractInput.setPosition(0);
byte byteTestValue = abstractInput.readSignedByte();
// check if high order bit is set
assertTrue("High Order bit set",
(byteTestValue > -128 && byteTestValue < 127));
out.println(byteTestValue);
out.printf("0x%X\n", byteTestValue);
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
}
}
/*
* Test that getUnsignedShort() returns 2 bytes
*/
@Test
public void testReadShort() {
int testValue = 0;
try {
abstractInput.setPosition(0);
abstractInput.setByteOrder(ByteOrder.BIG_ENDIAN);
testValue = abstractInput.readUnsignedShort();
String testStr = Integer.toHexString(testValue);
assertTrue("High Order Bit not set ", testValue > 32768
&& testValue < 65535);
assertTrue("Hex value does not match expected 'efbb'", testStr
.equalsIgnoreCase("EFBB"));
out.printf("%d\n", testValue);
out.printf("0x%X\n", testValue);
abstractInput.setPosition(0);
short shortTestValue = abstractInput.readSignedShort();
assertTrue("High Order Bit not set ", shortTestValue > -32768
&& shortTestValue < 32768);
assertTrue("Hex value does not match expected 'efbb'", testStr
.equalsIgnoreCase("EFBB"));
out.printf("%d\n", shortTestValue);
testStr = String.format("%X", shortTestValue);
assertTrue("Hex value does not match expected 'efbb'", testStr
.equalsIgnoreCase("EFBB"));
out.printf("0x%X\n", shortTestValue);
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
}
}
/*
* Test that getUnsignedInt() returns 4 bytes
*/
@Test
public void testReadInt() {
try {
// test ReadSignedInt()
abstractInput.setPosition(0);
int intTestValue = abstractInput.readSignedInt();
String testStr = Integer.toHexString(intTestValue);
assertTrue("Value returned is not signed", (intTestValue < 0));
assertTrue("Hex value does not match expected 'efbbbf46'", testStr
.equalsIgnoreCase("efbbbf46"));
out.println(intTestValue);
out.printf("0x%X\n", intTestValue);
// test ReadUnsignedInt()
abstractInput.setPosition(0);
long longTestValue = abstractInput.readUnsignedInt();
testStr = Long.toHexString(longTestValue);
assertTrue("Value returned is signed", (longTestValue > 0));
assertTrue("Hex value does not match expected 'efbbbf46'", testStr
.equalsIgnoreCase("efbbbf46"));
out.println(longTestValue);
out.printf("0x%X\n", longTestValue);
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
}
}
/**
* Test method for {@link org.jhove2.core.io.AbstractInput#setPosition(long)}.
*/
@Test
public void testSetPosition() {
try {
/*
* Test the position is set correctly
*/
long newPosition = 100;
abstractInput.setPosition(newPosition);
long position = abstractInput.getPosition();
assertTrue("Set Position not set to correct position",
position == newPosition);
/*
* Test that the value expected to be at new position is true
*/
short b = abstractInput.readUnsignedByte();
char byteChar = (char) (b);
assertTrue("Position of inputable is not where its expected to be",
byteChar == 'f');
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
}
}
/*
* test obtaining values that partially reside outside the current buffer
* are retrieved properly
*
* Buffer ends at offset 100, retrieve a 4-byte int at offset 98 to force
* going outside of buffer boundary
*
* bytes at position 98: 0A6F663A BIG_ENDIAN expected value = 0A6F663A
* LITTLE_ENDIAN expected value = 3A666F0A
*/
@Test
public void testBufferBoundaries() {
try {
// test going beyond boundary explicitly with BIG_ENDIAN byte
// ordering
abstractInput.setPosition(98);
long testValue = abstractInput.readUnsignedInt();
out.println(testValue);
out.printf("Byte Order = %s: 0x%X\n", abstractInput.getBuffer()
.order(), testValue);
String testStr = Long.toHexString(testValue);
assertTrue("Hex value does not match expected '0A 6F 66 3A'",
testStr.equalsIgnoreCase("A6F663A"));
// test going beyond boundary explicitly with LITTLE_ENDIAN byte
// ordering
ByteOrder bo = abstractInput.getBuffer().order();
abstractInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
abstractInput.setPosition(98);
testValue = abstractInput.readUnsignedInt();
out.println(testValue);
out.printf("Byte Order = %s: 0x%X\n", abstractInput.getBuffer()
.order(), testValue);
testStr = Long.toHexString(testValue);
assertTrue("Hex value does not match expected '3A666F0A'", testStr
.equalsIgnoreCase("3A666F0A"));
/*
* test going beyond boundary without setting position explicitly
* beyond boundary (setPosition() takes care of getting the next
* buffer properly)
*/
abstractInput.setPosition(0);
abstractInput.setByteOrder(ByteOrder.BIG_ENDIAN);
long position = 0;
while ((position = abstractInput.getPosition()) < 96)
testValue = abstractInput.readUnsignedInt();
int shortValue = abstractInput.readUnsignedShort();
position = abstractInput.getPosition();
assertTrue("Position not at value 98 as expected", position == 98);
testValue = abstractInput.readUnsignedInt();
out.println(testValue);
out.printf("Byte Order = %s: 0x%X\n", abstractInput.getBuffer()
.order(), testValue);
testStr = Long.toHexString(testValue);
assertTrue("Hex value does not match expected '3A666F0A'", testStr
.equalsIgnoreCase("A6F663A"));
/*
* same test as above but for LITTLE_ENDIAN
*/
abstractInput.setPosition(0);
abstractInput.setByteOrder(ByteOrder.LITTLE_ENDIAN);
position = 0;
while ((position = abstractInput.getPosition()) < 96)
testValue = abstractInput.readUnsignedInt();
shortValue = abstractInput.readSignedShort();
position = abstractInput.getPosition();
assertTrue("Position not at value 98 as expected", position == 98);
testValue = abstractInput.readUnsignedInt();
out.println(testValue);
out.printf("Byte Order = %s: 0x%X\n", abstractInput.getBuffer()
.order(), testValue);
testStr = Long.toHexString(testValue);
assertTrue("Hex value does not match expected '3A666F0A'", testStr
.equalsIgnoreCase("3A666F0A"));
} catch (IOException e) {
fail(e.getMessage());
e.printStackTrace();
}
}
public String getTestFile01() {
return testFile01;
}
@Resource
public void setTestFile01(String testFile01) {
this.testFile01 = testFile01;
}
public String getUtf8DirBaseBath() {
return utf8DirBasePath;
}
@Resource
public void setUtf8DirBasePath(String testDir) {
this.utf8DirBasePath = testDir;
}
}