PostgreSQL Source Code  git master
ascii.h File Reference
#include "port/simd.h"
Include dependency graph for ascii.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void ascii_safe_strlcpy (char *dest, const char *src, size_t destsiz)
 
static bool is_valid_ascii (const unsigned char *s, int len)
 

Function Documentation

◆ ascii_safe_strlcpy()

void ascii_safe_strlcpy ( char *  dest,
const char *  src,
size_t  destsiz 
)

Definition at line 174 of file ascii.c.

175 {
176  if (destsiz == 0) /* corner case: no room for trailing nul */
177  return;
178 
179  while (--destsiz > 0)
180  {
181  /* use unsigned char here to avoid compiler warning */
182  unsigned char ch = *src++;
183 
184  if (ch == '\0')
185  break;
186  /* Keep printable ASCII characters */
187  if (32 <= ch && ch <= 127)
188  *dest = ch;
189  /* White-space is also OK */
190  else if (ch == '\n' || ch == '\r' || ch == '\t')
191  *dest = ch;
192  /* Everything else is replaced with '?' */
193  else
194  *dest = '?';
195  dest++;
196  }
197 
198  *dest = '\0';
199 }

References generate_unaccent_rules::dest.

Referenced by BackgroundWorkerStateChange(), and pgstat_get_crashed_backend_activity().

◆ is_valid_ascii()

static bool is_valid_ascii ( const unsigned char *  s,
int  len 
)
inlinestatic

Definition at line 25 of file ascii.h.

26 {
27  const unsigned char *const s_end = s + len;
28  Vector8 chunk;
29  Vector8 highbit_cum = vector8_broadcast(0);
30 #ifdef USE_NO_SIMD
31  Vector8 zero_cum = vector8_broadcast(0x80);
32 #endif
33 
34  Assert(len % sizeof(chunk) == 0);
35 
36  while (s < s_end)
37  {
38  vector8_load(&chunk, s);
39 
40  /* Capture any zero bytes in this chunk. */
41 #ifdef USE_NO_SIMD
42 
43  /*
44  * First, add 0x7f to each byte. This sets the high bit in each byte,
45  * unless it was a zero. If any resulting high bits are zero, the
46  * corresponding high bits in the zero accumulator will be cleared.
47  *
48  * If none of the bytes in the chunk had the high bit set, the max
49  * value each byte can have after the addition is 0x7f + 0x7f = 0xfe,
50  * and we don't need to worry about carrying over to the next byte. If
51  * any input bytes did have the high bit set, it doesn't matter
52  * because we check for those separately.
53  */
54  zero_cum &= (chunk + vector8_broadcast(0x7F));
55 #else
56 
57  /*
58  * Set all bits in each lane of the highbit accumulator where input
59  * bytes are zero.
60  */
61  highbit_cum = vector8_or(highbit_cum,
62  vector8_eq(chunk, vector8_broadcast(0)));
63 #endif
64 
65  /* Capture all set bits in this chunk. */
66  highbit_cum = vector8_or(highbit_cum, chunk);
67 
68  s += sizeof(chunk);
69  }
70 
71  /* Check if any high bits in the high bit accumulator got set. */
72  if (vector8_is_highbit_set(highbit_cum))
73  return false;
74 
75 #ifdef USE_NO_SIMD
76  /* Check if any high bits in the zero accumulator got cleared. */
77  if (zero_cum != vector8_broadcast(0x80))
78  return false;
79 #endif
80 
81  return true;
82 }
#define Assert(condition)
Definition: c.h:858
uint64 chunk
const void size_t len
static Vector8 vector8_broadcast(const uint8 c)
Definition: simd.h:135
static void vector8_load(Vector8 *v, const uint8 *s)
Definition: simd.h:108
static Vector8 vector8_or(const Vector8 v1, const Vector8 v2)
Definition: simd.h:338
uint64 Vector8
Definition: simd.h:60
static bool vector8_is_highbit_set(const Vector8 v)
Definition: simd.h:271

References Assert, chunk, len, vector8_broadcast(), vector8_is_highbit_set(), vector8_load(), and vector8_or().

Referenced by pg_utf8_verifystr().