PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
encode.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "mb/pg_wchar.h"
#include "port/simd.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "varatt.h"
Include dependency graph for encode.c:

Go to the source code of this file.

Data Structures

struct  pg_encoding
 

Macros

#define VAL(CH)   ((CH) - '0')
 
#define DIG(VAL)   ((VAL) + '0')
 

Functions

static const struct pg_encodingpg_find_encoding (const char *name)
 
Datum binary_encode (PG_FUNCTION_ARGS)
 
Datum binary_decode (PG_FUNCTION_ARGS)
 
static uint64 hex_encode_scalar (const char *src, size_t len, char *dst)
 
uint64 hex_encode (const char *src, size_t len, char *dst)
 
static bool get_hex (const char *cp, char *out)
 
uint64 hex_decode (const char *src, size_t len, char *dst)
 
static uint64 hex_decode_safe_scalar (const char *src, size_t len, char *dst, Node *escontext)
 
uint64 hex_decode_safe (const char *src, size_t len, char *dst, Node *escontext)
 
static uint64 hex_enc_len (const char *src, size_t srclen)
 
static uint64 hex_dec_len (const char *src, size_t srclen)
 
static uint64 pg_base64_encode_internal (const char *src, size_t len, char *dst, bool url)
 
static uint64 pg_base64_encode (const char *src, size_t len, char *dst)
 
static uint64 pg_base64url_encode (const char *src, size_t len, char *dst)
 
static uint64 pg_base64_decode_internal (const char *src, size_t len, char *dst, bool url)
 
static uint64 pg_base64_decode (const char *src, size_t len, char *dst)
 
static uint64 pg_base64url_decode (const char *src, size_t len, char *dst)
 
static uint64 pg_base64_enc_len (const char *src, size_t srclen)
 
static uint64 pg_base64_dec_len (const char *src, size_t srclen)
 
static uint64 pg_base64url_enc_len (const char *src, size_t srclen)
 
static uint64 pg_base64url_dec_len (const char *src, size_t srclen)
 
static uint64 esc_encode (const char *src, size_t srclen, char *dst)
 
static uint64 esc_decode (const char *src, size_t srclen, char *dst)
 
static uint64 esc_enc_len (const char *src, size_t srclen)
 
static uint64 esc_dec_len (const char *src, size_t srclen)
 

Variables

static const char hextbl [512]
 
static const int8 hexlookup [128]
 
static const char _base64 []
 
static const char _base64url []
 
static const int8 b64lookup [128]
 
struct {
   const char *   name
 
   struct pg_encoding   enc
 
enclist []
 

Macro Definition Documentation

◆ DIG

#define DIG (   VAL)    ((VAL) + '0')

Definition at line 671 of file encode.c.

◆ VAL

#define VAL (   CH)    ((CH) - '0')

Definition at line 670 of file encode.c.

Function Documentation

◆ binary_decode()

Datum binary_decode ( PG_FUNCTION_ARGS  )

Definition at line 97 of file encode.c.

98{
101 bytea *result;
102 char *namebuf;
103 char *dataptr;
104 size_t datalen;
105 uint64 resultlen;
106 uint64 res;
107 const struct pg_encoding *enc;
108
109 namebuf = TextDatumGetCString(name);
110
111 enc = pg_find_encoding(namebuf);
112 if (enc == NULL)
114 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
115 errmsg("unrecognized encoding: \"%s\"", namebuf)));
116
117 dataptr = VARDATA_ANY(data);
118 datalen = VARSIZE_ANY_EXHDR(data);
119
120 resultlen = enc->decode_len(dataptr, datalen);
121
122 /*
123 * resultlen possibly overflows uint32, therefore on 32-bit machines it's
124 * unsafe to rely on palloc's internal check.
125 */
126 if (resultlen > MaxAllocSize - VARHDRSZ)
128 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
129 errmsg("result of decoding conversion is too large")));
130
131 result = palloc(VARHDRSZ + resultlen);
132
133 res = enc->decode(dataptr, datalen, VARDATA(result));
134
135 /* Make this FATAL 'cause we've trodden on memory ... */
136 if (res > resultlen)
137 elog(FATAL, "overflow - decode estimate too small");
138
139 SET_VARSIZE(result, VARHDRSZ + res);
140
141 PG_RETURN_BYTEA_P(result);
142}
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define VARHDRSZ
Definition: c.h:697
uint64_t uint64
Definition: c.h:539
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define FATAL
Definition: elog.h:41
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
static const struct pg_encoding * pg_find_encoding(const char *name)
Definition: encode.c:868
const char * name
Definition: encode.c:830
struct pg_encoding enc
Definition: encode.c:831
#define MaxAllocSize
Definition: fe_memutils.h:22
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
void * palloc(Size size)
Definition: mcxt.c:1365
const void * data
uint64_t Datum
Definition: postgres.h:70
uint64(* decode_len)(const char *data, size_t dlen)
Definition: encode.c:37
uint64(* decode)(const char *data, size_t dlen, char *res)
Definition: encode.c:39
Definition: c.h:692
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition: varatt.h:472
static char * VARDATA(const void *PTR)
Definition: varatt.h:305
static char * VARDATA_ANY(const void *PTR)
Definition: varatt.h:486
static void SET_VARSIZE(void *PTR, Size len)
Definition: varatt.h:432

References data, pg_encoding::decode, pg_encoding::decode_len, elog, enc, ereport, errcode(), errmsg(), ERROR, FATAL, MaxAllocSize, name, palloc(), pg_find_encoding(), PG_GETARG_DATUM, PG_GETARG_TEXT_PP, PG_RETURN_BYTEA_P, SET_VARSIZE(), TextDatumGetCString, VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

◆ binary_encode()

Datum binary_encode ( PG_FUNCTION_ARGS  )

Definition at line 49 of file encode.c.

50{
53 text *result;
54 char *namebuf;
55 char *dataptr;
56 size_t datalen;
57 uint64 resultlen;
58 uint64 res;
59 const struct pg_encoding *enc;
60
61 namebuf = TextDatumGetCString(name);
62
63 enc = pg_find_encoding(namebuf);
64 if (enc == NULL)
66 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
67 errmsg("unrecognized encoding: \"%s\"", namebuf)));
68
69 dataptr = VARDATA_ANY(data);
70 datalen = VARSIZE_ANY_EXHDR(data);
71
72 resultlen = enc->encode_len(dataptr, datalen);
73
74 /*
75 * resultlen possibly overflows uint32, therefore on 32-bit machines it's
76 * unsafe to rely on palloc's internal check.
77 */
78 if (resultlen > MaxAllocSize - VARHDRSZ)
80 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
81 errmsg("result of encoding conversion is too large")));
82
83 result = palloc(VARHDRSZ + resultlen);
84
85 res = enc->encode(dataptr, datalen, VARDATA(result));
86
87 /* Make this FATAL 'cause we've trodden on memory ... */
88 if (res > resultlen)
89 elog(FATAL, "overflow - encode estimate too small");
90
91 SET_VARSIZE(result, VARHDRSZ + res);
92
93 PG_RETURN_TEXT_P(result);
94}
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
uint64(* encode_len)(const char *data, size_t dlen)
Definition: encode.c:36
uint64(* encode)(const char *data, size_t dlen, char *res)
Definition: encode.c:38

References data, elog, enc, pg_encoding::encode, pg_encoding::encode_len, ereport, errcode(), errmsg(), ERROR, FATAL, MaxAllocSize, name, palloc(), pg_find_encoding(), PG_GETARG_BYTEA_PP, PG_GETARG_DATUM, PG_RETURN_TEXT_P, SET_VARSIZE(), TextDatumGetCString, VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

◆ esc_dec_len()

static uint64 esc_dec_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 782 of file encode.c.

783{
784 const char *end = src + srclen;
785 uint64 len = 0;
786
787 while (src < end)
788 {
789 if (src[0] != '\\')
790 src++;
791 else if (src + 3 < end &&
792 (src[1] >= '0' && src[1] <= '3') &&
793 (src[2] >= '0' && src[2] <= '7') &&
794 (src[3] >= '0' && src[3] <= '7'))
795 {
796 /*
797 * backslash + valid octal
798 */
799 src += 4;
800 }
801 else if (src + 1 < end &&
802 (src[1] == '\\'))
803 {
804 /*
805 * two backslashes = backslash
806 */
807 src += 2;
808 }
809 else
810 {
811 /*
812 * one backslash, not followed by ### valid octal
813 */
815 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
816 errmsg("invalid input syntax for type %s", "bytea")));
817 }
818
819 len++;
820 }
821 return len;
822}
const void size_t len

References ereport, errcode(), errmsg(), ERROR, and len.

◆ esc_decode()

static uint64 esc_decode ( const char *  src,
size_t  srclen,
char *  dst 
)
static

Definition at line 713 of file encode.c.

714{
715 const char *end = src + srclen;
716 char *rp = dst;
717 uint64 len = 0;
718
719 while (src < end)
720 {
721 if (src[0] != '\\')
722 *rp++ = *src++;
723 else if (src + 3 < end &&
724 (src[1] >= '0' && src[1] <= '3') &&
725 (src[2] >= '0' && src[2] <= '7') &&
726 (src[3] >= '0' && src[3] <= '7'))
727 {
728 int val;
729
730 val = VAL(src[1]);
731 val <<= 3;
732 val += VAL(src[2]);
733 val <<= 3;
734 *rp++ = val + VAL(src[3]);
735 src += 4;
736 }
737 else if (src + 1 < end &&
738 (src[1] == '\\'))
739 {
740 *rp++ = '\\';
741 src += 2;
742 }
743 else
744 {
745 /*
746 * One backslash, not followed by ### valid octal. Should never
747 * get here, since esc_dec_len does same check.
748 */
750 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
751 errmsg("invalid input syntax for type %s", "bytea")));
752 }
753
754 len++;
755 }
756
757 return len;
758}
#define VAL(CH)
Definition: encode.c:670
long val
Definition: informix.c:689

References ereport, errcode(), errmsg(), ERROR, len, VAL, and val.

◆ esc_enc_len()

static uint64 esc_enc_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 761 of file encode.c.

762{
763 const char *end = src + srclen;
764 uint64 len = 0;
765
766 while (src < end)
767 {
768 if (*src == '\0' || IS_HIGHBIT_SET(*src))
769 len += 4;
770 else if (*src == '\\')
771 len += 2;
772 else
773 len++;
774
775 src++;
776 }
777
778 return len;
779}
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1154

References IS_HIGHBIT_SET, and len.

◆ esc_encode()

static uint64 esc_encode ( const char *  src,
size_t  srclen,
char *  dst 
)
static

Definition at line 674 of file encode.c.

675{
676 const char *end = src + srclen;
677 char *rp = dst;
678 uint64 len = 0;
679
680 while (src < end)
681 {
682 unsigned char c = (unsigned char) *src;
683
684 if (c == '\0' || IS_HIGHBIT_SET(c))
685 {
686 rp[0] = '\\';
687 rp[1] = DIG(c >> 6);
688 rp[2] = DIG((c >> 3) & 7);
689 rp[3] = DIG(c & 7);
690 rp += 4;
691 len += 4;
692 }
693 else if (c == '\\')
694 {
695 rp[0] = '\\';
696 rp[1] = '\\';
697 rp += 2;
698 len += 2;
699 }
700 else
701 {
702 *rp++ = c;
703 len++;
704 }
705
706 src++;
707 }
708
709 return len;
710}
#define DIG(VAL)
Definition: encode.c:671
char * c

References DIG, IS_HIGHBIT_SET, and len.

◆ get_hex()

static bool get_hex ( const char *  cp,
char *  out 
)
inlinestatic

Definition at line 247 of file encode.c.

248{
249 unsigned char c = (unsigned char) *cp;
250 int res = -1;
251
252 if (c < 127)
253 res = hexlookup[c];
254
255 *out = (char) res;
256
257 return (res >= 0);
258}
static const int8 hexlookup[128]
Definition: encode.c:170

References hexlookup.

Referenced by hex_decode_safe_scalar().

◆ hex_dec_len()

static uint64 hex_dec_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 393 of file encode.c.

394{
395 return (uint64) srclen >> 1;
396}

◆ hex_decode()

uint64 hex_decode ( const char *  src,
size_t  len,
char *  dst 
)

Definition at line 261 of file encode.c.

262{
263 return hex_decode_safe(src, len, dst, NULL);
264}
uint64 hex_decode_safe(const char *src, size_t len, char *dst, Node *escontext)
Definition: encode.c:347

References hex_decode_safe(), and len.

◆ hex_decode_safe()

uint64 hex_decode_safe ( const char *  src,
size_t  len,
char *  dst,
Node escontext 
)

Definition at line 347 of file encode.c.

348{
349#ifdef USE_NO_SIMD
350 return hex_decode_safe_scalar(src, len, dst, escontext);
351#else
352 const uint64 tail_idx = len & ~(sizeof(Vector8) * 2 - 1);
353 uint64 i;
354 bool success = true;
355
356 /*
357 * We must process 2 vectors at a time since the output will be half the
358 * length of the input.
359 */
360 for (i = 0; i < tail_idx; i += sizeof(Vector8) * 2)
361 {
362 Vector8 srcv;
363 Vector8 dstv1;
364 Vector8 dstv2;
365
366 vector8_load(&srcv, (const uint8 *) &src[i]);
367 success &= hex_decode_simd_helper(srcv, &dstv1);
368
369 vector8_load(&srcv, (const uint8 *) &src[i + sizeof(Vector8)]);
370 success &= hex_decode_simd_helper(srcv, &dstv2);
371
372 vector8_store((uint8 *) &dst[i / 2], vector8_pack_16(dstv1, dstv2));
373 }
374
375 /*
376 * If something didn't look right in the vector path, try again in the
377 * scalar path so that we can handle it correctly.
378 */
379 if (!success)
380 i = 0;
381
382 return i / 2 + hex_decode_safe_scalar(src + i, len - i, dst + i / 2, escontext);
383#endif
384}
uint8_t uint8
Definition: c.h:536
static uint64 hex_decode_safe_scalar(const char *src, size_t len, char *dst, Node *escontext)
Definition: encode.c:267
static bool success
Definition: initdb.c:187
int i
Definition: isn.c:77
static void vector8_load(Vector8 *v, const uint8 *s)
Definition: simd.h:107
uint64 Vector8
Definition: simd.h:60

References hex_decode_safe_scalar(), i, len, success, and vector8_load().

Referenced by byteain(), and hex_decode().

◆ hex_decode_safe_scalar()

static uint64 hex_decode_safe_scalar ( const char *  src,
size_t  len,
char *  dst,
Node escontext 
)
inlinestatic

Definition at line 267 of file encode.c.

268{
269 const char *s,
270 *srcend;
271 char v1,
272 v2,
273 *p;
274
275 srcend = src + len;
276 s = src;
277 p = dst;
278 while (s < srcend)
279 {
280 if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
281 {
282 s++;
283 continue;
284 }
285 if (!get_hex(s, &v1))
286 ereturn(escontext, 0,
287 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
288 errmsg("invalid hexadecimal digit: \"%.*s\"",
289 pg_mblen(s), s)));
290 s++;
291 if (s >= srcend)
292 ereturn(escontext, 0,
293 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
294 errmsg("invalid hexadecimal data: odd number of digits")));
295 if (!get_hex(s, &v2))
296 ereturn(escontext, 0,
297 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
298 errmsg("invalid hexadecimal digit: \"%.*s\"",
299 pg_mblen(s), s)));
300 s++;
301 *p++ = (v1 << 4) | v2;
302 }
303
304 return p - dst;
305}
#define ereturn(context, dummy_value,...)
Definition: elog.h:278
static bool get_hex(const char *cp, char *out)
Definition: encode.c:247
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1024

References ereturn, errcode(), errmsg(), get_hex(), len, and pg_mblen().

Referenced by hex_decode_safe().

◆ hex_enc_len()

static uint64 hex_enc_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 387 of file encode.c.

388{
389 return (uint64) srclen << 1;
390}

◆ hex_encode()

uint64 hex_encode ( const char *  src,
size_t  len,
char *  dst 
)

Definition at line 198 of file encode.c.

199{
200#ifdef USE_NO_SIMD
201 return hex_encode_scalar(src, len, dst);
202#else
203 const uint64 tail_idx = len & ~(sizeof(Vector8) - 1);
204 uint64 i;
205
206 /*
207 * This splits the high and low nibbles of each byte into separate
208 * vectors, adds the vectors to a mask that converts the nibbles to their
209 * equivalent ASCII bytes, and interleaves those bytes back together to
210 * form the final hex-encoded string.
211 */
212 for (i = 0; i < tail_idx; i += sizeof(Vector8))
213 {
214 Vector8 srcv;
215 Vector8 lo;
216 Vector8 hi;
217 Vector8 mask;
218
219 vector8_load(&srcv, (const uint8 *) &src[i]);
220
221 lo = vector8_and(srcv, vector8_broadcast(0x0f));
222 mask = vector8_gt(lo, vector8_broadcast(0x9));
223 mask = vector8_and(mask, vector8_broadcast('a' - '0' - 10));
224 mask = vector8_add(mask, vector8_broadcast('0'));
225 lo = vector8_add(lo, mask);
226
227 hi = vector8_and(srcv, vector8_broadcast(0xf0));
228 hi = vector8_shift_right(hi, 4);
229 mask = vector8_gt(hi, vector8_broadcast(0x9));
230 mask = vector8_and(mask, vector8_broadcast('a' - '0' - 10));
231 mask = vector8_add(mask, vector8_broadcast('0'));
232 hi = vector8_add(hi, mask);
233
234 vector8_store((uint8 *) &dst[i * 2],
235 vector8_interleave_low(hi, lo));
236 vector8_store((uint8 *) &dst[i * 2 + sizeof(Vector8)],
237 vector8_interleave_high(hi, lo));
238 }
239
240 (void) hex_encode_scalar(src + i, len - i, dst + i * 2);
241
242 return (uint64) len * 2;
243#endif
244}
static uint64 hex_encode_scalar(const char *src, size_t len, char *dst)
Definition: encode.c:182
static Vector8 vector8_broadcast(const uint8 c)
Definition: simd.h:149

References hex_encode_scalar(), i, len, vector8_broadcast(), and vector8_load().

Referenced by AddFileToBackupManifest(), byteaout(), and SendBackupManifest().

◆ hex_encode_scalar()

static uint64 hex_encode_scalar ( const char *  src,
size_t  len,
char *  dst 
)
inlinestatic

Definition at line 182 of file encode.c.

183{
184 const char *end = src + len;
185
186 while (src < end)
187 {
188 unsigned char usrc = *((const unsigned char *) src);
189
190 memcpy(dst, &hextbl[2 * usrc], 2);
191 src++;
192 dst += 2;
193 }
194 return (uint64) len * 2;
195}
static const char hextbl[512]
Definition: encode.c:152

References hextbl, and len.

Referenced by hex_encode().

◆ pg_base64_dec_len()

static uint64 pg_base64_dec_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 625 of file encode.c.

626{
627 return ((uint64) srclen * 3) >> 2;
628}

◆ pg_base64_decode()

static uint64 pg_base64_decode ( const char *  src,
size_t  len,
char *  dst 
)
static

Definition at line 606 of file encode.c.

607{
608 return pg_base64_decode_internal(src, len, dst, false);
609}
static uint64 pg_base64_decode_internal(const char *src, size_t len, char *dst, bool url)
Definition: encode.c:506

References len, and pg_base64_decode_internal().

◆ pg_base64_decode_internal()

static uint64 pg_base64_decode_internal ( const char *  src,
size_t  len,
char *  dst,
bool  url 
)
static

Definition at line 506 of file encode.c.

507{
508 const char *srcend = src + len,
509 *s = src;
510 char *p = dst;
511 char c;
512 int b = 0;
513 uint32 buf = 0;
514 int pos = 0,
515 end = 0;
516
517 while (s < srcend)
518 {
519 c = *s++;
520
521 if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
522 continue;
523
524 /* convert base64url to base64 */
525 if (url)
526 {
527 if (c == '-')
528 c = '+';
529 else if (c == '_')
530 c = '/';
531 }
532
533 if (c == '=')
534 {
535 /* end sequence */
536 if (!end)
537 {
538 if (pos == 2)
539 end = 1;
540 else if (pos == 3)
541 end = 2;
542 else
543 {
544 /* translator: %s is the name of an encoding scheme */
546 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
547 errmsg("unexpected \"=\" while decoding %s sequence", url ? "base64url" : "base64")));
548 }
549 }
550 b = 0;
551 }
552 else
553 {
554 b = -1;
555 if (c > 0 && c < 127)
556 b = b64lookup[(unsigned char) c];
557 if (b < 0)
558 {
559 /* translator: %s is the name of an encoding scheme */
561 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
562 errmsg("invalid symbol \"%.*s\" found while decoding %s sequence",
563 pg_mblen(s - 1), s - 1,
564 url ? "base64url" : "base64")));
565 }
566 }
567 /* add it to buffer */
568 buf = (buf << 6) + b;
569 pos++;
570 if (pos == 4)
571 {
572 *p++ = (buf >> 16) & 255;
573 if (end == 0 || end > 1)
574 *p++ = (buf >> 8) & 255;
575 if (end == 0 || end > 2)
576 *p++ = buf & 255;
577 buf = 0;
578 pos = 0;
579 }
580 }
581
582 if (pos == 2)
583 {
584 buf <<= 12;
585 *p++ = (buf >> 16) & 0xFF;
586 }
587 else if (pos == 3)
588 {
589 buf <<= 6;
590 *p++ = (buf >> 16) & 0xFF;
591 *p++ = (buf >> 8) & 0xFF;
592 }
593 else if (pos != 0)
594 {
595 /* translator: %s is the name of an encoding scheme */
597 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
598 errmsg("invalid %s end sequence", url ? "base64url" : "base64"),
599 errhint("Input data is missing padding, is truncated, or is otherwise corrupted.")));
600 }
601
602 return p - dst;
603}
uint32_t uint32
Definition: c.h:538
int errhint(const char *fmt,...)
Definition: elog.c:1321
static const int8 b64lookup[128]
Definition: encode.c:408
int b
Definition: isn.c:74
static char * buf
Definition: pg_test_fsync.c:72

References b, b64lookup, buf, ereport, errcode(), errhint(), errmsg(), ERROR, len, and pg_mblen().

Referenced by pg_base64_decode(), and pg_base64url_decode().

◆ pg_base64_enc_len()

static uint64 pg_base64_enc_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 618 of file encode.c.

619{
620 /* 3 bytes will be converted to 4, linefeed after 76 chars */
621 return ((uint64) srclen + 2) / 3 * 4 + (uint64) srclen / (76 * 3 / 4);
622}

◆ pg_base64_encode()

static uint64 pg_base64_encode ( const char *  src,
size_t  len,
char *  dst 
)
static

Definition at line 488 of file encode.c.

489{
490 return pg_base64_encode_internal(src, len, dst, false);
491}
static uint64 pg_base64_encode_internal(const char *src, size_t len, char *dst, bool url)
Definition: encode.c:427

References len, and pg_base64_encode_internal().

◆ pg_base64_encode_internal()

static uint64 pg_base64_encode_internal ( const char *  src,
size_t  len,
char *  dst,
bool  url 
)
static

Definition at line 427 of file encode.c.

428{
429 char *p,
430 *lend = dst + 76;
431 const char *s,
432 *end = src + len;
433 int pos = 2;
434 uint32 buf = 0;
435 const char *alphabet = url ? _base64url : _base64;
436
437 s = src;
438 p = dst;
439
440 while (s < end)
441 {
442 buf |= (unsigned char) *s << (pos << 3);
443 pos--;
444 s++;
445
446 /* write it out */
447 if (pos < 0)
448 {
449 *p++ = alphabet[(buf >> 18) & 0x3f];
450 *p++ = alphabet[(buf >> 12) & 0x3f];
451 *p++ = alphabet[(buf >> 6) & 0x3f];
452 *p++ = alphabet[buf & 0x3f];
453
454 pos = 2;
455 buf = 0;
456
457 if (!url && p >= lend)
458 {
459 *p++ = '\n';
460 lend = p + 76;
461 }
462 }
463 }
464
465 /* Handle remaining bytes in buf */
466 if (pos != 2)
467 {
468 *p++ = alphabet[(buf >> 18) & 0x3f];
469 *p++ = alphabet[(buf >> 12) & 0x3f];
470
471 if (pos == 0)
472 {
473 *p++ = alphabet[(buf >> 6) & 0x3f];
474 if (!url)
475 *p++ = '=';
476 }
477 else if (!url)
478 {
479 *p++ = '=';
480 *p++ = '=';
481 }
482 }
483
484 return p - dst;
485}
static const char _base64url[]
Definition: encode.c:405
static const char _base64[]
Definition: encode.c:402

References _base64, _base64url, buf, and len.

Referenced by pg_base64_encode(), and pg_base64url_encode().

◆ pg_base64url_dec_len()

static uint64 pg_base64url_dec_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 641 of file encode.c.

642{
643 /*
644 * For base64, each 4 characters of input produce at most 3 bytes of
645 * output. For base64url without padding, we need to round up to the
646 * nearest 4
647 */
648 size_t adjusted_len = srclen;
649
650 if (srclen % 4 != 0)
651 adjusted_len += 4 - (srclen % 4);
652
653 return (adjusted_len * 3) / 4;
654}

◆ pg_base64url_decode()

static uint64 pg_base64url_decode ( const char *  src,
size_t  len,
char *  dst 
)
static

Definition at line 612 of file encode.c.

613{
614 return pg_base64_decode_internal(src, len, dst, true);
615}

References len, and pg_base64_decode_internal().

◆ pg_base64url_enc_len()

static uint64 pg_base64url_enc_len ( const char *  src,
size_t  srclen 
)
static

Definition at line 631 of file encode.c.

632{
633 /*
634 * Unlike standard base64, base64url doesn't use padding characters when
635 * the input length is not divisible by 3
636 */
637 return (srclen + 2) / 3 * 4;
638}

◆ pg_base64url_encode()

static uint64 pg_base64url_encode ( const char *  src,
size_t  len,
char *  dst 
)
static

Definition at line 494 of file encode.c.

495{
496 return pg_base64_encode_internal(src, len, dst, true);
497}

References len, and pg_base64_encode_internal().

◆ pg_find_encoding()

static const struct pg_encoding * pg_find_encoding ( const char *  name)
static

Definition at line 868 of file encode.c.

869{
870 int i;
871
872 for (i = 0; enclist[i].name; i++)
873 if (pg_strcasecmp(enclist[i].name, name) == 0)
874 return &enclist[i].enc;
875
876 return NULL;
877}
static const struct @24 enclist[]
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36

References enclist, i, name, and pg_strcasecmp().

Referenced by binary_decode(), and binary_encode().

Variable Documentation

◆ _base64

const char _base64[]
static
Initial value:
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

Definition at line 402 of file encode.c.

Referenced by pg_base64_encode_internal().

◆ _base64url

const char _base64url[]
static
Initial value:
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

Definition at line 405 of file encode.c.

Referenced by pg_base64_encode_internal().

◆ b64lookup

const int8 b64lookup[128]
static
Initial value:
= {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
}

Definition at line 408 of file encode.c.

Referenced by pg_base64_decode_internal().

◆ enc

struct pg_encoding enc

Definition at line 831 of file encode.c.

Referenced by binary_decode(), and binary_encode().

◆ 

const struct { ... } enclist[]

Referenced by pg_find_encoding().

◆ hexlookup

const int8 hexlookup[128]
static
Initial value:
= {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
}

Definition at line 170 of file encode.c.

Referenced by get_hex().

◆ hextbl

const char hextbl[512]
static
Initial value:
=
"000102030405060708090a0b0c0d0e0f"
"101112131415161718191a1b1c1d1e1f"
"202122232425262728292a2b2c2d2e2f"
"303132333435363738393a3b3c3d3e3f"
"404142434445464748494a4b4c4d4e4f"
"505152535455565758595a5b5c5d5e5f"
"606162636465666768696a6b6c6d6e6f"
"707172737475767778797a7b7c7d7e7f"
"808182838485868788898a8b8c8d8e8f"
"909192939495969798999a9b9c9d9e9f"
"a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
"b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
"c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
"d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
"e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"

Definition at line 152 of file encode.c.

Referenced by hex_encode_scalar().

◆ name

const char* name

Definition at line 830 of file encode.c.

Referenced by binary_decode(), binary_encode(), and pg_find_encoding().