/**
* Since i have to declare the return type of a function, and i have no idea
* ahead of time what value is being unserialized, this helper class is a hack
* so that i can return any variable type as PHPValue and deal with it later.
*
* @author Scott Hurring [scott at hurring dot com]
* @version v0.01a ALPHA!!
* @licence GNU GPL
*/
public class PHPValue {
/**
* The raw object given to us by unserialize()
*/
private Object obj = null;
private HashMap hobj = new HashMap();
/**
* The toString() value of the Object passed into PHPValue
*/
public String value = "";
/**
* Is the PHPValue one of the following?
*/
public boolean isNull = false;
public boolean isInteger = false;
public boolean isDouble = false;
public boolean isString = false;
public boolean isHashMap = false;
/**
* Pass in an object, and PHPValue: 1. Attempts to try and figure out what
* it is 2. Stringifies it 3. Sets a boolean flag to let everyone know what
* we think it is.
*
*/
public PHPValue(Object o) {
obj = o;
if (obj == null) {
isNull = true;
value = "";
} else if (obj.getClass().toString().equals("class java.lang.Integer")) {
isInteger = true;
value = ((Integer) obj).toString();
} else if (obj.getClass().toString().equals("class java.lang.Double")) {
isDouble = true;
value = ((Double) obj).toString();
} else if (obj.getClass().toString().equals("class java.util.HashMap")) {
isHashMap = true;
value = obj.toString();
} else if (obj.getClass().toString().equals("class java.lang.String")) {
isString = true;
value = obj.toString();
} else {
value = obj.toString();
}
// debug
if (obj != null) {
//System.out.println("PHPValue: '" + obj.getClass() + "' = " + value);
}
}
/**
* Convert PHPValue into a double
*
* @return double
*/
public double toDouble() {
if (isDouble) {
return Double.parseDouble(value);
} else {
return 0.0;
}
}
/**
* Convert PHPValue into an integer
*
* @return int
*/
public int toInteger() {
if (isInteger) {
return Integer.parseInt(value);
} else {
return 0;
}
}
/**
* PHPValue's string-ified value
*
* @return String
*/
public String toString() {
if (!isNull) {
return value;
} else {
return "";
}
}
/**
* Cast PHPValue into HashMap
*
* @return HashMap
*/
public HashMap toHashMap() {
return (HashMap) obj;
}
/**
* Return the raw object
*
* @return double
*/
public Object toObject() {
return obj;
}
}
import java.util.regex.*;
import java.util.*;
public class PHPSerialize {
/**
* To store partially decomposed serialized string
*/
private StringBuffer sb;
/** Creates a new instance of phpserialize */
public PHPSerialize() {
}
/**
* Unserializes a single value into a PHPValue
* @param String
* s String to unserialize
* @return PHPValue
*/
public PHPValue unserialize(String s) {
sb = new StringBuffer(s);
PHPValue phpvalue = getNext();
//println("value = " + phpvalue.toString());
return phpvalue;
}
/**
* Get the next token in the serialized string
*
*
*/
private PHPValue getNext() {
// println("getNext = "+ sb.toString());
PHPValue phpvalue;
Object value = new Object();
// Current character
String c;
// What type of value is this
String what = "";
// Consume & throw away characters
int consumeChars = 0;
// Length of the string/array
int len = -1;
// Buffer to read in string
StringBuffer tmp = new StringBuffer();
// length of sb is constantly changing.
while (sb.length() > 0) {
c = sb.substring(0, 1);
sb = sb.deleteCharAt(0);
// println(c +"\twhat="+what+"\ttmp="+tmp.toString());
// Ignore chars
if (consumeChars-- > 0) {
continue;
}
/**
* This is a hackish pseudo state machine 'what' is the state
*
*/
if (what.equals("array_length")) {
if (c.equals(":")) {
len = Integer.parseInt(tmp.toString());
tmp.delete(0, tmp.length());
// println("\tarray_length="+ len);
what = "array_value";
}
if (len == -1) {
tmp.append(c);
}
} else if (what.equals("array_value")) {
// value = new PHPValue( new HashMap() );
HashMap hash = new HashMap();
for (int i = 0; i < len; i++) {
PHPValue hashKey = getNext();
PHPValue hashValue = getNext();
// Force the keys of the HashMap to be type String
hash.put(hashKey.value, hashValue);
}
value = hash;
// return new PHPValue(value);
what = "set";
} else if (what.equals("string_length")) {
if (c.equals(":")) {
len = Integer.parseInt(tmp.toString());
tmp.delete(0, tmp.length());
// println("\tstring_length="+ len);
what = "string_value";
consumeChars = 1;
}
if (len == -1) {
tmp.append(c);
}
} else if (what.equals("string_value")) {
if (len-- > 0) {
tmp.append(c);
} else {
value = tmp.toString();
what = "set";
// println("\tstring_value="+ value);
}
}
else if (what.equals("integer")) {
if (c.equals(";")) {
value = tmp.toString();
what = "set";
} else {
tmp.append(c);
}
} else if (what.equals("double")) {
if (c.equals(";")) {
value = tmp.toString();
what = "set";
} else {
tmp.append(c);
}
} else if (what.equals("null")) {
if (c.equals(";")) {
value = null;
what = "set";
} else {
// Bad
}
}
// What kind of variable is coming up next
else {
if (c.equals("a")) {
what = "array_length";
} else if (c.equals("s")) {
what = "string_length";
} else if (c.equals("i")) {
what = "integer";
} else if (c.equals("d")) {
what = "double";
} else if (c.equals("n")) {
what = "null";
// do NOT consume the next char ";"
continue;
} else {
continue;
}
// Consume the ":" after variable type declaration
consumeChars = 1;
continue;
}
if (what.equals("set")) {
return new PHPValue(value);
}
}
return new PHPValue(value);
}
/********************************************************************/
public static void main(String args[]) {
//test();
String php = "a:1:{s:3:\"tel\";s:0:\"\";}";
//String php = "a:2:{s:11:\"peopleprice\";s:3:\"120\";s:10:\"childprice\";s:2:\"60\";}";
//String php = "a:2:{s:11:\"peopleprice\";s:3:\"300\";s:10:\"childprice\";s:3:\"100\";}";
//String php ="a:1:{s:3:\"tel\";s:12:\"0717-0351212\";}";
PHPSerialize p = new PHPSerialize();
PHPValue c = p.unserialize(php);
System.out.println(c.toHashMap().toString());
}
}