blob: c977fad3d408418262d167e0bf1ffd29a3d6f069 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/*
* This file is part of Hubbub.
* Licensed under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
* Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
*/
#include "utils/utils.h"
#include "tokeniser/entities.h"
/** Node in our entity tree */
typedef struct hubbub_entity_node {
/* Do not reorder this without fixing make-entities.pl */
uint8_t split; /**< Data to split on */
int32_t lt; /**< Subtree for data less than split */
int32_t eq; /**< Subtree for data equal to split */
int32_t gt; /**< Subtree for data greater than split */
uint32_t value; /**< Data for this node */
} hubbub_entity_node;
#include "entities.inc"
/**
* Step-wise search for a key in our entity tree
*
* \param c Character to look for
* \param result Pointer to location for result
* \param context Pointer to location for search context
* \return HUBBUB_OK if key found,
* HUBBUB_NEEDDATA if more steps are required
* HUBBUB_INVALID if nothing matches
*
* The value pointed to by \p context must be NULL for the first call.
* Thereafter, pass in the same value as returned by the previous call.
* The context is opaque to the caller and should not be inspected.
*
* The location pointed to by \p result will be set to NULL unless a match
* is found.
*/
static hubbub_error hubbub_entity_tree_search_step(uint8_t c,
uint32_t *result, int32_t *context)
{
bool match = false;
int32_t p;
if (result == NULL || context == NULL)
return HUBBUB_BADPARM;
if (*context == -1) {
p = dict_root;
} else {
p = *context;
}
while (p != -1) {
if (c < dict[p].split) {
p = dict[p].lt;
} else if (c == dict[p].split) {
if (dict[p].split == '\0') {
match = true;
p = -1;
} else if (dict[p].eq != -1 && dict[dict[p].eq].split == '\0') {
match = true;
*result = dict[dict[p].eq].value;
p = dict[p].eq;
} else if (dict[p].value != 0) {
match = true;
*result = dict[p].value;
p = dict[p].eq;
} else {
p = dict[p].eq;
}
break;
} else {
p = dict[p].gt;
}
}
*context = p;
return (match) ? HUBBUB_OK :
(p == -1) ? HUBBUB_INVALID : HUBBUB_NEEDDATA;
}
/**
* Step-wise search for an entity in the dictionary
*
* \param c Character to look for
* \param result Pointer to location for result
* \param context Pointer to location for search context
* \return HUBBUB_OK if key found,
* HUBBUB_NEEDDATA if more steps are required
* HUBBUB_INVALID if nothing matches
*
* The value pointed to by \p context should be -1 for the first call.
* Thereafter, pass in the same value as returned by the previous call.
* The context is opaque to the caller and should not be inspected.
*
* The location pointed to by \p result will be set to U+FFFD unless a match
* is found.
*/
hubbub_error hubbub_entities_search_step(uint8_t c, uint32_t *result,
int32_t *context)
{
if (result == NULL)
return HUBBUB_BADPARM;
*result = 0xFFFD;
return hubbub_entity_tree_search_step(c, result, context);
}
|