1function _to_utf8(s) {
2  var c, d = "";
3  for (var i = 0; i < s.length; i++) {
4    c = s.charCodeAt(i);
5    if (c <= 0x7f) {
6      d += s.charAt(i);
7    } else if (c >= 0x80 && c <= 0x7ff) {
8      d += String.fromCharCode(((c >> 6) & 0x1f) | 0xc0);
9      d += String.fromCharCode((c & 0x3f) | 0x80);
10    } else {
11      d += String.fromCharCode((c >> 12) | 0xe0);
12      d += String.fromCharCode(((c >> 6) & 0x3f) | 0x80);
13      d += String.fromCharCode((c & 0x3f) | 0x80);
14    }
15  }
16  return d;
17}
18
19function _from_utf8(s) {
20  var c, d = "", flag = 0, tmp;
21  for (var i = 0; i < s.length; i++) {
22    c = s.charCodeAt(i);
23    if (flag == 0) {
24      if ((c & 0xe0) == 0xe0) {
25        flag = 2;
26        tmp = (c & 0x0f) << 12;
27      } else if ((c & 0xc0) == 0xc0) {
28        flag = 1;
29        tmp = (c & 0x1f) << 6;
30      } else if ((c & 0x80) == 0) {
31        d += s.charAt(i);
32      } else {
33        flag = 0;
34      }
35    } else if (flag == 1) {
36      flag = 0;
37      d += String.fromCharCode(tmp | (c & 0x3f));
38    } else if (flag == 2) {
39      flag = 3;
40      tmp |= (c & 0x3f) << 6;
41    } else if (flag == 3) {
42      flag = 0;
43      d += String.fromCharCode(tmp | (c & 0x3f));
44    } else {
45      flag = 0;
46    }
47  }
48  return d;
49}