/*
This file is part of leafdigital picstory.
picstory is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
picstory is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with picstory. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Samuel Marshall.
*/
package com.leafdigital.picstory;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
/**
* Utility methods.
*/
public abstract class Util
{
private final static int BUFFERSIZE=65536;
/**
* Loads all the bytes from an inputstream, then closes it.
* @param is Stream
* @return Bytes
* @throws IOException
*/
public static byte[] loadBytes(InputStream is) throws IOException
{
byte[] buffer=new byte[BUFFERSIZE];
int pos=0;
while(true)
{
// Read data
int read=is.read(buffer,pos,buffer.length-pos);
// Check EOF
if(read==-1)
{
byte[] trimmed=new byte[pos];
System.arraycopy(buffer,0,trimmed,0,pos);
is.close();
return trimmed;
}
// Advance position in buffer
pos+=read;
// Enlarge buffer if needed
if(pos==buffer.length)
{
byte[] newBuffer=new byte[buffer.length*2];
System.arraycopy(buffer,0,newBuffer,0,buffer.length);
buffer=newBuffer;
}
}
}
/**
* Loads a UTF-8 string from an input stream, then closes it.
* @param is Stream to read
* @return String
* @throws IOException Any I/O error
*/
public static String loadString(InputStream is) throws IOException
{
return new String(loadBytes(is),"UTF-8");
}
/**
* Escapes special characters in a string (angle brackets, ampersands, both
* types of quote) so that it can be included in the text of an XML element
* or in an attribute.
* <p>
* Note that any control characters in the string will turn into
* <controlchar num='3'> as these cannot be represented in XML.
* @param s String to escape
* @return XML-escaped version of string
*/
public static String esc(String s)
{
StringBuffer sb=new StringBuffer();
for(int i=0;i<s.length();i++)
{
char c=s.charAt(i);
if(c<32 && c!=9 && c!=10 && c!=13)
{
sb.append("<controlchar num='" + (int)c + "'/>");
continue;
}
switch(c)
{
case '<' : sb.append("<"); break;
case '&' : sb.append("&"); break;
case '\'': sb.append("'"); break;
case '"' : sb.append("""); break;
default: sb.append(c); break;
}
}
return sb.toString();
}
/**
* @param string String to hash
* @return SHA-1 hash of strung
* @throws NoSuchAlgorithmException If Java is missing the SHA-1 provider
*/
public static String hash(String string) throws NoSuchAlgorithmException
{
// Get bytes
byte[] hashDataBytes;
try
{
hashDataBytes = string.getBytes("UTF-8");
}
catch(UnsupportedEncodingException e)
{
throw new Error("No UTF-8 support?!", e);
}
return hash(hashDataBytes);
}
/**
* @param hashDataBytes Data to hash
* @return SHA-1 hash of strung
* @throws NoSuchAlgorithmException If Java is missing the SHA-1 provider
*/
public static String hash(byte[] hashDataBytes) throws NoSuchAlgorithmException
{
// Hash data and return 40-character string
MessageDigest m;
m = MessageDigest.getInstance("SHA-1");
m.update(hashDataBytes, 0, hashDataBytes.length);
String sha1 = new BigInteger(1, m.digest()).toString(16);
while(sha1.length() < 40)
{
sha1 = "0" + sha1;
}
return sha1;
}
}