| 727 | |
| 728 | |
| 729 | CV_IMPL CvFileNode* |
| 730 | cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* _map_node, const char* str ) |
| 731 | { |
| 732 | CvFileNode* value = 0; |
| 733 | int i, len, tab_size; |
| 734 | unsigned hashval = 0; |
| 735 | int k = 0, attempts = 1; |
| 736 | |
| 737 | if( !fs ) |
| 738 | return 0; |
| 739 | |
| 740 | CV_CHECK_FILE_STORAGE(fs); |
| 741 | |
| 742 | if( !str ) |
| 743 | CV_Error( CV_StsNullPtr, "Null element name" ); |
| 744 | |
| 745 | for( i = 0; str[i] != '\0'; i++ ) |
| 746 | hashval = hashval*CV_HASHVAL_SCALE + (unsigned char)str[i]; |
| 747 | hashval &= INT_MAX; |
| 748 | len = i; |
| 749 | |
| 750 | if( !_map_node ) |
| 751 | { |
| 752 | if( !fs->roots ) |
| 753 | return 0; |
| 754 | attempts = fs->roots->total; |
| 755 | } |
| 756 | |
| 757 | for( k = 0; k < attempts; k++ ) |
| 758 | { |
| 759 | CvFileNodeHash* map; |
| 760 | const CvFileNode* map_node = _map_node; |
| 761 | CvFileMapNode* another; |
| 762 | |
| 763 | if( !map_node ) |
| 764 | map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k ); |
| 765 | |
| 766 | if( !CV_NODE_IS_MAP(map_node->tag) ) |
| 767 | { |
| 768 | if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) && |
| 769 | CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE ) |
| 770 | CV_Error( CV_StsError, "The node is neither a map nor an empty collection" ); |
| 771 | return 0; |
| 772 | } |
| 773 | |
| 774 | map = map_node->data.map; |
| 775 | tab_size = map->tab_size; |
| 776 | |
| 777 | if( (tab_size & (tab_size - 1)) == 0 ) |
| 778 | i = (int)(hashval & (tab_size - 1)); |
| 779 | else |
| 780 | i = (int)(hashval % tab_size); |
| 781 | |
| 782 | for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next ) |
| 783 | { |
| 784 | const CvStringHashNode* key = another->key; |
| 785 | |
| 786 | if( key->hashval == hashval && |
no test coverage detected