Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libts.h"
00025 #include "P_RecTree.h"
00026
00027 #define RecTreeDebug printf
00028 bool rec_debug = false;
00029
00030
00031
00032
00033
00034
00035
00036 RecTreeNode::RecTreeNode(const char *t):
00037 record_ptr(NULL),
00038 subtree_ptr(new RecTree(this)),
00039 var_name_ptr(NULL),
00040 num_leaf(0)
00041 {
00042 if (t) {
00043 node_name = ats_strdup(t);
00044 } else {
00045 node_name = ats_strdup("root");
00046 }
00047 }
00048
00049
00050
00051 RecTreeNode::~RecTreeNode()
00052 {
00053 ats_free(node_name);
00054 }
00055
00056
00057
00058
00059
00060
00061 void
00062 RecTreeNode::print()
00063 {
00064 if (num_leaf == 0) {
00065 RecTreeDebug("\t Leaf: %s\n", var_name_ptr);
00066 } else {
00067 subtree_ptr->print();
00068 RecTreeDebug("Node: %s\n", node_name);
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 RecTree::RecTree(RecTreeNode * n)
00079 {
00080 if (n == NULL) {
00081 n = new RecTreeNode("base");
00082 }
00083 this_node = n;
00084 }
00085
00086
00087
00088
00089
00090 void
00091 RecTree::rec_tree_insert(const char *var_name, const char *var_name_ptr)
00092 {
00093 if ((var_name == NULL) || (!strlen(var_name))) {
00094 return;
00095 }
00096
00097 if ((var_name_ptr == NULL) || (!strlen(var_name_ptr))) {
00098 var_name_ptr = var_name;
00099 }
00100
00101 Tokenizer targetTok(".");
00102 targetTok.Initialize(var_name);
00103 tok_iter_state targetTok_state;
00104 const char *first_token = targetTok.iterFirst(&targetTok_state);
00105
00106 const char *rest_token = strchr(var_name, REC_VAR_NAME_DELIMITOR);
00107 if (rest_token) {
00108 rest_token++;
00109 if (rec_debug) {
00110 RecTreeDebug("%s %s\n", first_token, rest_token);
00111 }
00112 }
00113
00114 RecTreeNode *subtree = NULL;
00115
00116
00117 for (subtree = first(); subtree; subtree = next(subtree)) {
00118 if (!strcmp(subtree->node_name, first_token)) {
00119 if (rec_debug) {
00120
00121 }
00122 break;
00123 }
00124 }
00125
00126
00127 if (!subtree) {
00128 if (rec_debug) {
00129 RecTreeDebug("RecTree::insert() -- add subtree with %s\n", first_token);
00130 }
00131 subtree = new RecTreeNode((char *) first_token);
00132 ink_assert(subtree);
00133 m_root.enqueue(subtree);
00134 }
00135
00136 if (rest_token) {
00137 if (rec_debug) {
00138 RecTreeDebug("RecTree::insert() -- insert the rest %s\n", rest_token);
00139 }
00140 subtree->subtree_ptr->rec_tree_insert(rest_token, var_name_ptr);
00141 } else {
00142 subtree->var_name_ptr = var_name_ptr;
00143 if (rec_debug) {
00144 RecTreeDebug("RecTree:insert() -- leaf node: %s\n", subtree->var_name_ptr);
00145 }
00146 }
00147
00148 if (this_node) {
00149 (this_node->num_leaf)++;
00150 }
00151
00152 }
00153
00154
00155
00156
00157
00158 void
00159 RecTree::print()
00160 {
00161 for (RecTreeNode * node = first(); node; node = next(node)) {
00162 node->print();
00163 }
00164 }
00165
00166
00167
00168
00169
00170 RecTree *
00171 RecTree::rec_tree_get(char *path_name)
00172 {
00173
00174 Tokenizer targetTok(".");
00175 targetTok.Initialize(path_name);
00176 tok_iter_state targetTok_state;
00177 const char *first_token = targetTok.iterFirst(&targetTok_state);
00178
00179 char *rest_token = strchr(path_name, REC_VAR_NAME_DELIMITOR);
00180 if (rest_token != NULL) {
00181 rest_token++;
00182 }
00183
00184 RecTreeNode *subtree = NULL;
00185
00186
00187 for (subtree = first(); subtree; subtree = next(subtree)) {
00188 if (!strcmp(subtree->node_name, first_token)) {
00189 if (rec_debug) {
00190 RecTreeDebug("RecTree::get() -- found subtree %s\n", first_token);
00191 }
00192 break;
00193 }
00194 }
00195
00196 if (!subtree) {
00197 if (rec_debug) {
00198 RecTreeDebug("RecTree::get() -- can't find subtree %s\n", first_token);
00199 }
00200 return NULL;
00201 } else {
00202 char wildcard[2];
00203 memset(wildcard, 0, 2);
00204 snprintf(wildcard, sizeof(wildcard), "%c", REC_VAR_NAME_WILDCARD);
00205 if (rest_token == NULL || !strcmp(rest_token, wildcard)) {
00206 return subtree->subtree_ptr;
00207 } else {
00208 if (rec_debug) {
00209 RecTreeDebug("RecTree::get() -- getting the rest %s\n", rest_token);
00210 }
00211 return subtree->subtree_ptr->rec_tree_get(rest_token);
00212 }
00213 }
00214
00215 }
00216
00217
00218
00219
00220
00221
00222 void
00223 RecTree::rec_tree_get_list(char *path_name, char ***buf, int *count)
00224 {
00225
00226 int i = 0;
00227 RecTree *subtree = rec_tree_get(path_name);
00228
00229 if (!subtree) {
00230 (*count) = 0;
00231 return;
00232 }
00233
00234 (*count) = subtree->this_node->num_leaf;
00235 if (rec_debug) {
00236 RecTreeDebug("RecTreeGetList subtree %s has %d leafs\n", subtree->this_node->node_name, (*count));
00237 }
00238
00239 *buf = (char **)ats_malloc(sizeof(char *) * (*count));
00240 for (i = 0; i < (*count); i++) {
00241 (*buf)[i] = (char *)ats_malloc(sizeof(char));
00242 }
00243
00244 int index = 0;
00245 subtree->p_rec_tree_get_list(path_name, &(*buf), &index);
00246 ink_assert((*count) == index);
00247
00248 if (rec_debug) {
00249 for (i = 0; i < (*count); i++) {
00250 RecTreeDebug("[%d] %s\n", i, (*buf)[i]);
00251 }
00252 }
00253
00254 }
00255
00256
00257
00258 void
00259 RecTree::p_rec_tree_get_list(char *path_name, char ***buffer, int *index)
00260 {
00261
00262 if (this_node->var_name_ptr) {
00263 (*buffer)[(*index)] = (char*)this_node->var_name_ptr;
00264 if (rec_debug) {
00265 RecTreeDebug("%d %s\n", (*index), (*buffer)[(*index)]);
00266 }
00267 (*index)++;
00268 }
00269
00270 for (RecTreeNode * subtree = first(); subtree; subtree = next(subtree)) {
00271 if (rec_debug) {
00272 RecTreeDebug("current node: %s, subtree node: %s\n", this_node->node_name, subtree->node_name);
00273 }
00274 subtree->subtree_ptr->p_rec_tree_get_list(&(*path_name), &(*buffer), &(*index));
00275 }
00276
00277 }