📄 pqformat.c
字号:
*/voidpq_endmessage(StringInfo buf){ /* msgtype was saved in cursor field */ (void) pq_putmessage(buf->cursor, buf->data, buf->len); /* no need to complain about any failure, since pqcomm.c already did */ pfree(buf->data); buf->data = NULL;}/* -------------------------------- * pq_begintypsend - initialize for constructing a bytea result * -------------------------------- */voidpq_begintypsend(StringInfo buf){ initStringInfo(buf); /* Reserve four bytes for the bytea length word */ appendStringInfoCharMacro(buf, '\0'); appendStringInfoCharMacro(buf, '\0'); appendStringInfoCharMacro(buf, '\0'); appendStringInfoCharMacro(buf, '\0');}/* -------------------------------- * pq_endtypsend - finish constructing a bytea result * * The data buffer is returned as the palloc'd bytea value. (We expect * that it will be suitably aligned for this because it has been palloc'd.) * We assume the StringInfoData is just a local variable in the caller and * need not be pfree'd. * -------------------------------- */bytea *pq_endtypsend(StringInfo buf){ bytea *result = (bytea *) buf->data; /* Insert correct length into bytea length word */ Assert(buf->len >= VARHDRSZ); VARATT_SIZEP(result) = buf->len; return result;}/* -------------------------------- * pq_puttextmessage - generate a character set-converted message in one step * * This is the same as the pqcomm.c routine pq_putmessage, except that * the message body is a null-terminated string to which encoding * conversion applies. * -------------------------------- */voidpq_puttextmessage(char msgtype, const char *str){ int slen = strlen(str); char *p; p = pg_server_to_client(str, slen); if (p != str) /* actual conversion has been done? */ { (void) pq_putmessage(msgtype, p, strlen(p) + 1); pfree(p); return; } (void) pq_putmessage(msgtype, str, slen + 1);}/* -------------------------------- * pq_putemptymessage - convenience routine for message with empty body * -------------------------------- */voidpq_putemptymessage(char msgtype){ (void) pq_putmessage(msgtype, NULL, 0);}/* -------------------------------- * pq_getmsgbyte - get a raw byte from a message buffer * -------------------------------- */intpq_getmsgbyte(StringInfo msg){ if (msg->cursor >= msg->len) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("no data left in message"))); return (unsigned char) msg->data[msg->cursor++];}/* -------------------------------- * pq_getmsgint - get a binary integer from a message buffer * * Values are treated as unsigned. * -------------------------------- */unsigned intpq_getmsgint(StringInfo msg, int b){ unsigned int result; unsigned char n8; uint16 n16; uint32 n32; switch (b) { case 1: pq_copymsgbytes(msg, (char *) &n8, 1); result = n8; break; case 2: pq_copymsgbytes(msg, (char *) &n16, 2); result = ntohs(n16); break; case 4: pq_copymsgbytes(msg, (char *) &n32, 4); result = ntohl(n32); break; default: elog(ERROR, "unsupported integer size %d", b); result = 0; /* keep compiler quiet */ break; } return result;}/* -------------------------------- * pq_getmsgint64 - get a binary 8-byte int from a message buffer * * It is tempting to merge this with pq_getmsgint, but we'd have to make the * result int64 for all data widths --- that could be a big performance * hit on machines where int64 isn't efficient. * -------------------------------- */int64pq_getmsgint64(StringInfo msg){ int64 result; uint32 h32; uint32 l32; pq_copymsgbytes(msg, (char *) &h32, 4); pq_copymsgbytes(msg, (char *) &l32, 4); h32 = ntohl(h32); l32 = ntohl(l32);#ifdef INT64_IS_BUSTED /* error out if incoming value is wider than 32 bits */ result = l32; if ((result < 0) ? (h32 != -1) : (h32 != 0)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("binary value is out of range for type bigint")));#else result = h32; result <<= 32; result |= l32;#endif return result;}/* -------------------------------- * pq_getmsgfloat4 - get a float4 from a message buffer * * See notes for pq_sendfloat4. * -------------------------------- */float4pq_getmsgfloat4(StringInfo msg){ union { float4 f; uint32 i; } swap; swap.i = pq_getmsgint(msg, 4); return swap.f;}/* -------------------------------- * pq_getmsgfloat8 - get a float8 from a message buffer * * See notes for pq_sendfloat8. * -------------------------------- */float8pq_getmsgfloat8(StringInfo msg){#ifdef INT64_IS_BUSTED union { float8 f; uint32 h[2]; } swap; /* Have to figure out endianness by testing... */ if (((uint32) 1) == htonl((uint32) 1)) { /* machine seems to be big-endian, receive h[0] first */ swap.h[0] = pq_getmsgint(msg, 4); swap.h[1] = pq_getmsgint(msg, 4); } else { /* machine seems to be little-endian, receive h[1] first */ swap.h[1] = pq_getmsgint(msg, 4); swap.h[0] = pq_getmsgint(msg, 4); } return swap.f;#else union { float8 f; int64 i; } swap; swap.i = pq_getmsgint64(msg); return swap.f;#endif}/* -------------------------------- * pq_getmsgbytes - get raw data from a message buffer * * Returns a pointer directly into the message buffer; note this * may not have any particular alignment. * -------------------------------- */const char *pq_getmsgbytes(StringInfo msg, int datalen){ const char *result; if (datalen < 0 || datalen > (msg->len - msg->cursor)) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("insufficient data left in message"))); result = &msg->data[msg->cursor]; msg->cursor += datalen; return result;}/* -------------------------------- * pq_copymsgbytes - copy raw data from a message buffer * * Same as above, except data is copied to caller's buffer. * -------------------------------- */voidpq_copymsgbytes(StringInfo msg, char *buf, int datalen){ if (datalen < 0 || datalen > (msg->len - msg->cursor)) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("insufficient data left in message"))); memcpy(buf, &msg->data[msg->cursor], datalen); msg->cursor += datalen;}/* -------------------------------- * pq_getmsgtext - get a counted text string (with conversion) * * Always returns a pointer to a freshly palloc'd result. * The result has a trailing null, *and* we return its strlen in *nbytes. * -------------------------------- */char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes){ char *str; char *p; if (rawbytes < 0 || rawbytes > (msg->len - msg->cursor)) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("insufficient data left in message"))); str = &msg->data[msg->cursor]; msg->cursor += rawbytes; p = pg_client_to_server(str, rawbytes); if (p != str) /* actual conversion has been done? */ *nbytes = strlen(p); else { p = (char *) palloc(rawbytes + 1); memcpy(p, str, rawbytes); p[rawbytes] = '\0'; *nbytes = rawbytes; } return p;}/* -------------------------------- * pq_getmsgstring - get a null-terminated text string (with conversion) * * May return a pointer directly into the message buffer, or a pointer * to a palloc'd conversion result. * -------------------------------- */const char *pq_getmsgstring(StringInfo msg){ char *str; int slen; str = &msg->data[msg->cursor]; /* * It's safe to use strlen() here because a StringInfo is guaranteed to * have a trailing null byte. But check we found a null inside the * message. */ slen = strlen(str); if (msg->cursor + slen >= msg->len) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid string in message"))); msg->cursor += slen + 1; return pg_client_to_server(str, slen);}/* -------------------------------- * pq_getmsgend - verify message fully consumed * -------------------------------- */voidpq_getmsgend(StringInfo msg){ if (msg->cursor != msg->len) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid message format")));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -