package php.runtime.loader.dump.io;
import php.runtime.Memory;
import php.runtime.common.HintType;
import php.runtime.common.LangMode;
import php.runtime.common.Modifier;
import php.runtime.env.Context;
import php.runtime.env.TraceInfo;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.DoubleMemory;
import php.runtime.memory.LongMemory;
import php.runtime.memory.StringMemory;
import php.runtime.memory.helper.ClassConstantMemory;
import php.runtime.memory.helper.ConstantMemory;
import php.runtime.reflection.ClassEntity;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
public class DumpInputStream extends DataInputStream {
public DumpInputStream(InputStream in) {
super(in);
}
public String readName(int max) throws IOException {
int nameLength = readInt();
if (nameLength == -1)
return null;
if (nameLength == 0)
return "";
if (nameLength > max || nameLength < 1){
throw new DumpException("Invalid name size, max " + max);
} else {
return readUTF();
}
}
public String readName() throws IOException {
return readName(2048);
}
public TraceInfo readTrace(Context context) throws IOException {
boolean exits = readBoolean();
if (exits){
int line = readInt();
int position = readInt();
String file = readUTF();
return new TraceInfo(file, line, position);
} else {
return new TraceInfo(context);
}
}
public Modifier readModifier() throws IOException {
int tmp = readInt();
if (tmp == -1) return null;
if (tmp >= 0 && tmp < Modifier.values().length) {
return Modifier.values()[tmp];
} else
throw new DumpException("Invalid ~Modifier value");
}
public HintType readHintType() throws IOException {
int tmp = readInt();
if (tmp == -1) return null;
if (tmp >= 0 && tmp < HintType.values().length)
return HintType.values()[tmp];
else
throw new DumpException("Invalid ~HintType value");
}
public ClassEntity.Type readClassType() throws IOException {
int tmp = readInt();
if (tmp == -1) return null;
if (tmp >= 0 && tmp < ClassEntity.Type.values().length)
return ClassEntity.Type.values()[tmp];
else
throw new DumpException("Invalid ~ClassEntity.Type value");
}
public LangMode readLangMode() throws IOException {
int tmp = readInt();
if (tmp == -1) return null;
if (tmp >= 0 && tmp < LangMode.values().length)
return LangMode.values()[tmp];
else
throw new DumpException("Invalid ~LangMode value");
}
public Memory readMemory() throws IOException {
int tmp = readInt();
if (tmp == -1)
return null;
if (tmp == -2)
return new ConstantMemory(readUTF());
if (tmp == -3)
return new ClassConstantMemory(readUTF(), readUTF());
if (tmp >= 0 && tmp < Memory.Type.values().length){
Memory.Type type = Memory.Type.values()[tmp];
switch (type){
case BOOL:
return readBoolean() ? Memory.TRUE : Memory.FALSE;
case INT:
return LongMemory.valueOf(readLong());
case DOUBLE:
return DoubleMemory.valueOf(readDouble());
case NULL:
return Memory.NULL;
case STRING:
return StringMemory.valueOf(readUTF());
case ARRAY:
ArrayMemory array = new ArrayMemory();
int size = readInt();
if (size < 0 || size > Short.MAX_VALUE)
throw new DumpException("Invalid array memory size");
for(int i = 0; i < size; i++){
Memory key = readMemory();
Memory value = readMemory();
array.refOfIndex(key).assign(value);
}
return array;
case OBJECT:
default:
throw new DumpException("Cannot read " + type.toString() + " memory");
}
} else
throw new DumpException("Invalid ~Memory.Type value");
}
public byte[] readRawData(int max) throws IOException {
int length = readInt();
if (length == 0)
return new byte[0];
else if (length < 0)
throw new DumpException("Invalid raw-data size");
else {
if (length > max){
throw new DumpException(
"Invalid raw-data size, max " + max + " bytes");
} else {
byte[] raw = new byte[length];
readFully(raw);
/*if (read != length)
throw new DumpException("Cannot read raw-data, length = " + length + ", but returns " + read);*/
return raw;
}
}
}
public byte[] readRawData() throws IOException {
return readRawData(DumpOutputStream.MAX_LENGTH_OF_RAW_DATA);
}
}