X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futf8.c;h=3964e8b1ce300e65f07b7ae849e1c492994fe29e;hb=9f26c90cb50c45d4549c4dd569917b4ac143b94d;hp=5f9f3c60c52b6f9b4224964a74b2e8caf92935a3;hpb=fd5b4ca11ea2b8a82343bc0db6a2f422beb305f1;p=elogind.git diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 5f9f3c60c..3964e8b1c 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 '_' @@ -284,3 +284,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; +}