117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*  $Id$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Part of SWI-Prolog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Author:        Jan Wielemaker
							 | 
						||
| 
								 | 
							
								    E-mail:        jan@science.uva.nl
							 | 
						||
| 
								 | 
							
								    WWW:           http://www.swi-prolog.org
							 | 
						||
| 
								 | 
							
								    Copyright (C): 1985-2005, University of Amsterdam
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This program is free software; you can redistribute it and/or
							 | 
						||
| 
								 | 
							
								    modify it under the terms of the GNU General Public License
							 | 
						||
| 
								 | 
							
								    as published by the Free Software Foundation; either version 2
							 | 
						||
| 
								 | 
							
								    of the License, or (at your option) any later version.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    This program 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 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    As a special exception, if you link this library with other files,
							 | 
						||
| 
								 | 
							
								    compiled with a Free Software compiler, to produce an executable, this
							 | 
						||
| 
								 | 
							
								    library does not by itself cause the resulting executable to be covered
							 | 
						||
| 
								 | 
							
								    by the GNU General Public License. This exception does not however
							 | 
						||
| 
								 | 
							
								    invalidate any other reasons why the executable file might be covered by
							 | 
						||
| 
								 | 
							
								    the GNU General Public License.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef PLVERSION
							 | 
						||
| 
								 | 
							
								#include <SWI-Prolog.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
							 | 
						||
| 
								 | 
							
								Ideally we should have various of these tables and distinguish the host,
							 | 
						||
| 
								 | 
							
								path, query and fragment parts. See RFC3986 for details.
							 | 
						||
| 
								 | 
							
								- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static char *
							 | 
						||
| 
								 | 
							
								uri_ok()
							 | 
						||
| 
								 | 
							
								{ static char ok[128];
							 | 
						||
| 
								 | 
							
								  int done = FALSE;
							 | 
						||
| 
								 | 
							
								  const char *s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if ( !done )
							 | 
						||
| 
								 | 
							
								  { int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for(i='a'; i<='z'; i++)
							 | 
						||
| 
								 | 
							
								      ok[i] = TRUE;
							 | 
						||
| 
								 | 
							
								    for(i='A'; i<='Z'; i++)
							 | 
						||
| 
								 | 
							
								      ok[i] = TRUE;
							 | 
						||
| 
								 | 
							
								    for(i='0'; i<='9'; i++)
							 | 
						||
| 
								 | 
							
								      ok[i] = TRUE;
							 | 
						||
| 
								 | 
							
								    for(s="-_.!~*'()"; *s; s++)		/* used to have [], but these general delimiters */
							 | 
						||
| 
								 | 
							
								      ok[(int)*s] = TRUE;		/* cannot be in a fragment or path */
							 | 
						||
| 
								 | 
							
								    for(s=";/&?:@=#"; *s; s++)
							 | 
						||
| 
								 | 
							
								      ok[(int)*s] = TRUE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    done = TRUE;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return ok;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
							 | 
						||
| 
								 | 
							
								RDF (Unicode) URIs are  first  mapped  to   UTF-8  and  then  unsafe and
							 | 
						||
| 
								 | 
							
								characters outside the printable US-ASCII range   are represented as %XX
							 | 
						||
| 
								 | 
							
								where XX is the hexadecimal version of the  octed. We moved this to C to
							 | 
						||
| 
								 | 
							
								exploit much faster character operations.
							 | 
						||
| 
								 | 
							
								- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static foreign_t
							 | 
						||
| 
								 | 
							
								rdf_quote_uri(term_t uri, term_t quoted)
							 | 
						||
| 
								 | 
							
								{ char *in;
							 | 
						||
| 
								 | 
							
								  const char *s;
							 | 
						||
| 
								 | 
							
								  const char *ok = uri_ok();
							 | 
						||
| 
								 | 
							
								  size_t len;
							 | 
						||
| 
								 | 
							
								  int nok;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if ( !PL_get_nchars(uri, &len, &in, CVT_ATOM|REP_UTF8|CVT_EXCEPTION) )
							 | 
						||
| 
								 | 
							
								    return FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for(s=in, nok=0; *s; s++)
							 | 
						||
| 
								 | 
							
								  { int c = *s&0xff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ( c >= 128 || !ok[c] )
							 | 
						||
| 
								 | 
							
								    { nok++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if ( nok )
							 | 
						||
| 
								 | 
							
								  { char *buf = alloca(len+nok*2+1);
							 | 
						||
| 
								 | 
							
								    char *o = buf;
							 | 
						||
| 
								 | 
							
								    static char xdigit[] = "0123456789ABCDEF";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for(s=in; *s; s++)
							 | 
						||
| 
								 | 
							
								    { int c = *s&0xff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if ( c >= 128 || !ok[c] )
							 | 
						||
| 
								 | 
							
								      { *o++ = '%';
							 | 
						||
| 
								 | 
							
								        *o++ = xdigit[(c>>4)&0xf];
							 | 
						||
| 
								 | 
							
								        *o++ = xdigit[c&0xf];
							 | 
						||
| 
								 | 
							
								      } else
							 | 
						||
| 
								 | 
							
								      { *o++ = c;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *o = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return PL_unify_atom_nchars(quoted, len+nok*2, buf);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return PL_unify(uri, quoted);
							 | 
						||
| 
								 | 
							
								}
							 |