コード例 #1
0
csi_status_t
csi_file_new (csi_t *ctx,
	      csi_object_t *obj,
	      const char *path, const char *mode)
{
    csi_file_t *file;

    file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
    if (file == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    file->base.type = CSI_OBJECT_TYPE_FILE;
    file->base.ref = 1;

    file->data = NULL;
    file->type = STDIO;
    file->flags = OWN_STREAM;
    file->src = fopen (path, mode);
    if (file->src == NULL) {
	_csi_slab_free (ctx, file, sizeof (csi_file_t));
	return _csi_error (CAIRO_STATUS_FILE_NOT_FOUND);
    }

    file->data = _csi_alloc (ctx, CHUNK_SIZE);
    if (file->data == NULL) {
	_csi_slab_free (ctx, file, sizeof (csi_file_t));
	return _csi_error (CAIRO_STATUS_NO_MEMORY);
    }
    file->bp = file->data;
    file->rem = 0;

    obj->type = CSI_OBJECT_TYPE_FILE;
    obj->datum.file = file;
    return CAIRO_STATUS_SUCCESS;
}
コード例 #2
0
csi_status_t
csi_file_new_for_stream (csi_t *ctx,
	                 csi_object_t *obj,
			 FILE *stream)
{
    csi_file_t *file;

    file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
    if (file == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    file->base.type = CSI_OBJECT_TYPE_FILE;
    file->base.ref = 1;

    file->data = NULL;
    file->type = STDIO;
    file->flags = 0;
    file->src = stream;
    if (file->src == NULL) {
	_csi_slab_free (ctx, file, sizeof (csi_file_t));
	return _csi_error (CAIRO_STATUS_FILE_NOT_FOUND);
    }

    file->data = _csi_alloc (ctx, CHUNK_SIZE);
    if (file->data == NULL) {
	_csi_slab_free (ctx, file, sizeof (csi_file_t));
	return _csi_error (CAIRO_STATUS_NO_MEMORY);
    }
    file->bp = file->data;
    file->rem = 0;

    obj->type = CSI_OBJECT_TYPE_FILE;
    obj->datum.file = file;
    return CAIRO_STATUS_SUCCESS;
}
コード例 #3
0
ファイル: cairo-script-stack.c プロジェクト: ghub/NVprSDK
csi_status_t
_csi_stack_grow (csi_t *ctx, csi_stack_t *stack, csi_integer_t cnt)
{
    csi_integer_t newsize;
    csi_object_t *newstack;

    if (_csi_likely (cnt <= stack->size))
	return CSI_STATUS_SUCCESS;
    if (_csi_unlikely ((unsigned) cnt >= INT_MAX / sizeof (csi_object_t)))
	return _csi_error (CSI_STATUS_NO_MEMORY);

    newsize = stack->size;
    do {
	newsize *= 2;
    } while (newsize <= cnt);

    newstack = _csi_realloc (ctx,
			     stack->objects,
			     newsize * sizeof (csi_object_t));
    if (_csi_unlikely (newstack == NULL))
	return _csi_error (CSI_STATUS_NO_MEMORY);

    stack->objects = newstack;
    stack->size  = newsize;

    return CSI_STATUS_SUCCESS;
}
コード例 #4
0
ファイル: cairo-script-stack.c プロジェクト: ghub/NVprSDK
csi_status_t
_csi_stack_roll (csi_t *ctx,
		 csi_stack_t *stack,
		 csi_integer_t mod, csi_integer_t n)
{
    csi_object_t stack_copy[128];
    csi_object_t *copy;
    csi_integer_t last, i, len;

    switch (mod) { /* special cases */
    case 1:
	last = stack->len - 1;
	stack_copy[0] = stack->objects[last];
	for (i = last; --n; i--)
	    stack->objects[i] = stack->objects[i-1];
	stack->objects[i] = stack_copy[0];
	return CSI_STATUS_SUCCESS;
    case -1:
	last = stack->len - 1;
	stack_copy[0] = stack->objects[i = last - n + 1];
	for (; --n; i++)
	    stack->objects[i] = stack->objects[i+1];
	stack->objects[i] = stack_copy[0];
	return CSI_STATUS_SUCCESS;
    }

    /* fall back to a copy */
    if (n > ARRAY_LENGTH (stack_copy)) {
	if (_csi_unlikely ((unsigned) n > INT_MAX / sizeof (csi_object_t)))
	    return _csi_error (CSI_STATUS_NO_MEMORY);
	copy = _csi_alloc (ctx, n * sizeof (csi_object_t));
	if (copy == NULL)
	    return _csi_error (CSI_STATUS_NO_MEMORY);
    } else
	copy = stack_copy;

    i = stack->len - n;
    memcpy (copy, stack->objects + i, n * sizeof (csi_object_t));
    mod = -mod;
    if (mod < 0)
	mod += n;
    last = mod;
    for (len = n; n--; i++) {
	stack->objects[i] = copy[last];
	if (++last == len)
	    last = 0;
    }

    if (copy != stack_copy)
	_csi_free (ctx, copy);

    return CSI_STATUS_SUCCESS;
}
コード例 #5
0
static csi_status_t
_csi_file_new_filter (csi_t *ctx,
		      csi_object_t *obj,
		      csi_object_t *src,
		      const csi_filter_funcs_t *funcs,
		      void *data)
{
    csi_file_t *file;
    csi_object_t src_file;
    csi_status_t status;

    file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
    if (file == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    obj->type = CSI_OBJECT_TYPE_FILE;
    obj->datum.file = file;

    file->base.type = CSI_OBJECT_TYPE_FILE;
    file->base.ref = 1;

    file->type = FILTER;
    file->data = data;
    file->filter = funcs;
    status = csi_object_as_file (ctx, src, &src_file);
    if (status) {
	csi_object_free (ctx, obj);
	return status;
    }
    file->src = src_file.datum.file;

    return CAIRO_STATUS_SUCCESS;
}
コード例 #6
0
csi_status_t
csi_file_new_for_bytes (csi_t *ctx,
			csi_object_t *obj,
			const char *bytes,
			unsigned int length)
{
    csi_file_t *file;

    file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
    if (file == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    file->base.type = CSI_OBJECT_TYPE_FILE;
    file->base.ref = 1;

    file->type = BYTES;
    file->src  = (uint8_t *) bytes;
    file->data = (uint8_t *) bytes;
    file->bp   = (uint8_t *) bytes;
    file->rem  = length;

    obj->type = CSI_OBJECT_TYPE_FILE;
    obj->datum.file = file;
    return CAIRO_STATUS_SUCCESS;
}
コード例 #7
0
csi_status_t
_csi_intern_string (csi_t *ctx, const char **str_inout, int len)
{
    char *str = (char *) *str_inout;
    csi_intern_string_t tmpl, *istring;
    csi_status_t status = CSI_STATUS_SUCCESS;

    tmpl.hash_entry.hash = _intern_string_hash (str, len);
    tmpl.len = len;
    tmpl.string = (char *) str;

    istring = _csi_hash_table_lookup (&ctx->strings, &tmpl.hash_entry);
    if (istring == NULL) {
	istring = _csi_perm_alloc (ctx,
				   sizeof (csi_intern_string_t) + len + 1);
	if (istring != NULL) {
	    istring->hash_entry.hash = tmpl.hash_entry.hash;
	    istring->len = tmpl.len;
	    istring->string = (char *) (istring + 1);
	    memcpy (istring->string, str, len);
	    istring->string[len] = '\0';

	    status = _csi_hash_table_insert (&ctx->strings,
					     &istring->hash_entry);
	    if (_csi_unlikely (status)) {
		_csi_free (ctx, istring);
		return status;
	    }
	} else
	    return _csi_error (CSI_STATUS_NO_MEMORY);
    }

    *str_inout = istring->string;
    return CSI_STATUS_SUCCESS;
}
コード例 #8
0
ファイル: cairo-script-stack.c プロジェクト: ghub/NVprSDK
csi_status_t
_csi_stack_init (csi_t *ctx, csi_stack_t *stack, csi_integer_t size)
{
    csi_status_t status = CSI_STATUS_SUCCESS;

    stack->len = 0;
    stack->size = size;
    /* assert ((unsigned) size < INT_MAX / sizeof (csi_object_t)); */
    stack->objects = _csi_alloc (ctx, size * sizeof (csi_object_t));
    if (_csi_unlikely (stack->objects == NULL))
	status = _csi_error (CSI_STATUS_NO_MEMORY);

    return status;
}
コード例 #9
0
csi_status_t
csi_file_new_from_stream (csi_t *ctx,
			  FILE *file,
			  csi_object_t **out)
{
    csi_file_t *obj;

    obj = (csi_file_t *) _csi_object_new (ctx, CSI_OBJECT_TYPE_FILE);
    if (obj == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    obj->type = STDIO;
    obj->src = file;
    obj->data = _csi_alloc (ctx, CHUNK_SIZE);
    if (obj->data == NULL) {
	csi_object_free (&obj->base);
	return _csi_error (CAIRO_STATUS_UNDEFINED_FILENAME_ERROR);
    }
    obj->bp = obj->data;
    obj->rem = 0;

    *out = &obj->base;
    return CAIRO_STATUS_SUCCESS;
}
コード例 #10
0
ファイル: cairo-script-stack.c プロジェクト: ghub/NVprSDK
csi_status_t
_csi_stack_exch (csi_stack_t *stack)
{
    csi_object_t tmp;
    csi_integer_t n;

    if (_csi_unlikely (stack->len < 2))
	return _csi_error (CSI_STATUS_INVALID_SCRIPT);

    n = stack->len - 1;
    tmp = stack->objects[n];
    stack->objects[n] = stack->objects[n - 1];
    stack->objects[n - 1] = tmp;

    return CSI_STATUS_SUCCESS;
}
コード例 #11
0
csi_status_t
_csi_name_undefine (csi_t *ctx, csi_name_t name)
{
    unsigned int i;

    for (i = ctx->dstack.len; --i; ) {
	if (csi_dictionary_has (ctx->dstack.objects[i].datum.dictionary,
				name))
	{
	    csi_dictionary_remove (ctx,
				   ctx->dstack.objects[i].datum.dictionary,
				   name);
	    return CSI_STATUS_SUCCESS;
	}
    }

    return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
コード例 #12
0
ファイル: cairo-script-hash.c プロジェクト: Distrotech/cairo
/**
 * _csi_hash_table_create:
 * @keys_equal: a function to return %TRUE if two keys are equal
 *
 * Creates a new hash table which will use the keys_equal() function
 * to compare hash keys. Data is provided to the hash table in the
 * form of user-derived versions of #csi_hash_entry_t. A hash entry
 * must be able to hold both a key (including a hash code) and a
 * value. Sometimes only the key will be necessary, (as in
 * _csi_hash_table_remove), and other times both a key and a value
 * will be necessary, (as in _csi_hash_table_insert).
 *
 * See #csi_hash_entry_t for more details.
 *
 * Return value: the new hash table or %NULL if out of memory.
 **/
csi_status_t
_csi_hash_table_init (csi_hash_table_t *hash_table,
		      csi_hash_keys_equal_func_t keys_equal)
{
    hash_table->keys_equal = keys_equal;

    hash_table->arrangement = &hash_table_arrangements[0];

    hash_table->entries = calloc (hash_table->arrangement->size,
				  sizeof(csi_hash_entry_t *));
    if (hash_table->entries == NULL)
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    hash_table->live_entries = 0;
    hash_table->used_entries = 0;
    hash_table->iterating = 0;

    return CSI_STATUS_SUCCESS;
}
コード例 #13
0
csi_status_t
_csi_name_lookup (csi_t *ctx, csi_name_t name, csi_object_t *obj)
{
    int i;

    for (i = ctx->dstack.len; i--; ) {
	csi_dictionary_t *dict;
	csi_dictionary_entry_t *entry;

	dict = ctx->dstack.objects[i].datum.dictionary;
	entry = _csi_hash_table_lookup (&dict->hash_table,
					(csi_hash_entry_t *) &name);
	if (entry != NULL) {
	    *obj = entry->value;
	    return CSI_STATUS_SUCCESS;
	}
    }

    return _csi_error (CSI_STATUS_INVALID_SCRIPT);
}
コード例 #14
0
csi_status_t
csi_file_new_from_string (csi_t *ctx,
			  csi_object_t *obj,
			  csi_string_t *src)
{
    csi_file_t *file;

    file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
    if (_csi_unlikely (file == NULL))
	return _csi_error (CAIRO_STATUS_NO_MEMORY);

    file->base.type = CSI_OBJECT_TYPE_FILE;
    file->base.ref = 1;

    if (src->deflate) {
	uLongf len = src->deflate;
	csi_object_t tmp_obj;
	csi_string_t *tmp_str;
	csi_status_t status;

	status = csi_string_new (ctx, &tmp_obj,  NULL, src->deflate);
	if (_csi_unlikely (status))
	    return status;

	tmp_str = tmp_obj.datum.string;
	switch (src->method) {
	case NONE:
	default:
	    status = _csi_error (CAIRO_STATUS_NO_MEMORY);
	    break;

	case ZLIB:
#if HAVE_ZLIB
	    if (uncompress ((Bytef *) tmp_str->string, &len,
			    (Bytef *) src->string, src->len) != Z_OK)
#endif
		status = _csi_error (CAIRO_STATUS_NO_MEMORY);
	    break;
	case LZO:
#if HAVE_LZO
	    if (lzo2a_decompress ((lzo_bytep) src->string, src->len,
				  (lzo_bytep) tmp_str->string, &len,
				  NULL))
#endif
		status = _csi_error (CAIRO_STATUS_NO_MEMORY);
	    break;
	}
	if (_csi_unlikely (status)) {
	    csi_string_free (ctx, tmp_str);
	    _csi_slab_free (ctx, file, sizeof (csi_file_t));
	    return status;
	}

	file->src  = tmp_str;
	file->data = tmp_str->string;
	file->rem  = tmp_str->len;
    } else {
	file->src  = src; src->base.ref++;
	file->data = src->string;
	file->rem  = src->len;
    }
    file->type = BYTES;
    file->bp   = file->data;

    obj->type = CSI_OBJECT_TYPE_FILE;
    obj->datum.file = file;
    return CAIRO_STATUS_SUCCESS;
}
コード例 #15
0
ファイル: cairo-script-hash.c プロジェクト: Distrotech/cairo
/**
 * _csi_hash_table_manage:
 * @hash_table: a hash table
 *
 * Resize the hash table if the number of entries has gotten much
 * bigger or smaller than the ideal number of entries for the current
 * size, or control the number of dead entries by moving the entries
 * within the table.
 *
 * Return value: %CAIRO_STATUS_SUCCESS if successful or
 * %CAIRO_STATUS_NO_MEMORY if out of memory.
 **/
static csi_status_t
_csi_hash_table_manage (csi_hash_table_t *hash_table)
{
    csi_hash_table_t tmp;
    csi_boolean_t realloc = TRUE;
    unsigned long i;

    /* This keeps the size of the hash table between 2 and approximately 8
     * times the number of live entries and keeps the proportion of free
     * entries (search-terminations) > 25%.
     */
    unsigned long high = hash_table->arrangement->high_water_mark;
    unsigned long low = high >> 2;
    unsigned long max_used = high  + high / 2;

    tmp = *hash_table;

    if (hash_table->live_entries > high) {
	tmp.arrangement = hash_table->arrangement + 1;
	/* This code is being abused if we can't make a table big enough. */
    } else if (hash_table->live_entries < low &&
	       /* Can't shrink if we're at the smallest size */
	       hash_table->arrangement != &hash_table_arrangements[0])
    {
	tmp.arrangement = hash_table->arrangement - 1;
    }
    else if (hash_table->used_entries > max_used)
    {
	/* Clean out dead entries to prevent lookups from becoming too slow. */
	for (i = 0; i < hash_table->arrangement->size; ++i) {
	    if (ENTRY_IS_DEAD (hash_table->entries[i]))
		hash_table->entries[i] = NULL;
	}
	hash_table->used_entries = hash_table->live_entries;

	/* There is no need to reallocate but some entries may need to be
	 * moved.  Typically the proportion of entries needing to be moved is
	 * small, but, if the moving should leave a large number of dead
	 * entries, they will be cleaned out next time this code is
	 * executed. */
	realloc = FALSE;
    }
    else
    {
	return CAIRO_STATUS_SUCCESS;
    }

    if (realloc) {
	tmp.entries = calloc (tmp.arrangement->size,
		              sizeof (csi_hash_entry_t*));
	if (tmp.entries == NULL)
	    return _csi_error (CAIRO_STATUS_NO_MEMORY);

	hash_table->used_entries = 0;
    }

    for (i = 0; i < hash_table->arrangement->size; ++i) {
	csi_hash_entry_t *entry, **pos;

	entry = hash_table->entries[i];
	if (ENTRY_IS_LIVE (entry)) {
	    hash_table->entries[i] = DEAD_ENTRY;

	    pos = _csi_hash_table_lookup_unique_key (&tmp, entry);
	    if (ENTRY_IS_FREE (*pos))
		hash_table->used_entries++;

	    *pos = entry;
	}
    }

    if (realloc) {
	free (hash_table->entries);
	hash_table->entries = tmp.entries;
	hash_table->arrangement = tmp.arrangement;
    }

    return CAIRO_STATUS_SUCCESS;
}