/* * Copyright 2006-2012 ICEsoft Technologies Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.icepdf.core.util; import org.icepdf.core.io.SeekableByteArrayInputStream; import org.icepdf.core.io.SeekableInput; import java.io.*; import java.lang.reflect.Method; import java.util.logging.Logger; import java.util.logging.Level; /** * @author Mark Collette * Date: 18-Feb-2005 * Time: 3:53:40 PM */ public class Utils { private static final Logger logger = Logger.getLogger(Utils.class.toString()); /** * Sets the value into the buffer, at the designated offset, using big-endian rules * Callers is responsible to ensure that value will fit into buffer, starting at offset * * @param value to be set into buffer * @param buffer into which value is to be set * @param offset into buffer which value is to be set */ public static void setIntIntoByteArrayBE(int value, byte[] buffer, int offset) { buffer[offset + 0] = (byte) ((value >>> 24) & 0xff); buffer[offset + 1] = (byte) ((value >>> 16) & 0xff); buffer[offset + 2] = (byte) ((value >>> 8) & 0xff); buffer[offset + 3] = (byte) ((value >>> 0) & 0xff); } /** * Sets the value into the buffer, at the designated offset, using big-endian rules * Callers is responsible to ensure that value will fit into buffer, starting at offset * * @param value to be set into buffer * @param buffer into which value is to be set * @param offset into buffer which value is to be set */ public static void setShortIntoByteArrayBE(short value, byte[] buffer, int offset) { buffer[offset + 0] = (byte) ((value >>> 8) & 0xff); buffer[offset + 1] = (byte) ((value >>> 0) & 0xff); } /** * @param in InputStream to read from * @param numBytes number of bytes to read to make integral value from [0, 8] * @return Integral value, which is composed of numBytes bytes, read using big-endian rules from in * @throws IOException */ public static long readLongWithVaryingBytesBE(InputStream in, int numBytes) throws IOException { //System.out.println("Utils.readLongWithVaryingBytesBE() numBytes: " + numBytes); long val = 0; for (int i = 0; i < numBytes; i++) { int curr = in.read(); if (curr < 0) throw new EOFException(); val <<= 8; val |= (((long) curr) & ((long) 0xFF)); } return val; } /** * @param in InputStream to read from * @param numBytes number of bytes to read to make integral value from [0, 4] * @return Integral value, which is composed of numBytes bytes, read using big-endian rules from in * @throws IOException */ public static int readIntWithVaryingBytesBE(InputStream in, int numBytes) throws IOException { //System.out.println("Utils.readIntWithVaryingBytesBE() numBytes: " + numBytes); int val = 0; for (int i = 0; i < numBytes; i++) { int curr = in.read(); if (curr < 0) throw new EOFException(); val <<= 8; val |= (curr & 0xFF); } return val; } public static String convertByteArrayToHexString(byte[] buffer, boolean addSpaceSeparator) { return convertByteArrayToHexString( buffer, 0, buffer.length, addSpaceSeparator, -1, (char) 0); } public static String convertByteArrayToHexString(byte[] buffer, boolean addSpaceSeparator, int addDelimiterEverNBytes, char delimiter) { return convertByteArrayToHexString( buffer, 0, buffer.length, addSpaceSeparator, addDelimiterEverNBytes, delimiter); } public static String convertByteArrayToHexString( byte[] buffer, int offset, int length, boolean addSpaceSeparator, int addDelimiterEverNBytes, char delimiter) { int presize = length * (addSpaceSeparator ? 3 : 2); if (addDelimiterEverNBytes > 0) presize += (length / addDelimiterEverNBytes); StringBuilder sb = new StringBuilder(presize); int delimiterCount = 0; int end = offset + length; for (int index = offset; index < end; index++) { int currValue = 0; currValue |= (0xff & ((int) buffer[index])); String s = Integer.toHexString(currValue); for (int i = s.length(); i < 2; i++) sb.append('0'); sb.append(s); if (addSpaceSeparator) sb.append(' '); delimiterCount++; if (addDelimiterEverNBytes > 0 && delimiterCount == addDelimiterEverNBytes) { delimiterCount = 0; sb.append(delimiter); } } return sb.toString(); } /** * boolean java.awt.GraphicsEnvironment.isHeadless() does not exist in Java 1.3, * since it was introduced in Java 1.4, so we use reflection to call it, * if it exists. * In the event of not being able to call graphicsEnvironment.isHeadless(), * instead of throwing an Exception, we simply return defaultReturnIfNoMethod * * @param graphicsEnvironment java.awt.GraphicsEnvironment to call isHeadless() on * @param defaultReturnIfNoMethod Value to return if could not call graphicsEnvironment.isHeadless() */ public static boolean reflectGraphicsEnvironmentISHeadlessInstance(Object graphicsEnvironment, boolean defaultReturnIfNoMethod) { try { Class clazz = graphicsEnvironment.getClass(); Method isHeadlessInstanceMethod = clazz.getMethod("isHeadlessInstance", new Class[]{}); if (isHeadlessInstanceMethod != null) { Object ret = isHeadlessInstanceMethod.invoke( graphicsEnvironment, new Object[]{}); if (ret instanceof Boolean) return ((Boolean) ret).booleanValue(); } } catch (Throwable t) { logger.log(Level.FINE, "ImageCache: Java 1.4 Headless support not found."); } return defaultReturnIfNoMethod; } public static String getContentAndReplaceInputStream(InputStream[] inArray, boolean convertToHex) { String content = null; try { ByteArrayOutputStream out = new ByteArrayOutputStream(1024); InputStream in = inArray[0]; byte[] buf = new byte[1024]; while (true) { int read = in.read(buf, 0, buf.length); if (read < 0) break; out.write(buf, 0, read); } // while( true ) { // int read = in.read(); // if( read < 0 ) // break; // out.write( read ); // } if (!(in instanceof SeekableInput)) in.close(); out.flush(); out.close(); byte[] data = out.toByteArray(); out = null; inArray[0] = new ByteArrayInputStream(data); if (convertToHex) content = Utils.convertByteArrayToHexString(data, true); else content = new String(data); } catch (IOException ioe) { logger.log(Level.FINE, "Problem getting debug string"); } catch (Throwable e) { logger.log(Level.FINE, "Problem getting content stream, skipping"); } return content; } public static String getContentFromSeekableInput(SeekableInput in, boolean convertToHex) { String content = null; try { in.beginThreadAccess(); long position = in.getAbsolutePosition(); ByteArrayOutputStream out = new ByteArrayOutputStream(); /* byte[] buf = new byte[1024]; while( true ) { int read = in.read( buf, 0, buf.length ); if( read < 0 ) break; out.write( buf, 0, read ); } */ while (true) { int read = in.getInputStream().read(); if (read < 0) break; out.write(read); } in.seekAbsolute(position); out.flush(); out.close(); byte[] data = out.toByteArray(); if (convertToHex) content = Utils.convertByteArrayToHexString(data, true); else content = new String(data); } catch (IOException ioe) { logger.log(Level.FINE, "Problem getting debug string"); } finally { in.endThreadAccess(); } return content; } public static SeekableInput replaceInputStreamWithSeekableInput(InputStream in) { if (in instanceof SeekableInput) return (SeekableInput) in; SeekableInput sin = null; try { ByteArrayOutputStream out = new ByteArrayOutputStream(1024); /* byte[] buf = new byte[1024]; while( true ) { int read = in.read( buf, 0, buf.length ); if( read < 0 ) break; out.write( buf, 0, read ); } */ while (true) { int read = in.read(); if (read < 0) break; out.write(read); } in.close(); out.flush(); out.close(); byte[] data = out.toByteArray(); sin = new SeekableByteArrayInputStream(data); } catch (IOException ioe) { logger.log(Level.FINE, "Problem getting debug string"); } return sin; } public static void printMemory(String str) { long total = Runtime.getRuntime().totalMemory(); long free = Runtime.getRuntime().freeMemory(); long used = total - free; System.out.println("MEM " + str + " used: " + (used / 1024) + " KB delta: " + ((used - lastMemUsed) / 1024) + " KB"); lastMemUsed = used; } private static long lastMemUsed = 0; public static int numBytesToHoldBits(int numBits) { int numBytes = (numBits / 8); if ((numBits % 8) > 0) numBytes++; return numBytes; } /** * When converting between String chars and bytes, there's an implied * encoding to be used, dependent on the context and platform. If * none is specified, then String(byte[]) will use the platform's * default encoding. This method is for when encoding is not relevant, * when the String simply holds byte values in each char. * * @see org.icepdf.core.pobjects.LiteralStringObject * @see org.icepdf.core.pobjects.HexStringObject * @see org.icepdf.core.pobjects.security.StandardEncryption */ public static byte[] convertByteCharSequenceToByteArray(CharSequence string) { final int max = string.length(); byte[] bytes = new byte[max]; for (int i = 0; i < max; i++) { bytes[i] = (byte) string.charAt(i); } return bytes; } /** * When converting between String chars and bytes, there's an implied * encoding to be used, dependent on the context and platform. If * none is specified, then String(byte[]) will use the platform's * default encoding. This method is for when encoding is not relevant, * when the String simply holds byte values in each char. * * @see org.icepdf.core.pobjects.LiteralStringObject * @see org.icepdf.core.pobjects.HexStringObject * @see org.icepdf.core.pobjects.security.StandardEncryption */ public static String convertByteArrayToByteString(byte[] bytes) { final int max = bytes.length; StringBuilder sb = new StringBuilder(max); for (int i = 0; i < max; i++) { int b = ((int) bytes[i]) & 0xFF; sb.append((char)b); } return sb.toString(); } }