| 652 | |
| 653 | |
| 654 | CV_IMPL CvFileNode* |
| 655 | cvGetFileNode( CvFileStorage* fs, CvFileNode* _map_node, |
| 656 | const CvStringHashNode* key, |
| 657 | int create_missing ) |
| 658 | { |
| 659 | CvFileNode* value = 0; |
| 660 | int k = 0, attempts = 1; |
| 661 | |
| 662 | if( !fs ) |
| 663 | return 0; |
| 664 | |
| 665 | CV_CHECK_FILE_STORAGE(fs); |
| 666 | |
| 667 | if( !key ) |
| 668 | CV_Error( CV_StsNullPtr, "Null key element" ); |
| 669 | |
| 670 | if( _map_node ) |
| 671 | { |
| 672 | if( !fs->roots ) |
| 673 | return 0; |
| 674 | attempts = fs->roots->total; |
| 675 | } |
| 676 | |
| 677 | for( k = 0; k < attempts; k++ ) |
| 678 | { |
| 679 | int i, tab_size; |
| 680 | CvFileNode* map_node = _map_node; |
| 681 | CvFileMapNode* another; |
| 682 | CvFileNodeHash* map; |
| 683 | |
| 684 | if( !map_node ) |
| 685 | map_node = (CvFileNode*)cvGetSeqElem( fs->roots, k ); |
| 686 | |
| 687 | if( !CV_NODE_IS_MAP(map_node->tag) ) |
| 688 | { |
| 689 | if( (!CV_NODE_IS_SEQ(map_node->tag) || map_node->data.seq->total != 0) && |
| 690 | CV_NODE_TYPE(map_node->tag) != CV_NODE_NONE ) |
| 691 | CV_Error( CV_StsError, "The node is neither a map nor an empty collection" ); |
| 692 | return 0; |
| 693 | } |
| 694 | |
| 695 | map = map_node->data.map; |
| 696 | tab_size = map->tab_size; |
| 697 | |
| 698 | if( (tab_size & (tab_size - 1)) == 0 ) |
| 699 | i = (int)(key->hashval & (tab_size - 1)); |
| 700 | else |
| 701 | i = (int)(key->hashval % tab_size); |
| 702 | |
| 703 | for( another = (CvFileMapNode*)(map->table[i]); another != 0; another = another->next ) |
| 704 | if( another->key == key ) |
| 705 | { |
| 706 | if( !create_missing ) |
| 707 | { |
| 708 | value = &another->value; |
| 709 | return value; |
| 710 | } |
| 711 | CV_PARSE_ERROR( "Duplicated key" ); |
no test coverage detected