summaryrefslogtreecommitdiff
path: root/apps/couch
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-08-23 13:51:50 -0400
committerAdam Kocoloski <adam@cloudant.com>2010-08-23 13:51:50 -0400
commit96a9fa9101e9ed50149d284ff32c361084223fa4 (patch)
tree51f7c69596df29a26beaf85a8f2376e271ade366 /apps/couch
parentdd586292bdb6b6ea16b70351c2ca4d20793ac772 (diff)
consolidate all couchjs stuff in one subdir
Diffstat (limited to 'apps/couch')
-rw-r--r--apps/couch/c_src/couch_js/SConscript53
-rw-r--r--apps/couch/c_src/couch_js/http.c684
-rw-r--r--apps/couch/c_src/couch_js/http.h18
-rw-r--r--apps/couch/c_src/couch_js/main.c345
-rw-r--r--apps/couch/c_src/couch_js/utf8.c293
-rw-r--r--apps/couch/c_src/couch_js/utf8.h19
-rw-r--r--apps/couch/js/SConscript23
-rw-r--r--apps/couch/js/filter.js23
-rw-r--r--apps/couch/js/json2.js481
-rw-r--r--apps/couch/js/loop.js140
-rw-r--r--apps/couch/js/mimeparse.js158
-rw-r--r--apps/couch/js/render.js352
-rw-r--r--apps/couch/js/state.js27
-rw-r--r--apps/couch/js/util.js112
-rw-r--r--apps/couch/js/validate.js22
-rw-r--r--apps/couch/js/views.js137
16 files changed, 0 insertions, 2887 deletions
diff --git a/apps/couch/c_src/couch_js/SConscript b/apps/couch/c_src/couch_js/SConscript
deleted file mode 100644
index b459ee94..00000000
--- a/apps/couch/c_src/couch_js/SConscript
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2010 Cloudant
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-def require_lib(name):
- if not conf.CheckLib(name):
- print 'Could not find required library', name
- Exit(1)
-
-env = Environment(CCFLAGS='-g -O2 -DXP_UNIX')
-if not env.GetOption('clean'):
- conf = Configure(env, config_h='config.h')
-
- require_lib('m')
- require_lib('pthread')
- require_lib('curl')
-
- ## check for SpiderMonkey development header
- if conf.CheckHeader('js/jsapi.h'):
- jsapi = 'js/jsapi.h'
- elif conf.CheckHeader('mozjs/jsapi.h'):
- jsapi = 'mozjs/jsapi.h'
- elif conf.CheckHeader('jsapi.h'):
- jsapi = 'jsapi.h'
- else:
- print 'Could not find jsapi.h.', \
- 'Are Mozilla SpiderMonkey headers installed?'
- Exit(1)
-
- ## check for SpiderMonkey library as libjs or libmozjs
- if not conf.CheckLibWithHeader('mozjs', jsapi, 'c', autoadd=1):
- if not conf.CheckLibWithHeader('js', jsapi, 'c', autoadd=1):
- print 'Could not find JS library.', \
- 'Is Mozilla SpiderMonkey installed?'
- Exit(1)
-
- ## SpiderMonkey 1.8 has this callback we use for memory management
- if conf.CheckDeclaration('JS_SetOperationCallback', '#include <%s>' % jsapi):
- conf.Define('USE_JS_SETOPCB')
-
- env = conf.Finish()
-
-env.Program('couchjs', ['main.c', 'http.c', 'utf8.c'])
diff --git a/apps/couch/c_src/couch_js/http.c b/apps/couch/c_src/couch_js/http.c
deleted file mode 100644
index b781f0ef..00000000
--- a/apps/couch/c_src/couch_js/http.c
+++ /dev/null
@@ -1,684 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "config.h"
-#ifdef HAVE_JS_JSAPI_H
-#include <js/jsapi.h>
-#elif HAVE_MOZJS_JSAPI_H
-#include <mozjs/jsapi.h>
-#else
-#include <jsapi.h>
-#endif
-
-#include <curl/curl.h>
-
-#include "utf8.h"
-
-#ifdef XP_WIN
-// Map some of the string function names to things which exist on Windows
-#define strcasecmp _strcmpi
-#define strncasecmp _strnicmp
-#define snprintf _snprintf
-#endif
-
-typedef struct curl_slist CurlHeaders;
-
-typedef struct {
- int method;
- char* url;
- CurlHeaders* req_headers;
- jsint last_status;
-} HTTPData;
-
-char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", NULL};
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-
-static JSBool
-go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t blen);
-
-static JSString*
-str_from_binary(JSContext* cx, char* data, size_t length);
-
-static JSBool
-constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{
- HTTPData* http = NULL;
- JSBool ret = JS_FALSE;
-
- http = (HTTPData*) malloc(sizeof(HTTPData));
- if(!http)
- {
- JS_ReportError(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->url = NULL;
- http->req_headers = NULL;
- http->last_status = -1;
-
- if(!JS_SetPrivate(cx, obj, http))
- {
- JS_ReportError(cx, "Failed to set private CouchHTTP data.");
- goto error;
- }
-
- ret = JS_TRUE;
- goto success;
-
-error:
- if(http) free(http);
-
-success:
- return ret;
-}
-
-static void
-destructor(JSContext* cx, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- if(!http)
- {
- fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n");
- }
- else
- {
- if(http->url) free(http->url);
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- free(http);
- }
-}
-
-static JSBool
-open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- char* method = NULL;
- char* url = NULL;
- JSBool ret = JS_FALSE;
- int methid;
-
- if(!http)
- {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(argv[0] == JSVAL_VOID)
- {
- JS_ReportError(cx, "You must specify a method.");
- goto done;
- }
-
- method = enc_string(cx, argv[0], NULL);
- if(!method)
- {
- JS_ReportError(cx, "Failed to encode method.");
- goto done;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++)
- {
- if(strcasecmp(METHODS[methid], method) == 0) break;
- }
-
- if(methid > COPY)
- {
- JS_ReportError(cx, "Invalid method specified.");
- goto done;
- }
-
- http->method = methid;
-
- if(argv[1] == JSVAL_VOID)
- {
- JS_ReportError(cx, "You must specify a URL.");
- goto done;
- }
-
- if(http->url)
- {
- free(http->url);
- http->url = NULL;
- }
-
- http->url = enc_string(cx, argv[1], NULL);
- if(!http->url)
- {
- JS_ReportError(cx, "Failed to encode URL.");
- goto done;
- }
-
- if(argv[2] != JSVAL_VOID && argv[2] != JSVAL_FALSE)
- {
- JS_ReportError(cx, "Synchronous flag must be false if specified.");
- goto done;
- }
-
- if(http->req_headers)
- {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- ret = JS_TRUE;
-
-done:
- if(method) free(method);
- return ret;
-}
-
-static JSBool
-setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- char* keystr = NULL;
- char* valstr = NULL;
- char* hdrbuf = NULL;
- size_t hdrlen = -1;
- JSBool ret = JS_FALSE;
-
- if(!http)
- {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(argv[0] == JSVAL_VOID)
- {
- JS_ReportError(cx, "You must speciy a header name.");
- goto done;
- }
-
- keystr = enc_string(cx, argv[0], NULL);
- if(!keystr)
- {
- JS_ReportError(cx, "Failed to encode header name.");
- goto done;
- }
-
- if(argv[1] == JSVAL_VOID)
- {
- JS_ReportError(cx, "You must specify a header value.");
- goto done;
- }
-
- valstr = enc_string(cx, argv[1], NULL);
- if(!valstr)
- {
- JS_ReportError(cx, "Failed to encode header value.");
- goto done;
- }
-
- hdrlen = strlen(keystr) + strlen(valstr) + 3;
- hdrbuf = (char*) malloc(hdrlen * sizeof(char));
- if(!hdrbuf)
- {
- JS_ReportError(cx, "Failed to allocate header buffer.");
- goto done;
- }
-
- snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr);
- http->req_headers = curl_slist_append(http->req_headers, hdrbuf);
-
- ret = JS_TRUE;
-
-done:
- if(keystr) free(keystr);
- if(valstr) free(valstr);
- if(hdrbuf) free(hdrbuf);
-
- return ret;
-}
-
-static JSBool
-sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- char* body = NULL;
- size_t bodylen = 0;
- JSBool ret = JS_FALSE;
-
- if(!http)
- {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(argv[0] != JSVAL_VOID && argv[0] != JS_GetEmptyStringValue(cx))
- {
- body = enc_string(cx, argv[0], &bodylen);
- if(!body)
- {
- JS_ReportError(cx, "Failed to encode body.");
- goto done;
- }
- }
-
- ret = go(cx, obj, http, body, bodylen);
-
-done:
- if(body) free(body);
- return ret;
-}
-
-static JSBool
-status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
-
- if(!http)
- {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- return JS_FALSE;
- }
-
- if(INT_FITS_IN_JSVAL(http->last_status))
- {
- *vp = INT_TO_JSVAL(http->last_status);
- return JS_TRUE;
- }
- else
- {
- JS_ReportError(cx, "INTERNAL: Invalid last_status");
- return JS_FALSE;
- }
-}
-
-JSClass CouchHTTPClass = {
- "CouchHTTP",
- JSCLASS_HAS_PRIVATE
- | JSCLASS_CONSTRUCT_PROTOTYPE
- | JSCLASS_HAS_RESERVED_SLOTS(2),
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- destructor,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-JSPropertySpec CouchHTTPProperties[] = {
- {"status", 0, JSPROP_READONLY, status, NULL},
- {0, 0, 0, 0, 0}
-};
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- {"_open", open, 3, 0, 0},
- {"_setRequestHeader", setheader, 2, 0, 0},
- {"_send", sendreq, 1, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-JSObject*
-install_http(JSContext* cx, JSObject* glbl)
-{
- JSObject* klass = NULL;
- HTTPData* http = NULL;
-
- klass = JS_InitClass(
- cx,
- glbl,
- NULL,
- &CouchHTTPClass,
- constructor,
- 0,
- CouchHTTPProperties,
- CouchHTTPFunctions,
- NULL,
- NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- return NULL;
- }
-
- return klass;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- char* sendbuf;
- size_t sendlen;
- size_t sent;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static JSBool
-go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen)
-{
- CurlState state;
- JSString* jsbody;
- JSBool ret = JS_FALSE;
- jsval tmp;
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body;
- state.sendlen = bodylen;
- state.sent = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- if(HTTP_HANDLE == NULL)
- {
- HTTP_HANDLE = curl_easy_init();
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE)
- {
- JS_ReportError(cx, "Failed to initialize cURL handle.");
- goto done;
- }
-
- if(http->method < 0 || http->method > COPY)
- {
- JS_ReportError(cx, "INTERNAL: Unknown method.");
- goto done;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- if(http->method == HEAD)
- {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
- else if(http->method == POST || http->method == PUT)
- {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body && bodylen)
- {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen);
- }
- else
- {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- //curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0)
- {
- JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF);
- goto done;
- }
-
- if(!state.resp_headers)
- {
- JS_ReportError(cx, "Failed to recieve HTTP headers.");
- goto done;
- }
-
- tmp = OBJECT_TO_JSVAL(state.resp_headers);
- if(!JS_DefineProperty(
- cx,
- obj,
- "_headers",
- tmp,
- NULL,
- NULL,
- JSPROP_READONLY
- ))
- {
- JS_ReportError(cx, "INTERNAL: Failed to set response headers.");
- goto done;
- }
-
- if(state.recvbuf) // Is good enough?
- {
- state.recvbuf[state.read] = '\0';
- jsbody = dec_string(cx, state.recvbuf, state.read+1);
- if(!jsbody)
- {
- // If we can't decode the body as UTF-8 we forcefully
- // convert it to a string by just forcing each byte
- // to a jschar.
- jsbody = str_from_binary(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportError(cx, "INTERNAL: Failed to decode body.");
- }
- goto done;
- }
- }
- tmp = STRING_TO_JSVAL(jsbody);
- }
- else
- {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- if(!JS_DefineProperty(
- cx,
- obj,
- "responseText",
- tmp,
- NULL,
- NULL,
- JSPROP_READONLY
- ))
- {
- JS_ReportError(cx, "INTERNAL: Failed to set responseText.");
- goto done;
- }
-
- ret = JS_TRUE;
-
-done:
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
- if(towrite == 0)
- {
- return 0;
- }
-
- if(length < towrite) towrite = length;
-
- //fprintf(stderr, "%lu %lu %lu %lu\n", state->bodyused, state->bodyread, length, towrite);
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = (CurlState*) ptr;
- if(origin != SEEK_SET) return -1;
-
- state->sent = (size_t) offset;
- return (int) state->sent;
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- char code[4];
- char* header = (char*) ptr;
- size_t length = size * nmem;
- size_t index = 0;
- JSString* hdr = NULL;
- jsuint hdrlen;
- jsval hdrval;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0)
- {
- if(length < 12)
- {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0, NULL);
- if(!state->resp_headers)
- {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2)
- {
- return length;
- }
-
- // Append the new header to our array.
- hdr = dec_string(state->cx, header, length);
- if(!hdr)
- {
- return CURLE_WRITE_ERROR;
- }
-
- if(!JS_GetArrayLength(state->cx, state->resp_headers, &hdrlen))
- {
- return CURLE_WRITE_ERROR;
- }
-
- hdrval = STRING_TO_JSVAL(hdr);
- if(!JS_SetElement(state->cx, state->resp_headers, hdrlen, &hdrval))
- {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf)
- {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = JS_malloc(state->cx, state->recvlen);
- }
-
- if(!state->recvbuf)
- {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = JS_realloc(state->cx, state->recvbuf, state->recvlen);
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-JSString*
-str_from_binary(JSContext* cx, char* data, size_t length)
-{
- jschar* conv = (jschar*) JS_malloc(cx, length * sizeof(jschar));
- JSString* ret = NULL;
- size_t i;
-
- if(!conv) return NULL;
-
- for(i = 0; i < length; i++)
- {
- conv[i] = (jschar) data[i];
- }
-
- ret = JS_NewUCString(cx, conv, length);
- if(!ret) JS_free(cx, conv);
-
- return ret;
-}
diff --git a/apps/couch/c_src/couch_js/http.h b/apps/couch/c_src/couch_js/http.h
deleted file mode 100644
index b5f8c70f..00000000
--- a/apps/couch/c_src/couch_js/http.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-JSObject* install_http(JSContext* cx, JSObject* global);
-
-#endif \ No newline at end of file
diff --git a/apps/couch/c_src/couch_js/main.c b/apps/couch/c_src/couch_js/main.c
deleted file mode 100644
index 25acaf55..00000000
--- a/apps/couch/c_src/couch_js/main.c
+++ /dev/null
@@ -1,345 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-#ifdef HAVE_JS_JSAPI_H
-#include <js/jsapi.h>
-#elif HAVE_MOZJS_JSAPI_H
-#include <mozjs/jsapi.h>
-#else
-#include <jsapi.h>
-#endif
-
-#include "utf8.h"
-#include "http.h"
-
-int gExitCode = 0;
-
-#ifdef JS_THREADSAFE
-#define SETUP_REQUEST(cx) \
- JS_SetContextThread(cx); \
- JS_BeginRequest(cx);
-#define FINISH_REQUEST(cx) \
- JS_EndRequest(cx); \
- JS_ClearContextThread(cx);
-#else
-#define SETUP_REQUEST(cx)
-#define FINISH_REQUEST(cx)
-#endif
-
-static JSBool
-evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JSString *str;
- JSObject *sandbox;
- JSContext *subcx;
- const jschar *src;
- size_t srclen;
- JSBool ret = JS_FALSE;
- jsval v;
-
- sandbox = NULL;
- if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox))
- {
- return JS_FALSE;
- }
-
- subcx = JS_NewContext(JS_GetRuntime(cx), 8L * 1024L);
- if(!subcx)
- {
- JS_ReportOutOfMemory(cx);
- return JS_FALSE;
- }
-
- SETUP_REQUEST(subcx);
-
- src = JS_GetStringChars(str);
- srclen = JS_GetStringLength(str);
-
- if(!sandbox)
- {
- sandbox = JS_NewObject(subcx, NULL, NULL, NULL);
- if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) goto done;
- }
-
- if(srclen == 0)
- {
- *rval = OBJECT_TO_JSVAL(sandbox);
- }
- else
- {
- JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval);
- }
-
- ret = JS_TRUE;
-
-done:
- FINISH_REQUEST(subcx);
- JS_DestroyContext(subcx);
- return ret;
-}
-
-static JSBool
-gc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JS_GC(cx);
- return JS_TRUE;
-}
-
-static JSBool
-print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- uintN i;
- char *bytes;
-
- for(i = 0; i < argc; i++)
- {
- bytes = enc_string(cx, argv[i], NULL);
- if(!bytes) return JS_FALSE;
-
- fprintf(stdout, "%s%s", i ? " " : "", bytes);
- JS_free(cx, bytes);
- }
-
- fputc('\n', stdout);
- fflush(stdout);
- return JS_TRUE;
-}
-
-static JSBool
-quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
- JS_ConvertArguments(cx, argc, argv, "/ i", &gExitCode);
- return JS_FALSE;
-}
-
-static char*
-readfp(JSContext* cx, FILE* fp, size_t* buflen)
-{
- char* bytes = NULL;
- char* tmp = NULL;
- size_t used = 0;
- size_t byteslen = 256;
- size_t readlen = 0;
-
- bytes = JS_malloc(cx, byteslen);
- if(bytes == NULL) return NULL;
-
- while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0)
- {
- used += readlen;
-
- if(bytes[used-1] == '\n')
- {
- bytes[used-1] = '\0';
- break;
- }
-
- // Double our buffer and read more.
- byteslen *= 2;
- tmp = JS_realloc(cx, bytes, byteslen);
- if(!tmp)
- {
- JS_free(cx, bytes);
- return NULL;
- }
- bytes = tmp;
- }
-
- *buflen = used;
- return bytes;
-}
-
-static JSBool
-readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
- jschar *chars;
- JSString *str;
- char* bytes;
- char* tmp;
- size_t byteslen;
-
- /* GC Occasionally */
- JS_MaybeGC(cx);
-
- bytes = readfp(cx, stdin, &byteslen);
- if(!bytes) return JS_FALSE;
-
- /* Treat the empty string specially */
- if(byteslen == 0)
- {
- *rval = JS_GetEmptyStringValue(cx);
- JS_free(cx, bytes);
- return JS_TRUE;
- }
-
- /* Shrink the buffer to the real size */
- tmp = JS_realloc(cx, bytes, byteslen);
- if(!tmp)
- {
- JS_free(cx, bytes);
- return JS_FALSE;
- }
- bytes = tmp;
-
- str = dec_string(cx, bytes, byteslen);
- JS_free(cx, bytes);
-
- if(!str) return JS_FALSE;
-
- *rval = STRING_TO_JSVAL(str);
-
- return JS_TRUE;
-}
-
-static JSBool
-seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
- JSObject *target;
- JSBool deep = JS_FALSE;
-
- if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
- return JS_FALSE;
- if (!target)
- return JS_TRUE;
- return JS_SealObject(cx, target, deep);
-}
-
-static void
-execute_script(JSContext *cx, JSObject *obj, const char *filename) {
- FILE *file;
- JSScript *script;
- jsval result;
-
- if(!filename || strcmp(filename, "-") == 0)
- {
- file = stdin;
- }
- else
- {
- file = fopen(filename, "r");
- if (!file)
- {
- fprintf(stderr, "could not open script file %s\n", filename);
- gExitCode = 1;
- return;
- }
- }
-
- script = JS_CompileFileHandle(cx, obj, filename, file);
- if(script)
- {
- JS_ExecuteScript(cx, obj, script, &result);
- JS_DestroyScript(cx, script);
- }
-}
-
-static void
-printerror(JSContext *cx, const char *mesg, JSErrorReport *report)
-{
- if(!report || !JSREPORT_IS_WARNING(report->flags))
- {
- fprintf(stderr, "%s\n", mesg);
- }
-}
-
-static JSFunctionSpec global_functions[] = {
- {"evalcx", evalcx, 0, 0, 0},
- {"gc", gc, 0, 0, 0},
- {"print", print, 0, 0, 0},
- {"quit", quit, 0, 0, 0},
- {"readline", readline, 0, 0, 0},
- {"seal", seal, 0, 0, 0},
- {0, 0, 0, 0, 0}
-};
-
-static JSClass global_class = {
- "GlobalClass",
- JSCLASS_GLOBAL_FLAGS,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- JS_FinalizeStub,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-int
-main(int argc, const char * argv[])
-{
- JSRuntime* rt = NULL;
- JSContext* cx = NULL;
- JSObject* global = NULL;
- JSFunctionSpec* sp = NULL;
- int i = 0;
-
- rt = JS_NewRuntime(64L * 1024L * 1024L);
- if (!rt) return 1;
-
- cx = JS_NewContext(rt, 8L * 1024L);
- if (!cx) return 1;
-
- JS_SetErrorReporter(cx, printerror);
- JS_ToggleOptions(cx, JSOPTION_XML);
-
- SETUP_REQUEST(cx);
-
- global = JS_NewObject(cx, &global_class, NULL, NULL);
- if (!global) return 1;
- if (!JS_InitStandardClasses(cx, global)) return 1;
-
- for(sp = global_functions; sp->name != NULL; sp++)
- {
- if(!JS_DefineFunction(cx, global,
- sp->name, sp->call, sp->nargs, sp->flags))
- {
- fprintf(stderr, "Failed to create function: %s\n", sp->name);
- return 1;
- }
- }
-
- if(!install_http(cx, global))
- {
- return 1;
- }
-
- JS_SetGlobalObject(cx, global);
-
- if(argc > 2)
- {
- fprintf(stderr, "incorrect number of arguments\n\n");
- fprintf(stderr, "usage: %s <scriptfile>\n", argv[0]);
- return 2;
- }
-
- if(argc == 0)
- {
- execute_script(cx, global, NULL);
- }
- else
- {
- execute_script(cx, global, argv[1]);
- }
-
- FINISH_REQUEST(cx);
-
- JS_DestroyContext(cx);
- JS_DestroyRuntime(rt);
- JS_ShutDown();
-
- return gExitCode;
-}
diff --git a/apps/couch/c_src/couch_js/utf8.c b/apps/couch/c_src/couch_js/utf8.c
deleted file mode 100644
index 57928ba9..00000000
--- a/apps/couch/c_src/couch_js/utf8.c
+++ /dev/null
@@ -1,293 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include "config.h"
-#ifdef HAVE_JS_JSAPI_H
-#include <js/jsapi.h>
-#elif HAVE_MOZJS_JSAPI_H
-#include <mozjs/jsapi.h>
-#else
-#include <jsapi.h>
-#endif
-
-static int
-enc_char(uint8 *utf8Buffer, uint32 ucs4Char)
-{
- int utf8Length = 1;
-
- if (ucs4Char < 0x80)
- {
- *utf8Buffer = (uint8)ucs4Char;
- }
- else
- {
- int i;
- uint32 a = ucs4Char >> 11;
- utf8Length = 2;
- while(a)
- {
- a >>= 5;
- utf8Length++;
- }
- i = utf8Length;
- while(--i)
- {
- utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80);
- ucs4Char >>= 6;
- }
- *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
- }
-
- return utf8Length;
-}
-
-static JSBool
-enc_charbuf(const jschar* src, size_t srclen, char* dst, size_t* dstlenp)
-{
- size_t i;
- size_t utf8Len;
- size_t dstlen = *dstlenp;
- size_t origDstlen = dstlen;
- jschar c;
- jschar c2;
- uint32 v;
- uint8 utf8buf[6];
-
- if(!dst)
- {
- dstlen = origDstlen = (size_t) -1;
- }
-
- while(srclen)
- {
- c = *src++;
- srclen--;
-
- if((c >= 0xDC00) && (c <= 0xDFFF)) goto bad_surrogate;
-
- if(c < 0xD800 || c > 0xDBFF)
- {
- v = c;
- }
- else
- {
- if(srclen < 1) goto buffer_too_small;
- c2 = *src++;
- srclen--;
- if ((c2 < 0xDC00) || (c2 > 0xDFFF))
- {
- c = c2;
- goto bad_surrogate;
- }
- v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
- }
- if(v < 0x0080)
- {
- /* no encoding necessary - performance hack */
- if(!dstlen) goto buffer_too_small;
- if(dst) *dst++ = (char) v;
- utf8Len = 1;
- }
- else
- {
- utf8Len = enc_char(utf8buf, v);
- if(utf8Len > dstlen) goto buffer_too_small;
- if(dst)
- {
- for (i = 0; i < utf8Len; i++)
- {
- *dst++ = (char) utf8buf[i];
- }
- }
- }
- dstlen -= utf8Len;
- }
-
- *dstlenp = (origDstlen - dstlen);
- return JS_TRUE;
-
-bad_surrogate:
- *dstlenp = (origDstlen - dstlen);
- return JS_FALSE;
-
-buffer_too_small:
- *dstlenp = (origDstlen - dstlen);
- return JS_FALSE;
-}
-
-char*
-enc_string(JSContext* cx, jsval arg, size_t* buflen)
-{
- JSString* str = NULL;
- jschar* src = NULL;
- char* bytes = NULL;
- size_t srclen = 0;
- size_t byteslen = 0;
-
- str = JS_ValueToString(cx, arg);
- if(!str) goto error;
-
- src = JS_GetStringChars(str);
- srclen = JS_GetStringLength(str);
-
- if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error;
-
- bytes = JS_malloc(cx, (byteslen) + 1);
- bytes[byteslen] = 0;
-
- if(!enc_charbuf(src, srclen, bytes, &byteslen)) goto error;
-
- if(buflen) *buflen = byteslen;
- goto success;
-
-error:
- if(bytes != NULL) JS_free(cx, bytes);
- bytes = NULL;
-
-success:
- return bytes;
-}
-
-static uint32
-dec_char(const uint8 *utf8Buffer, int utf8Length)
-{
- uint32 ucs4Char;
- uint32 minucs4Char;
-
- /* from Unicode 3.1, non-shortest form is illegal */
- static const uint32 minucs4Table[] = {
- 0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000
- };
-
- if (utf8Length == 1)
- {
- ucs4Char = *utf8Buffer;
- }
- else
- {
- ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1);
- minucs4Char = minucs4Table[utf8Length-2];
- while(--utf8Length)
- {
- ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F);
- }
- if(ucs4Char < minucs4Char || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF)
- {
- ucs4Char = 0xFFFD;
- }
- }
-
- return ucs4Char;
-}
-
-static JSBool
-dec_charbuf(const char *src, size_t srclen, jschar *dst, size_t *dstlenp)
-{
- uint32 v;
- size_t offset = 0;
- size_t j;
- size_t n;
- size_t dstlen = *dstlenp;
- size_t origDstlen = dstlen;
-
- if(!dst) dstlen = origDstlen = (size_t) -1;
-
- while(srclen)
- {
- v = (uint8) *src;
- n = 1;
-
- if(v & 0x80)
- {
- while(v & (0x80 >> n))
- {
- n++;
- }
-
- if(n > srclen) goto buffer_too_small;
- if(n == 1 || n > 6) goto bad_character;
-
- for(j = 1; j < n; j++)
- {
- if((src[j] & 0xC0) != 0x80) goto bad_character;
- }
-
- v = dec_char((const uint8 *) src, n);
- if(v >= 0x10000)
- {
- v -= 0x10000;
-
- if(v > 0xFFFFF || dstlen < 2)
- {
- *dstlenp = (origDstlen - dstlen);
- return JS_FALSE;
- }
-
- if(dstlen < 2) goto buffer_too_small;
-
- if(dst)
- {
- *dst++ = (jschar)((v >> 10) + 0xD800);
- v = (jschar)((v & 0x3FF) + 0xDC00);
- }
- dstlen--;
- }
- }
-
- if(!dstlen) goto buffer_too_small;
- if(dst) *dst++ = (jschar) v;
-
- dstlen--;
- offset += n;
- src += n;
- srclen -= n;
- }
-
- *dstlenp = (origDstlen - dstlen);
- return JS_TRUE;
-
-bad_character:
- *dstlenp = (origDstlen - dstlen);
- return JS_FALSE;
-
-buffer_too_small:
- *dstlenp = (origDstlen - dstlen);
- return JS_FALSE;
-}
-
-JSString*
-dec_string(JSContext* cx, const char* bytes, size_t byteslen)
-{
- JSString* str = NULL;
- jschar* chars = NULL;
- size_t charslen;
-
- if(!dec_charbuf(bytes, byteslen, NULL, &charslen)) goto error;
-
- chars = JS_malloc(cx, (charslen + 1) * sizeof(jschar));
- if(!chars) return NULL;
- chars[charslen] = 0;
-
- if(!dec_charbuf(bytes, byteslen, chars, &charslen)) goto error;
-
- str = JS_NewUCString(cx, chars, charslen - 1);
- if(!str) goto error;
-
- goto success;
-
-error:
- if(chars != NULL) JS_free(cx, chars);
- str = NULL;
-
-success:
- return str;
-}
diff --git a/apps/couch/c_src/couch_js/utf8.h b/apps/couch/c_src/couch_js/utf8.h
deleted file mode 100644
index 00f6b736..00000000
--- a/apps/couch/c_src/couch_js/utf8.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_UTF_8_H
-#define COUCH_JS_UTF_8_H
-
-char* enc_string(JSContext* cx, jsval arg, size_t* buflen);
-JSString* dec_string(JSContext* cx, const char* buf, size_t buflen);
-
-#endif \ No newline at end of file
diff --git a/apps/couch/js/SConscript b/apps/couch/js/SConscript
deleted file mode 100644
index db635665..00000000
--- a/apps/couch/js/SConscript
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2010 Cloudant
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-env = Environment()
-env['BUILDERS']['Cat'] = Builder(action = '''
- echo "// DO NOT EDIT THIS FILE BY HAND\\n" > $TARGET && \
- cat $SOURCES >> $TARGET
-''')
-
-## don't Glob() because loop.js must come last
-env.Cat('../../../build/main.js', ['json2.js', 'filter.js', 'mimeparse.js',
- 'render.js', 'state.js', 'util.js', 'validate.js', 'views.js', 'loop.js'])
diff --git a/apps/couch/js/filter.js b/apps/couch/js/filter.js
deleted file mode 100644
index 1e8556a4..00000000
--- a/apps/couch/js/filter.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-var Filter = {
- filter : function(fun, ddoc, args) {
- var results = [];
- var docs = args[0];
- var req = args[1];
- for (var i=0; i < docs.length; i++) {
- results.push((fun.apply(ddoc, [docs[i], req]) && true) || false);
- };
- respond([true, results]);
- }
-};
diff --git a/apps/couch/js/json2.js b/apps/couch/js/json2.js
deleted file mode 100644
index 39d8f370..00000000
--- a/apps/couch/js/json2.js
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- http://www.JSON.org/json2.js
- 2009-09-29
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, strict: false */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (!this.JSON) {
- this.JSON = {};
-}
-
-(function () {
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ?
- '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' :
- '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0 ? '[]' :
- gap ? '[\n' + gap +
- partial.join(',\n' + gap) + '\n' +
- mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- k = rep[i];
- if (typeof k === 'string') {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0 ? '{}' :
- gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
- mind + '}' : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/.
-test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
-replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
-replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/apps/couch/js/loop.js b/apps/couch/js/loop.js
deleted file mode 100644
index 300151e9..00000000
--- a/apps/couch/js/loop.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-var sandbox = null;
-
-function init_sandbox() {
- try {
- // if possible, use evalcx (not always available)
- sandbox = evalcx('');
- sandbox.emit = Views.emit;
- sandbox.sum = Views.sum;
- sandbox.log = log;
- sandbox.toJSON = Couch.toJSON;
- sandbox.JSON = JSON;
- sandbox.provides = Mime.provides;
- sandbox.registerType = Mime.registerType;
- sandbox.start = Render.start;
- sandbox.send = Render.send;
- sandbox.getRow = Render.getRow;
- } catch (e) {
- log(e.toSource());
- }
-};
-init_sandbox();
-
-// Commands are in the form of json arrays:
-// ["commandname",..optional args...]\n
-//
-// Responses are json values followed by a new line ("\n")
-
-var DDoc = (function() {
- var ddoc_dispatch = {
- "lists" : Render.list,
- "shows" : Render.show,
- "filters" : Filter.filter,
- "updates" : Render.update,
- "validate_doc_update" : Validate.validate
- };
- var ddocs = {};
- return {
- ddoc : function() {
- var args = [];
- for (var i=0; i < arguments.length; i++) {
- args.push(arguments[i]);
- };
- var ddocId = args.shift();
- if (ddocId == "new") {
- // get the real ddocId.
- ddocId = args.shift();
- // store the ddoc, functions are lazily compiled.
- ddocs[ddocId] = args.shift();
- print("true");
- } else {
- // Couch makes sure we know this ddoc already.
- var ddoc = ddocs[ddocId];
- if (!ddoc) throw(["fatal", "query_protocol_error", "uncached design doc: "+ddocId]);
- var funPath = args.shift();
- var cmd = funPath[0];
- // the first member of the fun path determines the type of operation
- var funArgs = args.shift();
- if (ddoc_dispatch[cmd]) {
- // get the function, call the command with it
- var point = ddoc;
- for (var i=0; i < funPath.length; i++) {
- if (i+1 == funPath.length) {
- fun = point[funPath[i]]
- if (typeof fun != "function") {
- fun = Couch.compileFunction(fun, ddoc);
- // cache the compiled fun on the ddoc
- point[funPath[i]] = fun
- };
- } else {
- point = point[funPath[i]]
- }
- };
-
- // run the correct responder with the cmd body
- ddoc_dispatch[cmd].apply(null, [fun, ddoc, funArgs]);
- } else {
- // unknown command, quit and hope the restarted version is better
- throw(["fatal", "unknown_command", "unknown ddoc command '" + cmd + "'"]);
- }
- }
- }
- };
-})();
-
-var Loop = function() {
- var line, cmd, cmdkey, dispatch = {
- "ddoc" : DDoc.ddoc,
- // "view" : Views.handler,
- "reset" : State.reset,
- "add_fun" : State.addFun,
- "map_doc" : Views.mapDoc,
- "reduce" : Views.reduce,
- "rereduce" : Views.rereduce
- };
- function handleError(e) {
- var type = e[0];
- if (type == "fatal") {
- e[0] = "error"; // we tell the client it was a fatal error by dying
- respond(e);
- quit(-1);
- } else if (type == "error") {
- respond(e);
- } else if (e.error && e.reason) {
- // compatibility with old error format
- respond(["error", e.error, e.reason]);
- } else {
- respond(["error","unnamed_error",e.toSource()]);
- }
- };
- while (line = readline()) {
- cmd = eval('('+line+')');
- State.line_length = line.length;
- try {
- cmdkey = cmd.shift();
- if (dispatch[cmdkey]) {
- // run the correct responder with the cmd body
- dispatch[cmdkey].apply(null, cmd);
- } else {
- // unknown command, quit and hope the restarted version is better
- throw(["fatal", "unknown_command", "unknown command '" + cmdkey + "'"]);
- }
- } catch(e) {
- handleError(e);
- }
- };
-};
-
-Loop();
diff --git a/apps/couch/js/mimeparse.js b/apps/couch/js/mimeparse.js
deleted file mode 100644
index 3642a194..00000000
--- a/apps/couch/js/mimeparse.js
+++ /dev/null
@@ -1,158 +0,0 @@
-// mimeparse.js
-//
-// This module provides basic functions for handling mime-types. It can
-// handle matching mime-types against a list of media-ranges. See section
-// 14.1 of the HTTP specification [RFC 2616] for a complete explanation.
-//
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
-//
-// A port to JavaScript of Joe Gregorio's MIME-Type Parser:
-//
-// http://code.google.com/p/mimeparse/
-//
-// Ported by J. Chris Anderson <jchris@apache.org>, targeting the Spidermonkey runtime.
-//
-// To run the tests, open mimeparse-js-test.html in a browser.
-// Ported from version 0.1.2
-// Comments are mostly excerpted from the original.
-
-var Mimeparse = (function() {
- // private helpers
- function strip(string) {
- return string.replace(/^\s+/, '').replace(/\s+$/, '')
- };
-
- function parseRanges(ranges) {
- var parsedRanges = [], rangeParts = ranges.split(",");
- for (var i=0; i < rangeParts.length; i++) {
- parsedRanges.push(publicMethods.parseMediaRange(rangeParts[i]))
- };
- return parsedRanges;
- };
-
- var publicMethods = {
- // Carves up a mime-type and returns an Array of the
- // [type, subtype, params] where "params" is a Hash of all
- // the parameters for the media range.
- //
- // For example, the media range "application/xhtml;q=0.5" would
- // get parsed into:
- //
- // ["application", "xhtml", { "q" : "0.5" }]
- parseMimeType : function(mimeType) {
- var fullType, typeParts, params = {}, parts = mimeType.split(';');
- for (var i=0; i < parts.length; i++) {
- var p = parts[i].split('=');
- if (p.length == 2) {
- params[strip(p[0])] = strip(p[1]);
- }
- };
- fullType = parts[0].replace(/^\s+/, '').replace(/\s+$/, '');
- if (fullType == '*') fullType = '*/*';
- typeParts = fullType.split('/');
- return [typeParts[0], typeParts[1], params];
- },
-
- // Carves up a media range and returns an Array of the
- // [type, subtype, params] where "params" is a Object with
- // all the parameters for the media range.
- //
- // For example, the media range "application/*;q=0.5" would
- // get parsed into:
- //
- // ["application", "*", { "q" : "0.5" }]
- //
- // In addition this function also guarantees that there
- // is a value for "q" in the params dictionary, filling it
- // in with a proper default if necessary.
- parseMediaRange : function(range) {
- var q, parsedType = this.parseMimeType(range);
- if (!parsedType[2]['q']) {
- parsedType[2]['q'] = '1';
- } else {
- q = parseFloat(parsedType[2]['q']);
- if (isNaN(q)) {
- parsedType[2]['q'] = '1';
- } else if (q > 1 || q < 0) {
- parsedType[2]['q'] = '1';
- }
- }
- return parsedType;
- },
-
- // Find the best match for a given mime-type against
- // a list of media_ranges that have already been
- // parsed by parseMediaRange(). Returns an array of
- // the fitness value and the value of the 'q' quality
- // parameter of the best match, or (-1, 0) if no match
- // was found. Just as for qualityParsed(), 'parsed_ranges'
- // must be a list of parsed media ranges.
- fitnessAndQualityParsed : function(mimeType, parsedRanges) {
- var bestFitness = -1, bestFitQ = 0, target = this.parseMediaRange(mimeType);
- var targetType = target[0], targetSubtype = target[1], targetParams = target[2];
-
- for (var i=0; i < parsedRanges.length; i++) {
- var parsed = parsedRanges[i];
- var type = parsed[0], subtype = parsed[1], params = parsed[2];
- if ((type == targetType || type == "*" || targetType == "*") &&
- (subtype == targetSubtype || subtype == "*" || targetSubtype == "*")) {
- var matchCount = 0;
- for (param in targetParams) {
- if (param != 'q' && params[param] && params[param] == targetParams[param]) {
- matchCount += 1;
- }
- }
-
- var fitness = (type == targetType) ? 100 : 0;
- fitness += (subtype == targetSubtype) ? 10 : 0;
- fitness += matchCount;
-
- if (fitness > bestFitness) {
- bestFitness = fitness;
- bestFitQ = params["q"];
- }
- }
- };
- return [bestFitness, parseFloat(bestFitQ)];
- },
-
- // Find the best match for a given mime-type against
- // a list of media_ranges that have already been
- // parsed by parseMediaRange(). Returns the
- // 'q' quality parameter of the best match, 0 if no
- // match was found. This function bahaves the same as quality()
- // except that 'parsedRanges' must be a list of
- // parsed media ranges.
- qualityParsed : function(mimeType, parsedRanges) {
- return this.fitnessAndQualityParsed(mimeType, parsedRanges)[1];
- },
-
- // Returns the quality 'q' of a mime-type when compared
- // against the media-ranges in ranges. For example:
- //
- // >>> Mimeparse.quality('text/html','text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
- // 0.7
- quality : function(mimeType, ranges) {
- return this.qualityParsed(mimeType, parseRanges(ranges));
- },
-
- // Takes a list of supported mime-types and finds the best
- // match for all the media-ranges listed in header. The value of
- // header must be a string that conforms to the format of the
- // HTTP Accept: header. The value of 'supported' is a list of
- // mime-types.
- //
- // >>> bestMatch(['application/xbel+xml', 'text/xml'], 'text/*;q=0.5,*/*; q=0.1')
- // 'text/xml'
- bestMatch : function(supported, header) {
- var parsedHeader = parseRanges(header);
- var weighted = [];
- for (var i=0; i < supported.length; i++) {
- weighted.push([publicMethods.fitnessAndQualityParsed(supported[i], parsedHeader), i, supported[i]])
- };
- weighted.sort();
- return weighted[weighted.length-1][0][1] ? weighted[weighted.length-1][2] : '';
- }
- }
- return publicMethods;
-})();
diff --git a/apps/couch/js/render.js b/apps/couch/js/render.js
deleted file mode 100644
index 9dcfbcd6..00000000
--- a/apps/couch/js/render.js
+++ /dev/null
@@ -1,352 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-
-var Mime = (function() {
- // registerType(name, mime-type, mime-type, ...)
- //
- // Available in query server sandbox. TODO: The list is cleared on reset.
- // This registers a particular name with the set of mimetypes it can handle.
- // Whoever registers last wins.
- //
- // Example:
- // registerType("html", "text/html; charset=utf-8");
-
- var mimesByKey = {};
- var keysByMime = {};
- function registerType() {
- var mimes = [], key = arguments[0];
- for (var i=1; i < arguments.length; i++) {
- mimes.push(arguments[i]);
- };
- mimesByKey[key] = mimes;
- for (var i=0; i < mimes.length; i++) {
- keysByMime[mimes[i]] = key;
- };
- }
-
- // Some default types
- // Ported from Ruby on Rails
- // Build list of Mime types for HTTP responses
- // http://www.iana.org/assignments/media-types/
- // http://dev.rubyonrails.org/svn/rails/trunk/actionpack/lib/action_controller/mime_types.rb
-
- registerType("all", "*/*");
- registerType("text", "text/plain; charset=utf-8", "txt");
- registerType("html", "text/html; charset=utf-8");
- registerType("xhtml", "application/xhtml+xml", "xhtml");
- registerType("xml", "application/xml", "text/xml", "application/x-xml");
- registerType("js", "text/javascript", "application/javascript", "application/x-javascript");
- registerType("css", "text/css");
- registerType("ics", "text/calendar");
- registerType("csv", "text/csv");
- registerType("rss", "application/rss+xml");
- registerType("atom", "application/atom+xml");
- registerType("yaml", "application/x-yaml", "text/yaml");
- // just like Rails
- registerType("multipart_form", "multipart/form-data");
- registerType("url_encoded_form", "application/x-www-form-urlencoded");
- // http://www.ietf.org/rfc/rfc4627.txt
- registerType("json", "application/json", "text/x-json");
-
-
- var mimeFuns = [];
- function provides(type, fun) {
- Mime.providesUsed = true;
- mimeFuns.push([type, fun]);
- };
-
- function resetProvides() {
- // set globals
- Mime.providesUsed = false;
- mimeFuns = [];
- Mime.responseContentType = null;
- };
-
- function runProvides(req) {
- var supportedMimes = [], bestFun, bestKey = null, accept = req.headers["Accept"];
- if (req.query && req.query.format) {
- bestKey = req.query.format;
- Mime.responseContentType = mimesByKey[bestKey][0];
- } else if (accept) {
- // log("using accept header: "+accept);
- mimeFuns.reverse().forEach(function(mimeFun) {
- var mimeKey = mimeFun[0];
- if (mimesByKey[mimeKey]) {
- supportedMimes = supportedMimes.concat(mimesByKey[mimeKey]);
- }
- });
- Mime.responseContentType = Mimeparse.bestMatch(supportedMimes, accept);
- bestKey = keysByMime[Mime.responseContentType];
- } else {
- // just do the first one
- bestKey = mimeFuns[0][0];
- Mime.responseContentType = mimesByKey[bestKey][0];
- }
-
- if (bestKey) {
- for (var i=0; i < mimeFuns.length; i++) {
- if (mimeFuns[i][0] == bestKey) {
- bestFun = mimeFuns[i][1];
- break;
- }
- };
- };
-
- if (bestFun) {
- return bestFun();
- } else {
- var supportedTypes = mimeFuns.map(function(mf) {return mimesByKey[mf[0]].join(', ') || mf[0]});
- throw(["error","not_acceptable",
- "Content-Type "+(accept||bestKey)+" not supported, try one of: "+supportedTypes.join(', ')]);
- }
- };
-
-
- return {
- registerType : registerType,
- provides : provides,
- resetProvides : resetProvides,
- runProvides : runProvides
- }
-})();
-
-
-
-
-////
-//// Render dispatcher
-////
-////
-////
-////
-
-var Render = (function() {
- var chunks = [];
-
-
- // Start chunks
- var startResp = {};
- function start(resp) {
- startResp = resp || {};
- };
-
- function sendStart() {
- startResp = applyContentType((startResp || {}), Mime.responseContentType);
- respond(["start", chunks, startResp]);
- chunks = [];
- startResp = {};
- }
-
- function applyContentType(resp, responseContentType) {
- resp["headers"] = resp["headers"] || {};
- if (responseContentType) {
- resp["headers"]["Content-Type"] = resp["headers"]["Content-Type"] || responseContentType;
- }
- return resp;
- }
-
- function send(chunk) {
- chunks.push(chunk.toString());
- };
-
- function blowChunks(label) {
- respond([label||"chunks", chunks]);
- chunks = [];
- };
-
- var gotRow = false, lastRow = false;
- function getRow() {
- if (lastRow) return null;
- if (!gotRow) {
- gotRow = true;
- sendStart();
- } else {
- blowChunks();
- }
- var line = readline();
- var json = eval('('+line+')');
- if (json[0] == "list_end") {
- lastRow = true;
- return null;
- }
- if (json[0] != "list_row") {
- throw(["fatal", "list_error", "not a row '" + json[0] + "'"]);
- }
- return json[1];
- };
-
-
- function maybeWrapResponse(resp) {
- var type = typeof resp;
- if ((type == "string") || (type == "xml")) {
- return {body:resp};
- } else {
- return resp;
- }
- };
-
- // from http://javascript.crockford.com/remedial.html
- function typeOf(value) {
- var s = typeof value;
- if (s === 'object') {
- if (value) {
- if (value instanceof Array) {
- s = 'array';
- }
- } else {
- s = 'null';
- }
- }
- return s;
- };
-
- function isDocRequestPath(info) {
- var path = info.path;
- return path.length > 5;
- };
-
- function runShow(fun, ddoc, args) {
- try {
- resetList();
- Mime.resetProvides();
- var resp = fun.apply(ddoc, args) || {};
-
- // handle list() style API
- if (chunks.length && chunks.length > 0) {
- resp = maybeWrapResponse(resp);
- resp.headers = resp.headers || {};
- for(var header in startResp) {
- resp.headers[header] = startResp[header]
- }
- resp.body = chunks.join("") + (resp.body || "");
- resetList();
- }
-
- if (Mime.providesUsed) {
- resp = Mime.runProvides(args[1]);
- resp = applyContentType(maybeWrapResponse(resp), Mime.responseContentType);
- }
-
- var type = typeOf(resp);
- if (type == 'object' || type == 'string') {
- respond(["resp", maybeWrapResponse(resp)]);
- } else {
- throw(["error", "render_error", "undefined response from show function"]);
- }
- } catch(e) {
- if (args[0] === null && isDocRequestPath(args[1])) {
- throw(["error", "not_found", "document not found"]);
- } else {
- renderError(e, fun.toSource());
- }
- }
- };
-
- function runUpdate(fun, ddoc, args) {
- try {
- var method = args[1].method;
- // for analytics logging applications you might want to remove the next line
- if (method == "GET") throw(["error","method_not_allowed","Update functions do not allow GET"]);
- var result = fun.apply(ddoc, args);
- var doc = result[0];
- var resp = result[1];
- var type = typeOf(resp);
- if (type == 'object' || type == 'string') {
- respond(["up", doc, maybeWrapResponse(resp)]);
- } else {
- throw(["error", "render_error", "undefined response from update function"]);
- }
- } catch(e) {
- renderError(e, fun.toSource());
- }
- };
-
- function resetList() {
- gotRow = false;
- lastRow = false;
- chunks = [];
- startResp = {};
- };
-
- function runList(listFun, ddoc, args) {
- try {
- Mime.resetProvides();
- resetList();
- head = args[0]
- req = args[1]
- var tail = listFun.apply(ddoc, args);
-
- if (Mime.providesUsed) {
- tail = Mime.runProvides(req);
- }
- if (!gotRow) getRow();
- if (typeof tail != "undefined") {
- chunks.push(tail);
- }
- blowChunks("end");
- } catch(e) {
- renderError(e, listFun.toSource());
- }
- };
-
- function renderError(e, funSrc) {
- if (e.error && e.reason || e[0] == "error" || e[0] == "fatal") {
- throw(e);
- } else {
- var logMessage = "function raised error: "+e.toSource()+" \nstacktrace: "+e.stack;
- log(logMessage);
- throw(["error", "render_error", logMessage]);
- }
- };
-
- function escapeHTML(string) {
- return string && string.replace(/&/g, "&amp;")
- .replace(/</g, "&lt;")
- .replace(/>/g, "&gt;");
- };
-
-
- return {
- start : start,
- send : send,
- getRow : getRow,
- show : function(fun, ddoc, args) {
- // var showFun = Couch.compileFunction(funSrc);
- runShow(fun, ddoc, args);
- },
- update : function(fun, ddoc, args) {
- // var upFun = Couch.compileFunction(funSrc);
- runUpdate(fun, ddoc, args);
- },
- list : function(fun, ddoc, args) {
- runList(fun, ddoc, args);
- }
- };
-})();
-
-// send = Render.send;
-// getRow = Render.getRow;
-// start = Render.start;
-
-// unused. this will be handled in the Erlang side of things.
-// function htmlRenderError(e, funSrc) {
-// var msg = ["<html><body><h1>Render Error</h1>",
-// "<p>JavaScript function raised error: ",
-// e.toString(),
-// "</p><h2>Stacktrace:</h2><code><pre>",
-// escapeHTML(e.stack),
-// "</pre></code><h2>Function source:</h2><code><pre>",
-// escapeHTML(funSrc),
-// "</pre></code></body></html>"].join('');
-// return {body:msg};
-// };
diff --git a/apps/couch/js/state.js b/apps/couch/js/state.js
deleted file mode 100644
index 9af9e475..00000000
--- a/apps/couch/js/state.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-var State = {
- reset : function(config) {
- // clear the globals and run gc
- State.funs = [];
- State.query_config = config || {};
- init_sandbox();
- gc();
- print("true"); // indicates success
- },
- addFun : function(newFun) {
- // Compile to a function and add it to funs array
- State.funs.push(Couch.compileFunction(newFun));
- print("true");
- }
-}
diff --git a/apps/couch/js/util.js b/apps/couch/js/util.js
deleted file mode 100644
index 9cc464c3..00000000
--- a/apps/couch/js/util.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-var resolveModule = function(names, parent, current, path) {
- if (names.length == 0) {
- if (typeof current != "string") {
- throw ["error","invalid_require_path",
- 'Must require a JavaScript string, not: '+(typeof current)];
- }
- return [current, parent, path];
- }
- // we need to traverse the path
- var n = names.shift();
- if (n == '..') {
- if (!(parent && parent.parent)) {
- throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
- }
- path = path.slice(0, path.lastIndexOf('/'));
- return resolveModule(names, parent.parent.parent, parent.parent, path);
- } else if (n == '.') {
- if (!parent) {
- throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
- }
- return resolveModule(names, parent.parent, parent, path);
- }
- if (!current[n]) {
- throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(current)];
- }
- var p = current;
- current = current[n];
- current.parent = p;
- path = path ? path + '/' + n : n;
- return resolveModule(names, p, current, path);
-};
-
-var Couch = {
- // moving this away from global so we can move to json2.js later
- toJSON : function (val) {
- return JSON.stringify(val);
- },
- compileFunction : function(source, ddoc) {
- if (!source) throw(["error","not_found","missing function"]);
- try {
- if (sandbox) {
- if (ddoc) {
- var require = function(name, parent) {
- if (!parent) {parent = {}};
- var resolved = resolveModule(name.split('/'), parent.actual, ddoc, parent.id);
- var s = "function (module, exports, require) { " + resolved[0] + " }";
- var module = {id:resolved[2], actual:resolved[1]};
- module.exports = {};
- try {
- var func = sandbox ? evalcx(s, sandbox) : eval(s);
- func.apply(sandbox, [module, module.exports, function(name) {return require(name, module)}]);
- } catch(e) {
- throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
- }
- return module.exports;
- }
- sandbox.require = require;
- }
- var functionObject = evalcx(source, sandbox);
- } else {
- var functionObject = eval(source);
- }
- } catch (err) {
- throw(["error", "compilation_error", err.toSource() + " (" + source + ")"]);
- };
- if (typeof(functionObject) == "function") {
- return functionObject;
- } else {
- throw(["error","compilation_error",
- "Expression does not eval to a function. (" + source.toSource() + ")"]);
- };
- },
- recursivelySeal : function(obj) {
- // seal() is broken in current Spidermonkey
- seal(obj);
- for (var propname in obj) {
- if (typeof doc[propname] == "object") {
- recursivelySeal(doc[propname]);
- }
- }
- }
-}
-
-// prints the object as JSON, and rescues and logs any toJSON() related errors
-function respond(obj) {
- try {
- print(Couch.toJSON(obj));
- } catch(e) {
- log("Error converting object to JSON: " + e.toString());
- log("error on obj: "+ obj.toSource());
- }
-};
-
-function log(message) {
- // idea: query_server_config option for log level
- if (typeof message != "string") {
- message = Couch.toJSON(message);
- }
- respond(["log", message]);
-};
diff --git a/apps/couch/js/validate.js b/apps/couch/js/validate.js
deleted file mode 100644
index 76a14129..00000000
--- a/apps/couch/js/validate.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-var Validate = {
- validate : function(fun, ddoc, args) {
- try {
- fun.apply(ddoc, args);
- print("1");
- } catch (error) {
- respond(error);
- }
- }
-};
diff --git a/apps/couch/js/views.js b/apps/couch/js/views.js
deleted file mode 100644
index ffe63377..00000000
--- a/apps/couch/js/views.js
+++ /dev/null
@@ -1,137 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-
-
-var Views = (function() {
-
- var map_results = []; // holds temporary emitted values during doc map
-
- function runReduce(reduceFuns, keys, values, rereduce) {
- for (var i in reduceFuns) {
- reduceFuns[i] = Couch.compileFunction(reduceFuns[i]);
- };
- var reductions = new Array(reduceFuns.length);
- for(var i = 0; i < reduceFuns.length; i++) {
- try {
- reductions[i] = reduceFuns[i](keys, values, rereduce);
- } catch (err) {
- handleViewError(err);
- // if the error is not fatal, ignore the results and continue
- reductions[i] = null;
- }
- };
- var reduce_line = Couch.toJSON(reductions);
- var reduce_length = reduce_line.length;
- // TODO make reduce_limit config into a number
- if (State.query_config && State.query_config.reduce_limit &&
- reduce_length > 200 && ((reduce_length * 2) > State.line_length)) {
- var reduce_preview = "Current output: '"+(reduce_line.substring(0,100) + "'... (first 100 of "+reduce_length+" bytes)");
- throw(["error",
- "reduce_overflow_error",
- "Reduce output must shrink more rapidly: "+reduce_preview]);
- } else {
- print("[true," + reduce_line + "]");
- }
- };
-
- function handleViewError(err, doc) {
- if (err == "fatal_error") {
- // Only if it's a "fatal_error" do we exit. What's a fatal error?
- // That's for the query to decide.
- //
- // This will make it possible for queries to completely error out,
- // by catching their own local exception and rethrowing a
- // fatal_error. But by default if they don't do error handling we
- // just eat the exception and carry on.
- //
- // In this case we abort map processing but don't destroy the
- // JavaScript process. If you need to destroy the JavaScript
- // process, throw the error form matched by the block below.
- throw(["error", "map_runtime_error", "function raised 'fatal_error'"]);
- } else if (err[0] == "fatal") {
- // Throwing errors of the form ["fatal","error_key","reason"]
- // will kill the OS process. This is not normally what you want.
- throw(err);
- }
- var message = "function raised exception " + err.toSource();
- if (doc) message += " with doc._id " + doc._id;
- log(message);
- };
-
- return {
- // view helper functions
- emit : function(key, value) {
- map_results.push([key, value]);
- },
- sum : function(values) {
- var rv = 0;
- for (var i in values) {
- rv += values[i];
- }
- return rv;
- },
- reduce : function(reduceFuns, kvs) {
- var keys = new Array(kvs.length);
- var values = new Array(kvs.length);
- for(var i = 0; i < kvs.length; i++) {
- keys[i] = kvs[i][0];
- values[i] = kvs[i][1];
- }
- runReduce(reduceFuns, keys, values, false);
- },
- rereduce : function(reduceFuns, values) {
- runReduce(reduceFuns, null, values, true);
- },
- mapDoc : function(doc) {
- // Compute all the map functions against the document.
- //
- // Each function can output multiple key/value pairs for each document.
- //
- // Example output of map_doc after three functions set by add_fun cmds:
- // [
- // [["Key","Value"]], <- fun 1 returned 1 key value
- // [], <- fun 2 returned 0 key values
- // [["Key1","Value1"],["Key2","Value2"]] <- fun 3 returned 2 key values
- // ]
- //
-
- /*
- Immutable document support temporarily removed.
-
- Removed because the seal function no longer works on JS 1.8 arrays,
- instead returning an error. The sealing is meant to prevent map
- functions from modifying the same document that is passed to other map
- functions. However, only map functions in the same design document are
- run together, so we have a reasonable expectation they can trust each
- other. Any map fun that can't be trusted can be placed in its own
- design document, and it cannot affect other map functions.
-
- recursivelySeal(doc); // seal to prevent map functions from changing doc
- */
- var buf = [];
- for (var i = 0; i < State.funs.length; i++) {
- map_results = [];
- try {
- State.funs[i](doc);
- buf.push(Couch.toJSON(map_results));
- } catch (err) {
- handleViewError(err, doc);
- // If the error is not fatal, we treat the doc as if it
- // did not emit anything, by buffering an empty array.
- buf.push("[]");
- }
- }
- print("[" + buf.join(", ") + "]");
- }
- }
-})();