153 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			153 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*  $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 <SWI-Stream.h>
							 | 
						||
| 
								 | 
							
								#include <SWI-Prolog.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#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<i/t; n++)
							 | 
						||
| 
								 | 
							
								      TRYPUTC('\t', out);
							 | 
						||
| 
								 | 
							
								    for(n=0; n<i%t; n++)
							 | 
						||
| 
								 | 
							
								      TRYPUTC(' ', out);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    PL_release_stream(out);
							 | 
						||
| 
								 | 
							
								    return rc;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return FALSE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								install_t
							 | 
						||
| 
								 | 
							
								install_json()
							 | 
						||
| 
								 | 
							
								{ PL_register_foreign("json_write_string", 2, json_write_string, 0);
							 | 
						||
| 
								 | 
							
								  PL_register_foreign("json_write_indent", 3, json_write_indent, 0);
							 | 
						||
| 
								 | 
							
								}
							 |