📄 charset.c
字号:
else if ((c & 0xFF) >= 0xE0 && (c & 0xFF) <= 0xE7) { if (source_count < size -2 && (source[source_count +1] & 0xC0) == 0x80 && (source[source_count +2] & 0xC0) == 0x80) { // 1110xxxx c &= 0x0F; iterations = 2; } } else if ((c & 0xFF) >= 0xF0 && (c & 0xFF) <= 0xF4) { if (source_count < size -3 && (source[source_count +1] & 0xC0) == 0x80 && (source[source_count +2] & 0xC0) == 0x80 && (source[source_count +3] & 0xC0) == 0x80) { // 11110xxx c &= 0x07; iterations = 3; } } if (iterations > 0) { int i; for (i = 0; i < iterations; i++) { c = (c << 6) | (source[++source_count] -0x80); if (log_charconv) sprintf(strchr(sourcechars, 0), "%02X", (unsigned char)source[source_count]); } // Euro character is 20AC in UTF-8, but A4 in ISO-8859-15: if ((c & 0xFF) == 0xAC) c = 0xA4; found = char2gsm((char)c, &newch); if (found == 2) { if (dest_count >= max -2) break; destination[dest_count++] = 0x1B; } if (found >= 1) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%s(%02X[%c])->%s%02X", sourcechars, (unsigned char)c, prch(c), (found == 2)? "Esc-" : "", (unsigned char)newch); if (gsm2char(newch, &tmpch, found)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } else { found = special_char2gsm((char)c, &newch); if (found) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%s(%02X[%c])~>%02X", sourcechars, (unsigned char)c, prch(c), (unsigned char)newch); if (gsm2char(newch, &tmpch, 1)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } else source_count = saved_source_count; } } } // 3.1beta7: Try additional table: if (found == 0) { found = special_char2gsm(source[source_count], &newch); if (found) { destination[dest_count++] = newch; if (log_charconv) { sprintf(logtmp, "%02X[%c]~>%02X", (unsigned char)source[source_count], prch(source[source_count]), (unsigned char)newch); if (gsm2char(newch, &tmpch, 1)) sprintf(strchr(logtmp, 0), "[%c]", tmpch); logch("%s ", logtmp); } } } if (found==0) { writelogfile0(LOG_NOTICE, process_title, tb_sprintf("Cannot convert %i. character %c 0x%2X to GSM, you might need to update the translation tables.", source_count +1, source[source_count], source[source_count]));#ifdef DEBUGMSG printf("%s\n", tb);#endif } source_count++; } if (log_charconv) logch(NULL); // Terminate destination string with 0, however 0x00 are also allowed within the string. destination[dest_count]=0; return dest_count;}// Outputs to the file. Return value: 0 = ok, -1 = error.int iso2utf8_file(FILE *fp, char *ascii, int userdatalength){ int result = 0; int idx; unsigned int c; char tmp[10]; int len; char logtmp[51]; int i; if (!fp || userdatalength < 0) return -1;#ifdef DEBUGMSG log_charconv = 1;#endif if (log_charconv) { *logch_buffer = 0; logch("!! iso2utf8_file(..., userdatalength=%i)", userdatalength); logch(NULL); } for (idx = 0; idx < userdatalength; idx++) { len = 0; c = ascii[idx] & 0xFF; // Euro character is 20AC in UTF-8, but A4 in ISO-8859-15: if (c == 0xA4) c = 0x20AC; if (c <= 0x7F) tmp[len++] = (char)c; else if (c <= 0x7FF) { tmp[len++] = (char)( 0xC0 | ((c >> 6) & 0x1F) ); tmp[len++] = (char)( 0x80 | (c & 0x3F) ); } else if (c <= 0x7FFF) // or <= 0xFFFF ? { tmp[len++] = (char)( 0xE0 | ((c >> 12) & 0x0F) ); tmp[len++] = (char)( 0x80 | ((c >> 6) & 0x3F) ); tmp[len++] = (char)( 0x80 | (c & 0x3F) ); } if (len == 0) { if (log_charconv) logch(NULL); writelogfile0(LOG_NOTICE, process_title, tb_sprintf("UTF-8 conversion error with %i. ch 0x%2X %c.", idx +1, c, (char)c));#ifdef DEBUGMSG printf("%s\n", tb);#endif } else { if (log_charconv) { sprintf(logtmp, "%02X[%c]", (unsigned char)ascii[idx], prch(ascii[idx])); if (len > 1 || ascii[idx] != tmp[0]) { strcat(logtmp, "->"); for (i = 0; i < len; i++) sprintf(strchr(logtmp, 0), "%02X", (unsigned char)tmp[i]); } logch("%s ", logtmp); } if (fwrite(tmp, 1, len, fp) != len) { if (log_charconv) logch(NULL); writelogfile0(LOG_NOTICE, process_title, tb_sprintf("Fatal file write error in UTF-8 conversion"));#ifdef DEBUGMSG printf("%s\n", tb);#endif result = -1; break; } } } if (log_charconv) logch(NULL); return result;}int iso2gsm(char* source, int size, char* destination, int max){ int table_row; int source_count=0; int dest_count=0; int found=0; destination[dest_count]=0; if (source==0 || size==0) return 0; // Convert each character untl end of string while (source_count<size && dest_count<max) { // search in normal translation table found=0; table_row=0; while (charset[table_row*2]) { if (charset[table_row*2]==source[source_count]) { destination[dest_count++]=charset[table_row*2+1]; found=1; break; } table_row++; } // if not found in normal table, then search in the extended table if (found==0) { table_row=0; while (ext_charset[table_row*2]) { if (ext_charset[table_row*2]==source[source_count]) { destination[dest_count++]=0x1B; if (dest_count<max) destination[dest_count++]=ext_charset[table_row*2+1]; found=1; break; } table_row++; } } // if also not found in the extended table, then log a note if (found==0) { writelogfile0(LOG_NOTICE, process_title, tb_sprintf("Cannot convert %i. ISO character %c 0x%2X to GSM, you might need to update the translation tables.", source_count +1, source[source_count], source[source_count]));#ifdef DEBUGMSG printf("%s\n", tb);#endif } source_count++; } // Terminate destination string with 0, however 0x00 are also allowed within the string. destination[dest_count]=0; return dest_count;}int gsm2iso(char* source, int size, char* destination, int max){ int source_count=0; int dest_count=0; char newch; if (source==0 || size==0) { destination[0]=0; return 0; } // Convert each character untl end of string while (source_count<size && dest_count<max) { if (source[source_count]!=0x1B) { // search in normal translation table if (gsm2char(source[source_count], &newch, 1)) destination[dest_count++] = newch; else if (source[source_count] == 0x24) destination[dest_count++] = (char)GSM_CURRENCY_SYMBOL_TO_ISO; else { writelogfile0(LOG_NOTICE, process_title, tb_sprintf("Cannot convert GSM character 0x%2X to ISO, you might need to update the 1st translation table.", source[source_count]));#ifdef DEBUGMSG printf("%s\n", tb);#endif } } else if (++source_count<size) { // search in extended translation table if (gsm2char(source[source_count], &newch, 2)) destination[dest_count++] = newch; else { writelogfile0(LOG_NOTICE, process_title, tb_sprintf("Cannot convert extended GSM character 0x1B 0x%2X, you might need to update the 2nd translation table.", source[source_count]));#ifdef DEBUGMSG printf("%s\n", tb);#endif } } source_count++; } // Terminate destination string with 0, however 0x00 are also allowed within the string. destination[dest_count]=0; return dest_count;}int unicode2sms(char* source, int size, char* destination, int max){ int foundstart=0; int position=1; unsigned char previous='\0'; int source_count=0; int dest_count=0; if (source==0 || size==0) { destination[0]=0; return 0; } while (source_count<size && dest_count<max) { if (position == 1) { if (foundstart == 1) destination[dest_count++] = source[source_count]; position = 2; } else { if ((unsigned char)source[source_count] != 0xFF) destination[dest_count++] = source[source_count]; if (foundstart == 0 && source[source_count] == 0x0A && previous == 0x0A) foundstart = 1; previous = source[source_count]; position = 1; } source_count++; } destination[dest_count]=0; return dest_count;}int decode_ucs2(char *buffer, int len){ int i; char *d = buffer; for (i = 0; i < len; ) { switch (wctomb(d +i, (*(buffer +i) << 8 | *(buffer +i +1)))) { case 2: i += 2; break; default: *(d +i) = *(buffer +i +1); d--; i += 2; break; } } i = (d -buffer) +len; *(buffer +i) = '\0'; return i;}// ******************************************************************************// Collect character conversion log, flush it if called with format==NULL.// Also prints to the stdout, if debugging.void logch(char* format, ...){ va_list argp; char text[2048]; int flush = 0; if (format) { va_start(argp, format); vsnprintf(text, sizeof(text), format, argp); va_end(argp); if (strlen(logch_buffer) +strlen(text) < sizeof(logch_buffer)) { sprintf(strchr(logch_buffer, 0), "%s", text); // Line wrap after space character: // Outgoing conversion: if (strlen(text) >= 3) if (strcmp(text +strlen(text) -3, "20 ") == 0) flush = 1; // Incoming conversion: if (!flush) if (strlen(text) >= 6) if (strcmp(text +strlen(text) -6, "20[ ] ") == 0) flush = 1; // Line wrap after a reasonable length reached: if (!flush) if (strlen(logch_buffer) > 80) flush = 1; }#ifdef DEBUGMSG printf("%s", text);#endif } else flush = 1; if (flush) { if (*logch_buffer) writelogfile(LOG_DEBUG, process_title, "charconv: %s", logch_buffer); *logch_buffer = 0;#ifdef DEBUGMSG printf("\n");#endif }}char prch(char ch){ if ((unsigned char)ch >= ' ') return ch; return '.';}// ******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -