Beispiel #1
0
/**
 * Adds a new element to the hash with a value
 *
 * Parameters:
 * - hash: A valid quickhash
 * - key: The key
 * - value: The value
 *
 * Returns:
 * - 1 if the element was added or 0 if the element couldn't be added
 */
int qhi_hash_add(qhi *hash, qhv key, qhv value)
{
	uint32_t idx;
	qhl     *list;

	// obtain the hashed key, and the bucket list for the hashed key
	idx = qhi_set_hash(hash, key);
	list = &(hash->bucket_list[idx]);

	// check if we already have the key in the list if requested
	if (hash->options->check_for_dupes && find_bucket_from_list(hash, list, key, NULL)) {
		return 0;
	}

	return qhi_add_entry_to_list(hash, list, hash_add_key(hash, key), hash_add_value(hash, value));
}
Beispiel #2
0
/**
 * Updates the value belonging to a bucket.
 *
 * This function updates the value that belongs to the bucket, by updating it
 * in the integer store when there is an integer values, or it will *add* a new
 * value to the store for string values. The function does not clean up holes
 * in the string store.
 *
 * Params:
 * - hash: the hash the bucket belongs to
 * - bucket: the bucket itself
 * - value: the new value
 *
 * Returns:
 * - 1 if the key was of a known type, or 0 otherwise. Only if something is
 *   really wrong, 0 should be returned.
 */
static int qhi_update_value_in_bucket(qhi *hash, qhb *bucket, qhv value)
{
	switch (hash->value_type) {
		case QHI_VALUE_TYPE_INT:
			hash->i.values[bucket->value_idx] = value.i;
			return 1;

		case QHI_VALUE_TYPE_STRING:
			bucket->value_idx = hash_add_value(hash, value);
			return 1;
			break;

		default:
			/* FAIL */
			break;
	}
	return 0;
}
Beispiel #3
0
/**
 * Adds a new element, or updates the value if the key already is part of the hash
 *
 * Parameters:
 * - hash: A valid quickhash
 * - key: The key
 * - value: The value
 *
 * Returns:
 * - 1 if the element is part of the hash and was updated, 2 if the element was
 *   added or 0 if an error occurred.
 */
int qhi_hash_set(qhi *hash, qhv key, qhv value)
{
	uint32_t idx;
	qhl     *list;
	qhb     *bucket;

	// obtain the hashed key, and the bucket list for the hashed key
	idx = qhi_set_hash(hash, key);
	list = &(hash->bucket_list[idx]);

	// check if we already have the key in the list if requested
	if (find_bucket_from_list(hash, list, key, &bucket)) {
		// update
		return qhi_update_value_in_bucket(hash, bucket, value);
	} else {
		// add
		return qhi_add_entry_to_list(hash, list, hash_add_key(hash, key), hash_add_value(hash, value)) ? 2 : 0;
	}
	return 0;
}
Beispiel #4
0
/**
 * Creates a hash from a string containing a serialized hash
 *
 * Parameters:
 * - options: the options to create the hash with. This structure contains at
 *   least the nr of hash buckets, and whether set additions should be checked
 *   for duplicates. See the description of qho for a full list of options.
 * - context: the context that reader functions can use to store specific data
 *   in (such as a filedescription, or a PHP stream)
 * - int32t_apply_func: The function to use for reading int32s.
 * - chars_apply_func: The function to use for reading chars.
 *
 * Returns:
 * - A new hash, or NULL upon failure
 */
qhi *qhi_obtain_hash(qho *options, void *context, qhi_int32t_read_buffer_apply_func int32t_apply_func, qhi_char_read_buffer_apply_func chars_apply_func)
{
	uint32_t    nr_of_elements, elements_read = 0;
	int32_t     key_buffer[1024];
	qhi        *tmp;

	// we read the first int32s for the signature and nr of items
	if (!int32t_apply_func(context, key_buffer, 2)) {
		return NULL;
	}
	if ((key_buffer[0] & 0xffff) != 0x4851) {
		return NULL;
	}
	options->key_type = (key_buffer[0] & 0xf00000) >> 20;
	options->value_type = (key_buffer[0] & 0x0f0000) >> 16;

	nr_of_elements = key_buffer[1];

	// override the nr of bucket lists if the size is still 0.
	options->size = qhi_normalize_size(options->size == 0 ? nr_of_elements : options->size);
#if DEBUG
	printf("Picking size: %u\n", options->size);
#endif

	// read the keys if we have QHI_KEY_TYPE_STRING
	if (options->key_type == QHI_KEY_TYPE_STRING) {
		int32t_apply_func(context, key_buffer, 2);
		options->size = key_buffer[1];
#if DEBUG
		printf("Loading size: %u\n", options->size);
#endif

		// create the hash
		tmp = qhi_create(options);
		if (!tmp) {
			return NULL;
		}

		// load the keys
		tmp->keys.values = tmp->options->memory.malloc(key_buffer[0] + 1);
		tmp->keys.size = tmp->keys.count = key_buffer[0];
		chars_apply_func(context, tmp->keys.values, key_buffer[0]);
		tmp->keys.values[key_buffer[0]] = '\0';
	} else {
		// create the hash
		tmp = qhi_create(options);
		if (!tmp) {
			return NULL;
		}
	}

	// read the strings if we have QHI_VALUE_TYPE_STRING
	if (tmp->value_type == QHI_VALUE_TYPE_STRING) {
		int32t_apply_func(context, key_buffer, 1);
		tmp->s.values = tmp->options->memory.malloc(key_buffer[0] + 1);
		tmp->s.size = tmp->s.count = key_buffer[0];
		chars_apply_func(context, tmp->s.values, key_buffer[0]);
		tmp->s.values[key_buffer[0]] = '\0';
	}

	if (tmp->key_type == QHI_KEY_TYPE_STRING) {
		do {
			int32_t idx, list_elements;
			qhl *list;

			// read hash key, and nr of elements in list
			int32t_apply_func(context, key_buffer, 2);
			idx = key_buffer[0];
			list_elements = key_buffer[1];

			// read the hash elements
			do {
				int32t_apply_func(context, key_buffer, 2);
				list = &(tmp->bucket_list[idx]);
				qhi_add_entry_to_list(tmp, list, key_buffer[0], hash_add_value(tmp, (qhv) key_buffer[1]));
				elements_read++;
				list_elements--;
			} while (list_elements);
		} while (elements_read < nr_of_elements);
	} else {
		// read the elements (key and value idx) and add them to the hash
		do {
			elements_read = int32t_apply_func(context, key_buffer, 1024) / 2;
			qhi_hash_add_elements_from_buffer(tmp, key_buffer, elements_read * 2);
			nr_of_elements -= elements_read;
		} while (elements_read && nr_of_elements);
	}

	return tmp;
}
  int ac_rtld_config::process_map_file(unsigned int fd, hash_node **hashtable)
  {
    unsigned int i, num1, num2;
    char buffer[20];
    unsigned int line = 0;

    buffer[0] = 'a';

    while (buffer[0] != '\0')
      {
	char* endptr;
	line++;

	request_read(fd, buffer, 1);

	/* Ignore line */
	if (buffer[0] == '#')
	  {
	    while (buffer[0] != '\n' && buffer[0] != '\0')
	      request_read(fd, buffer, 1);
	    continue;
	  }

	/* Skips whitespace */
	while (buffer[0] == ' ' || buffer[0] == '\t')
	  request_read(fd, buffer, 1);

	/* Nothing to parse here, go to next line */
	if (buffer[0] == '\n' || buffer[0] == '\0')
	  continue;

	/** Parse num = num statement **/
	/* Not a number */
	if (buffer[0] < '0' || buffer[0] > '9')
	  {
	    return ERROR;
	  }

	i = 0;

	while (buffer[i] >= '0' && buffer[i] <= '9')
	{ 
	  request_read(fd, &buffer[++i], 1);
	  if (i >= 20)
	    {
	      return ERROR;
	    }
	}
	
	/* Unexpected end of line */
	if (buffer[i] == '\n' || buffer[i] == '\0') 
	  {
	    return ERROR;
	  }

	endptr = NULL;

	num1 = strtol(buffer, &endptr, 10);
	if (endptr != &buffer[i])
	  {
	    return ERROR;
	  }
	buffer[0] = buffer[i];

	/* Skips whitespace */
	while (buffer[0] == ' ' || buffer[0] == '\t')
	  request_read(fd, buffer, 1);

	/* Unexpected token */
	if (buffer[0] != '=') 
	{
	  return ERROR;
	}

	request_read(fd, buffer, 1);
	
	/* Skips whitespace */
	while (buffer[0] == ' ' || buffer[0] == '\t')
	  request_read(fd, buffer, 1);

	/* Unexpected end of line */
	if (buffer[0] == '\n' || buffer[0] == '\0') 
	  {
	    return ERROR;
	  }

	/* Parse the second number at num = num statement */
	/* Not a number */
	if (buffer[0] < '0' || buffer[0] > '9')
	  { 
	    return ERROR;
	  }
	
	i = 0;

	while (buffer[i] >= '0' && buffer[i] <= '9')
	  { 
	    request_read(fd, &buffer[++i], 1);
	    if (i >= 20)
	      {
		return ERROR;
	      }
	  }
	
	endptr = NULL;

	num2 = strtol(buffer, &endptr, 10);
	if (endptr != &buffer[i])
	  {
	    return ERROR;
	  }
	buffer[0] = buffer[i];

	if (buffer[0] != '\n' && buffer[0] != '\0')
	  {
	    return ERROR;
	  }
       
	if (hash_add_value(hashtable, num1, num2) == ERROR)
	  {
	    return ERROR;
	  }
      

      }

    return FINE;
  }
Beispiel #6
0
int process_map_file(unsigned int fd, hash_node **hashtable, char reverse_mode)
{
  unsigned int i, num1, num2;
  char buffer[20];
  unsigned int line = 0;

  buffer[0] = 'a';

  while (buffer[0] != '\0')
    {
      char* endptr;
      line++;

      request_read(fd, buffer, 1, FALSE);

      /* Ignore line */
      if (buffer[0] == '#')
	{
	  while (buffer[0] != '\n' && buffer[0] != '\0')
	    request_read(fd, buffer, 1, FALSE);
	  continue;
	}

      /* Skips whitespace */
      while (buffer[0] == ' ' || buffer[0] == '\t')
	  request_read(fd, buffer, 1, FALSE);

      /* Nothing to parse here, go to next line */
      if (buffer[0] == '\n' || buffer[0] == '\0')
	continue;

      /** Parse num = num statement **/
      /* Not a number */
      if (buffer[0] < '0' || buffer[0] > '9')
	{
	  fprintf(stderr, "Error while parsing map file: expecting number = number statement at line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}

      i = 0;

      while (buffer[i] >= '0' && buffer[i] <= '9')
	{ 
	  request_read(fd, &buffer[++i], 1, FALSE);
	  if (i >= 20)
	    {
	      fprintf(stderr, "Error while parsing map file: number too large at line %d\n", line);
	      return ACRELCONVERT_FUNC_ERROR;
	    }
	}

      /* Unexpected end of line */
      if (buffer[i] == '\n' || buffer[i] == '\0') 
	{
	  fprintf(stderr, "Error while parsing map file: unexpected end of line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}

      endptr = NULL;

      num1 = strtol(buffer, &endptr, 10);
      if (endptr != &buffer[i])
	{
	  fprintf(stderr, "Error while parsing map file: first number of line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}
      buffer[0] = buffer[i];

       /* Skips whitespace */
      while (buffer[0] == ' ' || buffer[0] == '\t')
	  request_read(fd, buffer, 1, FALSE);

      /* Unexpected token */
      if (buffer[0] != '=') 
	{
	  fprintf(stderr, "Error while parsing map file: expected token \"=\" at line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}

      request_read(fd, buffer, 1, FALSE);

      /* Skips whitespace */
      while (buffer[0] == ' ' || buffer[0] == '\t')
	request_read(fd, buffer, 1, FALSE);

      /* Unexpected end of line */
      if (buffer[0] == '\n' || buffer[0] == '\0') 
	{
	  fprintf(stderr, "Error while parsing map file: unexpected end of line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}

      /* Parse the second number at num = num statement */
	 /* Not a number */
      if (buffer[0] < '0' || buffer[0] > '9')
	{
	  fprintf(stderr, "Error while parsing map file: expecting number = number statement at line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}

      i = 0;

      while (buffer[i] >= '0' && buffer[i] <= '9')
	{ 
	  request_read(fd, &buffer[++i], 1, FALSE);
	  if (i >= 20)
	    {
	      fprintf(stderr, "Error while parsing map file: number too large at line %d\n", line);
	      return ACRELCONVERT_FUNC_ERROR;
	    }
	}

      endptr = NULL;

      num2 = strtol(buffer, &endptr, 10);
      if (endptr != &buffer[i])
	{
	  fprintf(stderr, "Error while parsing map file: second number of line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}
      buffer[0] = buffer[i];

      if (buffer[0] != '\n' && buffer[0] != '\0')
	{
	  fprintf(stderr, "Error while parsing map file: junk at end of line %d\n", line);
	  return ACRELCONVERT_FUNC_ERROR;
	}
      if (!reverse_mode)
	{
	  if (hash_add_value(hashtable, num1, num2) == ACRELCONVERT_FUNC_ERROR)
	    {
	      fprintf(stderr, "Error while parsing map file: failed to add hash value corresponding to line %d\n", line);
	      return ACRELCONVERT_FUNC_ERROR;
	    }
	}
      else /* Reverse map */
	{
	  if (hash_add_value(hashtable, num2, num1) == ACRELCONVERT_FUNC_ERROR)
	    {
	      fprintf(stderr, "Error while parsing map file: failed to add hash value corresponding to line %d\n", line);
	      return ACRELCONVERT_FUNC_ERROR;
	    }
	}

    }

  return ACRELCONVERT_FUNC_OK;
}