author | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
commit | 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff) | |
tree | 6331418973714243beb674abc87692277b83869d /gammu/emb/common/service/gsmpbk.c | |
parent | ef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff) | |
download | kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2 |
Initial revision
Diffstat (limited to 'gammu/emb/common/service/gsmpbk.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/service/gsmpbk.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/gammu/emb/common/service/gsmpbk.c b/gammu/emb/common/service/gsmpbk.c new file mode 100644 index 0000000..05e5cb9 --- a/dev/null +++ b/gammu/emb/common/service/gsmpbk.c | |||
@@ -0,0 +1,370 @@ | |||
1 | /* (c) 2001-2003 by Marcin Wiacek,... */ | ||
2 | |||
3 | #include <string.h> | ||
4 | |||
5 | #include "../misc/coding/coding.h" | ||
6 | #include "gsmpbk.h" | ||
7 | #include "gsmmisc.h" | ||
8 | |||
9 | unsigned char *GSM_PhonebookGetEntryName (GSM_MemoryEntry *entry) | ||
10 | { | ||
11 | /* We possibly store here "LastName, FirstName" so allocate enough memory */ | ||
12 | static char dest[(GSM_PHONEBOOK_TEXT_LENGTH*2+2+1)*2]; | ||
13 | static char split[] = { '\0', ',', '\0', ' ', '\0', '\0'}; | ||
14 | int i; | ||
15 | int first = -1, last = -1, name = -1; | ||
16 | int len = 0; | ||
17 | |||
18 | for (i = 0; i < entry->EntriesNum; i++) { | ||
19 | switch (entry->Entries[i].EntryType) { | ||
20 | case PBK_Text_LastName: | ||
21 | last = i; | ||
22 | break; | ||
23 | case PBK_Text_FirstName: | ||
24 | first = i; | ||
25 | break; | ||
26 | case PBK_Text_Name: | ||
27 | name = i; | ||
28 | break; | ||
29 | default: | ||
30 | break; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | if (name != -1) { | ||
35 | CopyUnicodeString(dest, entry->Entries[name].Text); | ||
36 | } else { | ||
37 | if (last != -1 && first != -1) { | ||
38 | len = UnicodeLength(entry->Entries[last].Text); | ||
39 | CopyUnicodeString(dest, entry->Entries[last].Text); | ||
40 | CopyUnicodeString(dest + 2*len, split); | ||
41 | CopyUnicodeString(dest + 2*len + 4, entry->Entries[first].Text); | ||
42 | } else if (last != -1) { | ||
43 | CopyUnicodeString(dest, entry->Entries[last].Text); | ||
44 | } else if (first != -1) { | ||
45 | CopyUnicodeString(dest, entry->Entries[first].Text); | ||
46 | } else { | ||
47 | return NULL; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | return dest; | ||
52 | } | ||
53 | |||
54 | void GSM_PhonebookFindDefaultNameNumberGroup(GSM_MemoryEntry *entry, int *Name, int *Number, int *Group) | ||
55 | { | ||
56 | int i; | ||
57 | |||
58 | *Name = -1; | ||
59 | *Number = -1; | ||
60 | *Group = -1; | ||
61 | for (i = 0; i < entry->EntriesNum; i++) { | ||
62 | switch (entry->Entries[i].EntryType) { | ||
63 | case PBK_Number_General : if (*Number == -1) *Number = i; break; | ||
64 | case PBK_Text_Name : if (*Name == -1) *Name = i; break; | ||
65 | case PBK_Caller_Group : if (*Group == -1) *Group = i; break; | ||
66 | default : break; | ||
67 | } | ||
68 | } | ||
69 | if ((*Number) == -1) { | ||
70 | for (i = 0; i < entry->EntriesNum; i++) { | ||
71 | switch (entry->Entries[i].EntryType) { | ||
72 | case PBK_Number_Mobile: | ||
73 | case PBK_Number_Work: | ||
74 | case PBK_Number_Fax: | ||
75 | case PBK_Number_Home: | ||
76 | case PBK_Number_Pager: | ||
77 | case PBK_Number_Other: | ||
78 | *Number = i; | ||
79 | break; | ||
80 | default: | ||
81 | break; | ||
82 | } | ||
83 | if (*Number != -1) break; | ||
84 | } | ||
85 | } | ||
86 | if ((*Name) == -1) { | ||
87 | for (i = 0; i < entry->EntriesNum; i++) { | ||
88 | if (entry->Entries[i].EntryType != PBK_Text_LastName) continue; | ||
89 | *Name = i; | ||
90 | break; | ||
91 | } | ||
92 | } | ||
93 | if ((*Name) == -1) { | ||
94 | for (i = 0; i < entry->EntriesNum; i++) { | ||
95 | if (entry->Entries[i].EntryType != PBK_Text_FirstName) continue; | ||
96 | *Name = i; | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | void GSM_EncodeVCARD(char *Buffer, int *Length, GSM_MemoryEntry *pbk, bool header, GSM_VCardVersion Version) | ||
103 | { | ||
104 | int Name, Number, Group, i; | ||
105 | bool ignore; | ||
106 | |||
107 | GSM_PhonebookFindDefaultNameNumberGroup(pbk, &Name, &Number, &Group); | ||
108 | |||
109 | if (Version == Nokia_VCard10) { | ||
110 | if (header) *Length+=sprintf(Buffer+(*Length),"BEGIN:VCARD%c%c",13,10); | ||
111 | if (Name != -1) { | ||
112 | *Length+=sprintf(Buffer+(*Length),"N:%s%c%c",DecodeUnicodeString(pbk->Entries[Name].Text),13,10); | ||
113 | } | ||
114 | if (Number != -1) { | ||
115 | *Length +=sprintf(Buffer+(*Length),"TEL:%s%c%c",DecodeUnicodeString(pbk->Entries[Number].Text),13,10); | ||
116 | } | ||
117 | if (header) *Length+=sprintf(Buffer+(*Length),"END:VCARD%c%c",13,10); | ||
118 | } else if (Version == Nokia_VCard21) { | ||
119 | if (header) *Length+=sprintf(Buffer+(*Length),"BEGIN:VCARD%c%cVERSION:2.1%c%c",13,10,13,10); | ||
120 | if (Name != -1) { | ||
121 | SaveVCALText(Buffer, Length, pbk->Entries[Name].Text, "N"); | ||
122 | } | ||
123 | for (i=0; i < pbk->EntriesNum; i++) { | ||
124 | if (i != Name) { | ||
125 | ignore = false; | ||
126 | switch(pbk->Entries[i].EntryType) { | ||
127 | case PBK_Text_Name : | ||
128 | case PBK_Date : | ||
129 | case PBK_Caller_Group : | ||
130 | ignore = true; | ||
131 | break; | ||
132 | case PBK_Number_General : | ||
133 | *Length+=sprintf(Buffer+(*Length),"TEL"); | ||
134 | if (Number == i) (*Length)+=sprintf(Buffer+(*Length),";PREF"); | ||
135 | break; | ||
136 | case PBK_Number_Mobile : | ||
137 | *Length+=sprintf(Buffer+(*Length),"TEL"); | ||
138 | if (Number == i) (*Length)+=sprintf(Buffer+(*Length),";PREF"); | ||
139 | *Length+=sprintf(Buffer+(*Length),";CELL"); | ||
140 | break; | ||
141 | case PBK_Number_Work : | ||
142 | *Length+=sprintf(Buffer+(*Length),"TEL"); | ||
143 | if (Number == i) (*Length)+=sprintf(Buffer+(*Length),";PREF"); | ||
144 | *Length+=sprintf(Buffer+(*Length),";WORK;VOICE"); | ||
145 | break; | ||
146 | case PBK_Number_Fax : | ||
147 | *Length+=sprintf(Buffer+(*Length),"TEL"); | ||
148 | if (Number == i) (*Length)+=sprintf(Buffer+(*Length),";PREF"); | ||
149 | *Length+=sprintf(Buffer+(*Length),";FAX"); | ||
150 | break; | ||
151 | case PBK_Number_Home : | ||
152 | *Length+=sprintf(Buffer+(*Length),"TEL"); | ||
153 | if (Number == i) (*Length)+=sprintf(Buffer+(*Length),";PREF"); | ||
154 | *Length+=sprintf(Buffer+(*Length),";HOME;VOICE"); | ||
155 | break; | ||
156 | case PBK_Text_Note : | ||
157 | *Length+=sprintf(Buffer+(*Length),"NOTE"); | ||
158 | break; | ||
159 | case PBK_Text_Postal : | ||
160 | /* Don't ask why. Nokia phones save postal address | ||
161 | * double - once like LABEL, second like ADR | ||
162 | */ | ||
163 | SaveVCALText(Buffer, Length, pbk->Entries[i].Text, "LABEL"); | ||
164 | *Length+=sprintf(Buffer+(*Length),"ADR"); | ||
165 | break; | ||
166 | case PBK_Text_Email : | ||
167 | case PBK_Text_Email2 : | ||
168 | *Length+=sprintf(Buffer+(*Length),"EMAIL"); | ||
169 | break; | ||
170 | case PBK_Text_URL : | ||
171 | *Length+=sprintf(Buffer+(*Length),"URL"); | ||
172 | break; | ||
173 | default : | ||
174 | ignore = true; | ||
175 | break; | ||
176 | } | ||
177 | if (!ignore) { | ||
178 | SaveVCALText(Buffer, Length, pbk->Entries[i].Text, ""); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | if (header) *Length+=sprintf(Buffer+(*Length),"END:VCARD%c%c",13,10); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | GSM_Error GSM_DecodeVCARD(unsigned char *Buffer, int *Pos, GSM_MemoryEntry *Pbk, GSM_VCardVersion Version) | ||
187 | { | ||
188 | unsigned char Line[2000],Buff[2000]; | ||
189 | int Level = 0; | ||
190 | |||
191 | Buff[0] = 0; | ||
192 | Pbk->EntriesNum = 0; | ||
193 | |||
194 | while (1) { | ||
195 | MyGetLine(Buffer, Pos, Line, strlen(Buffer)); | ||
196 | if (strlen(Line) == 0) break; | ||
197 | switch (Level) { | ||
198 | case 0: | ||
199 | if (strstr(Line,"BEGIN:VCARD")) Level = 1; | ||
200 | break; | ||
201 | case 1: | ||
202 | if (strstr(Line,"END:VCARD")) { | ||
203 | if (Pbk->EntriesNum == 0) return ERR_EMPTY; | ||
204 | return ERR_NONE; | ||
205 | } | ||
206 | if (ReadVCALText(Line, "N", Buff)) { | ||
207 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
208 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Name; | ||
209 | Pbk->EntriesNum++; | ||
210 | } | ||
211 | if (ReadVCALText(Line, "TEL", Buff) || | ||
212 | ReadVCALText(Line, "TEL;VOICE", Buff) || | ||
213 | ReadVCALText(Line, "TEL;PREF", Buff) || | ||
214 | ReadVCALText(Line, "TEL;PREF;VOICE", Buff)) { | ||
215 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
216 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; | ||
217 | Pbk->EntriesNum++; | ||
218 | } | ||
219 | if (ReadVCALText(Line, "TEL;CELL", Buff) || | ||
220 | ReadVCALText(Line, "TEL;CELL;VOICE", Buff) || | ||
221 | ReadVCALText(Line, "TEL;PREF;CELL", Buff) || | ||
222 | ReadVCALText(Line, "TEL;PREF;CELL;VOICE", Buff)) { | ||
223 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
224 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; | ||
225 | Pbk->EntriesNum++; | ||
226 | } | ||
227 | if (ReadVCALText(Line, "TEL;WORK", Buff) || | ||
228 | ReadVCALText(Line, "TEL;PREF;WORK", Buff) || | ||
229 | ReadVCALText(Line, "TEL;WORK;VOICE", Buff) || | ||
230 | ReadVCALText(Line, "TEL;PREF;WORK;VOICE", Buff)) { | ||
231 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
232 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Work; | ||
233 | Pbk->EntriesNum++; | ||
234 | } | ||
235 | if (ReadVCALText(Line, "TEL;FAX", Buff) || | ||
236 | ReadVCALText(Line, "TEL;PREF;FAX", Buff) || | ||
237 | ReadVCALText(Line, "TEL;FAX;VOICE", Buff) || | ||
238 | ReadVCALText(Line, "TEL;PREF;FAX;VOICE", Buff)) { | ||
239 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
240 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Fax; | ||
241 | Pbk->EntriesNum++; | ||
242 | } | ||
243 | if (ReadVCALText(Line, "TEL;HOME", Buff) || | ||
244 | ReadVCALText(Line, "TEL;PREF;HOME", Buff) || | ||
245 | ReadVCALText(Line, "TEL;HOME;VOICE", Buff) || | ||
246 | ReadVCALText(Line, "TEL;PREF;HOME;VOICE", Buff)) { | ||
247 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
248 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Home; | ||
249 | Pbk->EntriesNum++; | ||
250 | } | ||
251 | if (ReadVCALText(Line, "NOTE", Buff)) { | ||
252 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
253 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Note; | ||
254 | Pbk->EntriesNum++; | ||
255 | } | ||
256 | if (ReadVCALText(Line, "ADR", Buff)) { | ||
257 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
258 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; | ||
259 | Pbk->EntriesNum++; | ||
260 | } | ||
261 | if (ReadVCALText(Line, "EMAIL", Buff)) { | ||
262 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
263 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Email; | ||
264 | Pbk->EntriesNum++; | ||
265 | } | ||
266 | if (ReadVCALText(Line, "URL", Buff)) { | ||
267 | CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); | ||
268 | Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_URL; | ||
269 | Pbk->EntriesNum++; | ||
270 | } | ||
271 | break; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | if (Pbk->EntriesNum == 0) return ERR_EMPTY; | ||
276 | return ERR_NONE; | ||
277 | } | ||
278 | |||
279 | /* -------------- OLD functions (c) by Timo Teras -------------------------- */ | ||
280 | |||
281 | #ifndef ENABLE_LGPL | ||
282 | |||
283 | static void ParseVCardLine(char **pos, char *Name, char *Parameters, char *Value) | ||
284 | { | ||
285 | int i; | ||
286 | |||
287 | Name[0] = Parameters[0] = Value[0] = 0; | ||
288 | |||
289 | if (**pos == 0) return; | ||
290 | |||
291 | for (i=0; **pos && **pos != ':' && **pos != ';'; i++, (*pos)++) Name[i] = **pos; | ||
292 | Name[i] = 0; | ||
293 | |||
294 | //dbgprintf("ParseVCardLine: name tag = '%s'\n", Name); | ||
295 | if (**pos == ';') { | ||
296 | (*pos)++; | ||
297 | for (i=0; **pos && **pos != ':'; i++, (*pos)++) Parameters[i] = **pos; | ||
298 | Parameters[i] = ';'; | ||
299 | Parameters[i+1] = 0; | ||
300 | //dbgprintf("ParseVCardLine: parameter tag = '%s'\n", Parameters); | ||
301 | } | ||
302 | |||
303 | if (**pos != 0) (*pos)++; | ||
304 | |||
305 | i=0; | ||
306 | while (**pos) { | ||
307 | if ((*pos)[0] == '\x0d' && (*pos)[1] == '\x0a') { | ||
308 | (*pos) += 2; | ||
309 | if (**pos != '\t' && **pos != ' ') break; | ||
310 | while (**pos == '\t' || **pos == ' ') (*pos)++; | ||
311 | continue; | ||
312 | } | ||
313 | Value[i++] = **pos; | ||
314 | (*pos)++; | ||
315 | } | ||
316 | Value[i] = 0; | ||
317 | |||
318 | //dbgprintf("ParseVCardLine: value tag = '%s'\n", Value); | ||
319 | } | ||
320 | |||
321 | void DecodeVCARD21Text(char *VCard, GSM_MemoryEntry *pbk) | ||
322 | { | ||
323 | char *pos = VCard; | ||
324 | char Name[32], Parameters[256], Value[1024]; | ||
325 | |||
326 | dbgprintf("Parsing VCard:\n%s\n", VCard); | ||
327 | |||
328 | ParseVCardLine(&pos, Name, Parameters, Value); | ||
329 | if (!mystrncasecmp(Name, "BEGIN", 0) || !mystrncasecmp(Value, "VCARD", 0)) { | ||
330 | dbgprintf("No valid VCARD signature\n"); | ||
331 | return; | ||
332 | } | ||
333 | |||
334 | while (1) { | ||
335 | GSM_SubMemoryEntry *pbe = &pbk->Entries[pbk->EntriesNum]; | ||
336 | |||
337 | ParseVCardLine(&pos, Name, Parameters, Value); | ||
338 | if (Name[0] == 0x00 || | ||
339 | (mystrncasecmp(Name, "END", 0) && mystrncasecmp(Value, "VCARD", 0))) | ||
340 | return; | ||
341 | |||
342 | if (mystrncasecmp(Name, "N", 0)) { | ||
343 | //FIXME: Name is tagged field which should be parsed | ||
344 | pbe->EntryType = PBK_Text_Name; | ||
345 | EncodeUnicode(pbe->Text, Value, strlen(Value)); | ||
346 | pbk->EntriesNum++; | ||
347 | } else if (mystrncasecmp(Name, "EMAIL", 0)) { | ||
348 | pbe->EntryType = PBK_Text_Email; | ||
349 | EncodeUnicode(pbe->Text, Value, strlen(Value)); | ||
350 | pbk->EntriesNum++; | ||
351 | } else if (mystrncasecmp(Name, "TEL", 0)) { | ||
352 | if (strstr(Parameters, "WORK;")) | ||
353 | pbe->EntryType = PBK_Number_Work; | ||
354 | else if (strstr(Name, "HOME;")) | ||
355 | pbe->EntryType = PBK_Number_Home; | ||
356 | else if (strstr(Name, "FAX;")) | ||
357 | pbe->EntryType = PBK_Number_Fax; | ||
358 | else pbe->EntryType = PBK_Number_General; | ||
359 | |||
360 | EncodeUnicode(pbe->Text, Value, strlen(Value)); | ||
361 | pbk->EntriesNum++; | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | |||
366 | #endif | ||
367 | |||
368 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
369 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
370 | */ | ||