import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
* @author James Ahlborn
* @usage _advanced_class_
*/
-public class OleUtil
+public class OleUtil
{
/**
* Interface used to allow optional inclusion of the poi library for working
}
private static final int PACKAGE_SIGNATURE = 0x1C15;
- private static final Charset OLE_CHARSET = Charset.forName("US-ASCII");
- private static final Charset OLE_UTF_CHARSET = Charset.forName("UTF-16LE");
- private static final byte[] COMPOUND_STORAGE_SIGNATURE =
+ private static final Charset OLE_CHARSET = StandardCharsets.US_ASCII;
+ private static final Charset OLE_UTF_CHARSET = StandardCharsets.UTF_16LE;
+ private static final byte[] COMPOUND_STORAGE_SIGNATURE =
{(byte)0xd0,(byte)0xcf,(byte)0x11,(byte)0xe0,
(byte)0xa1,(byte)0xb1,(byte)0x1a,(byte)0xe1};
private static final String SIMPLE_PACKAGE_TYPE = "Package";
};
// regex pattern which matches all the crazy extra stuff in unicode
- private static final Pattern UNICODE_ACCENT_PATTERN =
+ private static final Pattern UNICODE_ACCENT_PATTERN =
Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");
private static final CompoundPackageFactory COMPOUND_FACTORY;
throws IOException
{
try {
-
+
if(!WRITEABLE_TYPES.contains(oleBuilder.getType())) {
throw new IllegalArgumentException(
"Cannot currently create ole values of type " +
oleBuilder.getType());
}
-
+
long contentLen = oleBuilder.getContentLength();
byte[] contentBytes = oleBuilder.getBytes();
InputStream contentStream = oleBuilder.getStream();
contentBytes = getZeroTermStrBytes(oleBuilder.getFilePath());
contentLen = contentBytes.length;
break;
-
+
case SIMPLE_PACKAGE:
packageStreamHeader = writePackageStreamHeader(oleBuilder);
packageStreamFooter = writePackageStreamFooter(oleBuilder);
break;
-
+
case OTHER:
// nothing more to do
break;
long payloadLen = packageStreamHeader.length + packageStreamFooter.length +
contentLen;
byte[] packageHeader = writePackageHeader(oleBuilder, payloadLen);
-
+
long totalOleLen = packageHeader.length + PACKAGE_FOOTER.length +
payloadLen;
if(totalOleLen > DataType.OLE.getMaxSize()) {
throw new IllegalArgumentException("Content size of " + totalOleLen +
" is too large for ole column");
}
-
+
byte[] oleBytes = new byte[(int)totalOleLen];
ByteBuffer bb = PageChannel.wrap(oleBytes);
bb.put(packageHeader);
bb.put(packageStreamHeader);
-
+
if(contentLen > 0L) {
if(contentBytes != null) {
bb.put(contentBytes);
bb.put(packageStreamFooter);
bb.put(PACKAGE_FOOTER);
-
+
return parseBlob(oleBytes);
-
+
} finally {
ByteUtil.closeQuietly(oleBuilder.getStream());
}
}
byte[] classNameBytes = getZeroTermStrBytes(className);
byte[] typeNameBytes = getZeroTermStrBytes(typeName);
-
+
int packageHeaderLen = 20 + prettyNameBytes.length + classNameBytes.length;
int oleHeaderLen = 24 + typeNameBytes.length;
byte[] headerBytes = new byte[packageHeaderLen + oleHeaderLen];
-
+
ByteBuffer bb = PageChannel.wrap(headerBytes);
// write outer package header
bb.put(typeNameBytes);
bb.putLong(0L);
bb.putInt((int)contentLen);
-
+
return headerBytes;
}
if(oleBuilder.getType() == ContentType.SIMPLE_PACKAGE) {
headerLen += 8 + filePathBytes.length;
-
+
} else {
headerLen += 2;
bb.putInt(PS_LINKED_FILE);
bb.putShort((short)LINK_HEADER);
}
-
+
return headerBytes;
}
bb.putInt(fileNameBytes.length/2);
bb.put(fileNameBytes);
bb.putInt(filePathBytes.length/2);
- bb.put(filePathBytes);
+ bb.put(filePathBytes);
return footerBytes;
}
-
+
/**
* creates the appropriate ContentImpl for the given blob.
*/
- private static ContentImpl parseContent(OleBlobImpl blob)
- throws IOException
+ private static ContentImpl parseContent(OleBlobImpl blob)
+ throws IOException
{
ByteBuffer bb = PageChannel.wrap(blob.getBytes());
- if((bb.remaining() < 2) || (bb.getShort() != PACKAGE_SIGNATURE)) {
+ if((bb.remaining() < 2) || (bb.getShort() != PACKAGE_SIGNATURE)) {
return new UnknownContentImpl(blob);
}
int prettyNameLen = bb.getShort();
int classNameLen = bb.getShort();
int prettyNameOff = bb.getShort();
- int classNameOff = bb.getShort();
+ int classNameOff = bb.getShort();
/* int objSize = */ bb.getInt();
String prettyName = readStr(bb, prettyNameOff, prettyNameLen);
String className = readStr(bb, classNameOff, classNameLen);
return COMPOUND_FACTORY.createCompoundPackageContent(
blob, prettyName, className, typeName, bb, dataBlockLen);
}
-
+
// this is either some other "special" (as yet unhandled) format, or it is
// simply an embedded file (or it is compound data and poi isn't available)
return new OtherContentImpl(blob, prettyName, className,
ByteBuffer blobBb, int dataBlockLen) {
int dataBlockPos = blobBb.position();
- ByteBuffer bb = PageChannel.narrowBuffer(blobBb, dataBlockPos,
+ ByteBuffer bb = PageChannel.narrowBuffer(blobBb, dataBlockPos,
dataBlockPos + dataBlockLen);
-
+
int packageSig = bb.getShort();
if(packageSig != PACKAGE_STREAM_SIGNATURE) {
return new OtherContentImpl(blob, prettyName, className,
return new SimplePackageContentImpl(
blob, prettyName, className, typeName, dataPos, dataLen,
fileName, filePath, localFilePath);
- }
+ }
if(packageType == PS_LINKED_FILE) {
-
+
bb.getShort(); //unknown
String linkStr = readZeroTermStr(bb);
- return new LinkContentImpl(blob, prettyName, className, typeName,
+ return new LinkContentImpl(blob, prettyName, className, typeName,
fileName, linkStr, filePath);
}
return new OtherContentImpl(blob, prettyName, className,
- typeName, dataBlockPos, dataBlockLen);
+ typeName, dataBlockPos, dataBlockLen);
}
private static String readStr(ByteBuffer bb, int off, int len) {
return readStr(bb, off, len);
}
- private static String readStr(ByteBuffer bb, int off, int len,
+ private static String readStr(ByteBuffer bb, int off, int len,
Charset charset) {
String str = new String(bb.array(), off, len, charset);
bb.position(off + len);
}
@Override
- public InputStream getBinaryStream(long pos, long len)
- throws SQLException
+ public InputStream getBinaryStream(long pos, long len)
+ throws SQLException
{
return new ByteArrayInputStream(_bytes, fromJdbcOffset(pos), (int)len);
}
@Override
public long position(byte[] pattern, long start) throws SQLException {
- int pos = ByteUtil.findRange(PageChannel.wrap(_bytes),
+ int pos = ByteUtil.findRange(PageChannel.wrap(_bytes),
fromJdbcOffset(start), pattern);
return((pos >= 0) ? toJdbcOffset(pos) : pos);
}
-
+
@Override
public long position(Blob pattern, long start) throws SQLException {
return position(pattern.getBytes(1L, (int)pattern.length()), start);
public OutputStream setBinaryStream(long position) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
-
+
@Override
public void truncate(long len) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
-
+
@Override
public int setBytes(long pos, byte[] bytes) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
-
+
@Override
public int setBytes(long pos, byte[] bytes, int offset, int lesn)
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
-
+
@Override
public void free() {
close();
private static int toJdbcOffset(int off) {
return off + 1;
- }
+ }
private static int fromJdbcOffset(long off) {
return (int)off - 1;
- }
+ }
@Override
public String toString() {
protected byte[] getBytes() throws IOException {
return getBlob().getBytes();
}
-
+
@Override
public void close() {
// base does nothing
protected ToStringBuilder toString(ToStringBuilder sb) {
sb.append("type", getType());
return sb;
- }
+ }
}
static abstract class EmbeddedContentImpl extends ContentImpl
private final int _position;
private final int _length;
- protected EmbeddedContentImpl(OleBlobImpl blob, int position, int length)
+ protected EmbeddedContentImpl(OleBlobImpl blob, int position, int length)
{
super(blob);
_position = position;
sb.append("content", ByteBuffer.wrap(_blob._bytes, _position, _length));
}
return sb;
- }
+ }
}
- static abstract class EmbeddedPackageContentImpl
+ static abstract class EmbeddedPackageContentImpl
extends EmbeddedContentImpl
implements PackageContent
{
.append("typeName", _typeName);
super.toString(sb);
return sb;
- }
+ }
}
- private static final class LinkContentImpl
+ private static final class LinkContentImpl
extends EmbeddedPackageContentImpl
implements LinkContent
{
private LinkContentImpl(OleBlobImpl blob, String prettyName,
String className, String typeName,
- String fileName, String linkPath,
- String filePath)
+ String fileName, String linkPath,
+ String filePath)
{
super(blob, prettyName, className, typeName, -1, -1);
_fileName = fileName;
_linkPath = linkPath;
- _filePath = filePath;
+ _filePath = filePath;
}
@Override
}
}
- private static final class SimplePackageContentImpl
+ private static final class SimplePackageContentImpl
extends EmbeddedPackageContentImpl
implements SimplePackageContent
{
String className, String typeName,
int position, int length,
String fileName, String filePath,
- String localFilePath)
+ String localFilePath)
{
super(blob, prettyName, className, typeName, position, length);
_fileName = fileName;
- _filePath = filePath;
+ _filePath = filePath;
_localFilePath = localFilePath;
}
}
}
- private static final class OtherContentImpl
+ private static final class OtherContentImpl
extends EmbeddedPackageContentImpl
implements OtherContent
{
private OtherContentImpl(
OleBlobImpl blob, String prettyName, String className,
- String typeName, int position, int length)
+ String typeName, int position, int length)
{
super(blob, prettyName, className, typeName, position, length);
- }
+ }
@Override
public ContentType getType() {
.toString();
}
}
-
+
}