Commit dad75eb4 authored by David Rowley's avatar David Rowley

Have pg_itoa, pg_ltoa and pg_lltoa return the length of the string

Core by no means makes excessive use of these functions, but quite a large
number of those usages do require the caller to call strlen() on the
returned string.  This is quite wasteful since these functions do already
have a good idea of the length of the string, so we might as well just
have them return that.

Reviewed-by: Andrew Gierth
Discussion: https://postgr.es/m/CAApHDvrm2A5x2uHYxsqriO2cUaGcFvND%2BksC9e7Tjep0t2RK_A%40mail.gmail.com
parent 9a7fccd9
...@@ -103,9 +103,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self) ...@@ -103,9 +103,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
{ {
int32 num = DatumGetInt32(value); int32 num = DatumGetInt32(value);
char str[12]; /* sign, 10 digits and '\0' */ char str[12]; /* sign, 10 digits and '\0' */
int len;
pg_ltoa(num, str); len = pg_ltoa(num, str);
pq_sendcountedtext(&buf, str, strlen(str), false); pq_sendcountedtext(&buf, str, len, false);
} }
break; break;
...@@ -113,9 +114,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self) ...@@ -113,9 +114,10 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
{ {
int64 num = DatumGetInt64(value); int64 num = DatumGetInt64(value);
char str[MAXINT8LEN + 1]; char str[MAXINT8LEN + 1];
int len;
pg_lltoa(num, str); len = pg_lltoa(num, str);
pq_sendcountedtext(&buf, str, strlen(str), false); pq_sendcountedtext(&buf, str, len, false);
} }
break; break;
......
...@@ -191,9 +191,7 @@ int2vectorout(PG_FUNCTION_ARGS) ...@@ -191,9 +191,7 @@ int2vectorout(PG_FUNCTION_ARGS)
{ {
if (num != 0) if (num != 0)
*rp++ = ' '; *rp++ = ' ';
pg_itoa(int2Array->values[num], rp); rp += pg_itoa(int2Array->values[num], rp);
while (*++rp != '\0')
;
} }
*rp = '\0'; *rp = '\0';
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
......
...@@ -149,9 +149,16 @@ int8out(PG_FUNCTION_ARGS) ...@@ -149,9 +149,16 @@ int8out(PG_FUNCTION_ARGS)
int64 val = PG_GETARG_INT64(0); int64 val = PG_GETARG_INT64(0);
char buf[MAXINT8LEN + 1]; char buf[MAXINT8LEN + 1];
char *result; char *result;
int len;
pg_lltoa(val, buf); len = pg_lltoa(val, buf) + 1;
result = pstrdup(buf);
/*
* Since the length is already known, we do a manual palloc() and memcpy()
* to avoid the strlen() call that would otherwise be done in pstrdup().
*/
result = palloc(len);
memcpy(result, buf, len);
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
......
...@@ -327,16 +327,17 @@ invalid_syntax: ...@@ -327,16 +327,17 @@ invalid_syntax:
/* /*
* pg_itoa: converts a signed 16-bit integer to its string representation * pg_itoa: converts a signed 16-bit integer to its string representation
* and returns strlen(a).
* *
* Caller must ensure that 'a' points to enough memory to hold the result * Caller must ensure that 'a' points to enough memory to hold the result
* (at least 7 bytes, counting a leading sign and trailing NUL). * (at least 7 bytes, counting a leading sign and trailing NUL).
* *
* It doesn't seem worth implementing this separately. * It doesn't seem worth implementing this separately.
*/ */
void int
pg_itoa(int16 i, char *a) pg_itoa(int16 i, char *a)
{ {
pg_ltoa((int32) i, a); return pg_ltoa((int32) i, a);
} }
/* /*
...@@ -404,25 +405,27 @@ pg_ultoa_n(uint32 value, char *a) ...@@ -404,25 +405,27 @@ pg_ultoa_n(uint32 value, char *a)
} }
/* /*
* NUL-terminate the output of pg_ultoa_n. * pg_ltoa: converts a signed 32-bit integer to its string representation and
* returns strlen(a).
* *
* It is the caller's responsibility to ensure that a is at least 12 bytes long, * It is the caller's responsibility to ensure that a is at least 12 bytes long,
* which is enough room to hold a minus sign, a maximally long int32, and the * which is enough room to hold a minus sign, a maximally long int32, and the
* above terminating NUL. * above terminating NUL.
*/ */
void int
pg_ltoa(int32 value, char *a) pg_ltoa(int32 value, char *a)
{ {
uint32 uvalue = (uint32) value; uint32 uvalue = (uint32) value;
int len; int len = 0;
if (value < 0) if (value < 0)
{ {
uvalue = (uint32) 0 - uvalue; uvalue = (uint32) 0 - uvalue;
*a++ = '-'; a[len++] = '-';
} }
len = pg_ultoa_n(uvalue, a); len += pg_ultoa_n(uvalue, a + len);
a[len] = '\0'; a[len] = '\0';
return len;
} }
/* /*
...@@ -510,24 +513,27 @@ pg_ulltoa_n(uint64 value, char *a) ...@@ -510,24 +513,27 @@ pg_ulltoa_n(uint64 value, char *a)
} }
/* /*
* pg_lltoa: convert a signed 64-bit integer to its string representation * pg_lltoa: converts a signed 64-bit integer to its string representation and
* returns strlen(a).
* *
* Caller must ensure that 'a' points to enough memory to hold the result * Caller must ensure that 'a' points to enough memory to hold the result
* (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL). * (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
*/ */
void int
pg_lltoa(int64 value, char *a) pg_lltoa(int64 value, char *a)
{ {
int len;
uint64 uvalue = value; uint64 uvalue = value;
int len = 0;
if (value < 0) if (value < 0)
{ {
*a++ = '-';
uvalue = (uint64) 0 - uvalue; uvalue = (uint64) 0 - uvalue;
a[len++] = '-';
} }
len = pg_ulltoa_n(uvalue, a);
a[len] = 0; len += pg_ulltoa_n(uvalue, a + len);
a[len] = '\0';
return len;
} }
......
...@@ -47,11 +47,11 @@ extern int namestrcmp(Name name, const char *str); ...@@ -47,11 +47,11 @@ extern int namestrcmp(Name name, const char *str);
extern int32 pg_atoi(const char *s, int size, int c); extern int32 pg_atoi(const char *s, int size, int c);
extern int16 pg_strtoint16(const char *s); extern int16 pg_strtoint16(const char *s);
extern int32 pg_strtoint32(const char *s); extern int32 pg_strtoint32(const char *s);
extern void pg_itoa(int16 i, char *a); extern int pg_itoa(int16 i, char *a);
extern int pg_ultoa_n(uint32 l, char *a); extern int pg_ultoa_n(uint32 l, char *a);
extern int pg_ulltoa_n(uint64 l, char *a); extern int pg_ulltoa_n(uint64 l, char *a);
extern void pg_ltoa(int32 l, char *a); extern int pg_ltoa(int32 l, char *a);
extern void pg_lltoa(int64 ll, char *a); extern int pg_lltoa(int64 ll, char *a);
extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth); extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth);
extern char *pg_ultostr(char *str, uint32 value); extern char *pg_ultostr(char *str, uint32 value);
extern uint64 pg_strtouint64(const char *str, char **endptr, int base); extern uint64 pg_strtouint64(const char *str, char **endptr, int base);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment