package php.runtime.ext.core;
import php.runtime.Memory;
import php.runtime.env.Environment;
import php.runtime.env.TraceInfo;
import php.runtime.exceptions.support.ErrorType;
import php.runtime.ext.support.compile.FunctionsContainer;
import php.runtime.invoke.Invoker;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.LongMemory;
import php.runtime.output.OutputBuffer;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
public class OutputFunctions extends FunctionsContainer {
public static Memory print(Environment environment, Memory memory){
environment.echo(memory);
return Memory.CONST_INT_1;
}
public static void flush(Environment env) throws Throwable {
OutputBuffer root = env.getDefaultBuffer();
if (root != null) {
root.flush();
}
}
public static Memory ob_start(Environment env, TraceInfo trace, Memory outputCallback, Memory _chunkSize,
Memory erase){
Invoker invoker;
if (!outputCallback.isNull()){
invoker = expectingCallback(env, trace, 1, outputCallback);
if (invoker == null)
return Memory.FALSE;
invoker.check("ob_start", trace);
}
switch (_chunkSize.getRealType()){
case ARRAY:case STRING:case OBJECT:
env.warning(trace,
"ob_start() expects parameter 2 to be long, "+_chunkSize.getRealType().toString()+" given");
return Memory.NULL;
}
switch (erase.getRealType()){
case ARRAY:case STRING:case OBJECT:
env.warning(trace,
"ob_start() expects parameter 3 to be long, "+erase.getRealType().toString()+" given");
return Memory.NULL;
}
int chunkSize = _chunkSize.toInteger();
if (chunkSize < 0)
chunkSize = 0;
if (chunkSize < 0){
env.warning(trace, "ob_start(): chunk_size must be grater or equal than zero");
return Memory.FALSE;
}
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && buffer.isLock())
env.error(trace, "ob_start(): Cannot use output buffering in output buffering display handlers");
env.pushOutputBuffer(outputCallback, chunkSize, erase.toBoolean());
return Memory.TRUE;
}
public static Memory ob_start(Environment env, TraceInfo trace, Memory outputCallback, Memory chunkSize){
return ob_start(env, trace, outputCallback, chunkSize, Memory.TRUE);
}
public static Memory ob_start(Environment env, TraceInfo trace, Memory outputCallback){
return ob_start(env, trace, outputCallback, Memory.CONST_INT_0, Memory.TRUE);
}
public static Memory ob_start(Environment env, TraceInfo trace){
return ob_start(env, trace, Memory.NULL, Memory.CONST_INT_0, Memory.TRUE);
}
public static boolean ob_clean(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()){
buffer.setTrace(trace);
buffer.clean();
return true;
} else {
env.error(trace, ErrorType.E_NOTICE, "ob_clean(): failed to delete buffer. No buffer to delete");
return false;
}
}
public static boolean ob_end_clean(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()){
buffer.setTrace(trace);
buffer.setStatus(OutputBuffer.HANDLER_FINAL);
buffer.clean();
env.popOutputBuffer();
return true;
} else {
env.error(trace, ErrorType.E_NOTICE, "ob_end_clean(): failed to delete buffer. No buffer to delete");
return false;
}
}
public static boolean ob_end_flush(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()){
buffer.setTrace(trace);
buffer.flush();
env.popOutputBuffer();
return true;
} else {
env.error(trace, ErrorType.E_NOTICE, "ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush");
return false;
}
}
public static Memory ob_get_contents(Environment env, TraceInfo trace) throws UnsupportedEncodingException {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer == null || buffer.isRoot())
return Memory.FALSE;
return buffer.getContents();
}
public static boolean ob_flush(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()) {
buffer.setTrace(trace);
buffer.flush();
return true;
} else {
env.error(trace, ErrorType.E_NOTICE, "ob_flush(): failed to flush buffer. No buffer to flush");
return false;
}
}
public static Memory ob_get_clean(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()){
Memory result = buffer.getContents();
buffer.setTrace(trace);
buffer.clean();
return result;
} else {
//env.error(trace, ErrorType.E_NOTICE, "ob_get_clean(): failed to delete and clean buffer. No buffer to delete or clean");
return Memory.FALSE;
}
}
public static Memory ob_get_flush(Environment env, TraceInfo trace) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null){
if (buffer.isLock()){
env.error(trace, "ob_get_flush(): Cannot use output buffering in output buffering display handlers");
return Memory.FALSE;
}
Memory result = buffer.getContents();
buffer.setTrace(trace);
buffer.flush();
return result;
} else {
env.error(trace, ErrorType.E_NOTICE, "ob_get_flush(): failed to delete and flush buffer. No buffer to delete or flush");
return Memory.FALSE;
}
}
public static Memory ob_get_length(Environment env) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null && !buffer.isRoot()){
return LongMemory.valueOf(buffer.getBufferSize());
} else
return Memory.FALSE;
}
public static Memory ob_get_level(Environment env) throws Throwable {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer != null){
return LongMemory.valueOf(buffer.getLevel());
} else
return Memory.FALSE;
}
public static void ob_implicit_flush(Environment env, TraceInfo trace, Memory value){
OutputBuffer root = env.getDefaultBuffer();
switch (value.getRealType()){
case ARRAY:
case STRING:
case OBJECT:
env.warning(trace,
"ob_implicit_flush() expects parameter 1 to be long, " + value.getRealType().toString() + " given"
);
return;
}
if (root != null)
root.setImplicitFlush(value.toBoolean());
}
public static void ob_implicit_flush(Environment env, TraceInfo trace){
ob_implicit_flush(env, trace, Memory.TRUE);
}
private static ArrayMemory _get_status(OutputBuffer buffer){
ArrayMemory result = new ArrayMemory();
result.refOfIndex("name").assign(buffer.getName());
result.refOfIndex("type").assign(buffer.getInvoker() == null ? 0 : 1);
result.refOfIndex("flags").assign(buffer.getStatus());
result.refOfIndex("level").assign(buffer.getLevel() - 1);
result.refOfIndex("chunk_size").assign(buffer.getChunkSize());
result.refOfIndex("buffer_used").assign(buffer.getBufferSize());
return result;
}
public static Memory ob_get_status(Environment env, boolean fullStatus){
if (fullStatus){
ArrayMemory result = new ArrayMemory();
OutputBuffer peek = env.peekOutputBuffer();
ArrayList<OutputBuffer> list = new ArrayList<OutputBuffer>();
while (peek != null && !peek.isRoot()){
list.add(0, peek);
peek = peek.getParentOutput();
}
for(OutputBuffer e : list){
result.add(_get_status(e));
}
return result;
} else {
OutputBuffer buffer = env.peekOutputBuffer();
if (buffer == null || buffer.isRoot())
return new ArrayMemory().toConstant();
return _get_status(buffer).toConstant();
}
}
public static Memory ob_list_handlers(Environment env){
ArrayMemory result = new ArrayMemory();
OutputBuffer peek = env.peekOutputBuffer();
ArrayList<OutputBuffer> list = new ArrayList<OutputBuffer>();
while (peek != null && !peek.isRoot()){
list.add(0, peek);
peek = peek.getParentOutput();
}
for(OutputBuffer e : list){
result.refOfPush().assign(e.getName());
}
return result.toConstant();
}
public static Memory ob_get_status(Environment env){
return ob_get_status(env, false);
}
}