Exemplo n.º 1
0
Arquivo: sl_vector.c Projeto: vaplv/sl
/*******************************************************************************
 *
 * Helper functions.
 *
 ******************************************************************************/
static enum sl_error
ensure_allocated(struct sl_vector* vec, size_t capacity, bool keep_data)
{
  void* buffer = NULL;
  enum sl_error sl_err = SL_NO_ERROR;
  ASSERT(vec);

  if(capacity > vec->capacity) {
    size_t new_capacity = 0;
    NEXT_POWER_OF_2(capacity, new_capacity);
    buffer = MEM_ALIGNED_ALLOC
      (vec->allocator, new_capacity * vec->data_size, vec->data_alignment);
    if(!buffer) {
      sl_err = SL_MEMORY_ERROR;
      goto error;
    }
    if(keep_data) {
      buffer = memcpy(buffer, vec->buffer, vec->capacity * vec->data_size);
    }
    MEM_FREE(vec->allocator, vec->buffer);
    vec->buffer = buffer;
    vec->capacity = new_capacity;
    buffer = NULL;
  }

exit:
  return sl_err;
error:
  if(buffer) {
    MEM_FREE(vec->allocator, buffer);
    buffer = NULL;
  }
  goto exit;
}
Exemplo n.º 2
0
hwfont Tutf_UTF_32_to_CP437(hwfont c)
{
#define EL(x) +1
    enum {
        n = T_NLIST(CP437,EL) + 1,    /* +1 to manually map T_UTF_32_CHECK_MARK -> T_CP437_SQUARE_ROOT below */
        n_power_of_2 = NEXT_POWER_OF_2(n)
    };
#undef EL
    
    static utf32_hash_table * table = NULL;
    
    /* Codepage 437 (VGA) obviously cannot contain all unicode chars. this is just a best effort. */
    if (!table) {
	table = utf32_hash_create(Tutf_CP437_to_UTF_32, n, n_power_of_2);

        /* manually map T_UTF_32_CHECK_MARK -> T_CP437_SQUARE_ROOT */
        utf32_hash_insert_at(table, n - 1, T_UTF_32_CHECK_MARK, T_CP437_SQUARE_ROOT);
    }
    return utf32_hash_search(table, c, ttrue);
}
Exemplo n.º 3
0
hwfont T_CAT(Tutf_UTF_16_to_,T_TEMPLATE) (hwfont c)
{
#define EL(x) +1
    enum {
        n = T_NLIST(T_TEMPLATE,EL) + 0, /* +0 in case T_NLIST() expands to nothing */
        n_power_of_2 = NEXT_POWER_OF_2(n)
    };
#undef EL
    
    static utf16_hash_table * table = NULL;
    
    /* a single 8-bit charset obviously cannot contain all unicode chars. this is just a best effort. */
    if (!table)
	table = utf16_hash_create(T_CAT3(Tutf_,T_TEMPLATE,_to_UTF_16), n, n_power_of_2);

#ifdef TEMPLATE_REDEFINES_ASCII
    return utf16_hash_search(table, c, FALSE);
#else
    return utf16_hash_search(table, c, TRUE);
#endif
}
Exemplo n.º 4
0
Arquivo: sl_vector.c Projeto: vaplv/sl
EXPORT_SYM enum sl_error
sl_vector_insert_n
  (struct sl_vector* vec,
   size_t id,
   size_t count,
   const void* data)
{
  void* buffer = NULL;
  const void* src = NULL;
  void* dst = NULL;
  size_t i = 0;
  enum sl_error err = SL_NO_ERROR;

  if(!vec || (id > vec->length) || !data) {
    err = SL_INVALID_ARGUMENT;
    goto error;
  }
  if(0 == count) {
    goto exit;
  }
  if(!IS_ALIGNED(data, vec->data_alignment)) {
    err = SL_ALIGNMENT_ERROR;
    goto error;
  }
  if(vec->length == SIZE_MAX) {
    err = SL_OVERFLOW_ERROR;
    goto error;
  }
  if(id == vec->length) {
    err = ensure_allocated(vec, vec->length + count, true);
    if(err != SL_NO_ERROR)
      goto error;

    dst = (void*)((uintptr_t)(vec->buffer) + vec->data_size * id);
    src = data;
    for(i = 0; i < count; ++i) {
      dst = memcpy(dst, src, vec->data_size);
      dst = (void*)((uintptr_t)(dst) + vec->data_size);
    }
  } else {
    if(vec->length + count >= vec->capacity) {
      size_t new_capacity = 0;
      NEXT_POWER_OF_2(vec->length + count, new_capacity);

      buffer = MEM_ALIGNED_ALLOC
        (vec->allocator, new_capacity * vec->data_size, vec->data_alignment);
      if(!buffer) {
        err = SL_MEMORY_ERROR;
        goto error;
      }

      /* Copy the vector data ranging from [0, id[ into the new buffer. */
      if(id > 0)
        memcpy(buffer, vec->buffer, vec->data_size * id);

      if(id < vec->length) {
        /* Copy from the vector data [id, length[ to the new buffer
         * [id+count, length + count[. */
        src = (void*)((uintptr_t)(vec->buffer) + vec->data_size * id);
        dst = (void*)((uintptr_t)(buffer) + vec->data_size * (id + count));
        dst = memcpy(dst, src, vec->data_size * (vec->length - id));
      }

      /* Set the src/dst pointer of the data insertion process. */
      dst = (void*)((uintptr_t)(buffer) + vec->data_size * id);
      src = data;
      for(i = 0; i < count; ++i) {
        dst = memcpy(dst, src, vec->data_size);
        dst = (void*)((uintptr_t)(dst) + vec->data_size);
      }

      /* The data to insert may be contained in vec, i.e. free vec->buffer
       * *AFTER* the insertion. */
      if(vec->buffer)
        MEM_FREE(vec->allocator, vec->buffer);

      vec->buffer = buffer;
      vec->capacity = new_capacity;
      buffer = NULL;

    } else {
      if(id < vec->length) {
        src = (void*)((uintptr_t)(vec->buffer) + vec->data_size * id);
        dst = (void*)((uintptr_t)(vec->buffer) + vec->data_size * (id + count));
        dst = memmove(dst, src, vec->data_size * (vec->length - id));
      }

      /* Set the src/dst pointer of the data insertion process. Note that If the
       * data to insert lies in the vector range [id, vec.length[ then it was
       * previously memoved. Its new address is offseted by count * data_size
       * bytes. */
      dst = (void*)((uintptr_t)(vec->buffer) + vec->data_size * id);
      if(IS_MEMORY_OVERLAPPED
         (data,
          vec->data_size,
          (void*)((uintptr_t)(vec->buffer) + vec->data_size * id),
          (vec->length - id) * vec->data_size)) {
        src = (void*)((uintptr_t)data + count * vec->data_size);
      } else {
        src = data;
      }
      for(i = 0; i < count; ++i) {
        dst = memcpy(dst, src, vec->data_size);
        dst = (void*)((uintptr_t)(dst) + vec->data_size);
      }
    }
  }
  vec->length += count;

exit:
  return err;
error:
  if(buffer)
    MEM_FREE(vec->allocator, buffer);
  goto exit;

}