int gsm_hex4_to_short( const char* hex ) { int hi = gsm_hex2_to_byte(hex); int lo = gsm_hex2_to_byte(hex+2); if (hi < 0 || lo < 0) return -1; return ((hi << 8) | lo); }
int sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len ) { cbytes_t p = (cbytes_t)str; cbytes_t end = p + strlen; int count = 0; int escaped = 0; while (p < end) { int c = p[0]; /* read the value from the string */ p += 1; if (c >= 128) { if ((c & 0xe0) == 0xc0) c &= 0x1f; else if ((c & 0xf0) == 0xe0) c &= 0x0f; else c &= 0x07; p++; while (p < end && (p[0] & 0xc0) == 0x80) { c = (c << 6) | (p[0] & 0x3f); p++; } } if (escaped) { switch (c) { case '\\': break; case 'n': /* \n is line feed */ c = 10; break; case 'x': /* \xNN, where NN is a 2-digit hexadecimal value */ if (p+2 > end) return -1; c = gsm_hex2_to_byte( (const char*)p ); if (c < 0) return -1; p += 2; break; case 'u': /* \uNNNN where NNNN is a 4-digiti hexadecimal value */ if (p + 4 > end) return -1; c = gsm_hex4_to_short( (const char*)p ); if (c < 0) return -1; p += 4; break; default: /* invalid escape, return -1 */ return -1; } escaped = 0; } else if (c == '\\') { escaped = 1; continue; } /* now, try to write it to the destination */ if (c < 128) { if (count < utf8len) utf8[count] = (byte_t) c; count += 1; } else if (c < 0x800) { if (count < utf8len) utf8[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f)); if (count+1 < utf8len) utf8[count+1] = (byte_t)(0x80 | (c & 0x3f)); count += 2; } else { if (count < utf8len) utf8[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf)); if (count+1 < utf8len) utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f)); if (count+2 < utf8len) utf8[count+2] = (byte_t)(0x80 | (c & 0x3f)); count += 3; } }
int sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len ) { cbytes_t p = (cbytes_t)str; cbytes_t end = p + strlen; int count = 0; int escaped = 0; while (p < end) { int c = p[0]; p += 1; if (c >= 128) { if ((c & 0xe0) == 0xc0) c &= 0x1f; else if ((c & 0xf0) == 0xe0) c &= 0x0f; else c &= 0x07; p++; while (p < end && (p[0] & 0xc0) == 0x80) { c = (c << 6) | (p[0] & 0x3f); p++; } } if (escaped) { switch (c) { case '\\': break; case 'n': c = 10; break; case 'x': if (p+2 > end) return -1; c = gsm_hex2_to_byte( (const char*)p ); if (c < 0) return -1; p += 2; break; case 'u': if (p + 4 > end) return -1; c = gsm_hex4_to_short( (const char*)p ); if (c < 0) return -1; p += 4; break; default: return -1; } escaped = 0; } else if (c == '\\') { escaped = 1; continue; } if (c < 128) { if (count < utf8len) utf8[count] = (byte_t) c; count += 1; } else if (c < 0x800) { if (count < utf8len) utf8[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f)); if (count+1 < utf8len) utf8[count+1] = (byte_t)(0x80 | (c & 0x3f)); count += 2; } else { if (count < utf8len) utf8[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf)); if (count+1 < utf8len) utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f)); if (count+2 < utf8len) utf8[count+2] = (byte_t)(0x80 | (c & 0x3f)); count += 3; } }