1 29 30 package com.caucho.quercus.lib.json; 31 32 import com.caucho.quercus.annotation.Optional; 33 import com.caucho.quercus.env.*; 34 import com.caucho.quercus.module.AbstractQuercusModule; 35 import com.caucho.util.L10N; 36 37 import java.util.Map ; 38 import java.util.logging.Logger ; 39 40 public class JsonModule 41 extends AbstractQuercusModule 42 { 43 private static final Logger log 44 = Logger.getLogger(JsonModule.class.getName()); 45 private static final L10N L = new L10N(JsonModule.class); 46 47 public String []getLoadedExtensions() 48 { 49 return new String [] { "json" }; 50 } 51 52 62 public StringValue json_encode(Env env, Value val) 63 { 64 StringBuilderValue sb = new StringBuilderValue(); 65 66 jsonEncodeImpl(env, sb, val); 67 return sb; 68 } 69 70 private void jsonEncodeImpl(Env env, StringBuilderValue sb, Value val) 71 { 72 if (val instanceof StringValue) { 73 sb.append('"'); 74 encodeString(sb, (StringValue)val); 75 sb.append('"'); 76 } 77 78 else if (val == BooleanValue.TRUE) 79 sb.append("true"); 80 else if (val == BooleanValue.FALSE) 81 sb.append("false"); 82 83 else if (val instanceof NumberValue) 84 sb.append(val.toStringValue()); 85 86 else if (val instanceof ArrayValue) 87 encodeArray(env, sb, (ArrayValue)val); 88 89 else if (val instanceof ObjectValue) 90 encodeObject(env, sb, (ObjectValue)val); 91 92 else if (val == NullValue.NULL || val == null) 93 sb.append("null"); 94 95 else { 96 env.warning(L.l("type is unsupported; encoded as null")); 97 } 98 } 99 100 private void encodeArray(Env env, StringBuilderValue sb, ArrayValue val) 101 { 102 long length = 0; 103 for (Value key : val.keySet()) { 104 if ((! key.isLongConvertible()) || key.toLong() != length) { 105 encodeArrayToObject(env, sb, val); 106 return; 107 } 108 length++; 109 } 110 111 sb.append('['); 112 113 length = 0; 114 for (Value value : ((ArrayValue)val).values()) { 115 if (length > 0) 116 sb.append(','); 117 jsonEncodeImpl(env, sb, value); 118 length++; 119 } 120 121 sb.append(']'); 122 } 123 124 127 private void encodeArrayToObject(Env env, StringBuilderValue sb, ArrayValue val) 128 { 129 sb.append('{'); 130 131 int length = 0; 132 for (Map.Entry <Value,Value> entry : val.entrySet()) { 133 if (length > 0) 134 sb.append(','); 135 136 jsonEncodeImpl(env, sb, entry.getKey().toStringValue()); 137 sb.append(':'); 138 jsonEncodeImpl(env, sb, entry.getValue()); 139 length++; 140 } 141 142 sb.append('}'); 143 } 144 145 148 private void encodeObject(Env env, StringBuilderValue sb, ObjectValue val) 149 { 150 sb.append('{'); 151 152 int length = 0; 153 for (Map.Entry <String ,Value> entry : val.entrySet()) { 154 if (length > 0) 155 sb.append(','); 156 157 jsonEncodeImpl(env, sb, new StringValueImpl(entry.getKey())); 158 sb.append(':'); 159 jsonEncodeImpl(env, sb, entry.getValue()); 160 length++; 161 } 162 163 sb.append('}'); 164 } 165 166 169 private void encodeString(StringBuilderValue sb, StringValue val) 170 { 171 int len = val.length(); 172 for (int i = 0; i < len; i++) { 173 char c = val.charAt(i); 174 175 switch (c) { 176 case '\b': 177 sb.append('\\'); 178 sb.append('b'); 179 break; 180 case '\f': 181 sb.append('\\'); 182 sb.append('f'); 183 break; 184 case '\n': 185 sb.append('\\'); 186 sb.append('n'); 187 break; 188 case '\r': 189 sb.append('\\'); 190 sb.append('r'); 191 break; 192 case '\t': 193 sb.append('\\'); 194 sb.append('t'); 195 break; 196 case '\\': 197 sb.append('\\'); 198 sb.append('\\'); 199 break; 200 case '"': 201 sb.append('\\'); 202 sb.append('"'); 203 break; 204 case '/': 205 sb.append('\\'); 206 sb.append('/'); 207 break; 208 default: 209 if (c > 0x1F) { 210 sb.append(c); 211 break; 212 } 213 214 sb.append('\\'); 216 sb.append('u'); 217 sb.append('0'); 218 sb.append('0'); 219 220 if (c <= 0x0F) 221 sb.append('0'); 222 else { 223 sb.append('1'); 224 c &= 0x0F; 225 } 226 227 if (c <= 0x09) 228 c += '0'; 229 else 230 c += 'a' - 10; 231 232 sb.append(c); 233 } 234 } 235 } 236 237 246 public Value json_decode(Env env, 247 StringValue s, 248 @Optional("false") boolean assoc) 249 { 250 return (new JsonDecoder()).jsonDecode(env, s, assoc); 251 } 252 253 } 254 | Popular Tags |