X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futf8.c;h=655cc771d4030ad656993c2c3a4ca49381591bb7;hb=d7bd3de0654669e65b9642c248c5fa6d1d9a9f61;hp=a6f5b3f9e5dff38fc28efd4eb1d47943a2f49a87;hpb=ba961854ddec8a8efcffab44540c33cc7dffebfa;p=elogind.git diff --git a/src/shared/utf8.c b/src/shared/utf8.c index a6f5b3f9e..655cc771d 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -28,19 +28,18 @@ * Copyright (C) 2000 Red Hat, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public + * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -50,6 +49,7 @@ #include #include "utf8.h" +#include "util.h" #define FILTER_CHAR '_' @@ -86,11 +86,11 @@ static bool is_unicode_control(uint32_t ch) { '\t' is in C0 range, but more or less harmless and commonly used. */ - return (ch < ' ' && ch != '\t') || + return (ch < ' ' && ch != '\t' && ch != '\n') || (0x7F <= ch && ch <= 0x9F); } -char* utf8_is_printable_n(const char* str, size_t length) { +bool utf8_is_printable(const char* str, size_t length) { uint32_t val = 0; uint32_t min = 0; const uint8_t *p; @@ -113,40 +113,37 @@ char* utf8_is_printable_n(const char* str, size_t length) { min = (1 << 16); val = (uint32_t) (*p & 0x07); } else - goto error; + return false; p++; length--; if (!length || !is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); TWO_REMAINING: p++; length--; if (!is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); ONE_REMAINING: p++; length--; if (!is_continuation_char(*p)) - goto error; + return false; merge_continuation_char(&val, *p); if (val < min) - goto error; + return false; } if (is_unicode_control(val)) - goto error; + return false; } - return (char*) str; - -error: - return NULL; + return true; } static char* utf8_validate(const char *str, char *output) { @@ -265,7 +262,8 @@ char *ascii_is_valid(const char *str) { } char *ascii_filter(const char *str) { - char *r, *s, *d; + const char *s; + char *r, *d; size_t l; assert(str); @@ -275,7 +273,7 @@ char *ascii_filter(const char *str) { if (!r) return NULL; - for (s = r, d = r; *s; s++) + for (s = str, d = r; *s; s++) if ((unsigned char) *s < 128) *(d++) = *s; @@ -283,3 +281,39 @@ char *ascii_filter(const char *str) { return r; } + +char *utf16_to_utf8(const void *s, size_t length) { + char *r; + const uint8_t *f; + uint8_t *t; + + r = new(char, (length*3+1)/2 + 1); + if (!r) + return NULL; + + t = (uint8_t*) r; + + for (f = s; f < (const uint8_t*) s + length; f += 2) { + uint16_t c; + + c = (f[1] << 8) | f[0]; + + if (c == 0) { + *t = 0; + return r; + } else if (c < 0x80) { + *(t++) = (uint8_t) c; + } else if (c < 0x800) { + *(t++) = (uint8_t) (0xc0 | (c >> 6)); + *(t++) = (uint8_t) (0x80 | (c & 0x3f)); + } else { + *(t++) = (uint8_t) (0xe0 | (c >> 12)); + *(t++) = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); + *(t++) = (uint8_t) (0x80 | (c & 0x3f)); + } + } + + *t = 0; + + return r; +}