Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5ecd4e3

Browse files
committed
Binary send/receive routines for a few basic datatypes --- enough for
testing purposes.
1 parent4207d6b commit5ecd4e3

File tree

13 files changed

+691
-184
lines changed

13 files changed

+691
-184
lines changed

‎src/backend/libpq/pqformat.c

Lines changed: 181 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@
1515
* pq_getmessage, and then parsed and converted from that using the routines
1616
* in this module.
1717
*
18+
* These same routines support reading and writing of external binary formats
19+
* (typsend/typreceive routines). The conversion routines for individual
20+
* data types are exactly the same, only initialization and completion
21+
* are different.
22+
*
23+
*
1824
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1925
* Portions Copyright (c) 1994, Regents of the University of California
2026
*
21-
*$Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.29 2003/05/08 18:16:36 tgl Exp $
27+
*$Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.30 2003/05/09 15:44:40 tgl Exp $
2228
*
2329
*-------------------------------------------------------------------------
2430
*/
@@ -28,23 +34,31 @@
2834
*pq_beginmessage - initialize StringInfo buffer
2935
*pq_sendbyte- append a raw byte to a StringInfo buffer
3036
*pq_sendint- append a binary integer to a StringInfo buffer
37+
*pq_sendint64- append a binary 8-byte int to a StringInfo buffer
3138
*pq_sendbytes- append raw data to a StringInfo buffer
32-
*pq_sendcountedtext - append a text string (with character set conversion)
39+
*pq_sendcountedtext - append a counted text string (with character set conversion)
40+
*pq_sendtext- append a text string (with conversion)
3341
*pq_sendstring- append a null-terminated text string (with conversion)
3442
*pq_endmessage- send the completed message to the frontend
3543
* Note: it is also possible to append data to the StringInfo buffer using
3644
* the regular StringInfo routines, but this is discouraged since required
3745
* character set conversion may not occur.
3846
*
47+
* typsend support (construct a bytea value containing external binary data):
48+
*pq_begintypsend - initialize StringInfo buffer
49+
*pq_endtypsend- return the completed string as a "bytea*"
50+
*
3951
* Special-case message output:
4052
*pq_puttextmessage - generate a character set-converted message in one step
4153
*pq_putemptymessage - convenience routine for message with empty body
4254
*
4355
* Message parsing after input:
4456
*pq_getmsgbyte- get a raw byte from a message buffer
4557
*pq_getmsgint- get a binary integer from a message buffer
58+
*pq_getmsgint64- get a binary 8-byte int from a message buffer
4659
*pq_getmsgbytes- get raw data from a message buffer
4760
*pq_copymsgbytes- copy raw data from a message buffer
61+
*pq_getmsgtext- get a counted text string (with conversion)
4862
*pq_getmsgstring- get a null-terminated text string (with conversion)
4963
*pq_getmsgend- verify message fully consumed
5064
*/
@@ -101,7 +115,7 @@ pq_sendbytes(StringInfo buf, const char *data, int datalen)
101115
}
102116

103117
/* --------------------------------
104-
*pq_sendcountedtext - append a text string (with character set conversion)
118+
*pq_sendcountedtext - append acountedtext string (with character set conversion)
105119
*
106120
* The data sent to the frontend by this routine is a 4-byte count field
107121
* followed by the string. The count includes itself or not, as per the
@@ -132,6 +146,34 @@ pq_sendcountedtext(StringInfo buf, const char *str, int slen,
132146
}
133147
}
134148

149+
/* --------------------------------
150+
*pq_sendtext- append a text string (with conversion)
151+
*
152+
* The passed text string need not be null-terminated, and the data sent
153+
* to the frontend isn't either. Note that this is not actually useful
154+
* for direct frontend transmissions, since there'd be no way for the
155+
* frontend to determine the string length. But it is useful for binary
156+
* format conversions.
157+
* --------------------------------
158+
*/
159+
void
160+
pq_sendtext(StringInfobuf,constchar*str,intslen)
161+
{
162+
char*p;
163+
164+
p= (char*)pg_server_to_client((unsignedchar*)str,slen);
165+
if (p!=str)/* actual conversion has been done? */
166+
{
167+
slen=strlen(p);
168+
appendBinaryStringInfo(buf,p,slen);
169+
pfree(p);
170+
}
171+
else
172+
{
173+
appendBinaryStringInfo(buf,str,slen);
174+
}
175+
}
176+
135177
/* --------------------------------
136178
*pq_sendstring- append a null-terminated text string (with conversion)
137179
*
@@ -152,9 +194,11 @@ pq_sendstring(StringInfo buf, const char *str)
152194
slen=strlen(p);
153195
appendBinaryStringInfo(buf,p,slen+1);
154196
pfree(p);
155-
return;
156197
}
157-
appendBinaryStringInfo(buf,str,slen+1);
198+
else
199+
{
200+
appendBinaryStringInfo(buf,str,slen+1);
201+
}
158202
}
159203

160204
/* --------------------------------
@@ -188,6 +232,35 @@ pq_sendint(StringInfo buf, int i, int b)
188232
}
189233
}
190234

235+
/* --------------------------------
236+
*pq_sendint64- append a binary 8-byte int to a StringInfo buffer
237+
*
238+
* It is tempting to merge this with pq_sendint, but we'd have to make the
239+
* argument int64 for all data widths --- that could be a big performance
240+
* hit on machines where int64 isn't efficient.
241+
* --------------------------------
242+
*/
243+
void
244+
pq_sendint64(StringInfobuf,int64i)
245+
{
246+
uint32n32;
247+
248+
/* High order half first, since we're doing MSB-first */
249+
#ifdefINT64_IS_BUSTED
250+
/* don't try a right shift of 32 on a 32-bit word */
251+
n32= (i<0) ?-1 :0;
252+
#else
253+
n32= (uint32) (i >>32);
254+
#endif
255+
n32=htonl(n32);
256+
appendBinaryStringInfo(buf, (char*)&n32,4);
257+
258+
/* Now the low order half */
259+
n32= (uint32)i;
260+
n32=htonl(n32);
261+
appendBinaryStringInfo(buf, (char*)&n32,4);
262+
}
263+
191264
/* --------------------------------
192265
*pq_endmessage- send the completed message to the frontend
193266
*
@@ -205,6 +278,44 @@ pq_endmessage(StringInfo buf)
205278
buf->data=NULL;
206279
}
207280

281+
282+
/* --------------------------------
283+
*pq_begintypsend- initialize for constructing a bytea result
284+
* --------------------------------
285+
*/
286+
void
287+
pq_begintypsend(StringInfobuf)
288+
{
289+
initStringInfo(buf);
290+
/* Reserve four bytes for the bytea length word */
291+
appendStringInfoCharMacro(buf,'\0');
292+
appendStringInfoCharMacro(buf,'\0');
293+
appendStringInfoCharMacro(buf,'\0');
294+
appendStringInfoCharMacro(buf,'\0');
295+
}
296+
297+
/* --------------------------------
298+
*pq_endtypsend- finish constructing a bytea result
299+
*
300+
* The data buffer is returned as the palloc'd bytea value. (We expect
301+
* that it will be suitably aligned for this because it has been palloc'd.)
302+
* We assume the StringInfoData is just a local variable in the caller and
303+
* need not be pfree'd.
304+
* --------------------------------
305+
*/
306+
bytea*
307+
pq_endtypsend(StringInfobuf)
308+
{
309+
bytea*result= (bytea*)buf->data;
310+
311+
/* Insert correct length into bytea length word */
312+
Assert(buf->len >=VARHDRSZ);
313+
VARATT_SIZEP(result)=buf->len;
314+
315+
returnresult;
316+
}
317+
318+
208319
/* --------------------------------
209320
*pq_puttextmessage - generate a character set-converted message in one step
210321
*
@@ -289,6 +400,38 @@ pq_getmsgint(StringInfo msg, int b)
289400
returnresult;
290401
}
291402

403+
/* --------------------------------
404+
*pq_getmsgint64- get a binary 8-byte int from a message buffer
405+
*
406+
* It is tempting to merge this with pq_getmsgint, but we'd have to make the
407+
* result int64 for all data widths --- that could be a big performance
408+
* hit on machines where int64 isn't efficient.
409+
* --------------------------------
410+
*/
411+
int64
412+
pq_getmsgint64(StringInfomsg)
413+
{
414+
int64result;
415+
uint32h32;
416+
uint32l32;
417+
418+
pq_copymsgbytes(msg, (char*)&h32,4);
419+
pq_copymsgbytes(msg, (char*)&l32,4);
420+
h32=ntohl(h32);
421+
l32=ntohl(l32);
422+
423+
#ifdefINT64_IS_BUSTED
424+
/* just lose the high half */
425+
result=l32;
426+
#else
427+
result=h32;
428+
result <<=32;
429+
result |=l32;
430+
#endif
431+
432+
returnresult;
433+
}
434+
292435
/* --------------------------------
293436
*pq_getmsgbytes- get raw data from a message buffer
294437
*
@@ -323,6 +466,39 @@ pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
323466
msg->cursor+=datalen;
324467
}
325468

469+
/* --------------------------------
470+
*pq_getmsgtext- get a counted text string (with conversion)
471+
*
472+
*Always returns a pointer to a freshly palloc'd result.
473+
*The result has a trailing null, *and* we return its strlen in *nbytes.
474+
* --------------------------------
475+
*/
476+
char*
477+
pq_getmsgtext(StringInfomsg,intrawbytes,int*nbytes)
478+
{
479+
char*str;
480+
char*p;
481+
482+
if (rawbytes<0||rawbytes> (msg->len-msg->cursor))
483+
elog(ERROR,"pq_getmsgtext: insufficient data left in message");
484+
str=&msg->data[msg->cursor];
485+
msg->cursor+=rawbytes;
486+
487+
p= (char*)pg_client_to_server((unsignedchar*)str,rawbytes);
488+
if (p!=str)/* actual conversion has been done? */
489+
{
490+
*nbytes=strlen(p);
491+
}
492+
else
493+
{
494+
p= (char*)palloc(rawbytes+1);
495+
memcpy(p,str,rawbytes);
496+
p[rawbytes]='\0';
497+
*nbytes=rawbytes;
498+
}
499+
returnp;
500+
}
501+
326502
/* --------------------------------
327503
*pq_getmsgstring- get a null-terminated text string (with conversion)
328504
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp