예제 #1
0
str
ITRbunNext(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	BATiter bi;
	BAT *b;
	oid *head;
	bat *bid;
	ValPtr tail;

	(void) cntxt;
	(void) mb;
	head = (oid *) getArgReference(stk, pci, 0);
	tail = getArgReference(stk,pci,1);
	bid = (bat *) getArgReference(stk, pci, 2);

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "iterator.nextChunk", INTERNAL_BAT_ACCESS);
	}

	*head = (BUN)*head + 1;
	if (*head >= BUNlast(b)) {
		*head = oid_nil;
		BBPunfix(b->batCacheid);
		return MAL_SUCCEED;
	}
 	bi = bat_iterator(b);
	VALinit(tail, b->ttype, BUNtail(bi, *(BUN*) head));
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}
예제 #2
0
파일: gsl.c 프로젝트: cswxu/monetdb-mcs
static str
gsl_bat_chisqprob_cst(bat * retval, bat chi2, dbl datapoints) 
{
	BAT *b, *bn;
	BATiter bi;
	BUN p,q;
	dbl r;
	char *msg = NULL;

	if (datapoints == dbl_nil) {
		throw(MAL, "GSLbat_chisqprob_cst", "Parameter datapoints should not be nil");
	}
	if (datapoints < 0)
		throw(MAL, "gsl.chi2prob", "Wrong value for datapoints");

	if ((b = BATdescriptor(chi2)) == NULL) {
		throw(MAL, "chisqprob", "Cannot access descriptor");
	}
	bi = bat_iterator(b);
	bn = BATnew(TYPE_void, TYPE_dbl, BATcount(b), TRANSIENT);
	if (bn == NULL){
		BBPunfix(b->batCacheid);
		throw(MAL, "gsl.chisqprob", MAL_MALLOC_FAIL);
	}
	BATseqbase(bn, b->hseqbase);
	BATloop(b,p,q) {
		dbl d = *(dbl*)BUNtail(bi,p);
		if ((d == dbl_nil) || (d < 0))
			throw(MAL, "gsl.chi2prob", "Wrong value for chi2");
		r = gsl_cdf_chisq_Q(d, datapoints);
		BUNappend(bn, &r, FALSE);
	}
예제 #3
0
/*
 * @-
 * The BUN- and BAT-stream manipulate a long handle, i.e.
 * the destination variable. It assumes it has been set to
 * zero as part of runtime stack initialization. Subsequently,
 * it fetches a bun and returns the increment to the control
 * variable. If it returns zero the control variable has been reset
 * to zero and end of stream has been reached.
 */
str
ITRbunIterator(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	BATiter bi;
	BAT *b;
	oid *head;
	bat *bid;
	ValPtr tail;

	(void) cntxt;
	(void) mb;
	head = getArgReference_oid(stk, pci, 0);
	tail = &stk->stk[pci->argv[1]];
	bid = getArgReference_bat(stk, pci, 2);

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "iterator.nextChunk", INTERNAL_BAT_ACCESS);
	}

	if (BATcount(b) == 0) {
		*head = oid_nil;
		BBPunfix(b->batCacheid);
		return MAL_SUCCEED;
	}
	*head = BUNfirst(b);

 	bi = bat_iterator(b);
	VALinit(tail, b->ttype, BUNtail(bi, *(BUN*) head));
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}
예제 #4
0
str
MRgetCloud(int *ret, str *mrcluster)
{
	str msg;
	BAT *cloud;
	BUN p, q;
	BATiter bi;
	char nodes[BUFSIZ];
	char *n = nodes;
	int mapcount = 0;

	snprintf(nodes, sizeof(nodes), "*/%s/node/*", *mrcluster);
	
	if ((msg = RMTresolve(ret, &n)) != MAL_SUCCEED)
		return msg;

	MT_lock_set(&mal_contextLock, "mapreduce");
	cloud = BATdescriptor(*ret); /* should succeed */

	mapnodes = (mapnode*)GDKzalloc(sizeof(mapnode) * (BATcount(cloud) + 1));
	if (mapnodes == NULL) {
		BBPreleaseref(*ret);
		throw(MAL, "mapreduce.getCloud", MAL_MALLOC_FAIL);
	}

	bi = bat_iterator(cloud);
	BATloop(cloud, p, q) {
		str t = (str)BUNtail(bi, p);
		mapnodes[mapcount].uri = GDKstrdup(t);
		mapnodes[mapcount].user = GDKstrdup("monetdb");
		mapnodes[mapcount].pass = GDKstrdup("monetdb");
		mapcount++;
	}
예제 #5
0
/**
 * Function returns the highest file id that currently exists in the
 * bam.files table and stores this number + 1 in the next_file_id
 * variable. Function doesn't use a mutex to guarantee that the
 * returned value is up to date at return time. If this is required,
 * the calling function should activate a mutex.
 */
str
next_file_id(mvc * m, sql_table * files, lng * next_file_id)
{
	sql_column *c;
	BAT *b = NULL;
	BATiter li;
	BUN p = 0, q = 0;
	lng max_file_id = 0;

	sht i;

	assert(m != NULL);
	assert(files != NULL);

	/* Try to bind the file_id column of the bam.files table */
	if ((c = mvc_bind_column(m, files, "file_id")) == NULL) {
		throw(MAL, "next_file_id",
			  "Could not retrieve the next file id: Error binding file_id column of 'files' table");
	}

	/* Loop through BATs for this column and find the maximum file_id */
	for(i=0; i<3; ++i) {
		b = store_funcs.bind_col(m->session->tr, c, i);

		li = bat_iterator(b);
		BATloop(b, p, q) {
			lng t = *(lng *) BUNtail(li, p);
			max_file_id = MAX(max_file_id, t);
		}
		BBPunfix(b->batCacheid);
	}
예제 #6
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLdocument(bat *ret, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	BATiter bi;
	size_t size = BUFSIZ;
	str buf = GDKmalloc(size);
	const char *err = OPERATION_FAILED;

	if (buf == NULL)
		throw(MAL,"xml.document",MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.document", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "document", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		xmlDocPtr doc;
		int len;
		xmlChar *s;

		if (strNil(t)) {
			bunfastapp(bn, str_nil);
			bn->T->nonil = 0;
			continue;
		}
		len = (int) strlen(t);
		doc = xmlParseMemory(t, len);
		if (doc == NULL) {
			err = OPERATION_FAILED XML_PARSE_ERROR;
			goto bunins_failed;
		}
		xmlDocDumpMemory(doc, &s, &len);
		xmlFreeDoc(doc);
		if ((size_t) len + 2 >= size) {
			GDKfree(buf);
			size = (size_t) len + 128;
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err= MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		buf[0] = 'D';
		strcpy(buf + 1, (char *) s);
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	GDKfree(buf);
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	throw(MAL, "xml.document", "%s", err);
}
예제 #7
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLcomment(bat *ret, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf = GDKmalloc(size);
	BATiter bi;
	const char *err= OPERATION_FAILED;

	if (buf == NULL)
		throw(MAL, "xml.comment", MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.comment", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "comment", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;

		if (strNil(t)) {
			bunfastapp(bn, str_nil);
			bn->T->nonil = 0;
			continue;
		}
		if (strstr(t, "--") != NULL) {
			err = XML_COMMENT_ERROR;
			goto bunins_failed;
		}
		len = strlen(t);
		if (len + 9 >= size) {
			/* make sure there is enough space */
			size = len + 128;
			/* free/malloc so we don't copy */
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		snprintf(buf, size, "C<!--%s-->", t);
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.comment", "%s", err);
}
예제 #8
0
파일: udf.c 프로젝트: Clay-Birkett/monetdb
/* actual implementation */
static char *
UDFBATreverse_(BAT **ret, BAT *src)
{
	BATiter li;
	BAT *bn = NULL;
	BUN p = 0, q = 0;

	/* assert calling sanity */
	assert(ret != NULL);

	/* handle NULL pointer */
	if (src == NULL)
		throw(MAL, "batudf.reverse", RUNTIME_OBJECT_MISSING);

	/* check tail type */
	if (src->ttype != TYPE_str) {
		throw(MAL, "batudf.reverse",
		      "tail-type of input BAT must be TYPE_str");
	}

	/* allocate result BAT */
	bn = BATnew(src->htype, TYPE_str, BATcount(src));
	if (bn == NULL) {
		throw(MAL, "batudf.reverse", MAL_MALLOC_FAIL);
	}
	BATseqbase(bn, src->hseqbase);

	/* create BAT iterator */
	li = bat_iterator(src);

	/* the core of the algorithm, expensive due to malloc/frees */
	BATloop(src, p, q) {
		char *tr = NULL, *err = NULL;

		/* get original head & tail value */
		ptr h = BUNhead(li, p);
		const char *t = (const char *) BUNtail(li, p);

		/* revert tail value */
		err = UDFreverse_(&tr, t);
		if (err != MAL_SUCCEED) {
			/* error -> bail out */
			BBPreleaseref(bn->batCacheid);
			return err;
		}

		/* assert logical sanity */
		assert(tr != NULL);

		/* insert original head and reversed tail in result BAT */
		/* BUNins() takes care of all necessary administration */
		BUNins(bn, h, tr, FALSE);

		/* free memory allocated in UDFreverse_() */
		GDKfree(tr);
	}
예제 #9
0
파일: gdk_utils.c 프로젝트: lajus/monetinr
char *
GDKgetenv(const char *name)
{
	BUN b = BUNfnd(BATmirror(GDKkey), (ptr) name);

	if (b != BUN_NONE) {
		BATiter GDKenvi = bat_iterator(GDKval);
		return BUNtail(GDKenvi, b);
	}
	return NULL;
}
예제 #10
0
파일: batxml.c 프로젝트: f7753/monetdb
/*
 * The core of the activity is str2xml, where the actual strings
 * are constructed.
 * To avoid repetitive copying we make sure that the garbage
 * collector does not remove the xml intermediates.
 * This way, we know that as long as the xml-variables are not
 * reused, the complete structure of the xml document(s) are available.
 * We merely have to collect the pieces.
 * [FOR LATER, FIRST GO FOR THE EASY IMPLEMENTATION]
 * XML values are represented by strings already.
 */
str
BATXMLstr2xml(bat *ret, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf;
	const char *err= OPERATION_FAILED;
	BATiter bi;

	buf = GDKmalloc(size);
	if (buf == NULL)
		throw(MAL,"xml.str2xml",MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.xml", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "xml", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;

		if (strNil(t)) {
			bunfastapp(bn, str_nil);
			bn->T->nonil = 0;
			continue;
		}

		len = strlen(t) * 6 + 1;
		if (size < len) {
			size = len + 128;
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		buf[0] = 'C';
		XMLquotestring(t, buf + 1, size - 1);
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.xml", "%s", err);
}
예제 #11
0
파일: bat_utils.c 프로젝트: lajus/monetinr
BUN
append_inserted(BAT *b, BAT *i )
{
	BUN nr = 0, r;
       	BATiter ii = bat_iterator(i);

       	for (r = i->batInserted; r < BUNlast(i); r++) {
		BUNappend(b, BUNtail(ii,r), TRUE);
		nr++;
	}
	return nr;
}
예제 #12
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLgroup(xml *ret, const bat *bid)
{
	BAT *b;
	BUN p, q;
	const char *t;
	size_t len, size = BUFSIZ, offset;
	str buf = GDKmalloc(size);
	BATiter bi;
	const char *err = NULL;

	if (buf == NULL)
		throw(MAL, "xml.aggr",MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.aggr", RUNTIME_OBJECT_MISSING);
	}

	strcpy(buf, str_nil);
	offset = 0;
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		int n;

		t = (const char *) BUNtail(bi, p);

		if (strNil(t))
			continue;
		len = strlen(t) + 1;
		if (len >= size - offset) {
			size += len + 128;
			buf = GDKrealloc(buf, size);
			if (buf == NULL) {
				err= MAL_MALLOC_FAIL;
				goto failed;
			}
		}
		if (offset == 0)
			n = snprintf(buf, size, "%s", t);
		else if (buf[0] != *t) {
			err = "incompatible values in group";
			goto failed;
		} else if (buf[0] == 'A')
			n = snprintf(buf + offset, size - offset, " %s", t + 1);
		else if (buf[0] == 'C')
			n = snprintf(buf + offset, size - offset, "%s", t + 1);
		else {
			err = "can only group attributes and element content";
			goto failed;
		}
		offset += n;
	}
예제 #13
0
파일: bat_utils.c 프로젝트: lajus/monetinr
BUN
copy_inserted(BAT *b, BAT *i )
{
	BUN nr = 0;
	BUN r;
       	BATiter ii = bat_iterator(i);

	for (r = i->batInserted; r < BUNlast(i); r++) {
		BUNins(b, BUNhead(ii,r), BUNtail(ii,r), TRUE);
       		nr++;
	}
	return nr;
}
예제 #14
0
static int
bat_max_strlength(BAT *b)
{
	BUN p, q;
	int l = 0;
	int max = 0;
	BATiter bi = bat_iterator(b);

	BATloop(b, p, q) {
		str v = (str) BUNtail(bi, p);
		strLength(&l, v);

		if (l == int_nil) 
			l = 0;
		if (l > max)
			max = l;
	}
예제 #15
0
static oid
column_find_row(sql_trans *tr, sql_column *c, void *value, ...)
{
	va_list va;
	BUN q;
	BAT *b = NULL, *s = NULL, *r = NULL, *d = NULL;
	oid rid = oid_nil;
	sql_column *nc;
	void *nv;
	sql_dbat *bat = c->t->data;

	if (bat->dbid) 
		d = store_funcs.bind_del(tr, c->t, RDONLY);
	va_start(va, value);
	while ((nc = va_arg(va, sql_column *)) != NULL) {
		nv = va_arg(va, void *);

		b = full_column(c, d, s);
		if (s)
			bat_destroy(s);
		s = BATselect(b, value, value);
		bat_destroy(b);
		c = nc;
		value = nv;
	}
	va_end(va);
	b = full_column(c, d, s);
	if (s)
		bat_destroy(s);
	if (d)
		bat_destroy(d);

	r = BATmirror(b);
	q = BUNfnd(r, value);
	if (q != BUN_NONE) {
		BATiter ri = bat_iterator(r);
		rid = *(oid *) BUNtail(ri, q);
	}
	bat_destroy(b);
	return rid;
}
예제 #16
0
str
batnil_2_timestamp(bat *res, const bat *bid)
{
	BAT *b, *dst;
	BATiter bi;
	BUN p, q;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(SQL, "batcalc.nil_2_timestamp", "Cannot access descriptor");
	}
	bi = bat_iterator(b);
	dst = BATnew(b->htype, TYPE_timestamp, BATcount(b), TRANSIENT);
	if (dst == NULL) {
		BBPunfix(b->batCacheid);
		throw(SQL, "sql.2_timestamp", MAL_MALLOC_FAIL);
	}
	BATseqbase(dst, b->hseqbase);
	BATloop(b, p, q) {
		timestamp r = *timestamp_nil;
		BUNins(dst, BUNhead(bi, p), &r, FALSE);
	}
예제 #17
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLisdocument(bat *ret, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	BATiter bi;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "xml.isdocument", INTERNAL_BAT_ACCESS);
	prepareResult(bn, b, TYPE_bit, "isdocument", (void) 0);
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		xmlDocPtr doc;
		bit val;

		if (strNil(t)) {
			val = bit_nil;
			bn->T->nonil = 0;
		} else {
			doc = xmlParseMemory(t, (int) strlen(t));
			if (doc == NULL) {
				val = 0;
			} else {
				xmlFreeDoc(doc);
				val = 1;
			}
		}
		bunfastapp(bn, &val);
	}
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	throw(MAL, "xml.isdocument", OPERATION_FAILED " During bulk processing");
}
예제 #18
0
파일: json.c 프로젝트: f7753/monetdb
static str
JSONrenderRowObject(BAT **bl, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, BUN idx)
{
	int i, tpe;
	char *row, *name = 0, *val = 0;
	size_t len, lim, l;
	void *p;
	BATiter bi;

	row = (char *) GDKmalloc(lim = BUFSIZ);
	row[0] = '{';
	row[1] = 0;
	len = 1;
	val = (char *) GDKmalloc(BUFSIZ);
	for (i = pci->retc; i < pci->argc; i += 2) {
		name = stk->stk[getArg(pci, i)].val.sval;
		bi = bat_iterator(bl[i + 1]);
		p = BUNtail(bi, BUNfirst(bl[i + 1]) + idx);
		tpe = getColumnType(getArgType(mb, pci, i + 1));
		ATOMformat(tpe, p, &val);
		if (strncmp(val, "nil", 3) == 0)
			strcpy(val, "null");
		l = strlen(name) + strlen(val);
		while (l > lim - len)
			row = (char *) GDKrealloc(row, lim += BUFSIZ);
		snprintf(row + len, lim - len, "\"%s\":%s,", name, val);
		len += l + 4;
	}
	if (row[1])
		row[len - 1] = '}';
	else {
		row[1] = '}';
		row[2] = 0;
	}
	GDKfree(val);
	return row;
}
예제 #19
0
gdk_return
TMsubcommit(BAT *b)
{
	int cnt = 1;
	gdk_return ret = GDK_FAIL;
	bat *subcommit;
	BUN p, q;
	BATiter bi = bat_iterator(b);

	subcommit = (bat *) GDKmalloc((BATcount(b) + 1) * sizeof(bat));
	if (subcommit == NULL)
		return GDK_FAIL;

	subcommit[0] = 0;	/* BBP artifact: slot 0 in the array will be ignored */
	/* collect the list and save the new bats outside any
	 * locking */
	BATloop(b, p, q) {
		bat bid = BBPindex((str) BUNtail(bi, p));

		if (bid < 0)
			bid = -bid;
		if (bid)
			subcommit[cnt++] = bid;
	}
예제 #20
0
/*
 * The remainder are utilities to manipulate the BAT view and not to
 * forget some details in the process.  It expects a position range in
 * the underlying BAT and compensates for outliers.
 */
void
VIEWbounds(BAT *b, BAT *view, BUN l, BUN h)
{
	BUN cnt;
	BATiter bi = bat_iterator(b);

	if (b == NULL || view == NULL) {
		GDKerror("VIEWbounds: bat argument missing");
		return;
	}
	if (h > BATcount(b))
		h = BATcount(b);
	if (h < l)
		h = l;
	l += BUNfirst(b);
	view->batFirst = view->batDeleted = view->batInserted = 0;
	cnt = h - l;
	view->H->heap.base = (view->htype) ? BUNhloc(bi, l) : NULL;
	view->T->heap.base = (view->ttype) ? BUNtloc(bi, l) : NULL;
	view->H->heap.size = headsize(view, cnt);
	view->T->heap.size = tailsize(view, cnt);
	BATsetcount(view, cnt);
	BATsetcapacity(view, cnt);
}
예제 #21
0
파일: json.c 프로젝트: f7753/monetdb
static str
JSONrenderRowArray(BAT **bl, MalBlkPtr mb, InstrPtr pci, BUN idx)
{
	int i, tpe;
	char *row, *val = 0;
	size_t len, lim, l;
	void *p;
	BATiter bi;

	row = (char *) GDKmalloc(lim = BUFSIZ);
	row[0] = '[';
	row[1] = 0;
	len = 1;
	val = (char *) GDKmalloc(BUFSIZ);
	for (i = pci->retc; i < pci->argc; i++) {
		bi = bat_iterator(bl[i]);
		p = BUNtail(bi, BUNfirst(bl[i]) + idx);
		tpe = getColumnType(getArgType(mb, pci, i));
		ATOMformat(tpe, p, &val);
		if (strncmp(val, "nil", 3) == 0)
			strcpy(val, "null");
		l = strlen(val);
		while (l > lim - len)
			row = (char *) GDKrealloc(row, lim += BUFSIZ);
		snprintf(row + len, lim - len, "%s,", val);
		len += l + 1;
	}
	if (row[1])
		row[len - 1] = ']';
	else {
		row[1] = '}';
		row[2] = 0;
	}
	GDKfree(val);
	return row;
}
예제 #22
0
파일: batxml.c 프로젝트: f7753/monetdb
/*
 * The standard supports specific mappings for
 * NULL values,i.e. {null,absent,empty,nil,niloncontent)
 * in the context of an element and forest construction.
 * The standard should be studied in more detail, because
 * the syntax(rules) seem ambiguous.
 * It applies to all components of an element or their
 * concatenation.
 *
 * For the time being, the variaton on XMLtag seems the
 * most reasonable interpretation.
 */
str
BATXMLoptions(bat *ret, const char * const *name, const char * const *options, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	str buf = GDKmalloc(BUFSIZ);
	str val = GDKmalloc(BUFSIZ);
	size_t size = BUFSIZ, len = strlen(*name);
	BATiter bi;
	const char *err = OPERATION_FAILED " During bulk options analysis";

	if (val == NULL || buf == NULL) {
		if (val != NULL)
			GDKfree(val);
		if (buf != NULL)
			GDKfree(buf);
		throw(MAL, "batxml.options", MAL_MALLOC_FAIL);
	}
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(val);
		GDKfree(buf);
		throw(MAL, "xml.options", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "options", GDKfree(val); GDKfree(buf));

	if (strcmp(*options, "absent") == 0)
		buf[0] = 0;
	else if (strcmp(*options, "empty") == 0)
		snprintf(buf, size, "<%s></%s>", *name, *name);
	else if (strcmp(*options, "null") == 0)
		snprintf(buf, size, "null");
	else if (strcmp(*options, "nil") == 0)
		snprintf(buf, size, "nil");
	else {
		/*if(strcmp(*options,"niloncontent")==0) */
		err = PROGRAM_NYI;
		goto bunins_failed;
	}

	snprintf(val, size, "<%s>", *name);
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);

		if (strNil(t)) {
			bunfastapp(bn, buf);
		} else {
			if (strlen(t) > size - 2 * len - 6) {
				size += strlen(t);
				val = (char *) GDKrealloc(val, size + strlen(t));
				if (val == NULL) {
					err = MAL_MALLOC_FAIL;
					goto bunins_failed;
				}
			}
			snprintf(val + len + 2, size - len, "%s</%s>", t, *name);
			bunfastapp(bn, val);
		}
	}
	GDKfree(val);
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	if (val != NULL)
		GDKfree(val);
	throw(MAL, "batxml.options", "%s", err);
}
예제 #23
0
파일: mkey.c 프로젝트: Mytherin/MonetDBLite
str
MKEYbathash(bat *res, const bat *bid)
{
	BAT *b, *dst;
	wrd *r;
	BUN n;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(SQL, "mkey.bathash", RUNTIME_OBJECT_MISSING);

	assert(BAThvoid(b) || BAThrestricted(b));

	n = BATcount(b);
	dst = BATnew(TYPE_void, TYPE_wrd, n, TRANSIENT);
	if (dst == NULL) {
		BBPunfix(b->batCacheid);
		throw(SQL, "mkey.bathash", MAL_MALLOC_FAIL);
	}
	BATseqbase(dst, b->hseqbase);
	BATsetcount(dst, n);

	r = (wrd *) Tloc(dst, BUNfirst(dst));

	switch (ATOMstorage(b->ttype)) {
	case TYPE_void: {
		oid o = b->tseqbase;
		if (o == oid_nil)
			while (n-- > 0)
				*r++ = wrd_nil;
		else
			while (n-- > 0)
				*r++ = (wrd) o++;
		break;
	}
	case TYPE_bte: {
		bte *v = (bte *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_bte(v);
			v++;
		}
		break;
	}
	case TYPE_sht: {
		sht *v = (sht *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_sht(v);
			v++;
		}
		break;
	}
	case TYPE_int:
	case TYPE_flt: {
		int *v = (int *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_int(v);
			v++;
		}
		break;
	}
	case TYPE_lng:
	case TYPE_dbl: {
		lng *v = (lng *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_lng(v);
			v++;
		}
		break;
	}
#ifdef HAVE_HGE
	case TYPE_hge: {
		hge *v = (hge *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_hge(v);
			v++;
		}
		break;
	}
#endif
	default: {
		BATiter bi = bat_iterator(b);
		BUN (*hash)(const void *) = BATatoms[b->ttype].atomHash;
		int (*cmp)(const void *, const void *) = ATOMcompare(b->ttype);
		void *nil = ATOMnilptr(b->ttype);
		BUN i;
		const void *v;

		BATloop(b, i, n) {
			v = BUNtail(bi, i);
			if ((*cmp)(v, nil) == 0)
				*r++ = wrd_nil;
			else
				*r++ = (wrd) (*hash)(v);
		}
		break;
	}
	}
예제 #24
0
파일: gdk_search.c 프로젝트: lajus/monetinr
/*
 * The prime routine for the BAT layer is to create a new hash index.
 * Its argument is the element type and the maximum number of BUNs be
 * stored under the hash function.
 */
BAT *
BAThash(BAT *b, BUN masksize)
{
	BAT *o = NULL;
	lng t0,t1;
	(void) t0; 
	(void) t1;

	if (VIEWhparent(b)) {
		bat p = VIEWhparent(b);
		o = b;
		b = BATdescriptor(p);
		if (!ALIGNsynced(o, b) || BUNfirst(o) != BUNfirst(b)) {
			BBPunfix(b->batCacheid);
			b = o;
			o = NULL;
		}
	}
	MT_lock_set(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
	if (b->H->hash == NULL) {
		unsigned int tpe = ATOMstorage(b->htype);
		BUN cnt = BATcount(b);
		BUN mask;
		BUN p = BUNfirst(b), q = BUNlast(b), r;
		Hash *h = NULL;
		Heap *hp = NULL;
		str nme = BBP_physical(b->batCacheid);
		BATiter bi = bat_iterator(b);

		ALGODEBUG fprintf(stderr, "#BAThash: create hash(" BUNFMT ");\n", BATcount(b));
		/* cnt = 0, hopefully there is a proper capacity from
		 * which we can derive enough information */
		if (!cnt)
			cnt = BATcapacity(b);

		if (b->htype == TYPE_void) {
			if (b->hseqbase == oid_nil) {
				MT_lock_unset(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
				ALGODEBUG fprintf(stderr, "#BAThash: cannot create hash-table on void-NIL column.\n");
				return NULL;
			}
			ALGODEBUG fprintf(stderr, "#BAThash: creating hash-table on void column..\n");

			tpe = TYPE_void;
		}
		/* determine hash mask size p = first; then no dynamic
		 * scheme */
		if (masksize > 0) {
			mask = HASHmask(masksize);
		} else if (ATOMsize(ATOMstorage(tpe)) == 1) {
			mask = (1 << 8);
		} else if (ATOMsize(ATOMstorage(tpe)) == 2) {
			mask = (1 << 12);
		} else if (b->hkey) {
			mask = HASHmask(cnt);
		} else {
			/* dynamic hash: we start with
			 * HASHmask(cnt/64); if there are too many
			 * collisions we try HASHmask(cnt/16), then
			 * HASHmask(cnt/4), and finally
			 * HASHmask(cnt).  */
			mask = HASHmask(cnt >> 6);
			p += (cnt >> 2);	/* try out on first 25% of b */
			if (p > q)
				p = q;
		}

		if (mask < 1024)
			mask = 1024;
		t0 = GDKusec();
		do {
			BUN nslots = mask >> 3;	/* 1/8 full is too full */

			r = BUNfirst(b);
			if (hp) {
				HEAPfree(hp);
				GDKfree(hp);
			}
			if (h) {
				ALGODEBUG fprintf(stderr, "#BAThash: retry hash construction\n");
				GDKfree(h);
			}
			/* create the hash structures */
			hp = (Heap *) GDKzalloc(sizeof(Heap));
			if (hp &&
			    (hp->filename = GDKmalloc(strlen(nme) + 12)) != NULL)
				sprintf(hp->filename, "%s.%chash", nme, b->batCacheid > 0 ? 'h' : 't');
			if (hp == NULL ||
			    hp->filename == NULL ||
			    (h = HASHnew(hp, ATOMtype(b->htype), BATcapacity(b), mask)) == NULL) {

				MT_lock_unset(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
				if (hp != NULL) {
					GDKfree(hp->filename);
					GDKfree(hp);
				}
				return NULL;
			}

			switch (tpe) {
			case TYPE_bte:
				starthash(bte);
				break;
			case TYPE_sht:
				starthash(sht);
				break;
			case TYPE_int:
			case TYPE_flt:
				starthash(int);
				break;
			case TYPE_dbl:
			case TYPE_lng:
				starthash(lng);
				break;
			default:
				for (; r < p; r++) {
					ptr v = BUNhead(bi, r);
					BUN c = (BUN) heap_hash_any(b->H->vheap, h, v);

					if ( HASHget(h,c) == HASHnil(h) &&
					    nslots-- == 0)
						break;	/* mask too full */
					HASHputlink(h,r, HASHget(h,c));
					HASHput(h,c, r);
				}
				break;
			}
		} while (r < p && mask < cnt && (mask <<= 2));

		/* finish the hashtable with the current mask */
		p = r;
		switch (tpe) {
		case TYPE_bte:
			finishhash(bte);
			break;
		case TYPE_sht:
			finishhash(sht);
			break;
		case TYPE_int:
		case TYPE_flt:
			finishhash(int);
			break;
		case TYPE_dbl:
		case TYPE_lng:
			finishhash(lng);
			break;
		default:
			for (; p < q; p++) {
				ptr v = BUNhead(bi, p);
				BUN c = (BUN) heap_hash_any(b->H->vheap, h, v);

				HASHputlink(h,p, HASHget(h,c));
				HASHput(h,c,p);
			}
			break;
		}
		b->H->hash = h;
		t1 = GDKusec();
		ALGODEBUG 
				fprintf(stderr, "#BAThash: hash construction "LLFMT" usec\n", t1-t0);
		ALGODEBUG HASHcollisions(b,b->H->hash);
	}
예제 #25
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLcontent(bat *ret, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	BATiter bi;
	xmlDocPtr doc;
	xmlNodePtr root;
	size_t size = BUFSIZ;
	str buf = GDKmalloc(size);
	const char *err = OPERATION_FAILED;
	xmlBufferPtr xbuf;

	if (buf == NULL)
		throw(MAL,"xml.content",MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.content", INTERNAL_BAT_ACCESS);
	}
	doc = xmlParseMemory("<doc/>", 6);
	root = xmlDocGetRootElement(doc);
	prepareResult(bn, b, TYPE_xml, "content", GDKfree(buf));
	bi = bat_iterator(b);
	xbuf = xmlBufferCreate();
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;
		xmlNodePtr elem;
		xmlParserErrors xerr;
		const xmlChar *s;

		if (strNil(t)) {
			bunfastapp(bn, str_nil);
			bn->T->nonil = 0;
			continue;
		}
		len = strlen(t);
		xerr = xmlParseInNodeContext(root, t, (int) len, 0, &elem);
		if (xerr != XML_ERR_OK) {
			err = XML_PARSE_ERROR;
			goto bunins_failed;
		}
		xmlNodeDump(xbuf, doc, elem, 0, 0);
		s = xmlBufferContent(xbuf);
		len = strlen((const char *) s);
		if (len + 2 >= size) {
			GDKfree(buf);
			size = len + 128;
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		buf[0] = 'C';
		strcpy(buf + 1, (const char *) s);
		bunfastapp(bn, buf);
		xmlBufferEmpty(xbuf);
		xmlFreeNodeList(elem);
	}
	xmlBufferFree(xbuf);
	xmlFreeDoc(doc);
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	xmlBufferFree(xbuf);
	xmlFreeDoc(doc);
	if (buf != NULL)
		GDKfree(buf);
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	throw(MAL, "xml.document", "%s", err);
}
예제 #26
0
파일: rapi.c 프로젝트: MonetDB/MonetDB
str RAPIeval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, bit grouped) {
	sql_func * sqlfun = NULL;
	str exprStr = *getArgReference_str(stk, pci, pci->retc + 1);

	SEXP x, env, retval;
	SEXP varname = R_NilValue;
	SEXP varvalue = R_NilValue;
	ParseStatus status;
	int i = 0;
	char argbuf[64];
	char *argnames = NULL;
	size_t argnameslen;
	size_t pos;
	char* rcall = NULL;
	size_t rcalllen;
	int ret_cols = 0; /* int because pci->retc is int, too*/
	str *args;
	int evalErr;
	char *msg = MAL_SUCCEED;
	BAT *b;
	node * argnode;
	int seengrp = FALSE;

	rapiClient = cntxt;

	if (!RAPIEnabled()) {
		throw(MAL, "rapi.eval",
			  "Embedded R has not been enabled. Start server with --set %s=true",
			  rapi_enableflag);
	}
	if (!rapiInitialized) {
		throw(MAL, "rapi.eval",
			  "Embedded R initialization has failed");
	}

	if (!grouped) {
		sql_subfunc *sqlmorefun = (*(sql_subfunc**) getArgReference(stk, pci, pci->retc));
		if (sqlmorefun) sqlfun = (*(sql_subfunc**) getArgReference(stk, pci, pci->retc))->func;
	} else {
		sqlfun = *(sql_func**) getArgReference(stk, pci, pci->retc);
	}

	args = (str*) GDKzalloc(sizeof(str) * pci->argc);
	if (args == NULL) {
		throw(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
	}

	// get the lock even before initialization of the R interpreter, as this can take a second and must be done only once.
	MT_lock_set(&rapiLock);

	env = PROTECT(eval(lang1(install("new.env")), R_GlobalEnv));
	assert(env != NULL);

	// first argument after the return contains the pointer to the sql_func structure
	// NEW macro temporarily renamed to MNEW to allow including sql_catalog.h

	if (sqlfun != NULL && sqlfun->ops->cnt > 0) {
		int carg = pci->retc + 2;
		argnode = sqlfun->ops->h;
		while (argnode) {
			char* argname = ((sql_arg*) argnode->data)->name;
			args[carg] = GDKstrdup(argname);
			carg++;
			argnode = argnode->next;
		}
	}
	// the first unknown argument is the group, we don't really care for the rest.
	argnameslen = 2;
	for (i = pci->retc + 2; i < pci->argc; i++) {
		if (args[i] == NULL) {
			if (!seengrp && grouped) {
				args[i] = GDKstrdup("aggr_group");
				seengrp = TRUE;
			} else {
				snprintf(argbuf, sizeof(argbuf), "arg%i", i - pci->retc - 1);
				args[i] = GDKstrdup(argbuf);
			}
		}
		argnameslen += strlen(args[i]) + 2; /* extra for ", " */
	}

	// install the MAL variables into the R environment
	// we can basically map values to int ("INTEGER") or double ("REAL")
	for (i = pci->retc + 2; i < pci->argc; i++) {
		int bat_type = getBatType(getArgType(mb,pci,i));
		// check for BAT or scalar first, keep code left
		if (!isaBatType(getArgType(mb,pci,i))) {
			b = COLnew(0, getArgType(mb, pci, i), 0, TRANSIENT);
			if (b == NULL) {
				msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
				goto wrapup;
			}
			if ( getArgType(mb,pci,i) == TYPE_str) {
				if (BUNappend(b, *getArgReference_str(stk, pci, i), false) != GDK_SUCCEED) {
					BBPreclaim(b);
					b = NULL;
					msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
					goto wrapup;
				}
			} else {
				if (BUNappend(b, getArgReference(stk, pci, i), false) != GDK_SUCCEED) {
					BBPreclaim(b);
					b = NULL;
					msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
					goto wrapup;
				}
			}
		} else {
			b = BATdescriptor(*getArgReference_bat(stk, pci, i));
			if (b == NULL) {
				msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
				goto wrapup;
			}
		}

		// check the BAT count, if it is bigger than RAPI_MAX_TUPLES, fail
		if (BATcount(b) > RAPI_MAX_TUPLES) {
			msg = createException(MAL, "rapi.eval",
								  "Got "BUNFMT" rows, but can only handle "LLFMT". Sorry.",
								  BATcount(b), (lng) RAPI_MAX_TUPLES);
			BBPunfix(b->batCacheid);
			goto wrapup;
		}
		varname = PROTECT(Rf_install(args[i]));
		varvalue = bat_to_sexp(b, bat_type);
		if (varvalue == NULL) {
			msg = createException(MAL, "rapi.eval", "unknown argument type ");
			goto wrapup;
		}
		BBPunfix(b->batCacheid);

		// install vector into R environment
		Rf_defineVar(varname, varvalue, env);
		UNPROTECT(2);
	}

	/* we are going to evaluate the user function within an anonymous function call:
	 * ret <- (function(arg1){return(arg1*2)})(42)
	 * the user code is put inside the {}, this keeps our environment clean (TM) and gives
	 * a clear path for return values, namely using the builtin return() function
	 * this is also compatible with PL/R
	 */
	pos = 0;
	argnames = malloc(argnameslen);
	if (argnames == NULL) {
		msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
		goto wrapup;
	}
	argnames[0] = '\0';
	for (i = pci->retc + 2; i < pci->argc; i++) {
		pos += snprintf(argnames + pos, argnameslen - pos, "%s%s",
						args[i], i < pci->argc - 1 ? ", " : "");
	}
	rcalllen = 2 * pos + strlen(exprStr) + 100;
	rcall = malloc(rcalllen);
	if (rcall == NULL) {
		msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
		goto wrapup;
	}
	snprintf(rcall, rcalllen,
			 "ret <- as.data.frame((function(%s){%s})(%s), nm=NA, stringsAsFactors=F)\n",
			 argnames, exprStr, argnames);
	free(argnames);
	argnames = NULL;
#ifdef _RAPI_DEBUG_
	printf("# R call %s\n",rcall);
#endif

	x = R_ParseVector(mkString(rcall), 1, &status, R_NilValue);

	if (LENGTH(x) != 1 || status != PARSE_OK) {
		msg = createException(MAL, "rapi.eval",
							  "Error parsing R expression '%s'. ", exprStr);
		goto wrapup;
	}

	retval = R_tryEval(VECTOR_ELT(x, 0), env, &evalErr);
	if (evalErr != FALSE) {
		char* errormsg = strdup(R_curErrorBuf());
		size_t c;
		if (errormsg == NULL) {
			msg = createException(MAL, "rapi.eval", "Error running R expression.");
			goto wrapup;
		}
		// remove newlines from error message so it fits into a MAPI error (lol)
		for (c = 0; c < strlen(errormsg); c++) {
			if (errormsg[c] == '\r' || errormsg[c] == '\n') {
				errormsg[c] = ' ';
			}
		}
		msg = createException(MAL, "rapi.eval",
							  "Error running R expression: %s", errormsg);
		free(errormsg);
		goto wrapup;
	}

	// ret should be a data frame with exactly as many columns as we need from retc
	ret_cols = LENGTH(retval);
	if (ret_cols != pci->retc) {
		msg = createException(MAL, "rapi.eval",
							  "Expected result of %d columns, got %d", pci->retc, ret_cols);
		goto wrapup;
	}

	// collect the return values
	for (i = 0; i < pci->retc; i++) {
		SEXP ret_col = VECTOR_ELT(retval, i);
		int bat_type = getBatType(getArgType(mb,pci,i));
		if (bat_type == TYPE_any || bat_type == TYPE_void) {
			getArgType(mb,pci,i) = bat_type;
			msg = createException(MAL, "rapi.eval",
								  "Unknown return value, possibly projecting with no parameters.");
			goto wrapup;
		}

		// hand over the vector into a BAT
		b = sexp_to_bat(ret_col, bat_type);
		if (b == NULL) {
			msg = createException(MAL, "rapi.eval",
								  "Failed to convert column %i", i);
			goto wrapup;
		}
		// bat return
		if (isaBatType(getArgType(mb,pci,i))) {
			*getArgReference_bat(stk, pci, i) = b->batCacheid;
		} else { // single value return, only for non-grouped aggregations
			BATiter li = bat_iterator(b);
			if (VALinit(&stk->stk[pci->argv[i]], bat_type,
						BUNtail(li, 0)) == NULL) { // TODO BUNtail here
				msg = createException(MAL, "rapi.eval", SQLSTATE(HY001) MAL_MALLOC_FAIL);
				goto wrapup;
			}
		}
		msg = MAL_SUCCEED;
	}
	/* unprotect environment, so it will be eaten by the GC. */
	UNPROTECT(1);
  wrapup:
	MT_lock_unset(&rapiLock);
	if (argnames)
		free(argnames);
	if (rcall)
		free(rcall);
	for (i = 0; i < pci->argc; i++)
		GDKfree(args[i]);
	GDKfree(args);

	return msg;
}
예제 #27
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLelement(bat *ret, const char * const *name, xml *nspace, xml *attr, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf;
	BATiter bi;
	size_t elemlen, namelen;
	const char *err = OPERATION_FAILED;

	if (strNil(*name))
		throw(MAL, "xml.element", XML_NO_ELEMENT);
	if (xmlValidateName((xmlChar *) *name, 0) != 0)
		throw(MAL, "xml.element", XML_ATTRIBUTE_INVALID);
	if (nspace && !strNil(*nspace) && **nspace)
		throw(MAL, "xml.element", XML_NO_NAMESPACE);
	namelen = strlen(*name);
	elemlen = namelen + 5;
	if (nspace && !strNil(*nspace)) {
		if (**nspace != 'A')
			throw(MAL, "xml.element", XML_ILLEGAL_NAMESPACE);
		elemlen += strlen(*nspace);	/* " " + nspace (nspace contains initial 'A' which is replaced by space) */
	}
	if (attr && !strNil(*attr)) {
		if (**attr != 'A')
			throw(MAL, "xml.element", XML_ILLEGAL_ATTRIBUTE);
		elemlen += strlen(*attr);	/* " " + attr (attr contains initial 'A' which is replaced by space) */
	}
	buf = GDKmalloc(size);
	if (buf == NULL)
		throw(MAL, "xml.attribute", MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.element", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "element", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;

		len = elemlen;
		if (!strNil(t)) {
			if (*t != 'C') {
				err = XML_ILLEGAL_CONTENT;
				goto bunins_failed;
			}
			len += strlen(t + 1) + namelen + 2;  /* extra "<", ">", and name ("/" already counted) */
		}
		if (len >= size) {
			/* make sure there is enough space */
			size = len + 128;
			/* free/malloc so we don't copy */
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		if (strNil(t) && (!attr || strNil(*attr))) {
			strcpy(buf, str_nil);
			bn->T->nonil = 0;
		} else {
			int i = snprintf(buf, size, "C<%s", *name);
			if (nspace && !strNil(*nspace))
				i += snprintf(buf + i, size - i, " %s", *nspace + 1);
			if (attr && !strNil(*attr))
				i += snprintf(buf + i, size - i, " %s", *attr + 1);
			if (!strNil(t))
				i += snprintf(buf + i, size - i, ">%s</%s>", t + 1, *name);
			else
				i += snprintf(buf + i, size - i, "/>");
		}
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.element", "%s", err);
}
예제 #28
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLattribute(bat *ret, const char * const *name, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf;
	BATiter bi;
	size_t attrlen;
	const char *err = OPERATION_FAILED;

	if (strNil(*name))
		throw(MAL, "xml.attribute", XML_ATTRIBUTE_ERROR);
	if (xmlValidateName((xmlChar *) *name, 0) != 0)
		throw(MAL, "xml.attribute", XML_ATTRIBUTE_INVALID);
	attrlen = strlen(*name) + 5;
	buf = GDKmalloc(size);
	if (buf == NULL)
		throw(MAL, "xml.attribute", MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.attribute", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "attribute", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;

		len = attrlen;
		if (!strNil(t))
			len += strlen(t) * 6 + 1;
		if (len >= size) {
			/* make sure there is enough space */
			size = len + 128;
			/* free/malloc so we don't copy */
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		if (strNil(t)) {
			strcpy(buf, str_nil);
			bn->T->nonil = 0;
		} else {
			int n = snprintf(buf, size, "A%s = \"", *name);
			size_t m = XMLquotestring(t, buf + n, size - n);
			strcpy(buf + n + m, "\"");
		}
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.attribute", "%s", err);
}
예제 #29
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLroot(bat *ret, const bat *bid, const char * const *version, const char * const *standalone)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf;
	BATiter bi;
	size_t hdrlen;
	const char *err = OPERATION_FAILED;

	hdrlen = 8;
	if (!strNil(*version) && **version) {
		if (strcmp(*version, "1.0") != 0 && strcmp(*version, "1.1") != 0)
			throw(MAL, "xml.root", XML_VERSION_ERROR);
		hdrlen += 11 + strlen(*version);  /* strlen(" version=\"\"") */
	}
	if (!strNil(*standalone) && **standalone) {
		if (strcmp(*standalone, "yes") != 0 && strcmp(*standalone, "no") != 0)
			throw(MAL, "xml.root", XML_STANDALONE_ERROR "illegal XML standalone value");
		hdrlen += 14 + strlen(*standalone);  /* strlen(" standalone=\"\"") */
	}
	buf = GDKmalloc(size);
	if (buf == NULL)
		throw(MAL, "xml.root", MAL_MALLOC_FAIL);
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.pi", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "pi", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len, i;
		bit isdoc;

		len = hdrlen;
		if (!strNil(t))
			len += strlen(t);
		if (len >= size) {
			/* make sure there is enough space */
			size = len + 128;
			/* free/malloc so we don't copy */
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		if (strNil(t)) {
			strcpy(buf, str_nil);
			bn->T->nonil = 0;
		} else {
			strcpy(buf, "D<?xml");
			i = strlen(buf);
			if (!strNil(*version) && **version)
				i += snprintf(buf + i, len - i, " version=\"%s\"", *version);
			if (!strNil(*standalone) && **standalone)
				i += snprintf(buf + i, len - i, " standalone=\"%s\"", *standalone);
			snprintf(buf + i, len - i, "?>%s", t + 1);
			buf++;
			XMLisdocument(&isdoc, &buf); /* check well-formedness */
			buf--;
			if (!isdoc) {
				err = XML_NOT_WELL_FORMED;
				goto bunins_failed;
			}
		}
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.root", "%s", err);
}
예제 #30
0
파일: batxml.c 프로젝트: f7753/monetdb
str
BATXMLpi(bat *ret, const char * const *target, const bat *bid)
{
	BAT *b, *bn;
	BUN p, q;
	size_t size = BUFSIZ;
	str buf;
	BATiter bi;
	size_t tgtlen;
	const char *err = OPERATION_FAILED;

	if (strNil(*target))
		throw(MAL, "xml.pi", XML_PI_ERROR);
	buf = GDKmalloc(size);
	if (buf == NULL)
		throw(MAL, "xml.pi", MAL_MALLOC_FAIL);

	tgtlen = strlen(*target) + 6;
	if ((b = BATdescriptor(*bid)) == NULL) {
		GDKfree(buf);
		throw(MAL, "xml.pi", INTERNAL_BAT_ACCESS);
	}
	prepareResult(bn, b, TYPE_xml, "pi", GDKfree(buf));
	bi = bat_iterator(b);
	BATloop(b, p, q) {
		const char *t = (const char *) BUNtail(bi, p);
		size_t len;

		len = tgtlen;
		if (!strNil(t))
			len += strlen(t) * 6 + 1;
		if (len >= size) {
			/* make sure there is enough space */
			size = len + 128;
			/* free/malloc so we don't copy */
			GDKfree(buf);
			buf = GDKmalloc(size);
			if (buf == NULL) {
				err = MAL_MALLOC_FAIL;
				goto bunins_failed;
			}
		}
		if (strNil(t))
			snprintf(buf, size, "C<?%s?>", *target);
		else {
			int n = snprintf(buf, size, "C<?%s ", *target);
			size_t m = XMLquotestring(t, buf + n, size - n);
			strcpy(buf + n + m, "?>");
		}
		bunfastapp(bn, buf);
	}
	GDKfree(buf);
	finalizeResult(ret, bn, b);
	return MAL_SUCCEED;
  bunins_failed:
	BBPunfix(b->batCacheid);
	BBPunfix(bn->batCacheid);
	if (buf != NULL)
		GDKfree(buf);
	throw(MAL, "xml.pi", "%s", err);
}