use of php.runtime.lang.spl.Serializable in project jphp by jphp-compiler.
the class Deserializer method read.
public Memory read(String input, int offset) {
int length = input.length();
if (offset >= length) {
error(offset, length);
return Memory.NULL;
}
for (int i = offset; i < length; i++) {
char ch = input.charAt(i);
Memory.Type type = null;
switch(ch) {
case 'N':
i++;
if (i < length && input.charAt(i) == ';') {
this.pos = i + 1;
return Memory.NULL;
} else
return error(i, length);
case 'i':
type = Memory.Type.INT;
case 'd':
if (type == null)
type = Memory.Type.DOUBLE;
case 'b':
if (type == null)
type = Memory.Type.BOOL;
case 's':
if (type == null)
type = Memory.Type.STRING;
case 'a':
if (type == null)
type = Memory.Type.ARRAY;
case 'C':
case 'O':
if (type == null)
type = Memory.Type.OBJECT;
boolean isSerializable = ch == 'C';
i++;
ch = input.charAt(i);
if (ch != ':') {
error(i, length);
return Memory.NULL;
}
i++;
switch(type) {
case INT:
case DOUBLE:
case BOOL:
boolean done = false;
int j;
for (j = i; j < length; j++) {
ch = input.charAt(j);
if (ch == ';') {
done = true;
break;
}
}
if (!done) {
error(i, length);
return Memory.NULL;
}
String what = input.substring(i, j);
this.pos = i = j + 1;
switch(type) {
case BOOL:
if ("1".equals(what))
return Memory.TRUE;
else if ("0".equals(what))
return Memory.FALSE;
else {
error(i + 1, length);
return Memory.NULL;
}
case INT:
try {
return LongMemory.valueOf(Long.parseLong(what));
} catch (NumberFormatException e) {
error(i + 1, length);
return Memory.NULL;
}
case DOUBLE:
try {
return DoubleMemory.valueOf(Double.valueOf(what));
} catch (NumberFormatException e) {
error(i + 1, length);
return Memory.NULL;
}
}
break;
case STRING:
return readString(input, i, ';');
case ARRAY:
return readArray(input, i);
case OBJECT:
Memory memory = readString(input, i, ':');
if (this.pos == -1) {
return Memory.NULL;
}
if (!memory.isString()) {
error(i, length);
return Memory.NULL;
}
i = this.pos;
ClassEntity classEntity = env.fetchClass(memory.toString(), true);
if (classEntity == null) {
env.error(trace, ErrorType.E_ERROR, Messages.ERR_CLASS_NOT_FOUND, memory.toString());
return Memory.NULL;
}
try {
IObject iObject = classEntity.newObjectWithoutConstruct(env);
if (iObject == null) {
env.exception(trace, new Messages.Item("Unserialization of '%s' is not allowed").fetch(classEntity.getName()));
}
if (isSerializable) {
if (!(iObject instanceof Serializable)) {
env.warning(trace, "Class %s has no unserializer", classEntity.getName());
return Memory.NULL;
} else {
int size = readSize(input, i);
if (size == -1)
return error(i, length);
i = this.pos + 1;
what = input.substring(i + 1, i + size + 1);
if (i >= length || input.charAt(i) != '{')
return error(i, length);
i += size;
i++;
if (i >= length || input.charAt(i) != '}')
return error(i, length);
iObject.callMethod(env, "unserialize", new StringMemory(what));
}
} else {
ArrayMemory props = iObject.getPropertiesForChange();
Memory serProps = readArray(input, i);
if (serProps.isArray()) {
props.clear();
props.putAll(serProps.toValue(ArrayMemory.class));
if (classEntity.methodMagicWakeup != null) {
env.pushCall(trace, iObject, classEntity.methodMagicWakeup.getName());
try {
classEntity.methodMagicWakeup.invokeDynamic(iObject, env, trace);
} finally {
env.popCall();
}
}
} else
return Memory.NULL;
}
return new ObjectMemory(iObject);
} catch (RuntimeException e) {
throw e;
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
break;
default:
error(i, length);
return Memory.NULL;
}
}
return Memory.NULL;
}
use of php.runtime.lang.spl.Serializable in project jphp by jphp-compiler.
the class Serializer method writeObject.
public void writeObject(ObjectMemory memory, Set<Integer> used) {
if (used.add(memory.getPointer())) {
IObject object = memory.value;
ClassEntity reflection = object.getReflection();
if (object instanceof Serializable) {
Memory result;
result = object.callMethod(env, "serialize");
if (result.isNull()) {
writeNull();
return;
}
if (result.isString()) {
String value = result.toString();
printer.append("C:").append(reflection.getName().length()).append(":\"").append(reflection.getName()).append("\":").append(value.length()).append(":{").append(value).append("}");
return;
} else {
env.exception(trace, reflection.getName() + "::serialize() must return a string or NULL");
}
}
ArrayMemory only = null;
if (reflection.methodMagicSleep != null) {
env.pushCall(trace, object, reflection.methodMagicSleep.getName());
try {
Memory result = reflection.methodMagicSleep.invokeDynamic(object, env, trace);
if (!result.isArray()) {
env.error(ErrorType.E_NOTICE, "serialize(): __sleep() should return an array only containing the names of instance-variables to serialize");
writeNull();
return;
} else {
ForeachIterator iterator = result.getNewIterator(env, false, false);
only = new ArrayMemory(true);
ArrayMemory props = memory.getPropertiesForChange();
Set<String> need = new LinkedHashSet<String>();
while (iterator.next()) {
if (iterator.getValue().isNumber())
continue;
need.add(iterator.getValue().toString());
}
for (PropertyEntity e : reflection.getProperties()) {
if (need.contains(e.getName())) {
props.refOfIndex(e.getSpecificName());
} else {
props.removeByScalar(e.getSpecificName());
}
}
iterator = result.getNewIterator(env, false, false);
while (iterator.next()) {
Memory value = iterator.getValue().toValue();
PropertyEntity entity = reflection.findProperty(value.toString());
value = entity == null ? props.valueOfIndex(value).toValue() : props.valueOfIndex(entity.getSpecificName()).toValue();
if (value == Memory.UNDEFINED) {
env.error(trace, ErrorType.E_NOTICE, "serialize(): \"%s\" returned as member variable from __sleep() but does not exist", iterator.getValue().toString());
}
if (entity != null)
only.put(entity.getSpecificName(), value);
else
only.refOfIndex(iterator.getValue()).assign(value);
}
}
} catch (RuntimeException e) {
throw e;
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
} finally {
env.popCall();
}
}
printer.append("O:");
printer.append(String.valueOf(reflection.getName().length()));
printer.append(":\"");
printer.append(reflection.getName());
printer.append("\":");
if (reflection.getProperties() == null)
writeArray(new ArrayMemory(), used, false);
else
writeArray(only == null ? object.getProperties() : only, used, false);
} else
writeNull();
}
Aggregations