예제 #1
0
/*!
 @brief _fta_var_alloc_i

 allocate the list record(internal)

 @param [in] var_header     header of the area
 @param [in] access_info    access information
 @param [in] key_info       key
 @param [in] alloc_len      size of the record

 @retval       NULL: over the max record
 @retval     others: pointer of record
*/
static void *_fta_var_alloc_i(fta_var_store_header *var_header,
                              const fta_var_record_access_info *access_info, const void *key_info, uint32 alloc_len)
{
    uint8 *var_dataarea;
    void *var_record = NULL;

    uint32 key_size;
    uint32 datalen_size;
    uint32 datalen;

    if(!FTA_LIB_CHECKBIT(var_header->cmn.statbit, FTA_STORE_STATBIT_RECORDING)) {
        goto _fta_var_alloc_exit;
    }

    key_size = access_info->key_size;
    datalen_size = access_info->datalen_size;
    if(alloc_len < key_size + datalen_size ||
            alloc_len > var_header->cmn.size - var_header->cmn.offset) {
        goto _fta_var_alloc_exit;
    }
    datalen = alloc_len - (key_size + datalen_size);
    if((datalen_size == 0 && datalen > 0) ||
            (datalen_size == 1 && datalen > 0xFF) ||
            (datalen_size == 2 && datalen > 0xFFFF) ||
            (datalen_size == 3 && datalen > 0xFFFFFF)) {
        goto _fta_var_alloc_exit;
    }
    alloc_len = FTA_LIB_ALIGN4_32(alloc_len);

    if(access_info->check_func != NULL) {
        if(access_info->check_func(var_header, key_info, alloc_len) == FALSE) {
            goto _fta_var_alloc_exit;
        }
    }

    if(alloc_len > var_header->cmn.size - var_header->cmn.offset - var_header->bottom) {
        goto _fta_var_alloc_exit;
    }
    var_dataarea = FTA_LIB_OFFSET_ADDR(var_header, var_header->cmn.offset);

    /* append the record */
    var_record = (void *)FTA_LIB_OFFSET_ADDR(var_dataarea, var_header->bottom);
    memcpy(var_record, key_info, key_size);
    if(datalen_size > 0) {
        if(datalen_size <= sizeof(uint32)) {
            memcpy(FTA_LIB_OFFSET_ADDR(var_record, key_size), &datalen, datalen_size);
        } else {
            memcpy(FTA_LIB_OFFSET_ADDR(var_record, key_size), &datalen, sizeof(uint32));
            memset(FTA_LIB_OFFSET_ADDR(var_record, key_size + sizeof(uint32)), 0, datalen_size - sizeof(uint32));
        }
    }
    var_header->count++;
    var_header->bottom += alloc_len;

_fta_var_alloc_exit:
    ;

    return var_record;
}
예제 #2
0
/*!
 @brief _fta_listex_hash_init_common

 initialize for list hash area

 @param [in] store_item   item for manage

 @retval    none

 @note      it is necessary to use initialize macro FTA_CONFIG_STORE_ITEM_DEF2
 @note      instead of FTA_CONFIG_STORE_ITEN_DEF in configuration.
*/
void _fta_listex_hash_init_common(fta_manager_store_item *store_item)
{
  fta_list_store_header *list_header = (fta_list_store_header *)(store_item->addr);
  const fta_listex_hash_access_info *access_info;
  uint32 fixed_len;

  /* initialize */
  list_header->count = 0;
  list_header->version = FTA_LIST_VERSION_HASH;
  list_header->quota = FTA_LIST_QUOTA_DEFAULT;
  list_header->bottom = 0;

  /* set to record manager */
  access_info = store_item->def->add_param;
  if(access_info == NULL) {
    goto _fta_listex_hash_init_common_exit;
  }

  /* check record manager */
  fixed_len = FTA_LIB_ALIGN4_32(access_info->fixed_len);
  if((fixed_len < access_info->key_size) ||
     (fixed_len > list_header->cmn.size - list_header->cmn.offset) ||
     (access_info->entry_max == 0) ||
     (access_info->entry_max >= FTA_LISTEX_HASH_ID_EMPTY) ||
     (access_info->entry_max * fixed_len >= list_header->cmn.size - list_header->cmn.offset) ||
     (access_info->hash_size == 0) ||
     (access_info->work_buffer == 0)) {
    goto _fta_listex_hash_init_common_exit;
  }

  /* initialize wake area */
  memset(access_info->work_buffer, FTA_LISTEX_HASH_ID_EMPTY_RESET,
         FTA_LISTEX_HASH_WORK_MAX(access_info->entry_max, access_info->hash_size) *
         sizeof(fta_listex_hash_id_type));

  list_header->cmn.enabled = TRUE;

  FTA_LIB_CHANGEBIT_SET(list_header->cmn.statbit, FTA_STORE_STATBIT_RECORDING);

  return;

_fta_listex_hash_init_common_exit: ;
  FTA_LOG_MESSAGE(FTA_LIST, FTA_LOG_LEVEL_CRITICAL, "*** FTA LIST CONFIG ERROR", 0, 0, 0);

  return;
}
예제 #3
0
/*!
 @brief _fta_lisext_hash_record?i

 internal functionn of operating the list hash record

 @param [in] p_store_item   item for manage
 @param [in] access_info    access information
 @param [in] key_info       key
 @param [in] access_type    FTA_LISTEX_HASH_ACCESS_GET: get record
                            FTA_LISTEX_HASH_ACCESS_ADD: add record
                            FTA_LISTEX_HASH_ACCESS_DEL: del record

 @retval       NULL: not found / over the max record
 @retval     others: pointer of record
*/
static void *_fta_listex_hash_record_i(fta_list_store_header *list_header,
                                     const fta_listex_hash_access_info *access_info,
                                     const void *key_info, uint32 access_type)
{
  uint8 *list_dataarea;
  void *list_record = NULL;

  uint32 fixed_len;
  uint32 key_size;
  uint32 record_par;
  uint32 record_num;

  fta_listex_hash_id_type *work_buffer;
  boolean not_found;

  /* check of a recordable state or an effective state */
  if(access_type != FTA_LISTEX_HASH_ACCESS_GET) {
    if(!FTA_LIB_CHECKBIT(list_header->cmn.statbit, FTA_STORE_STATBIT_RECORDING)) {
      goto _fta_listex_hash_record_exit;
    }
  } else {
    if(list_header->cmn.enabled != FTA_STORE_ENABLED_TRUE) {
      goto _fta_listex_hash_record_exit;
    }
  }

  fixed_len = FTA_LIB_ALIGN4_32(access_info->fixed_len);
  key_size = access_info->key_size;
  list_dataarea = FTA_LIB_OFFSET_ADDR(list_header, list_header->cmn.offset);
  work_buffer = access_info->work_buffer;

  /* registered check */
  not_found = TRUE;
  record_par = 0;
  memcpy(&record_par, key_info, (key_size > sizeof(uint32) ? sizeof(uint32) : key_size));
  record_par %= access_info->hash_size; /* only to 4 bytes of low rank */
  record_par += FTA_LISTEX_HASH_BUF_HASHEDINDEX;
  if(list_header->count > 0) {
    /* search for the same item */
    record_num = work_buffer[record_par];
    while(record_num != FTA_LISTEX_HASH_ID_EMPTY) {
      list_record = (void *)FTA_LIB_OFFSET_ADDR(list_dataarea, record_num * fixed_len);
      if(memcmp(key_info, list_record, key_size) == 0) {
        not_found = FALSE;
        break;
      }
      record_par = record_num;
      record_num = work_buffer[record_par];
    }
  }

  if(not_found) {

    /* add record */
    if(access_type == FTA_LISTEX_HASH_ACCESS_ADD) {

      if(list_header->count == 0) {
        /* simple work area check only once after initialization */
        if(work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_BEGIN] != FTA_LISTEX_HASH_ID_EMPTY ||
           work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END]   != FTA_LISTEX_HASH_ID_EMPTY ||
           work_buffer[FTA_LISTEX_HASH_BUF_HASHEDINDEX] != FTA_LISTEX_HASH_ID_EMPTY ) {
          FTA_LOG_MESSAGE(FTA_LIST, FTA_LOG_LEVEL_CRITICAL, "*** FTA LIST CONFIG ERROR", 0, 0, 0);
          list_record = NULL;
          goto _fta_listex_hash_record_exit;
        }
      }

      /* a new record is added */
      if((uint32)(list_header->count) >= access_info->entry_max) {
        
        /* acquires from an empty list when the number of registration is a maximum */
        record_num = work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_BEGIN];
        if(record_num == FTA_LISTEX_HASH_ID_EMPTY) {
          list_record = NULL;
          goto _fta_listex_hash_record_exit;
        }
        /* deletes from an empty list */
        work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_BEGIN] = work_buffer[record_num];
        if(work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END] == record_num) {
          work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END] = FTA_LISTEX_HASH_ID_EMPTY;
        }

      } else {

        /* adds a new record until the number of registration is a maximum*/
        record_num = list_header->count;
        list_header->count++;
        list_header->bottom = list_header->count * fixed_len;

      }
      /* adds to hash table */
      work_buffer[record_num] = work_buffer[record_par];
      work_buffer[record_par] = (fta_listex_hash_id_type)record_num;

      /* return the record position */
      list_record = (void *)FTA_LIB_OFFSET_ADDR(list_dataarea, record_num * fixed_len);
      memcpy(list_record, key_info, key_size);

    } else {
      /* do noting */
      list_record = NULL;
    }

  } else {

    /* delete record */
    if(access_type == FTA_LISTEX_HASH_ACCESS_DEL) {

      /* set the delete bit */
      ((uint8*)list_record)[key_size - 1] |= 0x80;
      /* deletes from the list and adds to an empty entry */
      work_buffer[record_par] = work_buffer[record_num];
      work_buffer[record_num] = FTA_LISTEX_HASH_ID_EMPTY;
      if(work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_BEGIN] == FTA_LISTEX_HASH_ID_EMPTY) {
        /* with no empty entry */
        work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_BEGIN] = (fta_listex_hash_id_type)record_num;
        work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END] = (fta_listex_hash_id_type)record_num;
      } else {
        /* add to a termination */
        work_buffer[work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END]] = (fta_listex_hash_id_type)record_num;
        work_buffer[FTA_LISTEX_HASH_BUF_EMPTY_END] = (fta_listex_hash_id_type)record_num;
      }
    }
  }

_fta_listex_hash_record_exit: ;

  return list_record;
}
예제 #4
0
/*!
 @brief _fta_var_find

 sarch for the record

 @param [in] p_store_item   item for manage
 @param [in] key_info       key
 @param [in] alloc_len      size of the record

   @retval       NULL: not found
   @retval     others: pointer of record
*/
void *_fta_var_find(const fta_manager_store_item * const *p_store_item,
                    const fta_var_record_access_info *access_info, const void *key_info)
{
    fta_var_store_header *var_header;
    void *var_record = NULL;

    uint8 *var_dataarea = NULL;
    uint32 dataarea_size = 0;
    uint32 record_count = 0;
    uint32 record_num;
    uint32 record_pos;
    uint32 key_size;
    uint32 datalen_size;
    uint32 datalen;
    boolean bad_condition = FALSE;

    if(p_store_item == NULL || access_info == NULL || key_info == NULL) {
        FTA_LOG_MESSAGE(FTA_VAR, FTA_LOG_LEVEL_CRITICAL, "*** FTA VAR INTERNAL ERROR", 0, 0, 0);
        return NULL;
    }

    FTA_ENTER_LOCK();

    /* - - - - - - - - */
    do {
        if(access_info->lock_access) {
            if(*p_store_item == NULL) {
                bad_condition = TRUE;
                break;
            }
            if((*p_store_item)->lock_keeper->manager_status != FTA_MANAGER_STATUS_ENABLED) {
                bad_condition = TRUE;
                break;
            }
        }
        var_header = (fta_var_store_header *)((*p_store_item)->addr);
        if(var_header->cmn.enabled != FTA_STORE_ENABLED_TRUE) {
            bad_condition = TRUE;
            break;
        }
        var_dataarea = FTA_LIB_OFFSET_ADDR(var_header, var_header->cmn.offset);
        record_count = var_header->count;
        dataarea_size = var_header->bottom;

    } while(FALSE);
    /* - - - - - - - - */

    FTA_LEAVE_LOCK();

    if(bad_condition) {
        return var_record;
    }

    key_size = access_info->key_size;
    datalen_size = access_info->datalen_size;
    record_pos = 0;
    /* - - - - - - - - */
    for(record_num = 0; record_num < record_count; record_num++) {
        if(dataarea_size < key_size + datalen_size + record_pos) {
            var_record = NULL;
            break;
        }
        var_record = (void *)FTA_LIB_OFFSET_ADDR(var_dataarea, record_pos);
        if(memcmp(var_record, key_info, key_size) == 0) {
            /* matched */
            break;
        }
        datalen = 0;
        if(datalen_size <= sizeof(uint32)) {
            memcpy(&datalen, FTA_LIB_OFFSET_ADDR(var_record, key_size), datalen_size);
        } else {
            memcpy(&datalen, FTA_LIB_OFFSET_ADDR(var_record, key_size), sizeof(uint32));
        }
        var_record = NULL;
        datalen = FTA_LIB_ALIGN4_32(datalen);
        record_pos += key_size + datalen_size + datalen;
    }
    /* - - - - - - - - */

    return var_record;
}