mirror of
https://github.com/postgres/postgres.git
synced 2025-11-04 20:11:56 +03:00
- Move most of the I/O in both libpq and the backend to a set
of common routines in pqcomprim.c (pq communication primitives).
Not all adapted to it yet, but it's a start.
- Rewritten some of those routines, to write/read bigger chunks of
data, precomputing stuff in buffers instead of sending out byte
by byte.
- As a consequence, I need to know the endianness of the machine.
Currently I rely on getting it from machine/endian.h, but this
may not be available everywhere? (Who the hell thought it was
a good idea to pass integers to the backend the other way around
than the normal network byte order? *argl*)
- Libpq looks in the environment for magic variables, and upon
establishing a connection to the backend, sends it queries
of the form "SET var_name TO 'var_value'". This needs a change
in the backend parser (Mr. Parser, are you there? :)
- Currently it looks for two Env-Vars, namely PG_DATEFORMAT
and PG_FLOATFORMAT. What else makes sense? PG_TIMEFORMAT?
PG_TIMEZONE?
From: "Martin J. Laubach" <mjl@wwx.vip.at>
This commit is contained in:
@@ -27,6 +27,164 @@
|
||||
#error Please write byte order macros
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutShort(const int integer, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_short n;
|
||||
|
||||
n = hton_s(integer);
|
||||
if(fwrite(&n, sizeof(u_short), 1, f) != 1)
|
||||
retval = EOF;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutLong(const int integer, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_long n;
|
||||
|
||||
n = hton_l(integer);
|
||||
if(fwrite(&n, sizeof(u_long), 1, f) != 1)
|
||||
retval = EOF;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqGetShort(int *result, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_short n;
|
||||
|
||||
if(fread(&n, sizeof(u_short), 1, f) != 1)
|
||||
retval = EOF;
|
||||
|
||||
*result = ntoh_s(n);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqGetLong(int *result, FILE *f)
|
||||
{
|
||||
int retval = 0;
|
||||
u_long n;
|
||||
|
||||
if(fread(&n, sizeof(u_long), 1, f) != 1)
|
||||
retval = EOF;
|
||||
|
||||
*result = ntoh_l(n);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s.
|
||||
Return 0 if ok.
|
||||
*/
|
||||
int pqGetNBytes(char* s, const int len, FILE *f)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
||||
cnt = fread(s, 1, len, f);
|
||||
s[cnt] = '\0';
|
||||
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||
|
||||
return (cnt == len) ? 0 : EOF;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutNBytes(const char *s, const int len, FILE *f)
|
||||
{
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
if(fwrite(s, 1, len, f) != len)
|
||||
return EOF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqGetString(char *s, int len, FILE *f)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (f == NULL)
|
||||
return EOF;
|
||||
|
||||
while (len-- && (c = getc(f)) != EOF && c)
|
||||
*s++ = c;
|
||||
*s = '\0';
|
||||
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutString(const char *s, FILE *f)
|
||||
{
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
if (fputs(s, f) == EOF)
|
||||
return EOF;
|
||||
|
||||
fputc('\0', f); /* important to send an ending \0 since backend expects it */
|
||||
fflush(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqGetByte(FILE *f)
|
||||
{
|
||||
return getc(f);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutByte(const int c, FILE *f)
|
||||
{
|
||||
if(!f) return 0;
|
||||
|
||||
return (putc(c, f) == c) ? 0 : EOF;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "postgres.h"
|
||||
#include "libpq/pqcomm.h"
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Is the other way around than system ntoh/hton, so we roll our own
|
||||
here */
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define ntoh_s(n) n
|
||||
#define ntoh_l(n) n
|
||||
#define hton_s(n) n
|
||||
#define hton_l(n) n
|
||||
#endif
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define ntoh_s(n) (u_short)(((u_char *) &n)[0] << 8 | ((u_char *) &n)[1]);
|
||||
#define ntoh_l(n) (u_long)(((u_char *)&n)[0] << 24 | ((u_char *)&n)[1] << 16 |\
|
||||
((u_char *)&n)[2] << 8 | ((u_char *)&n)[3]);
|
||||
#define hton_s(n) (ntoh_s(n))
|
||||
#define hton_l(n) (ntoh_l(n))
|
||||
#endif
|
||||
#if BYTE_ORDER == PDP_ENDIAN
|
||||
#endif
|
||||
#ifndef ntoh_s
|
||||
#error Please write byte order macros
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
int pqPutShort(const int integer, FILE *f)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user