static unsigned int cassoclist_resize(cassoclist_t *cassoclist) { size_t element_counter = 0,array_size = cassoclist->array_size; void *temp = realloc(cassoclist->element_info_array ,sizeof(cassoclist_element_info_t)*array_size*2); cassoclist_element_info_t *element_info; if(!temp){ return CASSOCLIST_MEMORY_ALLOCATION_ERROR; } cassoclist->element_info_array = temp; temp = realloc(cassoclist->value_array ,cassoclist->element_size*array_size*2); if(!temp){ return CASSOCLIST_MEMORY_ALLOCATION_ERROR; } cassoclist->value_array = temp; while(element_counter != array_size){ element_info = get_element_info_by_offset(cassoclist,element_counter); if(get_used_flag(element_info) && (hash_function(get_key(element_info) ,get_hash_id(element_info))&array_size)){ *get_element_info_by_offset(cassoclist,element_counter+array_size) = *get_element_info_by_offset(cassoclist,element_counter); memcpy(get_value_by_offset(cassoclist,element_counter+array_size) ,get_value_by_offset(cassoclist,element_counter) ,cassoclist->element_size); get_used_flag(element_info) = 0; } else{ get_used_flag(element_info+array_size) = 0; } element_counter++; } cassoclist->array_size = array_size*2; return CASSOCLIST_SUCCESS; }
unsigned int cassoclist_add(cassoclist_t *cassoclist ,const char *key,const void *input) { size_t hash_value,hash_id,key_length; unsigned int errcode,counter = 1; cassoclist_element_info_t *element_info; if(!key){ return CASSOCLIST_INVALID_KEY; } if(!cassoclist_private_lookup(cassoclist,key,NULL)){ return CASSOCLIST_KEY_COLLISION; } if(cassoclist->size*4 >= cassoclist->array_size*3){ /* もしハッシュテーブルの3/4がデータで埋まっていれば、リサイズを試みる。 失敗した場合でもエラー処理の必要は無い。 */ cassoclist_resize(cassoclist); } while(1){ hash_id = 0; while(hash_id != CASSOCLIST_HASH_TYPES){ hash_value = hash(cassoclist,key,hash_id); if(!cassoclist_trymove(cassoclist,hash_value,counter*2)){ goto SUCCEED_IN_TRYMOVE; } hash_id++; } if(counter == 1 && (errcode = cassoclist_resize(cassoclist))){ return errcode; } else if(counter == 2){ return CASSOCLIST_HASH_COLLISION; } counter++; } SUCCEED_IN_TRYMOVE:; key_length = strlen(key); element_info = get_element_info_by_offset(cassoclist,hash_value); get_mode_flag(element_info) = (key_length >= CASSOCLIST_MAX_OF_SHORT_KEY_SIZE); if(get_mode_flag(element_info)){ get_long_key(element_info) = malloc(key_length+1); if(!get_long_key(element_info)){ return CASSOCLIST_MEMORY_ALLOCATION_ERROR; } memcpy(get_long_key(element_info),key,key_length+1); } else{ memcpy(get_short_key(element_info),key,key_length+1); } get_used_flag(element_info) = 1; get_hash_id(element_info) = hash_id; memcpy(get_value_by_offset(cassoclist,hash_value) ,input,cassoclist->element_size); cassoclist->size++; return CASSOCLIST_SUCCESS; }
QByteArray emsa3Encode(const QString &hashName, const QByteArray &digest, int size) { QByteArray hash_id = get_hash_id(hashName); if(hash_id.isEmpty()) return QByteArray(); // logic adapted from Botan int basesize = hash_id.size() + digest.size() + 2; if(size == -1) size = basesize + 1; // default to 1-byte pad int padlen = size - basesize; if(padlen < 1) return QByteArray(); QByteArray out(size, (char)0xff); // pad with 0xff out[0] = 0x01; out[padlen + 1] = 0x00; int at = padlen + 2; memcpy(out.data() + at, hash_id.data(), hash_id.size()); at += hash_id.size(); memcpy(out.data() + at, digest.data(), digest.size()); return out; }