summaryrefslogtreecommitdiff
path: root/src/backend/libpq/pqcomprim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/pqcomprim.c')
-rw-r--r--src/backend/libpq/pqcomprim.c160
1 files changed, 99 insertions, 61 deletions
diff --git a/src/backend/libpq/pqcomprim.c b/src/backend/libpq/pqcomprim.c
index 53742190f3e..0dd46d9205a 100644
--- a/src/backend/libpq/pqcomprim.c
+++ b/src/backend/libpq/pqcomprim.c
@@ -1,122 +1,150 @@
#include <stdlib.h>
#include <stdio.h>
+#include <netinet/in.h>
#include "postgres.h"
#include "libpq/pqcomm.h"
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#endif
-
-/* --------------------------------------------------------------------- */
-/* These definitions for ntoh/hton are the other way around from the
- * default system definitions, so we roll our own here.
+/*
+ * The backend supports the old little endian byte order and the current
+ * network byte order.
*/
+#ifndef FRONTEND
+
+#include "libpq/libpq-be.h"
+
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+
#ifndef BYTE_ORDER
#error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN
#endif
#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
-#else /* BYTE_ORDER != LITTLE_ENDIAN */
+
+#define ntoh_s(n) n
+#define ntoh_l(n) n
+#define hton_s(n) n
+#define hton_l(n) n
+
+#else
#if BYTE_ORDER == BIG_ENDIAN
-#define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \
- | ((u_char *)&n)[0])
-#define ntoh_l(n) (uint32) (((u_char *)&n)[3] << 24 \
- | ((u_char *)&n)[2] << 16 \
- | ((u_char *)&n)[1] << 8 \
- | ((u_char *)&n)[0])
-#define hton_s(n) (ntoh_s(n))
-#define hton_l(n) (ntoh_l(n))
+
+#define ntoh_s(n) (uint16)(((u_char *)&n)[1] << 8 \
+ | ((u_char *)&n)[0])
+#define ntoh_l(n) (uint32)(((u_char *)&n)[3] << 24 \
+ | ((u_char *)&n)[2] << 16 \
+ | ((u_char *)&n)[1] << 8 \
+ | ((u_char *)&n)[0])
+#define hton_s(n) (ntoh_s(n))
+#define hton_l(n) (ntoh_l(n))
+
#else
-/* BYTE_ORDER != BIG_ENDIAN */
#if BYTE_ORDER == PDP_ENDIAN
+
#error PDP_ENDIAN macros not written yet
+
#else
-/* BYTE_ORDER != anything known */
+
#error BYTE_ORDER not defined as anything understood
-#endif /* BYTE_ORDER == PDP_ENDIAN */
-#endif /* BYTE_ORDER == BIG_ENDIAN */
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#endif
+#endif
+#endif
+
+#endif
+
/* --------------------------------------------------------------------- */
int
pqPutShort(int integer, FILE *f)
{
- int retval = 0;
- u_short n,
- s;
+ uint16 n;
+
+#ifdef FRONTEND
+ n = htons((uint16)integer);
+#else
+ n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16)integer));
+#endif
- s = integer;
- n = hton_s(s);
- if (fwrite(&n, sizeof(u_short), 1, f) != 1)
- retval = EOF;
+ if (fwrite(&n, 2, 1, f) != 1)
+ return EOF;
- return retval;
+ return 0;
}
/* --------------------------------------------------------------------- */
int
pqPutLong(int integer, FILE *f)
{
- int retval = 0;
- uint32 n;
+ uint32 n;
- n = hton_l(integer);
- if (fwrite(&n, sizeof(uint32), 1, f) != 1)
- retval = EOF;
+#ifdef FRONTEND
+ n = htonl((uint32)integer);
+#else
+ n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32)integer));
+#endif
- return retval;
+ if (fwrite(&n, 4, 1, f) != 1)
+ return EOF;
+
+ return 0;
}
/* --------------------------------------------------------------------- */
int
pqGetShort(int *result, FILE *f)
{
- int retval = 0;
- u_short n;
+ uint16 n;
- if (fread(&n, sizeof(u_short), 1, f) != 1)
- retval = EOF;
+ if (fread(&n, 2, 1, f) != 1)
+ return EOF;
+
+#ifdef FRONTEND
+ *result = (int)ntohs(n);
+#else
+ *result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n));
+#endif
- *result = ntoh_s(n);
- return retval;
+ return 0;
}
/* --------------------------------------------------------------------- */
int
pqGetLong(int *result, FILE *f)
{
- int retval = 0;
- uint32 n;
+ uint32 n;
- if (fread(&n, sizeof(uint32), 1, f) != 1)
- retval = EOF;
+ if (fread(&n, 4, 1, f) != 1)
+ return EOF;
- *result = ntoh_l(n);
- return retval;
+#ifdef FRONTEND
+ *result = (int)ntohl(n);
+#else
+ *result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n));
+#endif
+
+ return 0;
}
/* --------------------------------------------------------------------- */
-/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s.
+/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s (which must be 1
+ byte longer) and terminate it with a '\0'.
Return 0 if ok.
*/
int
pqGetNBytes(char *s, size_t len, FILE *f)
{
- int cnt;
+ 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;
}
@@ -126,7 +154,7 @@ int
pqPutNBytes(const char *s, size_t len, FILE *f)
{
if (f == NULL)
- return 0;
+ return EOF;
if (fwrite(s, 1, len, f) != len)
return EOF;
@@ -138,15 +166,27 @@ pqPutNBytes(const char *s, size_t len, FILE *f)
int
pqGetString(char *s, size_t len, FILE *f)
{
- int c;
+ int c;
if (f == NULL)
return EOF;
- while (len-- && (c = getc(f)) != EOF && c)
- *s++ = c;
+ /*
+ * Keep on reading until we get the terminating '\0' and discard those
+ * bytes we don't have room for.
+ */
+
+ while ((c = getc(f)) != EOF && c != '\0')
+ if (len > 1)
+ {
+ *s++ = c;
+ len--;
+ }
+
*s = '\0';
- /* mjl: actually needs up to len+1 bytes, is this okay? XXX */
+
+ if (c == EOF)
+ return EOF;
return 0;
}
@@ -183,5 +223,3 @@ pqPutByte(int c, FILE *f)
return (putc(c, f) == c) ? 0 : EOF;
}
-
-/* --------------------------------------------------------------------- */