~ubuntu-branches/debian/sid/postgresql-9.3/sid

« back to all changes in this revision

Viewing changes to src/backend/utils/mb/mbutils.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 05:39:52 UTC
  • Revision ID: package-import@ubuntu.com-20130508053952-1j7uilp7mjtrvq8q
Tags: upstream-9.3~beta1
ImportĀ upstreamĀ versionĀ 9.3~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file contains public functions for conversion between
 
3
 * client encoding and server (database) encoding.
 
4
 *
 
5
 * Tatsuo Ishii
 
6
 *
 
7
 * src/backend/utils/mb/mbutils.c
 
8
 */
 
9
#include "postgres.h"
 
10
 
 
11
#include "access/xact.h"
 
12
#include "catalog/namespace.h"
 
13
#include "mb/pg_wchar.h"
 
14
#include "utils/builtins.h"
 
15
#include "utils/memutils.h"
 
16
#include "utils/syscache.h"
 
17
 
 
18
/*
 
19
 * When converting strings between different encodings, we assume that space
 
20
 * for converted result is 4-to-1 growth in the worst case. The rate for
 
21
 * currently supported encoding pairs are within 3 (SJIS JIS X0201 half width
 
22
 * kanna -> UTF8 is the worst case).  So "4" should be enough for the moment.
 
23
 *
 
24
 * Note that this is not the same as the maximum character width in any
 
25
 * particular encoding.
 
26
 */
 
27
#define MAX_CONVERSION_GROWTH  4
 
28
 
 
29
/*
 
30
 * We maintain a simple linked list caching the fmgr lookup info for the
 
31
 * currently selected conversion functions, as well as any that have been
 
32
 * selected previously in the current session.  (We remember previous
 
33
 * settings because we must be able to restore a previous setting during
 
34
 * transaction rollback, without doing any fresh catalog accesses.)
 
35
 *
 
36
 * Since we'll never release this data, we just keep it in TopMemoryContext.
 
37
 */
 
38
typedef struct ConvProcInfo
 
39
{
 
40
        int                     s_encoding;             /* server and client encoding IDs */
 
41
        int                     c_encoding;
 
42
        FmgrInfo        to_server_info; /* lookup info for conversion procs */
 
43
        FmgrInfo        to_client_info;
 
44
} ConvProcInfo;
 
45
 
 
46
static List *ConvProcList = NIL;        /* List of ConvProcInfo */
 
47
 
 
48
/*
 
49
 * These variables point to the currently active conversion functions,
 
50
 * or are NULL when no conversion is needed.
 
51
 */
 
52
static FmgrInfo *ToServerConvProc = NULL;
 
53
static FmgrInfo *ToClientConvProc = NULL;
 
54
 
 
55
/*
 
56
 * These variables track the currently selected FE and BE encodings.
 
57
 */
 
58
static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
 
59
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
 
60
static pg_enc2name *PlatformEncoding = NULL;
 
61
 
 
62
/*
 
63
 * During backend startup we can't set client encoding because we (a)
 
64
 * can't look up the conversion functions, and (b) may not know the database
 
65
 * encoding yet either.  So SetClientEncoding() just accepts anything and
 
66
 * remembers it for InitializeClientEncoding() to apply later.
 
67
 */
 
68
static bool backend_startup_complete = false;
 
69
static int      pending_client_encoding = PG_SQL_ASCII;
 
70
 
 
71
 
 
72
/* Internal functions */
 
73
static char *perform_default_encoding_conversion(const char *src,
 
74
                                                                        int len, bool is_client_to_server);
 
75
static int      cliplen(const char *str, int len, int limit);
 
76
 
 
77
 
 
78
/*
 
79
 * Prepare for a future call to SetClientEncoding.      Success should mean
 
80
 * that SetClientEncoding is guaranteed to succeed for this encoding request.
 
81
 *
 
82
 * (But note that success before backend_startup_complete does not guarantee
 
83
 * success after ...)
 
84
 *
 
85
 * Returns 0 if okay, -1 if not (bad encoding or can't support conversion)
 
86
 */
 
87
int
 
88
PrepareClientEncoding(int encoding)
 
89
{
 
90
        int                     current_server_encoding;
 
91
        ListCell   *lc;
 
92
 
 
93
        if (!PG_VALID_FE_ENCODING(encoding))
 
94
                return -1;
 
95
 
 
96
        /* Can't do anything during startup, per notes above */
 
97
        if (!backend_startup_complete)
 
98
                return 0;
 
99
 
 
100
        current_server_encoding = GetDatabaseEncoding();
 
101
 
 
102
        /*
 
103
         * Check for cases that require no conversion function.
 
104
         */
 
105
        if (current_server_encoding == encoding ||
 
106
                current_server_encoding == PG_SQL_ASCII ||
 
107
                encoding == PG_SQL_ASCII)
 
108
                return 0;
 
109
 
 
110
        if (IsTransactionState())
 
111
        {
 
112
                /*
 
113
                 * If we're in a live transaction, it's safe to access the catalogs,
 
114
                 * so look up the functions.  We repeat the lookup even if the info is
 
115
                 * already cached, so that we can react to changes in the contents of
 
116
                 * pg_conversion.
 
117
                 */
 
118
                Oid                     to_server_proc,
 
119
                                        to_client_proc;
 
120
                ConvProcInfo *convinfo;
 
121
                MemoryContext oldcontext;
 
122
 
 
123
                to_server_proc = FindDefaultConversionProc(encoding,
 
124
                                                                                                   current_server_encoding);
 
125
                if (!OidIsValid(to_server_proc))
 
126
                        return -1;
 
127
                to_client_proc = FindDefaultConversionProc(current_server_encoding,
 
128
                                                                                                   encoding);
 
129
                if (!OidIsValid(to_client_proc))
 
130
                        return -1;
 
131
 
 
132
                /*
 
133
                 * Load the fmgr info into TopMemoryContext (could still fail here)
 
134
                 */
 
135
                convinfo = (ConvProcInfo *) MemoryContextAlloc(TopMemoryContext,
 
136
                                                                                                           sizeof(ConvProcInfo));
 
137
                convinfo->s_encoding = current_server_encoding;
 
138
                convinfo->c_encoding = encoding;
 
139
                fmgr_info_cxt(to_server_proc, &convinfo->to_server_info,
 
140
                                          TopMemoryContext);
 
141
                fmgr_info_cxt(to_client_proc, &convinfo->to_client_info,
 
142
                                          TopMemoryContext);
 
143
 
 
144
                /* Attach new info to head of list */
 
145
                oldcontext = MemoryContextSwitchTo(TopMemoryContext);
 
146
                ConvProcList = lcons(convinfo, ConvProcList);
 
147
                MemoryContextSwitchTo(oldcontext);
 
148
 
 
149
                /*
 
150
                 * We cannot yet remove any older entry for the same encoding pair,
 
151
                 * since it could still be in use.      SetClientEncoding will clean up.
 
152
                 */
 
153
 
 
154
                return 0;                               /* success */
 
155
        }
 
156
        else
 
157
        {
 
158
                /*
 
159
                 * If we're not in a live transaction, the only thing we can do is
 
160
                 * restore a previous setting using the cache.  This covers all
 
161
                 * transaction-rollback cases.  The only case it might not work for is
 
162
                 * trying to change client_encoding on the fly by editing
 
163
                 * postgresql.conf and SIGHUP'ing.  Which would probably be a stupid
 
164
                 * thing to do anyway.
 
165
                 */
 
166
                foreach(lc, ConvProcList)
 
167
                {
 
168
                        ConvProcInfo *oldinfo = (ConvProcInfo *) lfirst(lc);
 
169
 
 
170
                        if (oldinfo->s_encoding == current_server_encoding &&
 
171
                                oldinfo->c_encoding == encoding)
 
172
                                return 0;
 
173
                }
 
174
 
 
175
                return -1;                              /* it's not cached, so fail */
 
176
        }
 
177
}
 
178
 
 
179
/*
 
180
 * Set the active client encoding and set up the conversion-function pointers.
 
181
 * PrepareClientEncoding should have been called previously for this encoding.
 
182
 *
 
183
 * Returns 0 if okay, -1 if not (bad encoding or can't support conversion)
 
184
 */
 
185
int
 
186
SetClientEncoding(int encoding)
 
187
{
 
188
        int                     current_server_encoding;
 
189
        bool            found;
 
190
        ListCell   *lc;
 
191
        ListCell   *prev;
 
192
        ListCell   *next;
 
193
 
 
194
        if (!PG_VALID_FE_ENCODING(encoding))
 
195
                return -1;
 
196
 
 
197
        /* Can't do anything during startup, per notes above */
 
198
        if (!backend_startup_complete)
 
199
        {
 
200
                pending_client_encoding = encoding;
 
201
                return 0;
 
202
        }
 
203
 
 
204
        current_server_encoding = GetDatabaseEncoding();
 
205
 
 
206
        /*
 
207
         * Check for cases that require no conversion function.
 
208
         */
 
209
        if (current_server_encoding == encoding ||
 
210
                current_server_encoding == PG_SQL_ASCII ||
 
211
                encoding == PG_SQL_ASCII)
 
212
        {
 
213
                ClientEncoding = &pg_enc2name_tbl[encoding];
 
214
                ToServerConvProc = NULL;
 
215
                ToClientConvProc = NULL;
 
216
                return 0;
 
217
        }
 
218
 
 
219
        /*
 
220
         * Search the cache for the entry previously prepared by
 
221
         * PrepareClientEncoding; if there isn't one, we lose.  While at it,
 
222
         * release any duplicate entries so that repeated Prepare/Set cycles don't
 
223
         * leak memory.
 
224
         */
 
225
        found = false;
 
226
        prev = NULL;
 
227
        for (lc = list_head(ConvProcList); lc; lc = next)
 
228
        {
 
229
                ConvProcInfo *convinfo = (ConvProcInfo *) lfirst(lc);
 
230
 
 
231
                next = lnext(lc);
 
232
 
 
233
                if (convinfo->s_encoding == current_server_encoding &&
 
234
                        convinfo->c_encoding == encoding)
 
235
                {
 
236
                        if (!found)
 
237
                        {
 
238
                                /* Found newest entry, so set up */
 
239
                                ClientEncoding = &pg_enc2name_tbl[encoding];
 
240
                                ToServerConvProc = &convinfo->to_server_info;
 
241
                                ToClientConvProc = &convinfo->to_client_info;
 
242
                                found = true;
 
243
                        }
 
244
                        else
 
245
                        {
 
246
                                /* Duplicate entry, release it */
 
247
                                ConvProcList = list_delete_cell(ConvProcList, lc, prev);
 
248
                                pfree(convinfo);
 
249
                                continue;               /* prev mustn't advance */
 
250
                        }
 
251
                }
 
252
 
 
253
                prev = lc;
 
254
        }
 
255
 
 
256
        if (found)
 
257
                return 0;                               /* success */
 
258
        else
 
259
                return -1;                              /* it's not cached, so fail */
 
260
}
 
261
 
 
262
/*
 
263
 * Initialize client encoding conversions.
 
264
 *              Called from InitPostgres() once during backend startup.
 
265
 */
 
266
void
 
267
InitializeClientEncoding(void)
 
268
{
 
269
        Assert(!backend_startup_complete);
 
270
        backend_startup_complete = true;
 
271
 
 
272
        if (PrepareClientEncoding(pending_client_encoding) < 0 ||
 
273
                SetClientEncoding(pending_client_encoding) < 0)
 
274
        {
 
275
                /*
 
276
                 * Oops, the requested conversion is not available. We couldn't fail
 
277
                 * before, but we can now.
 
278
                 */
 
279
                ereport(FATAL,
 
280
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
281
                                 errmsg("conversion between %s and %s is not supported",
 
282
                                                pg_enc2name_tbl[pending_client_encoding].name,
 
283
                                                GetDatabaseEncodingName())));
 
284
        }
 
285
}
 
286
 
 
287
/*
 
288
 * returns the current client encoding
 
289
 */
 
290
int
 
291
pg_get_client_encoding(void)
 
292
{
 
293
        Assert(ClientEncoding);
 
294
        return ClientEncoding->encoding;
 
295
}
 
296
 
 
297
/*
 
298
 * returns the current client encoding name
 
299
 */
 
300
const char *
 
301
pg_get_client_encoding_name(void)
 
302
{
 
303
        Assert(ClientEncoding);
 
304
        return ClientEncoding->name;
 
305
}
 
306
 
 
307
/*
 
308
 * Apply encoding conversion on src and return it. The encoding
 
309
 * conversion function is chosen from the pg_conversion system catalog
 
310
 * marked as "default". If it is not found in the schema search path,
 
311
 * it's taken from pg_catalog schema. If it even is not in the schema,
 
312
 * warn and return src.
 
313
 *
 
314
 * If conversion occurs, a palloc'd null-terminated string is returned.
 
315
 * In the case of no conversion, src is returned.
 
316
 *
 
317
 * CAUTION: although the presence of a length argument means that callers
 
318
 * can pass non-null-terminated strings, care is required because the same
 
319
 * string will be passed back if no conversion occurs.  Such callers *must*
 
320
 * check whether result == src and handle that case differently.
 
321
 *
 
322
 * Note: we try to avoid raising error, since that could get us into
 
323
 * infinite recursion when this function is invoked during error message
 
324
 * sending.  It should be OK to raise error for overlength strings though,
 
325
 * since the recursion will come with a shorter message.
 
326
 */
 
327
unsigned char *
 
328
pg_do_encoding_conversion(unsigned char *src, int len,
 
329
                                                  int src_encoding, int dest_encoding)
 
330
{
 
331
        unsigned char *result;
 
332
        Oid                     proc;
 
333
 
 
334
        if (!IsTransactionState())
 
335
                return src;
 
336
 
 
337
        if (src_encoding == dest_encoding)
 
338
                return src;
 
339
 
 
340
        if (src_encoding == PG_SQL_ASCII || dest_encoding == PG_SQL_ASCII)
 
341
                return src;
 
342
 
 
343
        if (len <= 0)
 
344
                return src;
 
345
 
 
346
        proc = FindDefaultConversionProc(src_encoding, dest_encoding);
 
347
        if (!OidIsValid(proc))
 
348
        {
 
349
                ereport(LOG,
 
350
                                (errcode(ERRCODE_UNDEFINED_FUNCTION),
 
351
                                 errmsg("default conversion function for encoding \"%s\" to \"%s\" does not exist",
 
352
                                                pg_encoding_to_char(src_encoding),
 
353
                                                pg_encoding_to_char(dest_encoding))));
 
354
                return src;
 
355
        }
 
356
 
 
357
        /*
 
358
         * XXX we should avoid throwing errors in OidFunctionCall. Otherwise we
 
359
         * are going into infinite loop!  So we have to make sure that the
 
360
         * function exists before calling OidFunctionCall.
 
361
         */
 
362
        if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(proc)))
 
363
        {
 
364
                elog(LOG, "cache lookup failed for function %u", proc);
 
365
                return src;
 
366
        }
 
367
 
 
368
        /*
 
369
         * Allocate space for conversion result, being wary of integer overflow
 
370
         */
 
371
        if ((Size) len >= (MaxAllocSize / (Size) MAX_CONVERSION_GROWTH))
 
372
                ereport(ERROR,
 
373
                                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
 
374
                                 errmsg("out of memory"),
 
375
                 errdetail("String of %d bytes is too long for encoding conversion.",
 
376
                                   len)));
 
377
 
 
378
        result = palloc(len * MAX_CONVERSION_GROWTH + 1);
 
379
 
 
380
        OidFunctionCall5(proc,
 
381
                                         Int32GetDatum(src_encoding),
 
382
                                         Int32GetDatum(dest_encoding),
 
383
                                         CStringGetDatum(src),
 
384
                                         CStringGetDatum(result),
 
385
                                         Int32GetDatum(len));
 
386
        return result;
 
387
}
 
388
 
 
389
/*
 
390
 * Convert string using encoding_name. The source
 
391
 * encoding is the DB encoding.
 
392
 *
 
393
 * BYTEA convert_to(TEXT string, NAME encoding_name) */
 
394
Datum
 
395
pg_convert_to(PG_FUNCTION_ARGS)
 
396
{
 
397
        Datum           string = PG_GETARG_DATUM(0);
 
398
        Datum           dest_encoding_name = PG_GETARG_DATUM(1);
 
399
        Datum           src_encoding_name = DirectFunctionCall1(namein,
 
400
                                                                        CStringGetDatum(DatabaseEncoding->name));
 
401
        Datum           result;
 
402
 
 
403
        /*
 
404
         * pg_convert expects a bytea as its first argument. We're passing it a
 
405
         * text argument here, relying on the fact that they are both in fact
 
406
         * varlena types, and thus structurally identical.
 
407
         */
 
408
        result = DirectFunctionCall3(pg_convert, string,
 
409
                                                                 src_encoding_name, dest_encoding_name);
 
410
 
 
411
        PG_RETURN_DATUM(result);
 
412
}
 
413
 
 
414
/*
 
415
 * Convert string using encoding_name. The destination
 
416
 * encoding is the DB encoding.
 
417
 *
 
418
 * TEXT convert_from(BYTEA string, NAME encoding_name) */
 
419
Datum
 
420
pg_convert_from(PG_FUNCTION_ARGS)
 
421
{
 
422
        Datum           string = PG_GETARG_DATUM(0);
 
423
        Datum           src_encoding_name = PG_GETARG_DATUM(1);
 
424
        Datum           dest_encoding_name = DirectFunctionCall1(namein,
 
425
                                                                        CStringGetDatum(DatabaseEncoding->name));
 
426
        Datum           result;
 
427
 
 
428
        result = DirectFunctionCall3(pg_convert, string,
 
429
                                                                 src_encoding_name, dest_encoding_name);
 
430
 
 
431
        /*
 
432
         * pg_convert returns a bytea, which we in turn return as text, relying on
 
433
         * the fact that they are both in fact varlena types, and thus
 
434
         * structurally identical. Although not all bytea values are valid text,
 
435
         * in this case it will be because we've told pg_convert to return one
 
436
         * that is valid as text in the current database encoding.
 
437
         */
 
438
        PG_RETURN_DATUM(result);
 
439
}
 
440
 
 
441
/*
 
442
 * Convert string using encoding_names.
 
443
 *
 
444
 * BYTEA convert(BYTEA string, NAME src_encoding_name, NAME dest_encoding_name)
 
445
 */
 
446
Datum
 
447
pg_convert(PG_FUNCTION_ARGS)
 
448
{
 
449
        bytea      *string = PG_GETARG_BYTEA_PP(0);
 
450
        char       *src_encoding_name = NameStr(*PG_GETARG_NAME(1));
 
451
        int                     src_encoding = pg_char_to_encoding(src_encoding_name);
 
452
        char       *dest_encoding_name = NameStr(*PG_GETARG_NAME(2));
 
453
        int                     dest_encoding = pg_char_to_encoding(dest_encoding_name);
 
454
        const char *src_str;
 
455
        char       *dest_str;
 
456
        bytea      *retval;
 
457
        int                     len;
 
458
 
 
459
        if (src_encoding < 0)
 
460
                ereport(ERROR,
 
461
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 
462
                                 errmsg("invalid source encoding name \"%s\"",
 
463
                                                src_encoding_name)));
 
464
        if (dest_encoding < 0)
 
465
                ereport(ERROR,
 
466
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 
467
                                 errmsg("invalid destination encoding name \"%s\"",
 
468
                                                dest_encoding_name)));
 
469
 
 
470
        /* make sure that source string is valid */
 
471
        len = VARSIZE_ANY_EXHDR(string);
 
472
        src_str = VARDATA_ANY(string);
 
473
        pg_verify_mbstr_len(src_encoding, src_str, len, false);
 
474
 
 
475
        dest_str = (char *) pg_do_encoding_conversion(
 
476
                                (unsigned char *) src_str, len, src_encoding, dest_encoding);
 
477
        if (dest_str != src_str)
 
478
                len = strlen(dest_str);
 
479
 
 
480
        /*
 
481
         * build bytea data type structure.
 
482
         */
 
483
        retval = (bytea *) palloc(len + VARHDRSZ);
 
484
        SET_VARSIZE(retval, len + VARHDRSZ);
 
485
        memcpy(VARDATA(retval), dest_str, len);
 
486
 
 
487
        if (dest_str != src_str)
 
488
                pfree(dest_str);
 
489
 
 
490
        /* free memory if allocated by the toaster */
 
491
        PG_FREE_IF_COPY(string, 0);
 
492
 
 
493
        PG_RETURN_BYTEA_P(retval);
 
494
}
 
495
 
 
496
/*
 
497
 * get the length of the string considered as text in the specified
 
498
 * encoding. Raises an error if the data is not valid in that
 
499
 * encoding.
 
500
 *
 
501
 * INT4 length (BYTEA string, NAME src_encoding_name)
 
502
 */
 
503
Datum
 
504
length_in_encoding(PG_FUNCTION_ARGS)
 
505
{
 
506
        bytea      *string = PG_GETARG_BYTEA_P(0);
 
507
        char       *src_encoding_name = NameStr(*PG_GETARG_NAME(1));
 
508
        int                     src_encoding = pg_char_to_encoding(src_encoding_name);
 
509
        int                     len = VARSIZE(string) - VARHDRSZ;
 
510
        int                     retval;
 
511
 
 
512
        if (src_encoding < 0)
 
513
                ereport(ERROR,
 
514
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 
515
                                 errmsg("invalid encoding name \"%s\"",
 
516
                                                src_encoding_name)));
 
517
 
 
518
        retval = pg_verify_mbstr_len(src_encoding, VARDATA(string), len, false);
 
519
        PG_RETURN_INT32(retval);
 
520
 
 
521
}
 
522
 
 
523
Datum
 
524
pg_encoding_max_length_sql(PG_FUNCTION_ARGS)
 
525
{
 
526
        int                     encoding = PG_GETARG_INT32(0);
 
527
 
 
528
        if (PG_VALID_ENCODING(encoding))
 
529
                PG_RETURN_INT32(pg_wchar_table[encoding].maxmblen);
 
530
        else
 
531
                PG_RETURN_NULL();
 
532
}
 
533
 
 
534
/*
 
535
 * convert client encoding to server encoding.
 
536
 */
 
537
char *
 
538
pg_client_to_server(const char *s, int len)
 
539
{
 
540
        Assert(ClientEncoding);
 
541
 
 
542
        return pg_any_to_server(s, len, ClientEncoding->encoding);
 
543
}
 
544
 
 
545
/*
 
546
 * convert any encoding to server encoding.
 
547
 */
 
548
char *
 
549
pg_any_to_server(const char *s, int len, int encoding)
 
550
{
 
551
        Assert(DatabaseEncoding);
 
552
        Assert(ClientEncoding);
 
553
 
 
554
        if (len <= 0)
 
555
                return (char *) s;
 
556
 
 
557
        if (encoding == DatabaseEncoding->encoding ||
 
558
                encoding == PG_SQL_ASCII)
 
559
        {
 
560
                /*
 
561
                 * No conversion is needed, but we must still validate the data.
 
562
                 */
 
563
                (void) pg_verify_mbstr(DatabaseEncoding->encoding, s, len, false);
 
564
                return (char *) s;
 
565
        }
 
566
 
 
567
        if (DatabaseEncoding->encoding == PG_SQL_ASCII)
 
568
        {
 
569
                /*
 
570
                 * No conversion is possible, but we must still validate the data,
 
571
                 * because the client-side code might have done string escaping using
 
572
                 * the selected client_encoding.  If the client encoding is ASCII-safe
 
573
                 * then we just do a straight validation under that encoding.  For an
 
574
                 * ASCII-unsafe encoding we have a problem: we dare not pass such data
 
575
                 * to the parser but we have no way to convert it.      We compromise by
 
576
                 * rejecting the data if it contains any non-ASCII characters.
 
577
                 */
 
578
                if (PG_VALID_BE_ENCODING(encoding))
 
579
                        (void) pg_verify_mbstr(encoding, s, len, false);
 
580
                else
 
581
                {
 
582
                        int                     i;
 
583
 
 
584
                        for (i = 0; i < len; i++)
 
585
                        {
 
586
                                if (s[i] == '\0' || IS_HIGHBIT_SET(s[i]))
 
587
                                        ereport(ERROR,
 
588
                                                        (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
 
589
                                         errmsg("invalid byte value for encoding \"%s\": 0x%02x",
 
590
                                                        pg_enc2name_tbl[PG_SQL_ASCII].name,
 
591
                                                        (unsigned char) s[i])));
 
592
                        }
 
593
                }
 
594
                return (char *) s;
 
595
        }
 
596
 
 
597
        if (ClientEncoding->encoding == encoding)
 
598
                return perform_default_encoding_conversion(s, len, true);
 
599
        else
 
600
                return (char *) pg_do_encoding_conversion(
 
601
                         (unsigned char *) s, len, encoding, DatabaseEncoding->encoding);
 
602
}
 
603
 
 
604
/*
 
605
 * convert server encoding to client encoding.
 
606
 */
 
607
char *
 
608
pg_server_to_client(const char *s, int len)
 
609
{
 
610
        Assert(ClientEncoding);
 
611
 
 
612
        return pg_server_to_any(s, len, ClientEncoding->encoding);
 
613
}
 
614
 
 
615
/*
 
616
 * convert server encoding to any encoding.
 
617
 */
 
618
char *
 
619
pg_server_to_any(const char *s, int len, int encoding)
 
620
{
 
621
        Assert(DatabaseEncoding);
 
622
        Assert(ClientEncoding);
 
623
 
 
624
        if (len <= 0)
 
625
                return (char *) s;
 
626
 
 
627
        if (encoding == DatabaseEncoding->encoding ||
 
628
                encoding == PG_SQL_ASCII ||
 
629
                DatabaseEncoding->encoding == PG_SQL_ASCII)
 
630
                return (char *) s;              /* assume data is valid */
 
631
 
 
632
        if (ClientEncoding->encoding == encoding)
 
633
                return perform_default_encoding_conversion(s, len, false);
 
634
        else
 
635
                return (char *) pg_do_encoding_conversion(
 
636
                         (unsigned char *) s, len, DatabaseEncoding->encoding, encoding);
 
637
}
 
638
 
 
639
/*
 
640
 *      Perform default encoding conversion using cached FmgrInfo. Since
 
641
 *      this function does not access database at all, it is safe to call
 
642
 *      outside transactions.  If the conversion has not been set up by
 
643
 *      SetClientEncoding(), no conversion is performed.
 
644
 */
 
645
static char *
 
646
perform_default_encoding_conversion(const char *src, int len, bool is_client_to_server)
 
647
{
 
648
        char       *result;
 
649
        int                     src_encoding,
 
650
                                dest_encoding;
 
651
        FmgrInfo   *flinfo;
 
652
 
 
653
        if (is_client_to_server)
 
654
        {
 
655
                src_encoding = ClientEncoding->encoding;
 
656
                dest_encoding = DatabaseEncoding->encoding;
 
657
                flinfo = ToServerConvProc;
 
658
        }
 
659
        else
 
660
        {
 
661
                src_encoding = DatabaseEncoding->encoding;
 
662
                dest_encoding = ClientEncoding->encoding;
 
663
                flinfo = ToClientConvProc;
 
664
        }
 
665
 
 
666
        if (flinfo == NULL)
 
667
                return (char *) src;
 
668
 
 
669
        /*
 
670
         * Allocate space for conversion result, being wary of integer overflow
 
671
         */
 
672
        if ((Size) len >= (MaxAllocSize / (Size) MAX_CONVERSION_GROWTH))
 
673
                ereport(ERROR,
 
674
                                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
 
675
                                 errmsg("out of memory"),
 
676
                 errdetail("String of %d bytes is too long for encoding conversion.",
 
677
                                   len)));
 
678
 
 
679
        result = palloc(len * MAX_CONVERSION_GROWTH + 1);
 
680
 
 
681
        FunctionCall5(flinfo,
 
682
                                  Int32GetDatum(src_encoding),
 
683
                                  Int32GetDatum(dest_encoding),
 
684
                                  CStringGetDatum(src),
 
685
                                  CStringGetDatum(result),
 
686
                                  Int32GetDatum(len));
 
687
        return result;
 
688
}
 
689
 
 
690
 
 
691
/* convert a multibyte string to a wchar */
 
692
int
 
693
pg_mb2wchar(const char *from, pg_wchar *to)
 
694
{
 
695
        return (*pg_wchar_table[DatabaseEncoding->encoding].mb2wchar_with_len) ((const unsigned char *) from, to, strlen(from));
 
696
}
 
697
 
 
698
/* convert a multibyte string to a wchar with a limited length */
 
699
int
 
700
pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
 
701
{
 
702
        return (*pg_wchar_table[DatabaseEncoding->encoding].mb2wchar_with_len) ((const unsigned char *) from, to, len);
 
703
}
 
704
 
 
705
/* same, with any encoding */
 
706
int
 
707
pg_encoding_mb2wchar_with_len(int encoding,
 
708
                                                          const char *from, pg_wchar *to, int len)
 
709
{
 
710
        return (*pg_wchar_table[encoding].mb2wchar_with_len) ((const unsigned char *) from, to, len);
 
711
}
 
712
 
 
713
/* convert a wchar string to a multibyte */
 
714
int
 
715
pg_wchar2mb(const pg_wchar *from, char *to)
 
716
{
 
717
        return (*pg_wchar_table[DatabaseEncoding->encoding].wchar2mb_with_len) (from, (unsigned char *)to, pg_wchar_strlen(from));
 
718
}
 
719
 
 
720
/* convert a wchar string to a multibyte with a limited length */
 
721
int
 
722
pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)
 
723
{
 
724
        return (*pg_wchar_table[DatabaseEncoding->encoding].wchar2mb_with_len) (from, (unsigned char *)to, len);
 
725
}
 
726
 
 
727
/* same, with any encoding */
 
728
int
 
729
pg_encoding_wchar2mb_with_len(int encoding,
 
730
                                                          const pg_wchar *from, char *to, int len)
 
731
{
 
732
        return (*pg_wchar_table[encoding].wchar2mb_with_len) (from, (unsigned char *)to, len);
 
733
}
 
734
 
 
735
/* returns the byte length of a multibyte character */
 
736
int
 
737
pg_mblen(const char *mbstr)
 
738
{
 
739
        return ((*pg_wchar_table[DatabaseEncoding->encoding].mblen) ((const unsigned char *) mbstr));
 
740
}
 
741
 
 
742
/* returns the display length of a multibyte character */
 
743
int
 
744
pg_dsplen(const char *mbstr)
 
745
{
 
746
        return ((*pg_wchar_table[DatabaseEncoding->encoding].dsplen) ((const unsigned char *) mbstr));
 
747
}
 
748
 
 
749
/* returns the length (counted in wchars) of a multibyte string */
 
750
int
 
751
pg_mbstrlen(const char *mbstr)
 
752
{
 
753
        int                     len = 0;
 
754
 
 
755
        /* optimization for single byte encoding */
 
756
        if (pg_database_encoding_max_length() == 1)
 
757
                return strlen(mbstr);
 
758
 
 
759
        while (*mbstr)
 
760
        {
 
761
                mbstr += pg_mblen(mbstr);
 
762
                len++;
 
763
        }
 
764
        return len;
 
765
}
 
766
 
 
767
/* returns the length (counted in wchars) of a multibyte string
 
768
 * (not necessarily NULL terminated)
 
769
 */
 
770
int
 
771
pg_mbstrlen_with_len(const char *mbstr, int limit)
 
772
{
 
773
        int                     len = 0;
 
774
 
 
775
        /* optimization for single byte encoding */
 
776
        if (pg_database_encoding_max_length() == 1)
 
777
                return limit;
 
778
 
 
779
        while (limit > 0 && *mbstr)
 
780
        {
 
781
                int                     l = pg_mblen(mbstr);
 
782
 
 
783
                limit -= l;
 
784
                mbstr += l;
 
785
                len++;
 
786
        }
 
787
        return len;
 
788
}
 
789
 
 
790
/*
 
791
 * returns the byte length of a multibyte string
 
792
 * (not necessarily NULL terminated)
 
793
 * that is no longer than limit.
 
794
 * this function does not break multibyte character boundary.
 
795
 */
 
796
int
 
797
pg_mbcliplen(const char *mbstr, int len, int limit)
 
798
{
 
799
        return pg_encoding_mbcliplen(DatabaseEncoding->encoding, mbstr,
 
800
                                                                 len, limit);
 
801
}
 
802
 
 
803
/*
 
804
 * pg_mbcliplen with specified encoding
 
805
 */
 
806
int
 
807
pg_encoding_mbcliplen(int encoding, const char *mbstr,
 
808
                                          int len, int limit)
 
809
{
 
810
        mblen_converter mblen_fn;
 
811
        int                     clen = 0;
 
812
        int                     l;
 
813
 
 
814
        /* optimization for single byte encoding */
 
815
        if (pg_encoding_max_length(encoding) == 1)
 
816
                return cliplen(mbstr, len, limit);
 
817
 
 
818
        mblen_fn = pg_wchar_table[encoding].mblen;
 
819
 
 
820
        while (len > 0 && *mbstr)
 
821
        {
 
822
                l = (*mblen_fn) ((const unsigned char *) mbstr);
 
823
                if ((clen + l) > limit)
 
824
                        break;
 
825
                clen += l;
 
826
                if (clen == limit)
 
827
                        break;
 
828
                len -= l;
 
829
                mbstr += l;
 
830
        }
 
831
        return clen;
 
832
}
 
833
 
 
834
/*
 
835
 * Similar to pg_mbcliplen except the limit parameter specifies the
 
836
 * character length, not the byte length.
 
837
 */
 
838
int
 
839
pg_mbcharcliplen(const char *mbstr, int len, int limit)
 
840
{
 
841
        int                     clen = 0;
 
842
        int                     nch = 0;
 
843
        int                     l;
 
844
 
 
845
        /* optimization for single byte encoding */
 
846
        if (pg_database_encoding_max_length() == 1)
 
847
                return cliplen(mbstr, len, limit);
 
848
 
 
849
        while (len > 0 && *mbstr)
 
850
        {
 
851
                l = pg_mblen(mbstr);
 
852
                nch++;
 
853
                if (nch > limit)
 
854
                        break;
 
855
                clen += l;
 
856
                len -= l;
 
857
                mbstr += l;
 
858
        }
 
859
        return clen;
 
860
}
 
861
 
 
862
/* mbcliplen for any single-byte encoding */
 
863
static int
 
864
cliplen(const char *str, int len, int limit)
 
865
{
 
866
        int                     l = 0;
 
867
 
 
868
        len = Min(len, limit);
 
869
        while (l < len && str[l])
 
870
                l++;
 
871
        return l;
 
872
}
 
873
 
 
874
void
 
875
SetDatabaseEncoding(int encoding)
 
876
{
 
877
        if (!PG_VALID_BE_ENCODING(encoding))
 
878
                elog(ERROR, "invalid database encoding: %d", encoding);
 
879
 
 
880
        DatabaseEncoding = &pg_enc2name_tbl[encoding];
 
881
        Assert(DatabaseEncoding->encoding == encoding);
 
882
}
 
883
 
 
884
/*
 
885
 * Bind gettext to the codeset equivalent with the database encoding.
 
886
 */
 
887
void
 
888
pg_bind_textdomain_codeset(const char *domainname)
 
889
{
 
890
#if defined(ENABLE_NLS)
 
891
        int                     encoding = GetDatabaseEncoding();
 
892
        int                     i;
 
893
 
 
894
        /*
 
895
         * gettext() uses the codeset specified by LC_CTYPE by default, so if that
 
896
         * matches the database encoding we don't need to do anything. In CREATE
 
897
         * DATABASE, we enforce or trust that the locale's codeset matches
 
898
         * database encoding, except for the C locale. In C locale, we bind
 
899
         * gettext() explicitly to the right codeset.
 
900
         *
 
901
         * On Windows, though, gettext() tends to get confused so we always bind
 
902
         * it.
 
903
         */
 
904
#ifndef WIN32
 
905
        const char *ctype = setlocale(LC_CTYPE, NULL);
 
906
 
 
907
        if (pg_strcasecmp(ctype, "C") != 0 && pg_strcasecmp(ctype, "POSIX") != 0)
 
908
                return;
 
909
#endif
 
910
 
 
911
        for (i = 0; pg_enc2gettext_tbl[i].name != NULL; i++)
 
912
        {
 
913
                if (pg_enc2gettext_tbl[i].encoding == encoding)
 
914
                {
 
915
                        if (bind_textdomain_codeset(domainname,
 
916
                                                                                pg_enc2gettext_tbl[i].name) == NULL)
 
917
                                elog(LOG, "bind_textdomain_codeset failed");
 
918
                        break;
 
919
                }
 
920
        }
 
921
#endif
 
922
}
 
923
 
 
924
int
 
925
GetDatabaseEncoding(void)
 
926
{
 
927
        Assert(DatabaseEncoding);
 
928
        return DatabaseEncoding->encoding;
 
929
}
 
930
 
 
931
const char *
 
932
GetDatabaseEncodingName(void)
 
933
{
 
934
        Assert(DatabaseEncoding);
 
935
        return DatabaseEncoding->name;
 
936
}
 
937
 
 
938
Datum
 
939
getdatabaseencoding(PG_FUNCTION_ARGS)
 
940
{
 
941
        Assert(DatabaseEncoding);
 
942
        return DirectFunctionCall1(namein, CStringGetDatum(DatabaseEncoding->name));
 
943
}
 
944
 
 
945
Datum
 
946
pg_client_encoding(PG_FUNCTION_ARGS)
 
947
{
 
948
        Assert(ClientEncoding);
 
949
        return DirectFunctionCall1(namein, CStringGetDatum(ClientEncoding->name));
 
950
}
 
951
 
 
952
int
 
953
GetPlatformEncoding(void)
 
954
{
 
955
        if (PlatformEncoding == NULL)
 
956
        {
 
957
                /* try to determine encoding of server's environment locale */
 
958
                int                     encoding = pg_get_encoding_from_locale("", true);
 
959
 
 
960
                if (encoding < 0)
 
961
                        encoding = PG_SQL_ASCII;
 
962
                PlatformEncoding = &pg_enc2name_tbl[encoding];
 
963
        }
 
964
        return PlatformEncoding->encoding;
 
965
}
 
966
 
 
967
#ifdef WIN32
 
968
 
 
969
/*
 
970
 * Result is palloc'ed null-terminated utf16 string. The character length
 
971
 * is also passed to utf16len if not null. Returns NULL iff failed.
 
972
 */
 
973
WCHAR *
 
974
pgwin32_toUTF16(const char *str, int len, int *utf16len)
 
975
{
 
976
        WCHAR      *utf16;
 
977
        int                     dstlen;
 
978
        UINT            codepage;
 
979
 
 
980
        codepage = pg_enc2name_tbl[GetDatabaseEncoding()].codepage;
 
981
 
 
982
        /*
 
983
         * Use MultiByteToWideChar directly if there is a corresponding codepage,
 
984
         * or double conversion through UTF8 if not.
 
985
         */
 
986
        if (codepage != 0)
 
987
        {
 
988
                utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
 
989
                dstlen = MultiByteToWideChar(codepage, 0, str, len, utf16, len);
 
990
                utf16[dstlen] = (WCHAR) 0;
 
991
        }
 
992
        else
 
993
        {
 
994
                char       *utf8;
 
995
 
 
996
                utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
 
997
                                                                                len, GetDatabaseEncoding(), PG_UTF8);
 
998
                if (utf8 != str)
 
999
                        len = strlen(utf8);
 
1000
 
 
1001
                utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
 
1002
                dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len);
 
1003
                utf16[dstlen] = (WCHAR) 0;
 
1004
 
 
1005
                if (utf8 != str)
 
1006
                        pfree(utf8);
 
1007
        }
 
1008
 
 
1009
        if (dstlen == 0 && len > 0)
 
1010
        {
 
1011
                pfree(utf16);
 
1012
                return NULL;                    /* error */
 
1013
        }
 
1014
 
 
1015
        if (utf16len)
 
1016
                *utf16len = dstlen;
 
1017
        return utf16;
 
1018
}
 
1019
 
 
1020
#endif