Ejemplo n.º 1
0
// Read one record completely and return it as a Ruby String object.
static VALUE sedna_read(SC *conn, int strip_n)
{
	int bytes_read = 0;
	char buffer[RESULT_BUF_LEN];
	VALUE str = rb_str_buf_new(0);
	OBJ_TAINT(str);

	do {
		bytes_read = SEgetData(conn, buffer, RESULT_BUF_LEN - 1);
		if(bytes_read == SEDNA_ERROR) {
			sedna_err(conn, SEDNA_ERROR);
		} else {
			if(bytes_read > 0) {
				if(strip_n) {
					// Strange bug adds newlines to beginning of every result
					// except the first. Strip them! This a known issue in the
					// network protocol and serialization mechanism.
					// See: http://sourceforge.net/mailarchive/forum.php?thread_name=3034886f0812030132v3bbd8e2erd86480d3dc640664%40mail.gmail.com&forum_name=sedna-discussion
					STR_CAT(str, buffer + 1, bytes_read - 1);
					// Do not strip newlines from subsequent buffer reads.
					strip_n = 0;
				} else {
					STR_CAT(str, buffer, bytes_read);
				}
			}
		}
	} while(bytes_read > 0);

	return str;
}
Ejemplo 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);
	}
}
Ejemplo n.º 3
0
/**
 * Terminate header, emitting the trailing "\r\n".
 * Further appending is forbidden.
 */
void
header_fmt_end(header_fmt_t *hf)
{
	header_fmt_check(hf);
	g_assert(!hf->frozen);

	if (!hf->empty)
		STR_CAT(hf->header, "\r\n");
	hf->frozen = TRUE;

	g_assert(str_len(hf->header) < hf->max_size);
}
Ejemplo n.º 4
0
/**
 * Create a new formatting context for a header line.
 *
 * @param `field' is the header field name, without trailing ':'.
 *
 * @param `separator' is the optional default separator to emit between
 * the values added via header_fmd_append_value().  To supersede the
 * default separator, use header_fmd_append() and specify another separator
 * explicitly.  If set to NULL, there will be no default separator and
 * values will be simply concatenated together.  The value given must
 * NOT be freed before the header_fmt_end() call (usually it will just
 * be a static string).  Trailing spaces in the separator will be stripped
 * if it is emitted at the end of a line before a continuation.
 *
 * @param `len_hint' is the expected line size, for pre-sizing purposes.
 * (0 to guess).
 *
 * @param `max_size' is the maximum header size, including the final "\r\n"
 * and the trailing NUL.  If the initial field name is larger than the
 * configured maximum size, the header field will remain completely empty.
 *
 * @return pointer to the formatting object.
 */
header_fmt_t *
header_fmt_make(const char *field, const char *separator,
	size_t len_hint, size_t max_size)
{
	struct header_fmt *hf;

	g_assert(size_is_non_negative(len_hint));

	WALLOC(hf);
	hf->magic = HEADER_FMT_MAGIC;
	hf->header = str_new(len_hint ? len_hint : HEADER_FMT_DFLT_LEN);
	hf->maxlen = HEADER_FMT_LINE_LEN;
	hf->data_emitted = FALSE;
	hf->frozen = FALSE;
	hf->max_size = max_size;
	hf->sep = atom_str_get(separator ? separator : "");
	hf->seplen = strlen(hf->sep);
	hf->stripped_seplen = stripped_strlen(hf->sep, hf->seplen);
	str_cat(hf->header, field);
	STR_CAT(hf->header, ": ");

	hf->current_len = str_len(hf->header);

	/*
	 * If right from the start the header would be larger than the configured
	 * size, force it to stay empty.  That means, the final string returned
	 * will be "", the empty string.
	 */

	if (str_len(hf->header) + sizeof("\r\n") > hf->max_size) {
		hf->empty = TRUE;
		str_setlen(hf->header, 0);
	} else {
		hf->empty = FALSE;
	}

	header_fmt_check(hf);

	return hf;
}
Ejemplo n.º 5
0
/*
 * @return stringified host vector as newly allocated string via halloc()
 */
char *
gnet_host_vec_to_string(const gnet_host_vec_t *hvec)
{
	str_t *s;
	uint i, n;

	g_return_val_if_fail(hvec, NULL);

	s = str_new(0);
	n = gnet_host_vec_count(hvec);
	for (i = 0; i < n; i++) {
		gnet_host_t host;
		gchar buf[128];

		if (i > 0) {
			STR_CAT(s, ", ");
		}
		host = gnet_host_vec_get(hvec, i);
		host_addr_port_to_string_buf(gnet_host_get_addr(&host),
			gnet_host_get_port(&host), buf, sizeof buf);
		str_cat(s, buf);
	}
	return str_s2c_null(&s);
}
Ejemplo n.º 6
0
/**
 * Append data `str' to the header line, atomically.
 *
 * @param `hf' no brief description.
 * @param `str' no brief description.
 * @param `separator' is an optional separator string that will be emitted
 *         BEFORE outputting the data, and only when nothing has been emitted
 *         already.
 * @param `slen' is the separator length, 0 if empty.
 * @param `sslen' is the stripped separator length, (size_t)-1 if unknown yet.
 *
 * @return TRUE if we were able to fit the string, FALSE if it would have
 * resulted in the header being larger than the configured max size (the
 * header line is left in the state it was in upon entry, in that case).
 */
static bool
header_fmt_append_full(header_fmt_t *hf, const char *str,
	const char *separator, size_t slen, size_t sslen)
{
	size_t len, curlen;
	gsize gslen;
	bool success;

	header_fmt_check(hf);
	g_assert(size_is_non_negative(slen));
	g_assert((size_t)-1 == sslen || size_is_non_negative(sslen));

	if (hf->empty)
		return FALSE;

	gslen = str_len(hf->header);
	len = strlen(str);
	curlen = hf->current_len;
	g_assert(size_is_non_negative(curlen));

	g_assert(len <= INT_MAX);	/* Legacy bug */

	if (
		size_saturate_add(curlen, size_saturate_add(len, slen)) >
			UNSIGNED(hf->maxlen)
	) {
		/*
		 * Emit sperator, if any and data was already emitted.
		 */

		if (separator != NULL && hf->data_emitted) {
			sslen = (size_t)-1 != sslen ? sslen :
				stripped_strlen(separator, slen);
			str_cat_len(hf->header, separator, sslen);
		}

		STR_CAT(hf->header, "\r\n\t");			/* Includes continuation */
		curlen = 1;								/* One tab */
	} else if (hf->data_emitted) {
		str_cat(hf->header, separator);
		curlen += slen;
	}

	str_cat(hf->header, str);

	/*
	 * Check for overflows, undoing string changes if needed.
	 */

	if (str_len(hf->header) + sizeof("\r\n") > hf->max_size) {
		success = FALSE;
		str_setlen(hf->header, gslen);			/* Undo! */
	} else {
		success = TRUE;
		hf->data_emitted = TRUE;
		hf->current_len = curlen + len;
	}

	g_assert(str_len(hf->header) + sizeof("\r\n") <= hf->max_size);

	return success;
}