/* Public domain */ /* * Compatibility string and UTF-8 conversion routines. */ __BEGIN_DECLS size_t CGI_Strlcpy(char *, const char *, size_t) BOUNDED_ATTRIBUTE(__string__, 1, 3); size_t CGI_Strlcat(char *, const char *, size_t) BOUNDED_ATTRIBUTE(__string__, 1, 3); char *CGI_Strsep(char **, const char *); char *CGI_Strdup(const char *); char *CGI_TryStrdup(const char *); /* * Parse the first byte of a possible UTF-8 sequence and return the length * of the sequence in bytes (or 1 if there is none). */ static __inline__ int CGI_CharLengthUTF8(unsigned char ch) { if ((ch >> 7) == 0) { return (1); } else if (((ch & 0xe0) >> 5) == 0x6) { return (2); } else if (((ch & 0xf0) >> 4) == 0xe) { return (3); } else if (((ch & 0xf8) >> 3) == 0x1e) { return (4); } else if (((ch & 0xfc) >> 2) == 0x3e) { return (5); } else if (((ch & 0xfe) >> 1) == 0x7e) { return (6); } else { return (-1); } } /* * Return the number of characters in the given UTF-8 string, not counting * the terminating NUL. */ static __inline__ size_t CGI_LengthUTF8(const char *s) { const char *c = &s[0]; size_t rv = 0; int i, cLen; if (s[0] == '\0') { return (0); } for (;;) { if ((cLen = CGI_CharLengthUTF8((unsigned char)*c)) == -1) { break; } for (i = 0; i < cLen; i++) { if (c[i] == '\0') return (rv); } rv++; c += cLen; } return (rv); } __END_DECLS #if defined(_PERCGI_INTERNAL) || defined(_USE_PERCGI_STD) #define Strlcat CGI_Strlcat #define Strlcpy CGI_Strlcpy #define Strsep CGI_Strsep #define Strdup CGI_Strdup #define TryStrdup CGI_TryStrdup #define LengthUTF8 CGI_LengthUTF8 #define CharLengthUTF8 CGI_CharLengthUTF8 #endif