• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

RecTree.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   RecTree and RecTreeNode definitions
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
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  * RecTreeNode
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   Print the current node's content. If this node is a leaf, that is,
00058   the subtree_list print count is zero, print the full variable name.
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  * RecTree
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   // First subtree who has the first token
00117   for (subtree = first(); subtree; subtree = next(subtree)) {
00118     if (!strcmp(subtree->node_name, first_token)) {
00119       if (rec_debug) {
00120         //      RecTreeDebug("RecTree::insert() -- found subtree %s\n", first_token);
00121       }
00122       break;
00123     }
00124   }
00125 
00126   // no subtree has the first token
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   // First subtree who has the first token
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  * rec_tree_get_list
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 /** Recursive/private version of RecTreeGetList(). */
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 }

Generated by  doxygen 1.7.1