2
2
* hash.c : dumping and reading hash tables to/from files.
4
4
* ====================================================================
5
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
7
* This software is licensed as described in the file COPYING, which
8
* you should have received as part of this distribution. The terms
9
* are also available at http://subversion.tigris.org/license-1.html.
10
* If newer versions of this license are posted there, you may use a
11
* newer version instead, at your option.
13
* This software consists of voluntary contributions made by many
14
* individuals. For exact contribution history, see the revision
15
* history and logs, available at http://subversion.tigris.org/.
5
* Licensed to the Apache Software Foundation (ASF) under one
6
* or more contributor license agreements. See the NOTICE file
7
* distributed with this work for additional information
8
* regarding copyright ownership. The ASF licenses this file
9
* to you under the Apache License, Version 2.0 (the
10
* "License"); you may not use this file except in compliance
11
* with the License. You may obtain a copy of the License at
13
* http://www.apache.org/licenses/LICENSE-2.0
15
* Unless required by applicable law or agreed to in writing,
16
* software distributed under the License is distributed on an
17
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18
* KIND, either express or implied. See the License for the
19
* specific language governing permissions and limitations
16
21
* ====================================================================
102
113
/* Check for unexpected end of stream */
104
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
115
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
116
_("Serialized hash missing terminator"));
106
118
if ((buf->len >= 3) && (buf->data[0] == 'K') && (buf->data[1] == ' '))
108
120
/* Get the length of the key */
109
121
keylen = (size_t) strtoul(buf->data + 2, &end, 10);
110
122
if (keylen == (size_t) ULONG_MAX || *end != '\0')
111
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
123
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
124
_("Serialized hash malformed"));
113
126
/* Now read that much into a buffer. */
114
127
keybuf = apr_palloc(pool, keylen + 1);
120
133
SVN_ERR(svn_stream_read(stream, &c, &len));
122
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
135
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
136
_("Serialized hash malformed"));
124
138
/* Read a val length line */
125
139
SVN_ERR(svn_stream_readline(stream, &buf, "\n", &eof, iterpool));
129
143
vallen = (size_t) strtoul(buf->data + 2, &end, 10);
130
144
if (vallen == (size_t) ULONG_MAX || *end != '\0')
131
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
145
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
146
_("Serialized hash malformed"));
133
148
valbuf = apr_palloc(iterpool, vallen + 1);
134
149
SVN_ERR(svn_stream_read(stream, valbuf, &vallen));
139
154
SVN_ERR(svn_stream_read(stream, &c, &len));
141
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
156
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
157
_("Serialized hash malformed"));
143
159
/* Add a new hash entry. */
144
160
apr_hash_set(hash, keybuf, keylen,
145
161
svn_string_ncreate(valbuf, vallen, pool));
148
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
164
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
165
_("Serialized hash malformed"));
150
167
else if (incremental && (buf->len >= 3)
151
168
&& (buf->data[0] == 'D') && (buf->data[1] == ' '))
153
170
/* Get the length of the key */
154
171
keylen = (size_t) strtoul(buf->data + 2, &end, 10);
155
172
if (keylen == (size_t) ULONG_MAX || *end != '\0')
156
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
173
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
174
_("Serialized hash malformed"));
158
176
/* Now read that much into a buffer. */
159
177
keybuf = apr_palloc(iterpool, keylen + 1);
165
183
SVN_ERR(svn_stream_read(stream, &c, &len));
167
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
185
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
186
_("Serialized hash malformed"));
169
188
/* Remove this hash entry. */
170
189
apr_hash_set(hash, keybuf, keylen, NULL);
174
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
193
return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
194
_("Serialized hash malformed"));
340
360
else if ((buf[0] == 'K') && (buf[1] == ' '))
342
366
/* Get the length of the key */
343
size_t keylen = (size_t) atoi(buf + 2);
367
SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
345
370
/* Now read that much into a buffer, + 1 byte for null terminator */
346
void *keybuf = apr_palloc(pool, keylen + 1);
347
SVN_ERR(svn_io_file_read_full(srcfile,
348
keybuf, keylen, &num_read, pool));
371
keybuf = apr_palloc(pool, keylen + 1);
372
SVN_ERR(svn_io_file_read_full2(srcfile,
374
&num_read, NULL, pool));
349
375
((char *) keybuf)[keylen] = '\0';
351
377
/* Suck up extra newline after key data */
360
386
if ((buf[0] == 'V') && (buf[1] == ' '))
362
388
svn_string_t *value = apr_palloc(pool, sizeof(*value));
364
392
/* Get the length of the value */
365
apr_size_t vallen = atoi(buf + 2);
393
SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
367
396
/* Again, 1 extra byte for the null termination. */
368
void *valbuf = apr_palloc(pool, vallen + 1);
369
SVN_ERR(svn_io_file_read_full(srcfile,
397
valbuf = apr_palloc(pool, vallen + 1);
398
SVN_ERR(svn_io_file_read_full2(srcfile,
400
&num_read, NULL, pool));
372
401
((char *) valbuf)[vallen] = '\0';
374
403
/* Suck up extra newline after val data */
454
483
for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
459
apr_hash_this(hi, &key, NULL, NULL);
462
APR_ARRAY_PUSH(*array, const char *) = path;
485
APR_ARRAY_PUSH(*array, const char *) = svn__apr_hash_index_key(hi);
465
488
return SVN_NO_ERROR;
488
svn_hash__clear(apr_hash_t *hash)
511
svn_hash__clear(apr_hash_t *hash, apr_pool_t *pool)
490
513
#if APR_VERSION_AT_LEAST(1, 3, 0)
491
514
apr_hash_clear(hash);
495
518
apr_ssize_t klen;
497
for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi))
520
for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
499
522
apr_hash_this(hi, &key, &klen, NULL);
500
523
apr_hash_set(hash, key, klen, NULL);
503
526
return SVN_NO_ERROR;
531
/*** Specialized getter APIs ***/
534
svn_hash__get_cstring(apr_hash_t *hash,
536
const char *default_value)
540
const char *value = apr_hash_get(hash, key, APR_HASH_KEY_STRING);
541
return value ? value : default_value;
544
return default_value;
549
svn_hash__get_bool(apr_hash_t *hash, const char *key,
550
svn_boolean_t default_value)
552
const char *tmp_value = svn_hash__get_cstring(hash, key, NULL);
553
svn_tristate_t value = svn_tristate__from_word(tmp_value);
555
if (value == svn_tristate_true)
557
else if (value == svn_tristate_false)
560
return default_value;