package org.develnext.jphp.zend.ext.json;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import org.develnext.jphp.json.gson.MemoryDeserializer;
import org.develnext.jphp.json.gson.MemorySerializer;
import php.runtime.Memory;
import php.runtime.env.Environment;
import php.runtime.ext.support.compile.FunctionsContainer;
import php.runtime.memory.StringMemory;
import static php.runtime.annotation.Runtime.Immutable;
public class JsonFunctions extends FunctionsContainer {
public static Memory json_decode(Environment env, String json, boolean assoc, int depth) {
MemoryDeserializer memoryDeserializer = new MemoryDeserializer();
memoryDeserializer.setEnv(env);
GsonBuilder gsonBuilder = JsonExtension.createGsonBuilderForDecode(memoryDeserializer);
memoryDeserializer.setAssoc(assoc);
memoryDeserializer.setMaxDepth(depth);
Gson gson = gsonBuilder.create();
try {
env.setUserValue(JsonFunctions.class.getName() + "#error", null);
Memory r = gson.fromJson(json, Memory.class);
if (r == null)
return Memory.NULL;
else
return assoc ? r.toImmutable() : r;
} catch (MemoryDeserializer.MaxDepthException e) {
env.setUserValue(JsonFunctions.class.getName() + "#error", JsonConstants.JSON_ERROR_DEPTH);
} catch (JsonSyntaxException e) {
env.setUserValue(JsonFunctions.class.getName() + "#error", JsonConstants.JSON_ERROR_SYNTAX);
} catch (JsonParseException e) {
env.setUserValue(JsonFunctions.class.getName() + "#error", JsonConstants.JSON_ERROR_STATE_MISMATCH);
}
return Memory.NULL;
}
public static Memory json_decode(Environment env, String json, boolean assoc) {
return json_decode(env, json, assoc, 512);
}
public static int json_last_error(Environment env) {
Integer error = env.getUserValue(JsonFunctions.class.getName() + "#error", Integer.class);
if (error == null)
return JsonConstants.JSON_ERROR_NONE;
return error;
}
public static Memory json_last_error_msg(Environment env) {
switch (json_last_error(env)) {
case JsonConstants.JSON_ERROR_NONE: return Memory.NULL;
case JsonConstants.JSON_ERROR_DEPTH: return new StringMemory("Maximum stack depth exceeded");
case JsonConstants.JSON_ERROR_STATE_MISMATCH: return new StringMemory("Underflow or the modes mismatch");
case JsonConstants.JSON_ERROR_SYNTAX: return new StringMemory("Syntax error, malformed JSON");
case JsonConstants.JSON_ERROR_UTF8: return new StringMemory("Malformed UTF-8 characters, possibly incorrectly encoded");
case JsonConstants.JSON_ERROR_CTRL_CHAR: return new StringMemory("Unexpected control character found");
default:
return Memory.NULL;
}
}
public static Memory json_decode(Environment env, String json) {
return json_decode(env, json, false);
}
@Immutable
public static String json_encode(Memory memory, int options) {
GsonBuilder builder;
if (options != 0){
MemorySerializer serializer = new MemorySerializer();
builder = JsonExtension.createGsonBuilder(serializer);
if ((options & JsonConstants.JSON_PRETTY_PRINT) == JsonConstants.JSON_PRETTY_PRINT){
builder.setPrettyPrinting();
}
if ((options & JsonConstants.JSON_HEX_TAG) != JsonConstants.JSON_HEX_TAG){
builder.disableHtmlEscaping();
}
if ((options & JsonConstants.JSON_FORCE_OBJECT) == JsonConstants.JSON_FORCE_OBJECT){
serializer.setForceObject(true);
}
if ((options & JsonConstants.JSON_NUMERIC_CHECK) == JsonConstants.JSON_NUMERIC_CHECK){
serializer.setNumericCheck(true);
}
} else {
builder = JsonExtension.DEFAULT_GSON_BUILDER;
}
Gson gson = builder.create();
return gson.toJson(memory);
}
@Immutable
public static String json_encode(Memory memory) {
return json_encode(memory, 0);
}
}