summaryrefslogtreecommitdiff
path: root/src/btree/bt_huffman.c
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2015-03-13 10:04:06 -0400
committerKeith Bostic <keith@wiredtiger.com>2015-03-13 10:04:06 -0400
commit48a6f6e76aafbf7b33dbb22325ddb4e8e27603a1 (patch)
tree7e9674432775ac3286fef9764b35cd915434ab7e /src/btree/bt_huffman.c
parent5fa3a04aa5eb4a9d5117c86ecb15153780f57065 (diff)
downloadmongo-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.c100
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);
}