| 21 | |
| 22 | // convert string to array (typed, when possible) |
| 23 | var string2buf = function (str) { |
| 24 | var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; |
| 25 | |
| 26 | // count binary size |
| 27 | for (m_pos = 0; m_pos < str_len; m_pos++) { |
| 28 | c = str.charCodeAt(m_pos); |
| 29 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { |
| 30 | c2 = str.charCodeAt(m_pos+1); |
| 31 | if ((c2 & 0xfc00) === 0xdc00) { |
| 32 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
| 33 | m_pos++; |
| 34 | } |
| 35 | } |
| 36 | buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; |
| 37 | } |
| 38 | |
| 39 | // allocate buffer |
| 40 | if (support.uint8array) { |
| 41 | buf = new Uint8Array(buf_len); |
| 42 | } else { |
| 43 | buf = new Array(buf_len); |
| 44 | } |
| 45 | |
| 46 | // convert |
| 47 | for (i=0, m_pos = 0; i < buf_len; m_pos++) { |
| 48 | c = str.charCodeAt(m_pos); |
| 49 | if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { |
| 50 | c2 = str.charCodeAt(m_pos+1); |
| 51 | if ((c2 & 0xfc00) === 0xdc00) { |
| 52 | c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); |
| 53 | m_pos++; |
| 54 | } |
| 55 | } |
| 56 | if (c < 0x80) { |
| 57 | /* one byte */ |
| 58 | buf[i++] = c; |
| 59 | } else if (c < 0x800) { |
| 60 | /* two bytes */ |
| 61 | buf[i++] = 0xC0 | (c >>> 6); |
| 62 | buf[i++] = 0x80 | (c & 0x3f); |
| 63 | } else if (c < 0x10000) { |
| 64 | /* three bytes */ |
| 65 | buf[i++] = 0xE0 | (c >>> 12); |
| 66 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); |
| 67 | buf[i++] = 0x80 | (c & 0x3f); |
| 68 | } else { |
| 69 | /* four bytes */ |
| 70 | buf[i++] = 0xf0 | (c >>> 18); |
| 71 | buf[i++] = 0x80 | (c >>> 12 & 0x3f); |
| 72 | buf[i++] = 0x80 | (c >>> 6 & 0x3f); |
| 73 | buf[i++] = 0x80 | (c & 0x3f); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | return buf; |
| 78 | }; |
| 79 | |
| 80 | // Calculate max possible position in utf8 buffer, |