structure.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2004, 2006, 2007 Free Software Foundation
00003  *      Copyright (C) 2002  Fabio Fiorina
00004  *
00005  * This file is part of LIBTASN1.
00006  *
00007  * The LIBTASN1 library is free software; you can redistribute it
00008  * and/or modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00020  * 02110-1301, USA
00021  */
00022 
00023 
00024 /*****************************************************/
00025 /* File: structure.c                                 */
00026 /* Description: Functions to create and delete an    */
00027 /*  ASN1 tree.                                       */
00028 /*****************************************************/
00029 
00030 
00031 #include <int.h>
00032 #include <structure.h>
00033 #include "parser_aux.h"
00034 #include <gstr.h>
00035 
00036 
00037 extern char MHD__asn1_identifierMissing[];
00038 
00039 static node_asn *MHD__asn1_copy_structure2 (node_asn * root,
00040                                             const char *source_name);
00041 
00042 
00043 
00044 /******************************************************/
00045 /* Function : MHD__asn1_add_node_only                     */
00046 /* Description: creates a new NODE_ASN element.       */
00047 /* Parameters:                                        */
00048 /*   type: type of the new element (see TYPE_         */
00049 /*         and CONST_ constants).                     */
00050 /* Return: pointer to the new element.                */
00051 /******************************************************/
00052 node_asn *
00053 MHD__asn1_add_node_only (unsigned int type)
00054 {
00055   node_asn *punt;
00056 
00057   punt = (node_asn *) MHD__asn1_calloc (1, sizeof (node_asn));
00058   if (punt == NULL)
00059     return NULL;
00060 
00061   punt->type = type;
00062 
00063   return punt;
00064 }
00065 
00066 
00067 /******************************************************************/
00068 /* Function : MHD__asn1_find_left                                     */
00069 /* Description: returns the NODE_ASN element with RIGHT field that*/
00070 /*              points the element NODE.                          */
00071 /* Parameters:                                                    */
00072 /*   node: NODE_ASN element pointer.                              */
00073 /* Return: NULL if not found.                                     */
00074 /******************************************************************/
00075 node_asn *
00076 MHD__asn1_find_left (node_asn * node)
00077 {
00078   if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
00079     return NULL;
00080 
00081   return node->left;
00082 }
00083 
00084 
00085 
00107 MHD__asn1_retCode
00108 MHD__asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
00109                       char *errorDescription)
00110 {
00111   node_asn *p, *p_last = NULL;
00112   unsigned long k;
00113   int move;
00114   MHD__asn1_retCode result;
00115 
00116 
00117   if (*definitions != ASN1_TYPE_EMPTY)
00118     return ASN1_ELEMENT_NOT_EMPTY;
00119 
00120   move = UP;
00121 
00122   k = 0;
00123   while (array[k].value || array[k].type || array[k].name)
00124     {
00125       p = MHD__asn1_add_node (array[k].type & (~CONST_DOWN));
00126       if (array[k].name)
00127         MHD__asn1_set_name (p, array[k].name);
00128       if (array[k].value)
00129         MHD__asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
00130 
00131       if (*definitions == NULL)
00132         *definitions = p;
00133 
00134       if (move == DOWN)
00135         MHD__asn1_set_down (p_last, p);
00136       else if (move == RIGHT)
00137         MHD__asn1_set_right (p_last, p);
00138 
00139       p_last = p;
00140 
00141       if (array[k].type & CONST_DOWN)
00142         move = DOWN;
00143       else if (array[k].type & CONST_RIGHT)
00144         move = RIGHT;
00145       else
00146         {
00147           while (1)
00148             {
00149               if (p_last == *definitions)
00150                 break;
00151 
00152               p_last = MHD__asn1_find_up (p_last);
00153 
00154               if (p_last == NULL)
00155                 break;
00156 
00157               if (p_last->type & CONST_RIGHT)
00158                 {
00159                   p_last->type &= ~CONST_RIGHT;
00160                   move = RIGHT;
00161                   break;
00162                 }
00163             }                   /* while */
00164         }
00165       k++;
00166     }                           /* while */
00167 
00168   if (p_last == *definitions)
00169     {
00170       result = MHD__asn1_check_identifier (*definitions);
00171       if (result == ASN1_SUCCESS)
00172         {
00173           MHD__asn1_change_integer_value (*definitions);
00174           MHD__asn1_expand_object_id (*definitions);
00175         }
00176     }
00177   else
00178     {
00179       result = ASN1_ARRAY_ERROR;
00180     }
00181 
00182   if (errorDescription != NULL)
00183     {
00184       if (result == ASN1_IDENTIFIER_NOT_FOUND)
00185         {
00186           Estrcpy (errorDescription, ":: identifier '");
00187           Estrcat (errorDescription, MHD__asn1_identifierMissing);
00188           Estrcat (errorDescription, "' not found");
00189         }
00190       else
00191         errorDescription[0] = 0;
00192     }
00193 
00194   if (result != ASN1_SUCCESS)
00195     {
00196       MHD__asn1_delete_list_and_nodes ();
00197       *definitions = ASN1_TYPE_EMPTY;
00198     }
00199   else
00200     MHD__asn1_delete_list ();
00201 
00202   return result;
00203 }
00204 
00219 MHD__asn1_retCode
00220 MHD__asn1_delete_structure (ASN1_TYPE * structure)
00221 {
00222   node_asn *p, *p2, *p3;
00223 
00224   if (*structure == ASN1_TYPE_EMPTY)
00225     return ASN1_ELEMENT_NOT_FOUND;
00226 
00227   p = *structure;
00228   while (p)
00229     {
00230       if (p->down)
00231         {
00232           p = p->down;
00233         }
00234       else
00235         {                       /* no down */
00236           p2 = p->right;
00237           if (p != *structure)
00238             {
00239               p3 = MHD__asn1_find_up (p);
00240               MHD__asn1_set_down (p3, p2);
00241               MHD__asn1_remove_node (p);
00242               p = p3;
00243             }
00244           else
00245             {                   /* p==root */
00246               p3 = MHD__asn1_find_left (p);
00247               if (!p3)
00248                 {
00249                   p3 = MHD__asn1_find_up (p);
00250                   if (p3)
00251                     MHD__asn1_set_down (p3, p2);
00252                   else
00253                     {
00254                       if (p->right)
00255                         p->right->left = NULL;
00256                     }
00257                 }
00258               else
00259                 MHD__asn1_set_right (p3, p2);
00260               MHD__asn1_remove_node (p);
00261               p = NULL;
00262             }
00263         }
00264     }
00265 
00266   *structure = ASN1_TYPE_EMPTY;
00267   return ASN1_SUCCESS;
00268 }
00269 
00270 node_asn *
00271 MHD__asn1_copy_structure3 (node_asn * source_node)
00272 {
00273   node_asn *dest_node, *p_s, *p_d, *p_d_prev;
00274   int move;
00275 
00276   if (source_node == NULL)
00277     return NULL;
00278 
00279   dest_node = MHD__asn1_add_node_only (source_node->type);
00280 
00281   p_s = source_node;
00282   p_d = dest_node;
00283 
00284   move = DOWN;
00285 
00286   do
00287     {
00288       if (move != UP)
00289         {
00290           if (p_s->name)
00291             MHD__asn1_set_name (p_d, p_s->name);
00292           if (p_s->value)
00293             MHD__asn1_set_value (p_d, p_s->value, p_s->value_len);
00294           move = DOWN;
00295         }
00296       else
00297         move = RIGHT;
00298 
00299       if (move == DOWN)
00300         {
00301           if (p_s->down)
00302             {
00303               p_s = p_s->down;
00304               p_d_prev = p_d;
00305               p_d = MHD__asn1_add_node_only (p_s->type);
00306               MHD__asn1_set_down (p_d_prev, p_d);
00307             }
00308           else
00309             move = RIGHT;
00310         }
00311 
00312       if (p_s == source_node)
00313         break;
00314 
00315       if (move == RIGHT)
00316         {
00317           if (p_s->right)
00318             {
00319               p_s = p_s->right;
00320               p_d_prev = p_d;
00321               p_d = MHD__asn1_add_node_only (p_s->type);
00322               MHD__asn1_set_right (p_d_prev, p_d);
00323             }
00324           else
00325             move = UP;
00326         }
00327       if (move == UP)
00328         {
00329           p_s = MHD__asn1_find_up (p_s);
00330           p_d = MHD__asn1_find_up (p_d);
00331         }
00332     }
00333   while (p_s != source_node);
00334 
00335   return dest_node;
00336 }
00337 
00338 
00339 static node_asn *
00340 MHD__asn1_copy_structure2 (node_asn * root, const char *source_name)
00341 {
00342   node_asn *source_node;
00343 
00344   source_node = MHD__asn1_find_node (root, source_name);
00345 
00346   return MHD__asn1_copy_structure3 (source_node);
00347 
00348 }
00349 
00350 
00351 static MHD__asn1_retCode
00352 MHD__asn1_type_choice_config (node_asn * node)
00353 {
00354   node_asn *p, *p2, *p3, *p4;
00355   int move, tlen;
00356 
00357   if (node == NULL)
00358     return ASN1_ELEMENT_NOT_FOUND;
00359 
00360   p = node;
00361   move = DOWN;
00362 
00363   while (!((p == node) && (move == UP)))
00364     {
00365       if (move != UP)
00366         {
00367           if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
00368             {
00369               p2 = p->down;
00370               while (p2)
00371                 {
00372                   if (type_field (p2->type) != TYPE_TAG)
00373                     {
00374                       p2->type |= CONST_TAG;
00375                       p3 = MHD__asn1_find_left (p2);
00376                       while (p3)
00377                         {
00378                           if (type_field (p3->type) == TYPE_TAG)
00379                             {
00380                               p4 = MHD__asn1_add_node_only (p3->type);
00381                               tlen = strlen ((const char *) p3->value);
00382                               if (tlen > 0)
00383                                 MHD__asn1_set_value (p4, p3->value, tlen + 1);
00384                               MHD__asn1_set_right (p4, p2->down);
00385                               MHD__asn1_set_down (p2, p4);
00386                             }
00387                           p3 = MHD__asn1_find_left (p3);
00388                         }
00389                     }
00390                   p2 = p2->right;
00391                 }
00392               p->type &= ~(CONST_TAG);
00393               p2 = p->down;
00394               while (p2)
00395                 {
00396                   p3 = p2->right;
00397                   if (type_field (p2->type) == TYPE_TAG)
00398                     MHD__asn1_delete_structure (&p2);
00399                   p2 = p3;
00400                 }
00401             }
00402           move = DOWN;
00403         }
00404       else
00405         move = RIGHT;
00406 
00407       if (move == DOWN)
00408         {
00409           if (p->down)
00410             p = p->down;
00411           else
00412             move = RIGHT;
00413         }
00414 
00415       if (p == node)
00416         {
00417           move = UP;
00418           continue;
00419         }
00420 
00421       if (move == RIGHT)
00422         {
00423           if (p->right)
00424             p = p->right;
00425           else
00426             move = UP;
00427         }
00428       if (move == UP)
00429         p = MHD__asn1_find_up (p);
00430     }
00431 
00432   return ASN1_SUCCESS;
00433 }
00434 
00435 
00436 static MHD__asn1_retCode
00437 MHD__asn1_expand_identifier (node_asn ** node, node_asn * root)
00438 {
00439   node_asn *p, *p2, *p3;
00440   char name2[MAX_NAME_SIZE + 2];
00441   int move;
00442 
00443   if (node == NULL)
00444     return ASN1_ELEMENT_NOT_FOUND;
00445 
00446   p = *node;
00447   move = DOWN;
00448 
00449   while (!((p == *node) && (move == UP)))
00450     {
00451       if (move != UP)
00452         {
00453           if (type_field (p->type) == TYPE_IDENTIFIER)
00454             {
00455               MHD__asn1_str_cpy (name2, sizeof (name2), root->name);
00456               MHD__asn1_str_cat (name2, sizeof (name2), ".");
00457               MHD__asn1_str_cat (name2, sizeof (name2),
00458                                  (const char *) p->value);
00459               p2 = MHD__asn1_copy_structure2 (root, name2);
00460               if (p2 == NULL)
00461                 {
00462                   return ASN1_IDENTIFIER_NOT_FOUND;
00463                 }
00464               MHD__asn1_set_name (p2, p->name);
00465               p2->right = p->right;
00466               p2->left = p->left;
00467               if (p->right)
00468                 p->right->left = p2;
00469               p3 = p->down;
00470               if (p3)
00471                 {
00472                   while (p3->right)
00473                     p3 = p3->right;
00474                   MHD__asn1_set_right (p3, p2->down);
00475                   MHD__asn1_set_down (p2, p->down);
00476                 }
00477 
00478               p3 = MHD__asn1_find_left (p);
00479               if (p3)
00480                 MHD__asn1_set_right (p3, p2);
00481               else
00482                 {
00483                   p3 = MHD__asn1_find_up (p);
00484                   if (p3)
00485                     MHD__asn1_set_down (p3, p2);
00486                   else
00487                     {
00488                       p2->left = NULL;
00489                     }
00490                 }
00491 
00492               if (p->type & CONST_SIZE)
00493                 p2->type |= CONST_SIZE;
00494               if (p->type & CONST_TAG)
00495                 p2->type |= CONST_TAG;
00496               if (p->type & CONST_OPTION)
00497                 p2->type |= CONST_OPTION;
00498               if (p->type & CONST_DEFAULT)
00499                 p2->type |= CONST_DEFAULT;
00500               if (p->type & CONST_SET)
00501                 p2->type |= CONST_SET;
00502               if (p->type & CONST_NOT_USED)
00503                 p2->type |= CONST_NOT_USED;
00504 
00505               if (p == *node)
00506                 *node = p2;
00507               MHD__asn1_remove_node (p);
00508               p = p2;
00509               move = DOWN;
00510               continue;
00511             }
00512           move = DOWN;
00513         }
00514       else
00515         move = RIGHT;
00516 
00517       if (move == DOWN)
00518         {
00519           if (p->down)
00520             p = p->down;
00521           else
00522             move = RIGHT;
00523         }
00524 
00525       if (p == *node)
00526         {
00527           move = UP;
00528           continue;
00529         }
00530 
00531       if (move == RIGHT)
00532         {
00533           if (p->right)
00534             p = p->right;
00535           else
00536             move = UP;
00537         }
00538       if (move == UP)
00539         p = MHD__asn1_find_up (p);
00540     }
00541 
00542   return ASN1_SUCCESS;
00543 }
00544 
00545 
00565 MHD__asn1_retCode
00566 MHD__asn1_create_element (ASN1_TYPE definitions, const char *source_name,
00567                           ASN1_TYPE * element)
00568 {
00569   node_asn *dest_node;
00570   int res;
00571 
00572   dest_node = MHD__asn1_copy_structure2 (definitions, source_name);
00573 
00574   if (dest_node == NULL)
00575     return ASN1_ELEMENT_NOT_FOUND;
00576 
00577   MHD__asn1_set_name (dest_node, "");
00578 
00579   res = MHD__asn1_expand_identifier (&dest_node, definitions);
00580   MHD__asn1_type_choice_config (dest_node);
00581 
00582   *element = dest_node;
00583 
00584   return res;
00585 }

Generated on Fri Feb 27 18:32:18 2009 for GNU libmicrohttpd by  doxygen 1.5.7.1