packages feed

hpqtypes-1.8.0.0: libpqtypes/src/misc.c

/*
 * misc.c
 *   Type handler for CHAR, BOOL, MONEY, UUID data types.
 *
 * Copyright (c) 2011 eSilo, LLC. All rights reserved.
 * This is free software; see the source for copying conditions.  There is
 * NO warranty; not even for MERCHANTABILITY or  FITNESS FOR A  PARTICULAR
 * PURPOSE.
 */

#include "libpqtypes-int.h"

int
pqt_put_char(PGtypeArgs *args)
{
	PGchar *chp = va_arg(args->ap, PGchar *);
	PUTNULLCHK(args, chp);
	*args->put.out = *chp;
	return 1;
}

int
pqt_get_char(PGtypeArgs *args)
{
	DECLVALUE(args);
	PGchar *chp = va_arg(args->ap, PGchar *);
	CHKGETVALS(args, chp);
	*chp = *value;
	return 0;
}

int
pqt_put_bool(PGtypeArgs *args)
{
	PGbool *boolp = va_arg(args->ap, PGbool *);
	PUTNULLCHK(args, boolp);
	*args->put.out = *boolp != 0 ? 1 : 0;
	return 1;
}

int
pqt_get_bool(PGtypeArgs *args)
{
	DECLVALUE(args);
	PGbool *boolp = va_arg(args->ap, PGbool *);

	CHKGETVALS(args, boolp);

	if (args->format == TEXTFMT)
		*boolp = (*value == 't') ? 1 : 0;
	else
		*boolp = (*value)!=0 ? 1 : 0;
	return 0;
}

int
pqt_put_money(PGtypeArgs *args)
{
	PGmoney *moneyp = va_arg(args->ap, PGmoney *);
	PUTNULLCHK(args, moneyp);
	int len = args->fmtinfo->sversion >= 80300 ? 8 : 4;

	if (len == 8)
		pqt_swap8(args->put.out, moneyp, 1);
	else /* truncate: pre 8.3 server expecting a 4 byte money */
		pqt_buf_putint4(args->put.out, (int)*moneyp);

	return len;
}

int
pqt_get_money(PGtypeArgs *args)
{
	DECLVALUE(args);
	DECLLENGTH(args);
	PGmoney *moneyp = va_arg(args->ap, PGmoney *);

	CHKGETVALS(args, moneyp);

	if (args->format == TEXTFMT)
	{
		char buf[64];
		char c, *p = buf;
		char *bufend = buf + sizeof(buf);

		for (; (c = *value) != '\0' && p<bufend; ++value)
		{
			if (isdigit(c) || c == '-')
			{
				*p = c;
				p++;
			}
		}

		buf[p - buf] = 0;

		if (pqt_text_to_int8(buf, moneyp) == -1)
			RERR_STR2INT(args);

		return 0;
	}

	/* 8.3 uses a 64-bit money type. Need compatibility
	 * for communicating with older servers.
	 */
	if (valuel == 4)
		pqt_buf_putint4(moneyp, pqt_buf_getint4(value));
	else
		pqt_swap8(moneyp, value, 0);

	return 0;
}

int
pqt_put_uuid(PGtypeArgs *args)
{
	PGuuid *uuid = va_arg(args->ap, PGuuid *);
	PUTNULLCHK(args, uuid);
	args->put.out = uuid->data;
	return sizeof(uuid->data);
}

int
pqt_get_uuid(PGtypeArgs *args)
{
	DECLVALUE(args);
	DECLLENGTH(args);
	PGuuid *uuid = va_arg(args->ap, PGuuid *);

	CHKGETVALS(args, uuid);

	if (args->format == TEXTFMT)
		return args->errorf(args, "text format is not supported");

	if (valuel != sizeof(uuid->data))
		return args->errorf(args,
		                    "invalid data: %d bytes expected, %d given",
		                    sizeof(uuid->data),
		                    valuel);

	memcpy(uuid->data, value, valuel);
	return 0;
}

int
pqt_put_null(PGtypeArgs *args)
{
	args->put.out = NULL;
	return 0;
}