]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Move is_valid_ascii() to ascii.h.
authorNathan Bossart <nathan@postgresql.org>
Mon, 29 Jan 2024 18:09:08 +0000 (12:09 -0600)
committerNathan Bossart <nathan@postgresql.org>
Mon, 29 Jan 2024 18:09:08 +0000 (12:09 -0600)
This function requires simd.h, which is a rather large dependency
for a widely-used header file like pg_wchar.h.  Furthermore, there
is a report of a third-party tool that is struggling to use
pg_wchar.h due to its dependence on simd.h (presumably because
simd.h uses several intrinsics).  Moving the function to the much
less popular ascii.h resolves these issues for now.

This commit is back-patched for the benefit of the aforementioned
third-party tool.  The simd.h dependency was only added in v16,
but we've opted to back-patch to v15 so that is_valid_ascii() lives
in the same file for all versions where it exists.  This could
break existing third-party code that uses the function, but we
couldn't find any examples of such code.  It should be possible to
fix any code that this commit breaks by including ascii.h in the
file that uses is_valid_ascii().

Author: Jubilee Young
Reviewed-by: Tom Lane, John Naylor, Andres Freund, Eric Ridge
Discussion: https://postgr.es/m/CAPNHn3oKJJxMsYq%2BqLYzVJOFrUcOr4OF1EC-KtFT-qh8nOOOtQ%40mail.gmail.com
Backpatch-through: 15

src/common/wchar.c
src/include/mb/pg_wchar.h
src/include/utils/ascii.h

index 1e6e198bf276963782ce5c244dfce9f50de393cc..ea46192e364e7e32de268c28841f01fedda4b346 100644 (file)
@@ -13,6 +13,7 @@
 #include "c.h"
 
 #include "mb/pg_wchar.h"
+#include "utils/ascii.h"
 
 
 /*
index 31f5b393da417d6226a33cb43ed743d682ee0997..4a0e6bfbccde9d6e630569f0eff3055696da06c3 100644 (file)
@@ -699,57 +699,4 @@ extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p,
 extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len);
 #endif
 
-
-/*
- * Verify a chunk of bytes for valid ASCII.
- *
- * Returns false if the input contains any zero bytes or bytes with the
- * high-bit set. Input len must be a multiple of 8.
- */
-static inline bool
-is_valid_ascii(const unsigned char *s, int len)
-{
-       uint64          chunk,
-                               highbit_cum = UINT64CONST(0),
-                               zero_cum = UINT64CONST(0x8080808080808080);
-
-       Assert(len % sizeof(chunk) == 0);
-
-       while (len > 0)
-       {
-               memcpy(&chunk, s, sizeof(chunk));
-
-               /*
-                * Capture any zero bytes in this chunk.
-                *
-                * First, add 0x7f to each byte. This sets the high bit in each byte,
-                * unless it was a zero. If any resulting high bits are zero, the
-                * corresponding high bits in the zero accumulator will be cleared.
-                *
-                * If none of the bytes in the chunk had the high bit set, the max
-                * value each byte can have after the addition is 0x7f + 0x7f = 0xfe,
-                * and we don't need to worry about carrying over to the next byte. If
-                * any input bytes did have the high bit set, it doesn't matter
-                * because we check for those separately.
-                */
-               zero_cum &= (chunk + UINT64CONST(0x7f7f7f7f7f7f7f7f));
-
-               /* Capture any set bits in this chunk. */
-               highbit_cum |= chunk;
-
-               s += sizeof(chunk);
-               len -= sizeof(chunk);
-       }
-
-       /* Check if any high bits in the high bit accumulator got set. */
-       if (highbit_cum & UINT64CONST(0x8080808080808080))
-               return false;
-
-       /* Check if any high bits in the zero accumulator got cleared. */
-       if (zero_cum != UINT64CONST(0x8080808080808080))
-               return false;
-
-       return true;
-}
-
 #endif                                                 /* PG_WCHAR_H */
index aed80197fc8ad961d7166ca7e1828ea4e9415836..4e3a1d4ac30997c96a475cf9dc7f2f779b0f3ae9 100644 (file)
 
 extern void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz);
 
+/*
+ * Verify a chunk of bytes for valid ASCII.
+ *
+ * Returns false if the input contains any zero bytes or bytes with the
+ * high-bit set. Input len must be a multiple of 8.
+ */
+static inline bool
+is_valid_ascii(const unsigned char *s, int len)
+{
+       uint64          chunk,
+                               highbit_cum = UINT64CONST(0),
+                               zero_cum = UINT64CONST(0x8080808080808080);
+
+       Assert(len % sizeof(chunk) == 0);
+
+       while (len > 0)
+       {
+               memcpy(&chunk, s, sizeof(chunk));
+
+               /*
+                * Capture any zero bytes in this chunk.
+                *
+                * First, add 0x7f to each byte. This sets the high bit in each byte,
+                * unless it was a zero. If any resulting high bits are zero, the
+                * corresponding high bits in the zero accumulator will be cleared.
+                *
+                * If none of the bytes in the chunk had the high bit set, the max
+                * value each byte can have after the addition is 0x7f + 0x7f = 0xfe,
+                * and we don't need to worry about carrying over to the next byte. If
+                * any input bytes did have the high bit set, it doesn't matter
+                * because we check for those separately.
+                */
+               zero_cum &= (chunk + UINT64CONST(0x7f7f7f7f7f7f7f7f));
+
+               /* Capture any set bits in this chunk. */
+               highbit_cum |= chunk;
+
+               s += sizeof(chunk);
+               len -= sizeof(chunk);
+       }
+
+       /* Check if any high bits in the high bit accumulator got set. */
+       if (highbit_cum & UINT64CONST(0x8080808080808080))
+               return false;
+
+       /* Check if any high bits in the zero accumulator got cleared. */
+       if (zero_cum != UINT64CONST(0x8080808080808080))
+               return false;
+
+       return true;
+}
+
 #endif                                                 /* _ASCII_H_ */