/** * asn1_delete_element: * @structure: pointer to the structure that contains the element you * want to delete. * @element_name: element's name you want to delete. * * Deletes the element named *@element_name inside *@structure. * * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if * the @element_name was not found. **/ asn1_retCode asn1_delete_element (ASN1_TYPE structure, const char *element_name) { ASN1_TYPE p2, p3, source_node; source_node = asn1_find_node (structure, element_name); if (source_node == ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; p2 = source_node->right; p3 = _asn1_find_left (source_node); if (!p3) { p3 = _asn1_find_up (source_node); if (p3) _asn1_set_down (p3, p2); else if (source_node->right) source_node->right->left = NULL; } else _asn1_set_right (p3, p2); return asn1_delete_structure (&source_node); }
/** * asn1_delete_structure: * @structure: pointer to the structure that you want to delete. * * Deletes the structure *@structure. At the end, *@structure is set * to ASN1_TYPE_EMPTY. * * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if * *@structure was ASN1_TYPE_EMPTY. **/ asn1_retCode asn1_delete_structure (ASN1_TYPE * structure) { ASN1_TYPE p, p2, p3; if (*structure == ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; p = *structure; while (p) { if (p->down) { p = p->down; } else { /* no down */ p2 = p->right; if (p != *structure) { p3 = _asn1_find_up (p); _asn1_set_down (p3, p2); _asn1_remove_node (p); p = p3; } else { /* p==root */ p3 = _asn1_find_left (p); if (!p3) { p3 = _asn1_find_up (p); if (p3) _asn1_set_down (p3, p2); else { if (p->right) p->right->left = NULL; } } else _asn1_set_right (p3, p2); _asn1_remove_node (p); p = NULL; } } } *structure = ASN1_TYPE_EMPTY; return ASN1_SUCCESS; }
static asn1_retCode _asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root) { ASN1_TYPE p, p2, p3; char name2[ASN1_MAX_NAME_SIZE + 2]; int move; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; p = *node; move = DOWN; while (!((p == *node) && (move == UP))) { if (move != UP) { if (type_field (p->type) == TYPE_IDENTIFIER) { _asn1_str_cpy (name2, sizeof (name2), root->name); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), p->value); p2 = _asn1_copy_structure2 (root, name2); if (p2 == NULL) { return ASN1_IDENTIFIER_NOT_FOUND; } _asn1_set_name (p2, p->name); p2->right = p->right; p2->left = p->left; if (p->right) p->right->left = p2; p3 = p->down; if (p3) { while (p3->right) p3 = p3->right; _asn1_set_right (p3, p2->down); _asn1_set_down (p2, p->down); } p3 = _asn1_find_left (p); if (p3) _asn1_set_right (p3, p2); else { p3 = _asn1_find_up (p); if (p3) _asn1_set_down (p3, p2); else { p2->left = NULL; } } if (p->type & CONST_SIZE) p2->type |= CONST_SIZE; if (p->type & CONST_TAG) p2->type |= CONST_TAG; if (p->type & CONST_OPTION) p2->type |= CONST_OPTION; if (p->type & CONST_DEFAULT) p2->type |= CONST_DEFAULT; if (p->type & CONST_SET) p2->type |= CONST_SET; if (p->type & CONST_NOT_USED) p2->type |= CONST_NOT_USED; if (p == *node) *node = p2; _asn1_remove_node (p); p = p2; move = DOWN; continue; } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == *node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } return ASN1_SUCCESS; }
static asn1_retCode _asn1_type_choice_config (ASN1_TYPE node) { ASN1_TYPE p, p2, p3, p4; int move, tlen; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; p = node; move = DOWN; while (!((p == node) && (move == UP))) { if (move != UP) { if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG)) { p2 = p->down; while (p2) { if (type_field (p2->type) != TYPE_TAG) { p2->type |= CONST_TAG; p3 = _asn1_find_left (p2); while (p3) { if (type_field (p3->type) == TYPE_TAG) { p4 = _asn1_add_node_only (p3->type); tlen = strlen (p3->value); if (tlen > 0) _asn1_set_value (p4, p3->value, tlen + 1); _asn1_set_right (p4, p2->down); _asn1_set_down (p2, p4); } p3 = _asn1_find_left (p3); } } p2 = p2->right; } p->type &= ~(CONST_TAG); p2 = p->down; while (p2) { p3 = p2->right; if (type_field (p2->type) == TYPE_TAG) asn1_delete_structure (&p2); p2 = p3; } } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } return ASN1_SUCCESS; }
ASN1_TYPE _asn1_copy_structure3 (ASN1_TYPE source_node) { ASN1_TYPE dest_node, p_s, p_d, p_d_prev; int move; if (source_node == NULL) return NULL; dest_node = _asn1_add_node_only (source_node->type); p_s = source_node; p_d = dest_node; move = DOWN; do { if (move != UP) { if (p_s->name) _asn1_set_name (p_d, p_s->name); if (p_s->value) _asn1_set_value (p_d, p_s->value, p_s->value_len); move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p_s->down) { p_s = p_s->down; p_d_prev = p_d; p_d = _asn1_add_node_only (p_s->type); _asn1_set_down (p_d_prev, p_d); } else move = RIGHT; } if (p_s == source_node) break; if (move == RIGHT) { if (p_s->right) { p_s = p_s->right; p_d_prev = p_d; p_d = _asn1_add_node_only (p_s->type); _asn1_set_right (p_d_prev, p_d); } else move = UP; } if (move == UP) { p_s = _asn1_find_up (p_s); p_d = _asn1_find_up (p_d); } } while (p_s != source_node); return dest_node; }
/** * asn1_array2tree: * @array: specify the array that contains ASN.1 declarations * @definitions: return the pointer to the structure created by * *ARRAY ASN.1 declarations * @errorDescription: return the error description. * * Creates the structures needed to manage the ASN.1 definitions. * @array is a vector created by asn1_parser2array(). * * Returns: %ASN1_SUCCESS if structure was created correctly, * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not ASN1_TYPE_EMPTY, * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier * that is not defined (see @errorDescription for more information), * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong. **/ asn1_retCode asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions, char *errorDescription) { ASN1_TYPE p, p_last = NULL; unsigned long k; int move; asn1_retCode result; if (*definitions != ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_EMPTY; move = UP; k = 0; while (array[k].value || array[k].type || array[k].name) { p = _asn1_add_node (array[k].type & (~CONST_DOWN)); if (array[k].name) _asn1_set_name (p, array[k].name); if (array[k].value) _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); if (*definitions == NULL) *definitions = p; if (move == DOWN) _asn1_set_down (p_last, p); else if (move == RIGHT) _asn1_set_right (p_last, p); p_last = p; if (array[k].type & CONST_DOWN) move = DOWN; else if (array[k].type & CONST_RIGHT) move = RIGHT; else { while (1) { if (p_last == *definitions) break; p_last = _asn1_find_up (p_last); if (p_last == NULL) break; if (p_last->type & CONST_RIGHT) { p_last->type &= ~CONST_RIGHT; move = RIGHT; break; } } /* while */ } k++; } /* while */ if (p_last == *definitions) { result = _asn1_check_identifier (*definitions); if (result == ASN1_SUCCESS) { _asn1_change_integer_value (*definitions); _asn1_expand_object_id (*definitions); } } else { result = ASN1_ARRAY_ERROR; } if (errorDescription != NULL) { if (result == ASN1_IDENTIFIER_NOT_FOUND) { Estrcpy (errorDescription, ":: identifier '"); Estrcat (errorDescription, _asn1_identifierMissing); Estrcat (errorDescription, "' not found"); } else errorDescription[0] = 0; } if (result != ASN1_SUCCESS) { _asn1_delete_list_and_nodes (); *definitions = ASN1_TYPE_EMPTY; } else _asn1_delete_list (); return result; }
asn1_retCode _asn1_expand_object_id (ASN1_TYPE node) { ASN1_TYPE p, p2, p3, p4, p5; char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; int move, tlen; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; _asn1_str_cpy (name_root, sizeof (name_root), node->name); p = node; move = DOWN; while (!((p == node) && (move == UP))) { if (move != UP) { if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_ASSIGN)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) { if (p2->value && !isdigit (p2->value[0])) { _asn1_str_cpy (name2, sizeof (name2), name_root); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); p3 = asn1_find_node (node, name2); if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || !(p3->type & CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; _asn1_set_down (p, p2->right); _asn1_remove_node (p2); p2 = p; p4 = p3->down; while (p4) { if (type_field (p4->type) == TYPE_CONSTANT) { p5 = _asn1_add_node_only (TYPE_CONSTANT); _asn1_set_name (p5, p4->name); tlen = _asn1_strlen (p4->value); if (tlen > 0) _asn1_set_value (p5, p4->value, tlen + 1); if (p2 == p) { _asn1_set_right (p5, p->down); _asn1_set_down (p, p5); } else { _asn1_set_right (p5, p2->right); _asn1_set_right (p2, p5); } p2 = p5; } p4 = p4->right; } move = DOWN; continue; } } } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } /*******************************/ /* expand DEFAULT */ /*******************************/ p = node; move = DOWN; while (!((p == node) && (move == UP))) { if (move != UP) { if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_DEFAULT)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) { _asn1_str_cpy (name2, sizeof (name2), name_root); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); p3 = asn1_find_node (node, name2); if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || !(p3->type & CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; p4 = p3->down; name2[0] = 0; while (p4) { if (type_field (p4->type) == TYPE_CONSTANT) { if (name2[0]) _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p4->value); } p4 = p4->right; } tlen = strlen (name2); if (tlen > 0) _asn1_set_value (p2, name2, tlen + 1); } } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } return ASN1_SUCCESS; }