1 /* go-int-array-to-string.c -- convert an array of ints to a string in Go. 2 3 Copyright 2009 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 "go-assert.h" 8 #include "runtime.h" 9 #include "arch.h" 10 #include "malloc.h" 11 12 String __go_int_array_to_string(const void * p,intgo len)13__go_int_array_to_string (const void* p, intgo len) 14 { 15 const int32 *ints; 16 intgo slen; 17 intgo i; 18 unsigned char *retdata; 19 String ret; 20 unsigned char *s; 21 22 ints = (const int32 *) p; 23 24 slen = 0; 25 for (i = 0; i < len; ++i) 26 { 27 int32 v; 28 29 v = ints[i]; 30 31 if (v < 0 || v > 0x10ffff) 32 v = 0xfffd; 33 else if (0xd800 <= v && v <= 0xdfff) 34 v = 0xfffd; 35 36 if (v <= 0x7f) 37 slen += 1; 38 else if (v <= 0x7ff) 39 slen += 2; 40 else if (v <= 0xffff) 41 slen += 3; 42 else 43 slen += 4; 44 } 45 46 retdata = runtime_mallocgc ((uintptr) slen, 0, FlagNoScan); 47 ret.str = retdata; 48 ret.len = slen; 49 50 s = retdata; 51 for (i = 0; i < len; ++i) 52 { 53 int32 v; 54 55 v = ints[i]; 56 57 /* If V is out of range for UTF-8, substitute the replacement 58 character. */ 59 if (v < 0 || v > 0x10ffff) 60 v = 0xfffd; 61 else if (0xd800 <= v && v <= 0xdfff) 62 v = 0xfffd; 63 64 if (v <= 0x7f) 65 *s++ = v; 66 else if (v <= 0x7ff) 67 { 68 *s++ = 0xc0 | ((v >> 6) & 0x1f); 69 *s++ = 0x80 | (v & 0x3f); 70 } 71 else if (v <= 0xffff) 72 { 73 *s++ = 0xe0 | ((v >> 12) & 0xf); 74 *s++ = 0x80 | ((v >> 6) & 0x3f); 75 *s++ = 0x80 | (v & 0x3f); 76 } 77 else 78 { 79 *s++ = 0xf0 | ((v >> 18) & 0x7); 80 *s++ = 0x80 | ((v >> 12) & 0x3f); 81 *s++ = 0x80 | ((v >> 6) & 0x3f); 82 *s++ = 0x80 | (v & 0x3f); 83 } 84 } 85 86 __go_assert (s - retdata == slen); 87 88 return ret; 89 } 90