Exemplo n.º 1
0
void SLAB_Free(const struct Allocator* a, void* mem)
{
   if (mem)
   {
      struct SMem_Header *header = (struct SMem_Header *) MEM2HEADER(mem);

      if(header_check(header, SLAB_USED_MAGIC))
      {
         header->smagic = SLAB_FREE_MAGIC;

         if (header->level)
         {
            _atomic_stack_push(&header->level->stk, &header->item);
            _atomic_cnt_dec(&header->level->used);
         }
         else
         {
#ifndef __amigaos4__
            FreeVec(header);
#else
            IExec->FreeVec(header);
#endif
         }
      }
   }
}
Exemplo n.º 2
0
/**
 * Add header line to the `headers' hash for specified field name.
 * A private copy of the `field' name and of the `text' data is made.
 */
static void
add_header(header_t *o, const char *field, const char *text)
{
	htable_t *ht;
	str_t *v;

	header_check(o);

	ht = header_get_table(o);
	v = htable_lookup(ht, field);
	if (v) {
		/*
		 * Header already exists, according to RFC2616 we need to append
		 * the value, comma-separated.
		 */

		STR_CAT(v, ", ");
		str_cat(v, text);

	} else {
		char *key;

		/*
		 * Create a new header entry in the hash table.
		 */

		key = h_strdup(field);
		v = str_new_from(text);
		htable_insert(ht, key, v);
	}
}
Exemplo n.º 3
0
/**
 * Take an extra reference on the header object.
 * @return the header object.
 */
header_t *
header_refcnt_inc(header_t *o)
{
	header_check(o);

	o->refcnt++;
	return o;
}
Exemplo n.º 4
0
static GHashTable *
header_get_table(header_t *o)
{
	header_check(o);

	if (!o->headers)
		o->headers = g_hash_table_new(ascii_strcase_hash, ascii_strcase_eq);

	return o->headers;
}
Exemplo n.º 5
0
/**
 * Reset header object, for new header parsing.
 */
void
header_reset(header_t *o)
{
	header_check(o);

	if (o->headers != NULL) {
		htable_foreach_remove(o->headers, free_header_data, NULL);
		htable_free_null(&o->headers);
	}
	slist_free_all(&o->fields, cast_to_free_fn(hfield_free));
	o->flags = o->size = o->num_lines = 0;
}
Exemplo n.º 6
0
static htable_t *
header_get_table(header_t *o)
{
	header_check(o);

	if (NULL == o->headers) {
		o->headers = htable_create_any(ascii_strcase_hash,
			NULL, ascii_strcase_eq);
	}

	return o->headers;
}
Exemplo n.º 7
0
/**
 * Reset header object, for new header parsing.
 */
void
header_reset(header_t *o)
{
	header_check(o);

	if (o->headers) {
		g_hash_table_foreach_remove(o->headers, free_header_data, NULL);
		gm_hash_table_destroy_null(&o->headers);
	}
	slist_free_all(&o->fields, cast_to_slist_destroy(hfield_free));
	o->flags = o->size = o->num_lines = 0;
}
Exemplo n.º 8
0
/**
 * Add continuation line to the `headers' hash for specified field name.
 * A private copy of the data is made.
 */
static void
add_continuation(header_t *o, const char *field, const char *text)
{
	str_t *v;

	header_check(o);
	g_assert(o->headers);

	v = htable_lookup(o->headers, field);
	g_assert(v != NULL);
	str_putc(v, ' ');
	str_cat(v, text);
}
Exemplo n.º 9
0
/**
 * Dump whole header on specified file, followed by trailer string
 * (if not NULL) and a final "\n".
 */
void
header_dump(FILE *out, const header_t *o, const char *trailer)
{
	header_check(o);

	if (!log_file_printable(out))
		return;

	if (o->fields) {
		slist_foreach(o->fields, header_dump_item, out);
	}
	if (trailer)
		fprintf(out, "%s\n", trailer);
}
Exemplo n.º 10
0
/**
 * Get field value, or NULL if not present.  The value returned is a
 * pointer to the internals of the header structure, so it must not be
 * kept around.
 */
char *
header_get(const header_t *o, const char *field)
{
	str_t *v;

	header_check(o);

	if (o->headers) {
		v = htable_lookup(o->headers, deconstify_char(field));
	} else {
		v = NULL;
	}
	return str_2c(v);
}
Exemplo n.º 11
0
/**
 * Destroy header object.
 */
void
header_free(header_t *o)
{
	header_check(o);

	if (o->refcnt > 1) {
		o->refcnt--;
		return;
	}

	header_reset(o);
	o->magic = 0;
	WFREE(o);
}
Exemplo n.º 12
0
/**
 * Get field value, or NULL if not present.  The value returned is a
 * pointer to the internals of the header structure, so it must not be
 * kept around.
 *
 * If the len_ptr pointer is not NULL, it is filled with the length
 * of the header string.
 */
char *
header_get_extended(const header_t *o, const char *field, size_t *len_ptr)
{
	str_t *v;

	header_check(o);

	if (o->headers) {
		v = htable_lookup(o->headers, deconstify_char(field));
	} else {
		v = NULL;
	}
	if (v && len_ptr != NULL) {
		*len_ptr = str_len(v);
	}
	return str_2c(v);
}
Exemplo n.º 13
0
void* SLAB_Alloc(const struct Allocator* s, size_t bytes)
{
   void* res = 0;
   struct SLAB_Allocator *sa = (struct SLAB_Allocator*)s;

   if (bytes)
   {
      struct SLAB_Level *sl = level_classify(sa, bytes);

      if (sl)
      {
         struct SMem_Header *header;
         header = (struct SMem_Header*)_atomic_stack_pop(&sl->stk);

         if (header && header_check(header, SLAB_FREE_MAGIC))
         {
            _atomic_cnt_inc(&sl->used);
            header->smagic = SLAB_USED_MAGIC;
            res = HEADER2MEM(header);
         }
         else
         {
#ifndef __amigaos4__
            header = (struct SMem_Header*)AllocVec(bytes + sizeof(struct SMem_Header), MEMF_PUBLIC);
#else
            header = (struct SMem_Header*)IExec->AllocVec(bytes + sizeof(struct SMem_Header), MEMF_PUBLIC);
#endif

            if(header)
            {
               _atomic_item_init(&header->item);
               header->smagic = SLAB_USED_MAGIC;
               header->level  = 0;
               res = HEADER2MEM(header);
            }
         }
      }
   }

   /* End */
   return(res);
}
Exemplo n.º 14
0
/**
 * Append a new line of text at the end of the header.
 * A private copy of the text is made.
 *
 * @return an error code, or HEAD_OK if appending was successful.
 */
int
header_append(header_t *o, const char *text, int len)
{
	char buf[MAX_LINE_SIZE];
	const char *p = text;
	uchar c;
	header_field_t *hf;

	header_check(o);
	g_assert(len >= 0);

	if (o->flags & HEAD_F_EOH)
		return HEAD_EOH_REACHED;

	/*
	 * If empty line, we reached EOH.
	 */

	if (len == 0) {
		o->flags |= HEAD_F_EOH;				/* Mark we reached EOH */
		return HEAD_EOH;
	}

	/*
	 * Sanity checks.
	 */

	if (o->size >= HEAD_MAX_SIZE)
		return HEAD_TOO_LARGE;

	if (++(o->num_lines) >= HEAD_MAX_LINES)
		return HEAD_MANY_LINES;

	/*
	 * Detect whether line is a new header or a continuation.
	 */

	c = *p;
	if (is_ascii_space(c)) {

		/*
		 * It's a continuation.
		 *
		 * Make sure we already have recorded something, or we have
		 * an unexpected continuation line.
		 */

		if (NULL == o->fields)
			return HEAD_CONTINUATION;		/* Unexpected continuation */

		/*
		 * When a previous header line was malformed, we cannot accept
		 * further continuation lines.
		 */

		if (o->flags & HEAD_F_SKIP)
			return HEAD_SKIPPED;

		/*
		 * We strip leading spaces of all continuations before storing
		 * them.  If we have to dump the header, we will have to put
		 * some spaces, but we don't guarantee we'll put the same amount.
		 */

		p++;								/* First char is known space */
		while ((c = *p)) {
			if (!is_ascii_space(c))
				break;
			p++;
		}

		/*
		 * If we've reached the end of the line, then the continuation
		 * line was made of spaces only.  Weird, but we can ignore it.
		 * Note that it's not an EOH mark.
		 */

		if (*p == '\0')
			return HEAD_OK;

		/*
		 * Save the continuation line by appending into the last header
		 * field we handled.
		 */

		hf = slist_tail(o->fields);
		hfield_append(hf, p);
		add_continuation(o, hf->name, p);
		o->size += len - (p - text);	/* Count only effective text */

		/*
		 * Also append the data in the hash table.
		 */

	} else {
		char *b;
		bool seen_space = FALSE;

		/*
		 * It's a new header line.
		 */

		o->flags &= ~HEAD_F_SKIP;		/* Assume this line will be OK */

		/*
		 * Parse header field.  Must be composed of ascii chars only.
		 * (no control characters, no space, no ISO Latin or other extension).
		 * The field name ends with ':', after possible white spaces.
		 */

		for (b = buf, c = *p; c; c = *(++p)) {
			if (c == ':') {
				*b++ = '\0';			/* Reached end of field */
				break;					/* Done, buf[] holds field name */
			}
			if (is_ascii_space(c)) {
				seen_space = TRUE;		/* Only trailing spaces allowed */
				continue;
			}
			if (
				seen_space || (c != '-' && c != '.' &&
					(!isascii(c) || is_ascii_cntrl(c) || is_ascii_punct(c)))
			) {
				o->flags |= HEAD_F_SKIP;
				return HEAD_BAD_CHARS;
			}
			*b++ = c;
		}

		/*
		 * If buf[] does not end with a NUL, we did not fully recognize
		 * the header: we reached the end of the line without encountering
		 * the ':' marker.
		 *
		 * If the buffer starts with a NUL char, it's also clearly malformed.
		 */

		g_assert(b > buf || (b == buf && *text == '\0'));

		if (b == buf || *(b-1) != '\0') {
			o->flags |= HEAD_F_SKIP;
			return HEAD_MALFORMED;
		}

		/*
		 * We have a valid header field in buf[].
		 */

		hf = hfield_make(buf);

		/*
		 * Strip leading spaces in the value.
		 */

		g_assert(*p == ':');

		p++;							/* First char is field separator */
		p = skip_ascii_spaces(p);

		/*
		 * Record field value.
		 */

		hfield_append(hf, p);
		add_header(o, buf, p);
		if (!o->fields) {
			o->fields = slist_new();
		}
		slist_append(o->fields, hf);
		o->size += len - (p - text);	/* Count only effective text */
	}

	return HEAD_OK;
}