github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/go-rune.c (about) 1 /* go-rune.c -- rune functions for Go. 2 3 Copyright 2009, 2010 The Go Authors. All rights reserved. 4 Use of this source code is governed by a BSD-style 5 license that can be found in the LICENSE file. */ 6 7 #include <stddef.h> 8 9 #include "runtime.h" 10 #include "go-string.h" 11 12 /* Get a character from the UTF-8 string STR, of length LEN. Store 13 the Unicode character, if any, in *RUNE. Return the number of 14 characters used from STR. */ 15 16 int 17 __go_get_rune (const unsigned char *str, size_t len, int32 *rune) 18 { 19 int c, c1, c2, c3, l; 20 21 /* Default to the "replacement character". */ 22 *rune = 0xfffd; 23 24 if (len <= 0) 25 return 1; 26 27 c = *str; 28 if (c <= 0x7f) 29 { 30 *rune = c; 31 return 1; 32 } 33 34 if (len <= 1) 35 return 1; 36 37 c1 = str[1]; 38 if ((c & 0xe0) == 0xc0 39 && (c1 & 0xc0) == 0x80) 40 { 41 l = (((c & 0x1f) << 6) + (c1 & 0x3f)); 42 if (l <= 0x7f) 43 return 1; 44 *rune = l; 45 return 2; 46 } 47 48 if (len <= 2) 49 return 1; 50 51 c2 = str[2]; 52 if ((c & 0xf0) == 0xe0 53 && (c1 & 0xc0) == 0x80 54 && (c2 & 0xc0) == 0x80) 55 { 56 l = (((c & 0xf) << 12) 57 + ((c1 & 0x3f) << 6) 58 + (c2 & 0x3f)); 59 60 if (l <= 0x7ff) 61 return 1; 62 63 if (l >= 0xd800 && l < 0xe000) 64 { 65 /* Invalid surrogate half; return replace character. */ 66 return 1; 67 } 68 69 *rune = l; 70 71 return 3; 72 } 73 74 if (len <= 3) 75 return 1; 76 77 c3 = str[3]; 78 if ((c & 0xf8) == 0xf0 79 && (c1 & 0xc0) == 0x80 80 && (c2 & 0xc0) == 0x80 81 && (c3 & 0xc0) == 0x80) 82 { 83 l = (((c & 0x7) << 18) 84 + ((c1 & 0x3f) << 12) 85 + ((c2 & 0x3f) << 6) 86 + (c3 & 0x3f)); 87 88 if (l <= 0xffff || l > 0x10ffff) 89 return 1; 90 91 *rune = l; 92 return 4; 93 } 94 95 /* Invalid encoding. Return 1 so that we advance. */ 96 return 1; 97 }