mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-22 10:22:06 +03:00
allow hash table add inline to be uncompressed
This commit is contained in:
parent
d196ea7795
commit
43582c5055
@ -81,6 +81,175 @@ static inline unsigned int hash_string_fnv(const char *datum, unsigned int *len)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* process a line of input.
|
||||
*
|
||||
* \param hash The hash table to add the line to
|
||||
* \param ln The line to process
|
||||
* \param lnlen The length of \ln
|
||||
* \return NSERROR_OK on success else NSERROR_INVALID
|
||||
*/
|
||||
static nserror
|
||||
process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
|
||||
{
|
||||
uint8_t *key;
|
||||
uint8_t *value;
|
||||
uint8_t *colon;
|
||||
|
||||
key = ln; /* set key to start of line */
|
||||
value = ln + lnlen; /* set value to end of line */
|
||||
|
||||
/* skip leading whitespace */
|
||||
while ((key < value) &&
|
||||
((*key == ' ') || (*key == '\t'))) {
|
||||
key++;
|
||||
}
|
||||
|
||||
/* empty or comment lines */
|
||||
if ((*key == 0) || (*key == '#')) {
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* find first colon as key/value separator */
|
||||
for (colon = key; colon < value; colon++) {
|
||||
if (*colon == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (colon == value) {
|
||||
/* no colon found */
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
|
||||
*colon = 0; /* terminate key */
|
||||
value = colon + 1;
|
||||
|
||||
if (hash_add(hash, (char *)key, (char *)value) == false) {
|
||||
NSLOG(netsurf, INFO,
|
||||
"Unable to add %s:%s to hash table", ln, value);
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* adds key/value pairs to a hash from a memory area
|
||||
*/
|
||||
static nserror
|
||||
hash_add_inline_plain(struct hash_table *ht, const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
|
||||
unsigned int slen = 0;
|
||||
nserror res = NSERROR_OK;
|
||||
|
||||
while (size > 0) {
|
||||
s[slen] = *data;
|
||||
|
||||
if (s[slen] == '\n') {
|
||||
s[slen] = 0; /* replace newline with null termination */
|
||||
res = process_line(ht, s, slen);
|
||||
slen = 0;
|
||||
if (res != NSERROR_OK) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
slen++;
|
||||
if (slen > sizeof s) {
|
||||
NSLOG(netsurf, INFO, "Overlength line\n");
|
||||
slen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size--;
|
||||
data++;
|
||||
}
|
||||
if (slen > 0) {
|
||||
s[slen] = 0;
|
||||
res = process_line(ht, s, slen);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds key/value pairs to a hash from a compressed memory area
|
||||
*/
|
||||
static nserror
|
||||
hash_add_inline_gzip(struct hash_table *ht, const uint8_t *data, size_t size)
|
||||
{
|
||||
nserror res;
|
||||
int ret; /* zlib return value */
|
||||
z_stream strm;
|
||||
uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
|
||||
size_t used = 0; /* number of bytes in buffer in use */
|
||||
uint8_t *nl;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
strm.next_in = (uint8_t *)data;
|
||||
strm.avail_in = size;
|
||||
|
||||
ret = inflateInit2(&strm, 32 + MAX_WBITS);
|
||||
if (ret != Z_OK) {
|
||||
NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
|
||||
do {
|
||||
strm.next_out = s + used;
|
||||
strm.avail_out = sizeof(s) - used;
|
||||
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
|
||||
break;
|
||||
}
|
||||
|
||||
used = sizeof(s) - strm.avail_out;
|
||||
while (used > 0) {
|
||||
/* find nl */
|
||||
for (nl = &s[0]; nl < &s[used]; nl++) {
|
||||
if (*nl == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nl == &s[used]) {
|
||||
/* no nl found */
|
||||
break;
|
||||
}
|
||||
/* found newline */
|
||||
*nl = 0; /* null terminate line */
|
||||
res = process_line(ht, &s[0], nl - &s[0]);
|
||||
if (res != NSERROR_OK) {
|
||||
inflateEnd(&strm);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* move data down */
|
||||
memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
|
||||
used -= ((nl +1) - &s[0]);
|
||||
}
|
||||
if (used == sizeof(s)) {
|
||||
/* entire buffer used and no newline */
|
||||
NSLOG(netsurf, INFO, "Overlength line");
|
||||
used = 0;
|
||||
}
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
inflateEnd(&strm);
|
||||
|
||||
if (ret != Z_STREAM_END) {
|
||||
NSLOG(netsurf, INFO, "inflate returned %d", ret);
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
return NSERROR_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* exported interface documented in utils/hashtable.h */
|
||||
struct hash_table *hash_create(unsigned int chains)
|
||||
{
|
||||
@ -187,57 +356,6 @@ const char *hash_get(struct hash_table *ht, const char *key)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* process a line of input.
|
||||
*
|
||||
* \param hash The hash table to add the line to
|
||||
* \param ln The line to process
|
||||
* \param lnlen The length of \ln
|
||||
* \return NSERROR_OK on success else NSERROR_INVALID
|
||||
*/
|
||||
static nserror
|
||||
process_line(struct hash_table *hash, uint8_t *ln, int lnlen)
|
||||
{
|
||||
uint8_t *key;
|
||||
uint8_t *value;
|
||||
uint8_t *colon;
|
||||
|
||||
key = ln; /* set key to start of line */
|
||||
value = ln + lnlen; /* set value to end of line */
|
||||
|
||||
/* skip leading whitespace */
|
||||
while ((key < value) &&
|
||||
((*key == ' ') || (*key == '\t'))) {
|
||||
key++;
|
||||
}
|
||||
|
||||
/* empty or comment lines */
|
||||
if ((*key == 0) || (*key == '#')) {
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
/* find first colon as key/value separator */
|
||||
for (colon = key; colon < value; colon++) {
|
||||
if (*colon == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (colon == value) {
|
||||
/* no colon found */
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
|
||||
*colon = 0; /* terminate key */
|
||||
value = colon + 1;
|
||||
|
||||
if (hash_add(hash, (char *)key, (char *)value) == false) {
|
||||
NSLOG(netsurf, INFO,
|
||||
"Unable to add %s:%s to hash table", ln, value);
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* exported interface documented in utils/hashtable.h */
|
||||
nserror hash_add_file(struct hash_table *ht, const char *path)
|
||||
@ -274,75 +392,13 @@ nserror hash_add_file(struct hash_table *ht, const char *path)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* exported interface documented in utils/hashtable.h */
|
||||
nserror hash_add_inline(struct hash_table *ht, const uint8_t *data, size_t size)
|
||||
{
|
||||
nserror res;
|
||||
int ret; /* zlib return value */
|
||||
z_stream strm;
|
||||
uint8_t s[LINE_BUFFER_SIZE]; /* line buffer */
|
||||
size_t used = 0; /* number of bytes in buffer in use */
|
||||
uint8_t *nl;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
strm.next_in = (uint8_t *)data;
|
||||
strm.avail_in = size;
|
||||
|
||||
ret = inflateInit2(&strm, 32 + MAX_WBITS);
|
||||
if (ret != Z_OK) {
|
||||
NSLOG(netsurf, INFO, "inflateInit returned %d", ret);
|
||||
return NSERROR_INVALID;
|
||||
if ((data[0]==0x1f) && (data[1] == 0x8b)) {
|
||||
/* gzip header detected */
|
||||
return hash_add_inline_gzip(ht, data, size);
|
||||
}
|
||||
|
||||
do {
|
||||
strm.next_out = s + used;
|
||||
strm.avail_out = sizeof(s) - used;
|
||||
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
|
||||
break;
|
||||
}
|
||||
|
||||
used = sizeof(s) - strm.avail_out;
|
||||
while (used > 0) {
|
||||
/* find nl */
|
||||
for (nl = &s[0]; nl < &s[used]; nl++) {
|
||||
if (*nl == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nl == &s[used]) {
|
||||
/* no nl found */
|
||||
break;
|
||||
}
|
||||
/* found newline */
|
||||
*nl = 0; /* null terminate line */
|
||||
res = process_line(ht, &s[0], nl - &s[0]);
|
||||
if (res != NSERROR_OK) {
|
||||
inflateEnd(&strm);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* move data down */
|
||||
memmove(&s[0], nl + 1, used - ((nl + 1) - &s[0]) );
|
||||
used -= ((nl +1) - &s[0]);
|
||||
}
|
||||
if (used == sizeof(s)) {
|
||||
/* entire buffer used and no newline */
|
||||
NSLOG(netsurf, INFO, "Overlength line");
|
||||
used = 0;
|
||||
}
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
inflateEnd(&strm);
|
||||
|
||||
if (ret != Z_STREAM_END) {
|
||||
NSLOG(netsurf, INFO, "inflate returned %d", ret);
|
||||
return NSERROR_INVALID;
|
||||
}
|
||||
return NSERROR_OK;
|
||||
|
||||
return hash_add_inline_plain(ht, data, size);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user