00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <stdbool.h>
00056 #include <stdarg.h>
00057 #include <string.h>
00058 #include <fcntl.h>
00059 #include <unistd.h>
00060 #include <sys/types.h>
00061 #include <sys/stat.h>
00062 #include "qDecoder.h"
00063 #include "qInternal.h"
00064
00074 Q_ENTRY *qEntryInit(void) {
00075 Q_ENTRY *entry = (Q_ENTRY *)malloc(sizeof(Q_ENTRY));
00076 if(entry == NULL) return NULL;
00077
00078 memset((void *)entry, 0, sizeof(Q_ENTRY));
00079 return entry;
00080 }
00081
00089 const Q_NLOBJ *qEntryFirst(Q_ENTRY *entry) {
00090 if(entry == NULL) return NULL;
00091
00092 entry->next = entry->first;
00093 return qEntryNext(entry);
00094 }
00095
00103 const Q_NLOBJ *qEntryNext(Q_ENTRY *entry) {
00104 if(entry == NULL) return NULL;
00105
00106 Q_NLOBJ *obj = entry->next;
00107 if(obj != NULL) {
00108 entry->next = obj->next;
00109 }
00110 return obj;
00111 }
00112
00121 int qEntryRemove(Q_ENTRY *entry, const char *name) {
00122 if(entry == NULL || name == NULL) return 0;
00123
00124 int entrynum = entry->num;
00125 Q_NLOBJ *prev, *obj;
00126 for (prev = NULL, obj = entry->first; obj;) {
00127 if (!strcmp(obj->name, name)) {
00128
00129 Q_NLOBJ *next = obj->next;
00130
00131
00132 entry->size -= obj->size;
00133 entry->num--;
00134
00135
00136 free(obj->name);
00137 free(obj->object);
00138 free(obj);
00139
00140
00141 if(next == NULL) entry->last = prev;
00142 if(prev == NULL) entry->first = next;
00143 else prev->next = next;
00144
00145
00146 obj = next;
00147 } else {
00148
00149 prev = obj;
00150
00151
00152 obj = obj->next;
00153 }
00154 }
00155
00156 return (entrynum - entry->num);
00157 }
00158
00170 bool qEntryPut(Q_ENTRY *entry, const char *name, const void *object, int size, bool update) {
00171
00172 if(entry == NULL || name == NULL || object == NULL || size < 0) return false;
00173
00174
00175 char *dup_name = strdup(name);
00176 if(dup_name == NULL) return false;
00177
00178
00179 void *dup_object = (size>0?malloc(size):strdup(""));
00180 if(dup_object == NULL) {
00181 free(dup_name);
00182 return false;
00183 }
00184 memcpy(dup_object, object, size);
00185
00186
00187 if (update == true) qEntryRemove(entry, dup_name);
00188
00189
00190 Q_NLOBJ *obj = (Q_NLOBJ*)malloc(sizeof(Q_NLOBJ));
00191 if(obj == NULL) {
00192 free(dup_name);
00193 free(dup_object);
00194 return false;
00195 }
00196 obj->name = dup_name;
00197 obj->object = dup_object;
00198 obj->size = size;
00199 obj->next = NULL;
00200
00201
00202 if(entry->first == NULL) entry->first = entry->last = obj;
00203 else {
00204 entry->last->next = obj;
00205 entry->last = obj;
00206 }
00207
00208 entry->size += size;
00209 entry->num++;
00210 return true;
00211 }
00212
00223 bool qEntryPutStr(Q_ENTRY *entry, const char *name, const char *str, bool update) {
00224 int size = (str!=NULL) ? (strlen(str) + 1) : 0;
00225 return qEntryPut(entry, name, (const void *)str, size, update);
00226 }
00227
00238 bool qEntryPutStrf(Q_ENTRY *entry, const char *name, bool update, char *format, ...) {
00239 char str[MAX_LINEBUF];
00240 va_list arglist;
00241
00242 va_start(arglist, format);
00243 vsnprintf(str, sizeof(str), format, arglist);
00244 va_end(arglist);
00245
00246 return qEntryPutStr(entry, name, str, update);
00247 }
00248
00259 bool qEntryPutInt(Q_ENTRY *entry, const char *name, int num, bool update) {
00260 char str[10+1];
00261 sprintf(str, "%d", num);
00262 return qEntryPut(entry, name, (void *)str, strlen(str) + 1, update);
00263 }
00264
00279 const void *qEntryGet(Q_ENTRY *entry, const char *name, int *size) {
00280 if(entry == NULL || name == NULL) return NULL;
00281
00282 Q_NLOBJ *obj;
00283 for(obj = entry->first; obj; obj = obj->next) {
00284 if(!strcmp(obj->name, name)) {
00285 if(size != NULL) *size = obj->size;
00286 entry->cont = obj->next;
00287 return obj->object;
00288 }
00289 }
00290
00291 entry->cont = NULL;
00292 return NULL;
00293 }
00294
00304 const void *qEntryGetCase(Q_ENTRY *entry, const char *name, int *size) {
00305 if(entry == NULL || name == NULL) return NULL;
00306
00307 Q_NLOBJ *obj;
00308 for(obj = entry->first; obj; obj = obj->next) {
00309 if(!strcasecmp(name, obj->name)) {
00310 if(size != NULL) *size = obj->size;
00311 entry->cont = obj->next;
00312 return obj->object;
00313 }
00314 }
00315
00316 entry->cont = NULL;
00317 return NULL;
00318 }
00319
00332 const void *qEntryGetNext(Q_ENTRY *entry, const char *name, int *size) {
00333 if(entry == NULL || name == NULL) return NULL;
00334
00335 const Q_NLOBJ *obj;
00336 for(obj = entry->cont; obj; obj = obj->next) {
00337 if(!strcmp(obj->name, name)) {
00338 entry->next = obj->next;
00339 if(size != NULL) *size = obj->size;
00340 entry->cont = obj->next;
00341 return obj->object;
00342 }
00343 }
00344
00345 entry->cont = NULL;
00346 return NULL;
00347 }
00348
00361 const void *qEntryGetNextCase(Q_ENTRY *entry, const char *name, int *size) {
00362 if(entry == NULL || name == NULL) return NULL;
00363
00364 const Q_NLOBJ *obj;
00365 for(obj = entry->cont; obj; obj = obj->next) {
00366 if(!strcasecmp(name, obj->name)) {
00367 entry->next = obj->next;
00368 if(size != NULL) *size = obj->size;
00369 entry->cont = obj->next;
00370 return obj->object;
00371 }
00372 }
00373
00374 entry->cont = NULL;
00375 return NULL;
00376 }
00377
00391 const void *qEntryGetLast(Q_ENTRY *entry, const char *name, int *size) {
00392 if(entry == NULL || name == NULL) return NULL;
00393
00394 void *object = NULL;
00395 Q_NLOBJ *obj;
00396 for(obj = entry->first; obj; obj = obj->next) {
00397 if (!strcmp(name, obj->name)) {
00398 object = obj->object;
00399 if(size != NULL) *size = obj->size;
00400 }
00401 }
00402
00403 return object;
00404 }
00405
00417 const char *qEntryGetStr(Q_ENTRY *entry, const char *name) {
00418 return (char *)qEntryGet(entry, name, NULL);
00419 }
00420
00429 const char *qEntryGetStrCase(Q_ENTRY *entry, const char *name) {
00430 return (char *)qEntryGetCase(entry, name, NULL);
00431 }
00432
00441 const char *qEntryGetStrf(Q_ENTRY *entry, char *format, ...) {
00442 char name[MAX_LINEBUF];
00443 va_list arglist;
00444
00445 va_start(arglist, format);
00446 vsnprintf(name, sizeof(name), format, arglist);
00447 va_end(arglist);
00448
00449 return (char *)qEntryGet(entry, name, NULL);
00450 }
00451
00460 const char *qEntryGetStrNext(Q_ENTRY *entry, const char *name) {
00461 return (char *)qEntryGetNext(entry, name, NULL);
00462 }
00463
00472 const char *qEntryGetStrNextCase(Q_ENTRY *entry, const char *name) {
00473 return (char *)qEntryGetNextCase(entry, name, NULL);
00474 }
00475
00484 const char *qEntryGetStrLast(Q_ENTRY *entry, const char *name) {
00485 return (char *)qEntryGetLast(entry, name, NULL);
00486 }
00487
00499 int qEntryGetInt(Q_ENTRY *entry, const char *name) {
00500 const char *str =qEntryGet(entry, name, NULL);
00501 if(str != NULL) return atoi((char *)str);
00502 return 0;
00503 }
00504
00513 int qEntryGetIntCase(Q_ENTRY *entry, const char *name) {
00514 const char *str =qEntryGetCase(entry, name, NULL);
00515 if(str != NULL) return atoi((char *)str);
00516 return 0;
00517 }
00518
00527 int qEntryGetIntf(Q_ENTRY *entry, char *format, ...) {
00528 char name[MAX_LINEBUF];
00529 va_list arglist;
00530
00531 va_start(arglist, format);
00532 vsnprintf(name, sizeof(name), format, arglist);
00533 va_end(arglist);
00534
00535 return qEntryGetInt(entry, name);
00536 }
00537
00546 int qEntryGetIntNext(Q_ENTRY *entry, const char *name) {
00547 const char *str =qEntryGetNext(entry, name, NULL);
00548 if(str != NULL) return atoi((char *)str);
00549 return 0;
00550 }
00551
00560 int qEntryGetIntNextCase(Q_ENTRY *entry, const char *name) {
00561 const char *str =qEntryGetNextCase(entry, name, NULL);
00562 if(str != NULL) return atoi((char *)str);
00563 return 0;
00564 }
00565
00574 int qEntryGetIntLast(Q_ENTRY *entry, const char *name) {
00575 const char *str =qEntryGetLast(entry, name, NULL);
00576 if(str != NULL) return atoi(str);
00577 return 0;
00578 }
00579
00587 int qEntryGetNum(Q_ENTRY *entry) {
00588 if(entry == NULL) return 0;
00589
00590 return entry->num;
00591 }
00592
00601 int qEntryGetNo(Q_ENTRY *entry, const char *name) {
00602 if(entry == NULL || name == NULL) return 0;
00603
00604 int no;
00605 Q_NLOBJ *obj;
00606 for(obj = entry->first, no = 1; obj; obj = obj->next, no++) {
00607 if (!strcmp(name, obj->name)) return no;
00608 }
00609 return 0;
00610 }
00611
00621 bool qEntryReverse(Q_ENTRY *entry) {
00622 if(entry == NULL) return false;
00623
00624 Q_NLOBJ *prev, *obj;
00625 for (prev = NULL, obj = entry->first; obj;) {
00626 Q_NLOBJ *next = obj->next;
00627 obj->next = prev;
00628 prev = obj;
00629 obj = next;
00630 }
00631
00632 entry->last = entry->first;
00633 entry->first = prev;
00634
00635 return true;
00636 }
00637
00645 bool qEntryPrint(Q_ENTRY *entry, FILE *out, bool print_object) {
00646 if(entry == NULL || out == NULL) return false;
00647
00648 const Q_NLOBJ *obj;
00649 for(obj = entry->first; obj; obj = obj->next) {
00650 fprintf(out, "%s=%s (%d)\n" , obj->name, (print_object?(char*)obj->object:"(object)"), obj->size);
00651 }
00652
00653 return true;
00654 }
00655
00663 bool qEntryFree(Q_ENTRY *entry) {
00664 if(entry == NULL) return false;
00665
00666 Q_NLOBJ *obj;
00667 for(obj = entry->first; obj;) {
00668 Q_NLOBJ *next = obj->next;
00669 free(obj->name);
00670 free(obj->object);
00671 free(obj);
00672 obj = next;
00673 }
00674 free(entry);
00675
00676 return true;
00677 }
00678
00690 bool qEntrySave(Q_ENTRY *entry, const char *filepath, char sepchar, bool encode) {
00691 if(entry == NULL) return false;
00692
00693 int fd;
00694 if ((fd = open(filepath, O_CREAT|O_WRONLY|O_TRUNC, DEF_FILE_MODE)) < 0) return false;
00695
00696 char *gmtstr = qTimeGetGmtStr(0);
00697 _q_writef(fd, "# automatically generated by qDecoder at %s.\n", gmtstr);
00698 _q_writef(fd, "# %s\n", filepath);
00699 free(gmtstr);
00700
00701 const Q_NLOBJ *obj;
00702 for(obj = entry->first; obj; obj = obj->next) {
00703 char *encval;
00704 if(encode == true) encval = qEncodeUrl(obj->object);
00705 else encval = obj->object;
00706 _q_writef(fd, "%s%c%s\n", obj->name, sepchar, encval);
00707 if(encode == true) free(encval);
00708 }
00709
00710 close(fd);
00711 return true;
00712 }
00713
00724 int qEntryLoad(Q_ENTRY *entry, const char *filepath, char sepchar, bool decode) {
00725 if(entry == NULL) return 0;
00726
00727 Q_ENTRY *loaded;
00728 if ((loaded = qConfigParseFile(NULL, filepath, sepchar)) == NULL) return false;
00729
00730 int cnt = 0;
00731 Q_NLOBJ *obj;
00732 for(obj = loaded->first; obj; obj = obj->next) {
00733 if(decode == true) qDecodeUrl(obj->object);
00734 qEntryPut(entry, obj->name, obj->object, obj->size, false);
00735 cnt++;
00736 }
00737
00738 qEntryFree(loaded);
00739
00740 return cnt;
00741 }