Diffstat (limited to 'gammu/emb/common/misc/coding/coding.c') (more/less context) (show whitespace changes)
-rw-r--r-- | gammu/emb/common/misc/coding/coding.c | 177 |
1 files changed, 165 insertions, 12 deletions
diff --git a/gammu/emb/common/misc/coding/coding.c b/gammu/emb/common/misc/coding/coding.c index 62543ac..b30b645 100644 --- a/gammu/emb/common/misc/coding/coding.c +++ b/gammu/emb/common/misc/coding/coding.c | |||
@@ -1,6 +1,10 @@ | |||
1 | /* (c) 2002-2004 by Marcin Wiacek, Michal Cihar and others */ | 1 | /* (c) 2002-2004 by Marcin Wiacek, Michal Cihar and others */ |
2 | /* based on some work from MyGnokii and Gnokii */ | 2 | /* based on some work from MyGnokii (www.mwiacek.com) */ |
3 | /* based on some work from Gnokii (www.gnokii.org) | ||
4 | * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot | ||
5 | * GNU GPL version 2 or later | ||
6 | */ | ||
3 | 7 | ||
4 | #include <stdio.h> | 8 | #include <stdio.h> |
5 | #include <stdlib.h> | 9 | #include <stdlib.h> |
6 | #include <string.h> | 10 | #include <string.h> |
@@ -15,8 +19,157 @@ | |||
15 | 19 | ||
16 | #include "../misc.h" | 20 | #include "../misc.h" |
17 | #include "coding.h" | 21 | #include "coding.h" |
18 | 22 | ||
23 | /* function changes #10 #13 chars to \n \r */ | ||
24 | char *EncodeUnicodeSpecialChars(unsigned char *buffer) | ||
25 | { | ||
26 | int Pos=0, Pos2=0; | ||
27 | static unsigned charBuf[20000]; | ||
28 | |||
29 | while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { | ||
30 | if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 10) { | ||
31 | Buf[Pos2*2] = 0x00; | ||
32 | Buf[Pos2*2+1] = '\\'; | ||
33 | Pos2++; | ||
34 | Buf[Pos2*2] = 0x00; | ||
35 | Buf[Pos2*2+1] = 'n'; | ||
36 | Pos2++; | ||
37 | } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 13) { | ||
38 | Buf[Pos2*2] = 0x00; | ||
39 | Buf[Pos2*2+1] = '\\'; | ||
40 | Pos2++; | ||
41 | Buf[Pos2*2] = 0x00; | ||
42 | Buf[Pos2*2+1] = 'r'; | ||
43 | Pos2++; | ||
44 | } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { | ||
45 | Buf[Pos2*2] = 0x00; | ||
46 | Buf[Pos2*2+1] = '\\'; | ||
47 | Pos2++; | ||
48 | Buf[Pos2*2] = 0x00; | ||
49 | Buf[Pos2*2+1] = '\\'; | ||
50 | Pos2++; | ||
51 | } else { | ||
52 | Buf[Pos2*2] = buffer[Pos*2]; | ||
53 | Buf[Pos2*2+1] = buffer[Pos*2+1]; | ||
54 | Pos2++; | ||
55 | } | ||
56 | Pos++; | ||
57 | } | ||
58 | Buf[Pos2*2] = 0; | ||
59 | Buf[Pos2*2+1] = 0; | ||
60 | return Buf; | ||
61 | } | ||
62 | |||
63 | /* function changes #10 #13 chars to \n \r */ | ||
64 | char *EncodeSpecialChars(unsigned char *buffer) | ||
65 | { | ||
66 | int Pos=0, Pos2=0; | ||
67 | static unsigned charBuf[10000]; | ||
68 | |||
69 | while (buffer[Pos]!=0x00) { | ||
70 | switch (buffer[Pos]) { | ||
71 | case 10: | ||
72 | Buf[Pos2++] = '\\'; | ||
73 | Buf[Pos2++] = 'n'; | ||
74 | break; | ||
75 | case 13: | ||
76 | Buf[Pos2++] = '\\'; | ||
77 | Buf[Pos2++] = 'r'; | ||
78 | break; | ||
79 | case '\\': | ||
80 | Buf[Pos2++] = '\\'; | ||
81 | Buf[Pos2++] = '\\'; | ||
82 | break; | ||
83 | default: | ||
84 | Buf[Pos2++] = buffer[Pos]; | ||
85 | } | ||
86 | Pos++; | ||
87 | } | ||
88 | Buf[Pos2] = 0; | ||
89 | return Buf; | ||
90 | } | ||
91 | |||
92 | char *DecodeUnicodeSpecialChars(unsigned char *buffer) | ||
93 | { | ||
94 | int Pos=0, Pos2=0, level=0; | ||
95 | static unsigned charBuf[10000]; | ||
96 | |||
97 | while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { | ||
98 | Buf[Pos2*2] = buffer[Pos*2]; | ||
99 | Buf[Pos2*2+1] = buffer[Pos*2+1]; | ||
100 | switch (level) { | ||
101 | case 0: | ||
102 | if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { | ||
103 | level = 1; | ||
104 | } else { | ||
105 | Pos2++; | ||
106 | } | ||
107 | break; | ||
108 | case 1: | ||
109 | if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'n') { | ||
110 | Buf[Pos2*2] = 0; | ||
111 | Buf[Pos2*2+1] = 10; | ||
112 | } | ||
113 | if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'r') { | ||
114 | Buf[Pos2*2] = 0; | ||
115 | Buf[Pos2*2+1] = 13; | ||
116 | } | ||
117 | if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { | ||
118 | Buf[Pos2*2] = 0; | ||
119 | Buf[Pos2*2+1] = '\\'; | ||
120 | } | ||
121 | Pos2++; | ||
122 | level = 0; | ||
123 | } | ||
124 | Pos++; | ||
125 | } | ||
126 | Buf[Pos2*2] = 0; | ||
127 | Buf[Pos2*2+1] = 0; | ||
128 | return Buf; | ||
129 | } | ||
130 | |||
131 | char *DecodeSpecialChars(unsigned char *buffer) | ||
132 | { | ||
133 | int Pos=0, Pos2=0, level=0; | ||
134 | static unsigned charBuf[10000]; | ||
135 | |||
136 | while (buffer[Pos]!=0x00) { | ||
137 | Buf[Pos2] = buffer[Pos]; | ||
138 | switch (level) { | ||
139 | case 0: | ||
140 | if (buffer[Pos] == '\\') { | ||
141 | level = 1; | ||
142 | } else { | ||
143 | Pos2++; | ||
144 | } | ||
145 | break; | ||
146 | case 1: | ||
147 | if (buffer[Pos] == 'n') Buf[Pos2] = 10; | ||
148 | if (buffer[Pos] == 'r') Buf[Pos2] = 13; | ||
149 | if (buffer[Pos] == '\\') Buf[Pos2] = '\\'; | ||
150 | Pos2++; | ||
151 | level = 0; | ||
152 | } | ||
153 | Pos++; | ||
154 | } | ||
155 | Buf[Pos2] = 0; | ||
156 | return Buf; | ||
157 | } | ||
158 | |||
159 | char *mystrcasestr(unsigned const char *a, unsigned const char *b) | ||
160 | { | ||
161 | unsigned char A[2000], B[200]; | ||
162 | int i; | ||
163 | |||
164 | memset(A,0,sizeof(A)); | ||
165 | memset(B,0,sizeof(B)); | ||
166 | for (i=0;i<(int)strlen(a);i++) A[i] = tolower(a[i]); | ||
167 | for (i=0;i<(int)strlen(b);i++) B[i] = tolower(b[i]); | ||
168 | |||
169 | return strstr(A,B); | ||
170 | } | ||
171 | |||
19 | unsigned int UnicodeLength(const unsigned char *str) | 172 | unsigned int UnicodeLength(const unsigned char *str) |
20 | { | 173 | { |
21 | unsigned int len = 0; | 174 | unsigned int len = 0; |
22 | 175 | ||
@@ -585,16 +738,16 @@ void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, boo | |||
585 | 738 | ||
586 | /*without leading byte with format of number*/ | 739 | /*without leading byte with format of number*/ |
587 | length--; | 740 | length--; |
588 | 741 | ||
589 | switch (Number[1]) { | 742 | switch ((Number[1] & 112)) { |
590 | case NUMBER_ALPHANUMERIC: | 743 | case (NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN & 112): |
591 | if (length > 6) length++; | 744 | if (length > 6) length++; |
592 | dbgprintf("Alphanumeric number, length %i\n",length); | 745 | dbgprintf("Alphanumeric number, length %i\n",length); |
593 | GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer); | 746 | GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer); |
594 | Buffer[length]=0; | 747 | Buffer[length]=0; |
595 | break; | 748 | break; |
596 | case NUMBER_INTERNATIONAL: | 749 | case (NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN & 112): |
597 | dbgprintf("International number\n"); | 750 | dbgprintf("International number\n"); |
598 | Buffer[0]='+'; | 751 | Buffer[0]='+'; |
599 | DecodeBCD(Buffer+1,Number+2, length); | 752 | DecodeBCD(Buffer+1,Number+2, length); |
600 | break; | 753 | break; |
@@ -630,16 +783,16 @@ int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool s | |||
630 | length=UnicodeLength(Number); | 783 | length=UnicodeLength(Number); |
631 | memcpy(buffer,DecodeUnicodeString(Number),length+1); | 784 | memcpy(buffer,DecodeUnicodeString(Number),length+1); |
632 | 785 | ||
633 | /* Checking for format number */ | 786 | /* Checking for format number */ |
634 | format = NUMBER_UNKNOWN; | 787 | format = NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN; |
635 | for (i=0;i<length;i++) { | 788 | for (i=0;i<length;i++) { |
636 | /* first byte is '+'. Number can be international */ | 789 | /* first byte is '+'. Number can be international */ |
637 | if (i==0 && buffer[i]=='+') { | 790 | if (i==0 && buffer[i]=='+') { |
638 | format=NUMBER_INTERNATIONAL; | 791 | format=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN; |
639 | } else { | 792 | } else { |
640 | /*char is not number. It must be alphanumeric*/ | 793 | /*char is not number. It must be alphanumeric*/ |
641 | if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC; | 794 | if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN; |
642 | } | 795 | } |
643 | } | 796 | } |
644 | 797 | ||
645 | /** | 798 | /** |
@@ -649,13 +802,13 @@ int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool s | |||
649 | Output[0]=format; | 802 | Output[0]=format; |
650 | 803 | ||
651 | /* After number type we will have number. GSM 03.40 section 9.1.2 */ | 804 | /* After number type we will have number. GSM 03.40 section 9.1.2 */ |
652 | switch (format) { | 805 | switch (format) { |
653 | case NUMBER_ALPHANUMERIC: | 806 | case NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN: |
654 | length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2; | 807 | length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2; |
655 | if (strlen(buffer)==7) length--; | 808 | if (strlen(buffer)==7) length--; |
656 | break; | 809 | break; |
657 | case NUMBER_INTERNATIONAL: | 810 | case NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN: |
658 | length--; | 811 | length--; |
659 | EncodeBCD (Output+1, buffer+1, length, true); | 812 | EncodeBCD (Output+1, buffer+1, length, true); |
660 | break; | 813 | break; |
661 | default: | 814 | default: |
@@ -918,9 +1071,9 @@ bool mystrncasecmp(unsigned const char *a, unsigned const char *b, int num) | |||
918 | int i; | 1071 | int i; |
919 | 1072 | ||
920 | if (a == NULL || b == NULL) return false; | 1073 | if (a == NULL || b == NULL) return false; |
921 | 1074 | ||
922 | num--; | 1075 | if (num == 0) num = -1; |
923 | 1076 | ||
924 | for (i = 0; i != num; i++) { | 1077 | for (i = 0; i != num; i++) { |
925 | if (a[i] == 0x00 && b[i] == 0x00) return true; | 1078 | if (a[i] == 0x00 && b[i] == 0x00) return true; |
926 | if (a[i] == 0x00 || b[i] == 0x00) return false; | 1079 | if (a[i] == 0x00 || b[i] == 0x00) return false; |
@@ -938,9 +1091,9 @@ bool mywstrncasecmp(unsigned const char *a, unsigned const char *b, int num) | |||
938 | wchar_t wc,wc2; | 1091 | wchar_t wc,wc2; |
939 | 1092 | ||
940 | if (a == NULL || b == NULL) return false; | 1093 | if (a == NULL || b == NULL) return false; |
941 | 1094 | ||
942 | num--; | 1095 | if (num == 0) num = -1; |
943 | 1096 | ||
944 | for (i = 0; i != num; i++) { | 1097 | for (i = 0; i != num; i++) { |
945 | if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) && (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return true; | 1098 | if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) && (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return true; |
946 | if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) || (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return false; | 1099 | if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) || (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return false; |
@@ -1014,9 +1167,9 @@ int mytowlower(wchar_t c) | |||
1014 | * as much fun trying to understand it, as I had to write it :-). | 1167 | * as much fun trying to understand it, as I had to write it :-). |
1015 | * | 1168 | * |
1016 | * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ | 1169 | * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ |
1017 | 1170 | ||
1018 | unsigned char *mystrstr (const unsigned char *haystack, const unsigned char *needle) | 1171 | unsigned char *mywstrstr (const unsigned char *haystack, const unsigned char *needle) |
1019 | { | 1172 | { |
1020 | /* One crazy define to convert unicode used in Gammu to standard wchar_t */ | 1173 | /* One crazy define to convert unicode used in Gammu to standard wchar_t */ |
1021 | #define tolowerwchar(x) (mytowlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) ))) | 1174 | #define tolowerwchar(x) (mytowlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) ))) |
1022 | register wchar_t b, c; | 1175 | register wchar_t b, c; |