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 }