/* $Id$ Part of SWI-Prolog Author: Jan Wielemaker E-mail: wielemak@science.uva.nl WWW: http://www.swi-prolog.org Copyright (C): 1985-2007, University of Amsterdam This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #define TRYPUTC(c, s) if ( Sputcode(c, s) < 0 ) { return -1; } static int json_put_code(IOSTREAM *out, int c) { static char escape[128]; static int escape_initialized = FALSE; if ( !escape_initialized ) { memset(escape, 0, sizeof(escape)); escape['"'] = '"'; escape['\\'] = '\\'; escape['\b'] = 'b'; escape['\f'] = 'f'; escape['\n'] = 'n'; escape['\r'] = 'r'; escape['\t'] = 't'; escape_initialized = TRUE; } if ( c < 128 ) { if ( escape[c] ) { TRYPUTC('\\', out); TRYPUTC(escape[c], out); } else if ( c < ' ' ) /* control characters *must* be escaped */ { TRYPUTC('\\', out); if ( Sfprintf(out, "u%04x", c) < 0 ) return -1; } else { TRYPUTC(c, out); } } else { TRYPUTC(c, out); } return 0; } #undef TRYPUTC #define TRYPUTC(c, s) if ( Sputcode(c, s) < 0 ) { rc = FALSE; goto out; } static foreign_t json_write_string(term_t stream, term_t text) { IOSTREAM *out; char *a; pl_wchar_t *w; size_t len; int rc = TRUE; if ( !PL_get_stream_handle(stream, &out) ) return FALSE; if ( PL_get_nchars(text, &len, &a, CVT_ATOM|CVT_STRING|CVT_LIST) ) { const char *ap; size_t todo; TRYPUTC('"', out); for(todo=len, ap=a; todo-- > 0; ap++) { int c = *ap&0xff; if ( json_put_code(out, c) < 0 ) { rc = FALSE; goto out; } } TRYPUTC('"', out); } else if ( PL_get_wchars(text, &len, &w, CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION) ) { const pl_wchar_t *wp; size_t todo; TRYPUTC('"', out); for(todo=len, wp=w; todo-- > 0; wp++) { int c = *wp; if ( json_put_code(out, c) < 0 ) { rc = FALSE; goto out; } } TRYPUTC('"', out); } else { rc = FALSE; } out: PL_release_stream(out); return rc; } static foreign_t json_write_indent(term_t stream, term_t indent, term_t tab) { int i, t, n; IOSTREAM *out; if ( !PL_get_integer(indent, &i) || !PL_get_integer(tab, &t) ) return FALSE; if ( PL_get_stream_handle(stream, &out) ) { int rc = TRUE; if ( !out->position || out->position->linepos > 0 ) { TRYPUTC('\n', out); } for(n=0; n