1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00

lookup_interned_symbol uses get_handle_by_hash

* libguile/symbols.c (lookup_interned_symbol): Change to use
  scm_hash_fn_get_handle_by_hash.
This commit is contained in:
Andy Wingo 2011-01-07 08:42:15 -08:00
parent 6efbc280c5
commit 17072fd2c6
2 changed files with 176 additions and 108 deletions

View file

@ -472,14 +472,49 @@ Write the first line of an HTTP response to @var{port}.
@node HTTP Headers @node HTTP Headers
@subsection HTTP Headers @subsection HTTP Headers
The @code{(web http)} module defines parsers and unparsers for all In addition to defining the infrastructure to parse headers, the
headers defined in the HTTP/1.1 standard. This section describes the @code{(web http)} module defines specific parsers and unparsers for all
headers defined in the HTTP/1.1 standard.
For example, if you receive a header named @samp{Accept-Language} with a
value @samp{en, es;q=0.8}, Guile parses it as follows:
@example
(parse-header "Accept-Language" "en, es;q=0.8")
@result{} accept-language
@result{} ((1000 . "en") (800 . "es"))
@end example
There are two results, because @code{parse-header} returns two
values. The first value is a symbol, because the @code{accept-language}
header is known to Guile and has a parser registered. The format of the
value for @code{accept-language} headers is defined below, along with
all other headers defined in the HTTP standard. (If the header were not
recognized, it and the value would be returned as strings.)
For brevity, the header definitions below are given in the form,
@var{type} @code{@var{name}}, indicating that values for the header
@code{@var{name}} will be of the given @var{type}. A short description
of the each header's purpose and an example follow. For full details on
the meanings of all of these headers, see the HTTP 1.1 standard, RFC
2616.
@subsubsection HTTP Header Types
@deftp {HTTP Header Type} Date
foo
@end deftp
So for example if you are implementing a
This section describes the
parsed format of the various headers. parsed format of the various headers.
We cannot describe the function of all of these headers, however, in We cannot describe the function of all of these headers, however, in
sufficient detail. The interested reader would do well to download a sufficient detail. The interested reader would do well to download a
copy of RFC 2616 and have it on hand. copy of RFC 2616 and have it on hand.
example? and examples in each, and brief meaning description.
To begin with, we should make a few definitions: To begin with, we should make a few definitions:
@table @dfn @table @dfn
@ -491,11 +526,6 @@ which is the symbol or string key, and the cdr is the parsed value.
Parsed values for known keys have key-dependent formats. Parsed values Parsed values for known keys have key-dependent formats. Parsed values
for unknown keys are strings. for unknown keys are strings.
@item param list
A param list is a list of key-value lists. When serialized to a string,
items in the inner lists are separated by semicolons. Again, known keys
are parsed to symbols.
@item quality @item quality
A number of headers have quality values in them, which are decimal A number of headers have quality values in them, which are decimal
fractions between zero and one indicating a preference for various kinds fractions between zero and one indicating a preference for various kinds
@ -515,8 +545,7 @@ true iff the entity tag is a ``strong'' entity tag.
@subsubsection General Headers @subsubsection General Headers
@table @code @deftypevr {HTTP Header} KVList cache-control
@item cache-control
A key-value list of cache-control directives. Known keys are A key-value list of cache-control directives. Known keys are
@code{max-age}, @code{max-stale}, @code{min-fresh}, @code{max-age}, @code{max-stale}, @code{min-fresh},
@code{must-revalidate}, @code{no-cache}, @code{no-store}, @code{must-revalidate}, @code{no-cache}, @code{no-store},
@ -530,68 +559,82 @@ integers.
If present, parameters to @code{private} and @code{no-cache} are parsed If present, parameters to @code{private} and @code{no-cache} are parsed
as lists of header names, represented as symbols if they are known as lists of header names, represented as symbols if they are known
headers or strings otherwise. headers or strings otherwise.
@end deftypevr
@item connection @deftypevr {HTTP Header} @i{List of Strings} connection
A list of connection tokens. A connection token is a string. A list of connection tokens. A connection token is a string.
@end deftypevr
@item date @deftypevr {HTTP Header} {date} date
A SRFI-19 date record. A SRFI-19 date record.
@end deftypevr
@item pragma @deftypevr {HTTP Header} {Key-Value List} pragma
A key-value list of pragma directives. @code{no-cache} is the only A key-value list of pragma directives. @code{no-cache} is the only
known key. known key.
@end deftypevr
@item trailer @deftypevr {HTTP Header} {tp} trailer
A list of header names. Known header names are parsed to symbols, A list of header names. Known header names are parsed to symbols,
otherwise they are left as strings. otherwise they are left as strings.
@end deftypevr
@item transfer-encoding @deftypevr {HTTP Header} {tp} transfer-encoding
A param list of transfer codings. @code{chunked} is the only known key. A param list of transfer codings. @code{chunked} is the only known key.
@end deftypevr
@item upgrade @deftypevr {HTTP Header} {tp} upgrade
A list of strings. A list of strings.
@end deftypevr
@item via @deftypevr {HTTP Header} {tp} via
A list of strings. There may be multiple @code{via} headers in ne A list of strings. There may be multiple @code{via} headers in ne
message. message.
@end deftypevr
@item warning @deftypevr {HTTP Header} {tp} warning
A list of warnings. Each warning is a itself a list of four elements: a A list of warnings. Each warning is a itself a list of four elements: a
code, as an exact integer between 0 and 1000, a host as a string, the code, as an exact integer between 0 and 1000, a host as a string, the
warning text as a string, and either @code{#f} or a SRFI-19 date. warning text as a string, and either @code{#f} or a SRFI-19 date.
There may be multiple @code{warning} headers in one message. There may be multiple @code{warning} headers in one message.
@end table @end deftypevr
@subsubsection Entity Headers @subsubsection Entity Headers
@table @code @deftypevr {HTTP Header} {tp} allow
@item allow
A list of methods, as strings. Methods are parsed as strings instead of A list of methods, as strings. Methods are parsed as strings instead of
@code{parse-http-method} so as to allow for new methods. @code{parse-http-method} so as to allow for new methods.
@end deftypevr
@item content-encoding @deftypevr {HTTP Header} {tp} content-encoding
A list of content codings, as strings. A list of content codings, as strings.
@end deftypevr
@item content-language @deftypevr {HTTP Header} {tp} content-language
A list of language tags, as strings. A list of language tags, as strings.
@end deftypevr
@item content-length @deftypevr {HTTP Header} {tp} content-length
An exact, non-negative integer. An exact, non-negative integer.
@end deftypevr
@item content-location @deftypevr {HTTP Header} {tp} content-location
A URI record. A URI record.
@end deftypevr
@item content-md5 @deftypevr {HTTP Header} {tp} content-md5
A string. A string.
@end deftypevr
@item content-range @deftypevr {HTTP Header} {tp} content-range
A list of three elements: the symbol @code{bytes}, either the symbol A list of three elements: the symbol @code{bytes}, either the symbol
@code{*} or a pair of integers, indicating the byte rage, and either @code{*} or a pair of integers, indicating the byte rage, and either
@code{*} or an integer, for the instance length. @code{*} or an integer, for the instance length.
@end deftypevr
@item content-type @deftypevr {HTTP Header} {tp} content-type
A pair, the car of which is the media type as a string, and the cdr is A pair, the car of which is the media type as a string, and the cdr is
an alist of parameters, with strings as keys and values. an alist of parameters, with strings as keys and values.
@ -599,116 +642,144 @@ For example, @code{"text/plain"} parses as @code{("text/plain")}, and
@code{"text/plain;charset=utf-8"} parses as @code{("text/plain" @code{"text/plain;charset=utf-8"} parses as @code{("text/plain"
("charset" . "utf-8"))}. ("charset" . "utf-8"))}.
@item expires note charset and encoding
A SRFI-19 date. @end deftypevr
@item last-modified @deftypevr {HTTP Header} {tp} expires
A SRFI-19 date. A SRFI-19 date.
@end deftypevr
@end table @deftypevr {HTTP Header} {tp} last-modified
A SRFI-19 date.
@end deftypevr
@subsubsection Request Headers @subsubsection Request Headers
@table @code @deftypevr {HTTP Header} {tp} accept
@item accept
A param list. Each element in the list indicates one media-range A param list. Each element in the list indicates one media-range
with accept-params. They only known key is @code{q}, whose value is with accept-params. They only known key is @code{q}, whose value is
parsed as a quality value. parsed as a quality value.
@end deftypevr
@item accept-charset @deftypevr {HTTP Header} {tp} accept-charset
A quality-list of charsets, as strings. A quality-list of charsets, as strings.
@item accept-encoding charset and encoding
@end deftypevr
@deftypevr {HTTP Header} {tp} accept-encoding
A quality-list of content codings, as strings. A quality-list of content codings, as strings.
@end deftypevr
@item accept-language @deftypevr {HTTP Header} {tp} accept-language
A quality-list of languages, as strings. A quality-list of languages, as strings.
@end deftypevr
@item authorization @deftypevr {HTTP Header} {tp} authorization
A string. A string.
@end deftypevr
@item expect @deftypevr {HTTP Header} {tp} expect
A param list of expectations. The only known key is A param list of expectations. The only known key is
@code{100-continue}. @code{100-continue}.
@end deftypevr
@item from @deftypevr {HTTP Header} {tp} from
A string. A string.
@end deftypevr
@item host @deftypevr {HTTP Header} {tp} host
A pair of the host, as a string, and the port, as an integer. If no port A pair of the host, as a string, and the port, as an integer. If no port
is given, port is @code{#f}. is given, port is @code{#f}.
@end deftypevr
@item if-match @deftypevr {HTTP Header} {tp} if-match
Either the symbol @code{*}, or a list of entity tags (see above). Either the symbol @code{*}, or a list of entity tags (see above).
@end deftypevr
@item if-modified-since @deftypevr {HTTP Header} {tp} if-modified-since
A SRFI-19 date. A SRFI-19 date.
@end deftypevr
@item if-none-match @deftypevr {HTTP Header} {tp} if-none-match
Either the symbol @code{*}, or a list of entity tags (see above). Either the symbol @code{*}, or a list of entity tags (see above).
@end deftypevr
@item if-range @deftypevr {HTTP Header} {tp} if-range
Either an entity tag, or a SRFI-19 date. Either an entity tag, or a SRFI-19 date.
@end deftypevr
@item if-unmodified-since @deftypevr {HTTP Header} {tp} if-unmodified-since
A SRFI-19 date. A SRFI-19 date.
@end deftypevr
@item max-forwards @deftypevr {HTTP Header} {tp} max-forwards
An exact non-negative integer. An exact non-negative integer.
@end deftypevr
@item proxy-authorization @deftypevr {HTTP Header} {tp} proxy-authorization
A string. A string.
@end deftypevr
@item range @deftypevr {HTTP Header} {tp} range
A pair whose car is the symbol @code{bytes}, and whose cdr is a list of A pair whose car is the symbol @code{bytes}, and whose cdr is a list of
pairs. Each element of the cdr indicates a range; the car is the first pairs. Each element of the cdr indicates a range; the car is the first
byte position and the cdr is the last byte position, as integers, or byte position and the cdr is the last byte position, as integers, or
@code{#f} if not given. @code{#f} if not given.
@end deftypevr
@item referer @deftypevr {HTTP Header} {tp} referer
A URI. A URI.
@end deftypevr
@item te @deftypevr {HTTP Header} {tp} te
A param list of transfer-codings. The only known key is A param list of transfer-codings. The only known key is
@code{trailers}. @code{trailers}.
@end deftypevr
@item user-agent @deftypevr {HTTP Header} {tp} user-agent
A string. A string.
@end table @end deftypevr
@subsubsection Response Headers @subsubsection Response Headers
@table @code @deftypevr {HTTP Header} {tp} accept-ranges
@item accept-ranges
A list of strings. A list of strings.
@end deftypevr
@item age @deftypevr {HTTP Header} {tp} age
An exact, non-negative integer. An exact, non-negative integer.
@end deftypevr
@item etag @deftypevr {HTTP Header} {tp} etag
An entity tag. An entity tag.
@end deftypevr
@item location @deftypevr {HTTP Header} {tp} location
A URI. A URI.
@end deftypevr
@item proxy-authenticate @deftypevr {HTTP Header} {tp} proxy-authenticate
A string. A string.
@end deftypevr
@item retry-after @deftypevr {HTTP Header} {tp} retry-after
Either an exact, non-negative integer, or a SRFI-19 date. Either an exact, non-negative integer, or a SRFI-19 date.
@end deftypevr
@item server @deftypevr {HTTP Header} {tp} server
A string. A string.
@end deftypevr
@item vary @deftypevr {HTTP Header} {tp} vary
Either the symbol @code{*}, or a list of headers, with known headers Either the symbol @code{*}, or a list of headers, with known headers
parsed to symbols. parsed to symbols.
@end deftypevr
@item www-authenticate @deftypevr {HTTP Header} {tp} www-authenticate
A string. A string. (FIXME)
@end table @end deftypevr
@node Requests @node Requests
@ -723,6 +794,8 @@ the body is not part of the request, but the port is. Once you have
read a request, you may read the body separately, and likewise for read a request, you may read the body separately, and likewise for
writing requests. writing requests.
discussion of charsets and bytes and stuff.
@defun build-request [#:method] [#:uri] [#:version] [#:headers] [#:port] [#:meta] [#:validate-headers?] @defun build-request [#:method] [#:uri] [#:version] [#:headers] [#:port] [#:meta] [#:validate-headers?]
Construct an HTTP request object. If @var{validate-headers?} is true, Construct an HTTP request object. If @var{validate-headers?} is true,
the headers are each run through their respective validators. the headers are each run through their respective validators.
@ -765,10 +838,12 @@ discussion of character sets in "HTTP Requests" in the manual, for more
information. information.
@end defun @end defun
Fixme^
@defun write-request r port @defun write-request r port
Write the given HTTP request to @var{port}. Write the given HTTP request to @var{port}.
Returns a new request, whose @code{request-port} will continue writing Return a new request, whose @code{request-port} will continue writing
on @var{port}, perhaps using some transfer encoding. on @var{port}, perhaps using some transfer encoding.
@end defun @end defun
@ -777,7 +852,7 @@ Reads the request body from @var{r}, as a string.
Assumes that the request port has ISO-8859-1 encoding, so that the Assumes that the request port has ISO-8859-1 encoding, so that the
number of characters to read is the same as the number of characters to read is the same as the
@code{request-content-length}. Returns @code{#f} if there was no request @code{request-content-length}. Return @code{#f} if there was no request
body. body.
@end defun @end defun
@ -787,7 +862,7 @@ corresponding to the HTTP request @var{r}.
@end defun @end defun
@defun read-request-body/bytevector r @defun read-request-body/bytevector r
Reads the request body from @var{r}, as a bytevector. Returns @code{#f} Reads the request body from @var{r}, as a bytevector. Return @code{#f}
if there was no request body. if there was no request body.
@end defun @end defun
@ -896,13 +971,14 @@ Construct an HTTP response object. If @var{validate-headers?} is true,
the headers are each run through their respective validators. the headers are each run through their respective validators.
@end defun @end defun
FIXME
@defun extend-response r k v . additional @defun extend-response r k v . additional
Extend an HTTP response by setting additional HTTP headers @var{k}, Extend an HTTP response by setting additional HTTP headers @var{k},
@var{v}. Returns a new HTTP response. @var{v}. Return a new HTTP response.
@end defun @end defun
@defun adapt-response-version response version @defun adapt-response-version response version
Adapt the given response to a different HTTP version. Returns a new HTTP Adapt the given response to a different HTTP version. Return a new HTTP
response. response.
The idea is that many applications might just build a response for the The idea is that many applications might just build a response for the
@ -915,7 +991,7 @@ the version field.
@defun write-response r port @defun write-response r port
Write the given HTTP response to @var{port}. Write the given HTTP response to @var{port}.
Returns a new response, whose @code{response-port} will continue writing Return a new response, whose @code{response-port} will continue writing
on @var{port}, perhaps using some transfer encoding. on @var{port}, perhaps using some transfer encoding.
@end defun @end defun
@ -924,7 +1000,7 @@ Reads the response body from @var{r}, as a string.
Assumes that the response port has ISO-8859-1 encoding, so that the Assumes that the response port has ISO-8859-1 encoding, so that the
number of characters to read is the same as the number of characters to read is the same as the
@code{response-content-length}. Returns @code{#f} if there was no @code{response-content-length}. Return @code{#f} if there was no
response body. response body.
@end defun @end defun
@ -934,7 +1010,7 @@ corresponding to the HTTP response @var{r}.
@end defun @end defun
@defun read-response-body/bytevector r @defun read-response-body/bytevector r
Reads the response body from @var{r}, as a bytevector. Returns @code{#f} Read the response body from @var{r}, as a bytevector. Return @code{#f}
if there was no response body. if there was no response body.
@end defun @end defun
@ -1028,7 +1104,7 @@ A user-provided handler procedure is called, with the request
and body as its arguments. The handler should return two and body as its arguments. The handler should return two
values: the response, as a @code{<response>} record from @code{(web values: the response, as a @code{<response>} record from @code{(web
response)}, and the response body as a string, bytevector, or response)}, and the response body as a string, bytevector, or
@code{#f} if not present. We also allow the reponse to be simply an @code{#f} if not present. We also allow the response to be simply an
alist of headers, in which case a default response object is alist of headers, in which case a default response object is
constructed with those headers. constructed with those headers.
@ -1071,16 +1147,16 @@ that we don't expose the accessors for the various fields of a
any access to the impl objects. any access to the impl objects.
@defun open-server impl open-params @defun open-server impl open-params
Open a server for the given implementation. Returns one value, the new Open a server for the given implementation. Return one value, the new
server object. The implementation's @code{open} procedure is applied to server object. The implementation's @code{open} procedure is applied to
@var{open-params}, which should be a list. @var{open-params}, which should be a list.
@end defun @end defun
@defun read-client impl server @defun read-client impl server
Read a new client from @var{server}, by applying the implementation's Read a new client from @var{server}, by applying the implementation's
@code{read} procedure to the server. If successful, returns three @code{read} procedure to the server. If successful, return three
values: an object corresponding to the client, a request object, and the values: an object corresponding to the client, a request object, and the
request body. If any exception occurs, returns @code{#f} for all three request body. If any exception occurs, return @code{#f} for all three
values. values.
@end defun @end defun
@ -1132,7 +1208,7 @@ Given the procedures above, it is a small matter to make a web server:
@defun serve-one-client handler impl server state @defun serve-one-client handler impl server state
Read one request from @var{server}, call @var{handler} on the request Read one request from @var{server}, call @var{handler} on the request
and body, and write the response to the client. Returns the new state and body, and write the response to the client. Return the new state
produced by the handler procedure. produced by the handler procedure.
@end defun @end defun
@ -1160,6 +1236,8 @@ Additional return values are accumulated into a new @var{state}, which
will be used for subsequent requests. In this way a handler can will be used for subsequent requests. In this way a handler can
explicitly manage its state. explicitly manage its state.
FIXME: elide?
The default server implementation is @code{http}, which accepts The default server implementation is @code{http}, which accepts
@var{open-params} like @code{(#:port 8081)}, among others. See "Web @var{open-params} like @code{(#:port 8081)}, among others. See "Web
Server" in the manual, for more information. Server" in the manual, for more information.
@ -1335,9 +1413,9 @@ Here we see the power of keyword arguments with default initializers. By
the time the arguments are fully parsed, the @code{sxml} local variable the time the arguments are fully parsed, the @code{sxml} local variable
will hold the templated SXML, ready for sending out to the client. will hold the templated SXML, ready for sending out to the client.
Instead of returning the body as a string, here we give a procedure, Also, instead of returning the body as a string, @code{respond} gives a
which will be called by the web server to write out the response to the procedure, which will be called by the web server to write out the
client. response to the client.
Now, a simple example using this responder, which lays out the incoming Now, a simple example using this responder, which lays out the incoming
headers in an HTML table. headers in an HTML table.

View file

@ -76,35 +76,26 @@ scm_i_hash_symbol (SCM obj, unsigned long n, void *closure)
struct string_lookup_data struct string_lookup_data
{ {
SCM string;
unsigned long string_hash; unsigned long string_hash;
}; };
static unsigned long static int
string_lookup_hash_fn (SCM obj, unsigned long max, void *closure) string_lookup_predicate_fn (SCM sym, void *closure)
{ {
struct string_lookup_data *data = closure; struct string_lookup_data *data = closure;
if (scm_is_symbol (obj)) if (scm_i_symbol_hash (sym) == data->string_hash
return scm_i_symbol_hash (obj) % max; && scm_i_symbol_length (sym) == scm_i_string_length (data->string))
else
return data->string_hash % max;
}
static SCM
string_lookup_assoc_fn (SCM obj, SCM alist, void *closure)
{
struct string_lookup_data *data = closure;
for (; !scm_is_null (alist); alist = SCM_CDR (alist))
{ {
SCM sym = SCM_CAAR (alist); size_t n = scm_i_symbol_length (sym);
while (n--)
if (scm_i_symbol_hash (sym) == data->string_hash if (scm_i_symbol_ref (sym, n) != scm_i_string_ref (data->string, n))
&& scm_is_true (scm_string_equal_p (scm_symbol_to_string (sym), obj))) return 0;
return SCM_CAR (alist); return 1;
} }
else
return SCM_BOOL_F; return 0;
} }
static SCM static SCM
@ -113,17 +104,16 @@ lookup_interned_symbol (SCM name, unsigned long raw_hash)
struct string_lookup_data data; struct string_lookup_data data;
SCM handle; SCM handle;
data.string = name;
data.string_hash = raw_hash; data.string_hash = raw_hash;
/* Strictly speaking, we should take a lock here. But instead we rely /* Strictly speaking, we should take a lock here. But instead we rely
on the fact that if this fails, we do take the lock on the on the fact that if this fails, we do take the lock on the
intern_symbol path; and since nothing deletes from the hash table, intern_symbol path; and since nothing deletes from the hash table
we should be OK. Though, weak pair deletion is somewhat except GC, we should be OK. */
worrying... */ handle = scm_hash_fn_get_handle_by_hash (symbols, raw_hash,
handle = scm_hash_fn_get_handle (symbols, name, string_lookup_predicate_fn,
string_lookup_hash_fn, &data);
string_lookup_assoc_fn,
&data);
if (scm_is_true (handle)) if (scm_is_true (handle))
return SCM_CAR (handle); return SCM_CAR (handle);