+const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSValueRef value) {
+ JSValueRef exception(NULL);
+ const char *cyon(CYPoolCCYON(pool, context, value, &exception));
+ CYThrow(context, exception);
+ return cyon;
+}
+
+const char *CYPoolCCYON(apr_pool_t *pool, JSContextRef context, JSObjectRef object) {
+ JSValueRef toCYON(CYGetProperty(context, object, toCYON_));
+ if (CYIsCallable(context, toCYON)) {
+ JSValueRef value(CYCallAsFunction(context, (JSObjectRef) toCYON, object, 0, NULL));
+ return CYPoolCString(pool, context, value);
+ }
+
+ JSValueRef toJSON(CYGetProperty(context, object, toJSON_));
+ if (CYIsCallable(context, toJSON)) {
+ JSValueRef arguments[1] = {CYCastJSValue(context, CYJSString(""))};
+ JSValueRef exception(NULL);
+ const char *cyon(CYPoolCCYON(pool, context, CYCallAsFunction(context, (JSObjectRef) toJSON, object, 1, arguments), &exception));
+ CYThrow(context, exception);
+ return cyon;
+ }
+
+ std::ostringstream str;
+
+ str << '{';
+
+ // XXX: this is, sadly, going to leak
+ JSPropertyNameArrayRef names(JSObjectCopyPropertyNames(context, object));
+
+ bool comma(false);
+
+ for (size_t index(0), count(JSPropertyNameArrayGetCount(names)); index != count; ++index) {
+ JSStringRef name(JSPropertyNameArrayGetNameAtIndex(names, index));
+ JSValueRef value(CYGetProperty(context, object, name));
+
+ if (comma)
+ str << ',';
+ else
+ comma = true;
+
+ CYUTF8String string(CYPoolUTF8String(pool, name));
+ if (CYIsKey(string))
+ str << string.data;
+ else
+ CYStringify(str, string.data, string.size);
+
+ str << ':' << CYPoolCCYON(pool, context, value);
+ }
+
+ str << '}';
+
+ JSPropertyNameArrayRelease(names);
+
+ std::string string(str.str());
+ return apr_pstrmemdup(pool, string.c_str(), string.size());
+}
+
+static JSValueRef Array_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ CYPool pool;
+ std::ostringstream str;
+
+ str << '[';
+
+ // XXX: this is, sadly, going to leak
+ // XXX: shouldn't this be done with .length?!
+ JSPropertyNameArrayRef names(JSObjectCopyPropertyNames(context, _this));
+
+ bool comma(false);
+
+ for (size_t index(0), count(JSPropertyNameArrayGetCount(names)); index != count; ++index) {
+ JSStringRef name(JSPropertyNameArrayGetNameAtIndex(names, index));
+ JSValueRef value(CYGetProperty(context, _this, name));
+
+ if (comma)
+ str << ',';
+ else
+ comma = true;
+
+ if (!JSValueIsUndefined(context, value))
+ str << CYPoolCCYON(pool, context, value);
+ else {
+ str << ',';
+ comma = false;
+ }
+ }
+
+ str << ']';
+
+ JSPropertyNameArrayRelease(names);
+
+ std::string value(str.str());
+ return CYCastJSValue(context, CYJSString(CYUTF8String(value.c_str(), value.size())));
+} CYCatch }
+