package php.runtime.memory.output; import php.runtime.Memory; import php.runtime.common.StringUtils; import php.runtime.env.Environment; import php.runtime.lang.Closure; import php.runtime.lang.ForeachIterator; import php.runtime.memory.*; import php.runtime.reflection.ClassEntity; import java.io.Writer; import java.util.Set; public class VarExport extends Printer { private final static int PRINT_INDENT = 2; public VarExport(Environment env, Writer writer) { super(env, writer); } @Override protected void printNull() { printer.append("NULL"); } @Override protected void printFalse() { printer.append("false"); } @Override protected void printTrue() { printer.append("true"); } @Override protected void printLong(LongMemory value) { printer.print(value.toLong() + ""); } @Override protected void printDouble(DoubleMemory value) { printer.print(value.toDouble() + ""); } @Override protected void printString(StringMemory value) { String v = value.toString(); int length = v.length(); printer.append('\''); for(int i = 0; i < length; i++){ char ch = v.charAt(i); if (ch == '\'') printer.append("\\'"); else if (ch == '\0'){ printer.append("' . \"\\0\" . '"); } else printer.append(ch); } printer.append('\''); } @Override protected void printArray(ArrayMemory value, int level, Set<Integer> used) { printArray(value, level, used, false); } protected void printArray(ArrayMemory value, int level, Set<Integer> used, boolean stripNulls) { if (!used.add(value.getPointer())){ recursionExists = true; printNull(); } else { printer.write(StringUtils.repeat(' ', level * PRINT_INDENT)); printer.write("array (\n"); ForeachIterator iterator = value.foreachIterator(false, false); level += 1; while (iterator.next()){ Memory el = iterator.getValue(); if (el == Memory.UNDEFINED) continue; printer.write(StringUtils.repeat(' ', level * PRINT_INDENT)); Memory key = iterator.getMemoryKey(); if (key.isString()){ String k = key.toString(); if (stripNulls){ int pos = k.lastIndexOf('\0'); if (pos > -1) k = k.substring(pos + 1); } printString(new StringMemory(k)); } else { printer.write(key.toString()); } printer.write(" =>"); if (el.isArray()) { if (!used.contains(el.getPointer())) printer.write("\n"); else printer.write(" "); print(el, level, used); } else { printer.write(" "); print(el, level + 1, used); } printer.append(",\n"); } level -= 1; printer.write(StringUtils.repeat(' ', level * PRINT_INDENT)); printer.append(")"); used.remove(value.getPointer()); } } @Override protected void printObject(ObjectMemory value, int level, Set<Integer> used) { if (used.contains(value.getPointer())){ recursionExists = true; printNull(); } else { used.add(value.getPointer()); ClassEntity entity = value.getReflection(); printer.write(entity.getName()); printer.write("::"); printer.write("__set_state("); printArray(value.value.getProperties(), 0, used, true); printer.write(")"); used.remove(value.getPointer()); } } @Override protected void printClosure(Closure value, int level, Set<Integer> used) { printObject(new ObjectMemory(value), level, used); } }