diff options
author | Keith Bostic <keith@wiredtiger.com> | 2015-03-13 10:04:06 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2015-03-13 10:04:06 -0400 |
commit | 48a6f6e76aafbf7b33dbb22325ddb4e8e27603a1 (patch) | |
tree | 7e9674432775ac3286fef9764b35cd915434ab7e /src/btree/bt_huffman.c | |
parent | 5fa3a04aa5eb4a9d5117c86ecb15153780f57065 (diff) | |
download | mongo-48a6f6e76aafbf7b33dbb22325ddb4e8e27603a1.tar.gz |
Fix problems with configuration value parsing, break out the Huffman
configuration file parsing code into a single routine.
Diffstat (limited to 'src/btree/bt_huffman.c')
-rw-r--r-- | src/btree/bt_huffman.c | 100 |
1 files changed, 56 insertions, 44 deletions
diff --git a/src/btree/bt_huffman.c b/src/btree/bt_huffman.c index a25283e49d9..519902d42e8 100644 --- a/src/btree/bt_huffman.c +++ b/src/btree/bt_huffman.c @@ -129,36 +129,66 @@ static int __wt_huffman_read(WT_SESSION_IMPL *, WT_CONFIG_ITEM *, struct __wt_huffman_table **, u_int *, u_int *); /* + * __huffman_confchk_file -- + * Check for a Huffman configuration file and return the file name. + */ +static int +__huffman_confchk_file( + WT_SESSION_IMPL *session, WT_CONFIG_ITEM *v, int *is_utf8p, FILE **fpp) +{ + FILE *fp; + size_t len; + char *fname; + + /* Look for a prefix and file name. */ + len = 0; + if (WT_PREFIX_MATCH(v->str, "utf8")) { + if (is_utf8p != NULL) + *is_utf8p = 1; + len = strlen("utf8"); + } else if (WT_PREFIX_MATCH(v->str, "utf16")) { + if (is_utf8p != NULL) + *is_utf8p = 0; + len = strlen("utf16"); + } + if (len == 0 || len >= v->len) + WT_RET_MSG(session, EINVAL, + "illegal Huffman configuration: %.*s", (int)v->len, v->str); + + /* Check the file exists. */ + WT_RET(__wt_strndup(session, v->str + len, v->len - len, &fname)); + fp = fopen(fname, "r"); + __wt_free(session, fname); + if (fp == NULL) + WT_RET_MSG(session, __wt_errno(), + "unable to read Huffman table file %s", fname); + + /* Optionally return the file handle. */ + if (fpp == NULL) + (void)fclose(fp); + else + *fpp = fp; + + return (0); +} + +/* * __wt_huffman_confchk -- * Verify Huffman configuration. */ int __wt_huffman_confchk(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *v) { - FILE *fp; - const char *p; - if (v->len == 0) return (0); + /* Standard Huffman encodings, no work to be done. */ if (WT_STRING_MATCH("english", v->str, v->len)) return (0); + if (WT_STRING_MATCH("none", v->str, v->len)) + return (0); - if (WT_PREFIX_MATCH(v->str, "utf8")) - p = v->str + strlen("utf8"); - else if (WT_PREFIX_MATCH(v->str, "utf16")) - p = v->str + strlen("utf16"); - else - WT_RET_MSG(session, EINVAL, - "illegal Huffman configuration: %.*s", (int)v->len, v->str); - - if ((fp = fopen(p, "r")) == NULL) - WT_RET_MSG(session, __wt_errno(), - "unable to read Huffman table file %.*s", - (int)v->len, v->str); - (void)fclose(fp); - - return (0); + return (__huffman_confchk_file(session, v, NULL, NULL)); } /* @@ -273,50 +303,33 @@ __wt_huffman_read(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *ip, WT_DECL_RET; uint64_t symbol, frequency; u_int entries, lineno; - char *file; + int is_utf8; *tablep = NULL; *entriesp = *numbytesp = 0; fp = NULL; - file = NULL; table = NULL; /* + * Try and open the backing file. + */ + WT_RET(__huffman_confchk_file(session, ip, &is_utf8, &fp)); + + /* * UTF-8 table is 256 bytes, with a range of 0-255. * UTF-16 is 128KB (2 * 65536) bytes, with a range of 0-65535. */ - if (strncmp(ip->str, "utf8", 4) == 0) { + if (is_utf8) { entries = UINT8_MAX; *numbytesp = 1; WT_ERR(__wt_calloc_def(session, entries, &table)); - - if (ip->len == 4) - WT_ERR_MSG(session, EINVAL, - "no Huffman table file name specified"); - WT_ERR(__wt_calloc_def(session, ip->len, &file)); - memcpy(file, ip->str + 4, ip->len - 4); - } else if (strncmp(ip->str, "utf16", 5) == 0) { + } else { entries = UINT16_MAX; *numbytesp = 2; WT_ERR(__wt_calloc_def(session, entries, &table)); - - if (ip->len == 5) - WT_ERR_MSG(session, EINVAL, - "no Huffman table file name specified"); - WT_ERR(__wt_calloc_def(session, ip->len, &file)); - memcpy(file, ip->str + 5, ip->len - 5); - } else { - WT_ERR_MSG(session, EINVAL, - "unknown Huffman configuration value %.*s", - (int)ip->len, ip->str); } - if ((fp = fopen(file, "r")) == NULL) - WT_ERR_MSG(session, __wt_errno(), - "unable to read Huffman table file %.*s", - (int)ip->len, ip->str); - for (tp = table, lineno = 1; (ret = fscanf(fp, "%" SCNu64 " %" SCNu64, &symbol, &frequency)) != EOF; ++tp, ++lineno) { @@ -355,7 +368,6 @@ err: __wt_free(session, table); } if (fp != NULL) (void)fclose(fp); - __wt_free(session, file); return (ret); } |