/* get a user from hash table. if not exist, create one by img_user(). */ static UserNode* get_afriend(char *userid) { UserNode *punode; punode = ght_get(fidx, strlen(userid), userid); if(punode) return punode; if(img_user(userid) == -1) return NULL; punode = ght_get(fidx, strlen(userid), userid); return punode; }
struct cgi_applet * get_cgi_applet(char *needcgi) { static ght_hash_table_t *p_table = NULL; struct cgi_applet *a; if (p_table == NULL) { int i; a = applets; p_table = ght_create(250, NULL, 0); while (a->main != NULL) { a->count = 0; a->utime = 0; a->stime = 0; for (i = 0; a->name[i] != NULL; i++) ght_insert(p_table, (void *) a, strlen(a->name[i]), (void *) a->name[i]); a++; } } if (p_table == NULL) return NULL; return ght_get(p_table, strlen(needcgi), needcgi); }
static void query_adiv(char *userid) { ght_iterator_t it; void *key; int div, count; UserNode *punode; FILE *fp; char tmpf[256], fpath[256]; sprintf(tmpf, FRIENDS_TMPDIR "/%s.div.tmp", userid); if((fp = fopen(tmpf, "w+")) == NULL) return; punode = ght_get(fidx, strlen(userid), userid); if(punode == NULL) { fprintf(fp, "Query return null result."); goto END_WITH_RESULT; } div = punode->div; count = 0; for(punode = ght_first(fidx, &it, &key); punode; punode = ght_next(fidx, &it, &key)) { if(div == punode->div && div > 0) { count++; fprintf(fp, "%s%c", punode->userid, (count % 6 == 5) ? '\n' : '\t'); } } END_WITH_RESULT: fclose(fp); sprintf(fpath, FRIENDS_TMPDIR "/%s.div", userid); rename(tmpf, fpath); return; }
int bansiteop(struct in_addr *from) { struct bansite *b; ght_iterator_t iterator; ght_hash_table_t *tmptable; void *key; static time_t last = 0; time_t now_t = time(NULL); FILE *fp; if (!bansitetable) bansitetable = ght_create(200); if (!bansitetable) return -1; if (from) { if ((b = ght_get(bansitetable, sizeof (*from), from))) { b->t = now_t; return 0; } b = malloc(sizeof (*b)); if (!b) return -1; b->t = time(NULL); b->from = *from; if (ght_insert(bansitetable, b, sizeof (*from), from) < 0) { free(b); return -1; } } if (!from && now_t - last < 100) return 0; fp = fopen(MY_BBS_HOME "/bbstmpfs/dynamic/bansite", "w"); if (!fp) return -1; last = now_t; tmptable = bansitetable; bansitetable = ght_create(200); if (!bansitetable) { bansitetable = tmptable; return -1; } for (b = ght_first(tmptable, &iterator, &key); b; b = ght_next(tmptable, &iterator, &key)) { if (b->t < now_t - 6000) { free(b); continue; } fprintf(fp, "%s\n", inet_ntoa(b->from)); if (ght_insert(bansitetable, b, sizeof (b->from), &b->from) < 0) { free(b); } } ght_finalize(tmptable); fclose(fp); return 0; }
/* 查询userid的邻居,最多查找1024个,按照距离升序排列,并最多显示topn个。 * 由于子进程执行完该函数很快退出,因此就不一一释放内存了。 */ static void query_neighbour(int flag, char *userid, int topn, int distance) { int i; UserNode *punode; QueryCondt qc; FILE *fp; char tmpf[256], fpath[256]; if(topn <= 0 || distance <= 0) return; sprintf(tmpf, FRIENDS_TMPDIR "/%s.%d.tmp", userid, flag); if((fp = fopen(tmpf, "w+")) == NULL) return; punode = ght_get(fidx, strlen(userid), userid); if(punode == NULL) { fprintf(fp, "Query return null result."); goto END_WITH_RESULT; } qc.max = flag ? queue_len(punode->to) : queue_len(punode->from); qc.list = malloc(sizeof(Neighbour)*(qc.max+1)); if(qc.list == NULL) goto END_WITH_ERROR; qc.count = 0; qc.distance = distance; if(flag) apply_queue(punode->to, get_neighbour, &qc); else apply_queue(punode->from, get_neighbour, &qc); if(qc.count == 0) fprintf(fp, "Query return null result."); qsort(qc.list, qc.count, sizeof(Neighbour), (void*)cmp_dist); for(i = 0; i < qc.count && i < topn; i++) { fprintf(fp, "%s%c", qc.list[i].userid, (i % 6 == 5) ? '\n' : '\t'); } END_WITH_RESULT: fclose(fp); sprintf(fpath, FRIENDS_TMPDIR "/%s.%d", userid, flag); rename(tmpf, fpath); return; END_WITH_ERROR: fclose(fp); unlink(tmpf); return; }
int filter_passerr(int n, char *arg[]) { struct event *e; int *count; if (n < 4 || strcmp(arg[1], "system") || strcmp(arg[2], "passerr")) return 0; if (passerrtable == NULL) passerrtable = ght_create(10000); if (!passerrtable) goto ERROR; e = malloc(sizeof (struct event)); if (!e) goto ERROR; e->t = time(NULL); inet_aton(arg[3], &e->from); if ((count = ght_get(passerrtable, sizeof (e->from), &e->from))) { (*count)++; if (*count > site_limit(&e->from)) bansiteop(&e->from); } else { count = malloc(sizeof (int)); if (!count) goto ERROR1; *count = 1; if (ght_insert(passerrtable, count, sizeof (e->from), &e->from) < 0) goto ERROR2; } //add to list if (eventhead == NULL) { eventhead = e; eventtail = e; } else { eventtail->next = e; eventtail = e; } e->next = NULL; return 1; ERROR2: free(count); ERROR1: free(e); ERROR: return 1; }
struct boardmem * getbcache(char *board) { int i, j; static int num = 0; char upperstr[STRLEN]; static ght_hash_table_t *p_table = NULL; static time_t uptime = 0; struct boardmem *ptr; if (board[0] == 0) return NULL; if (p_table && (num != shm_bcache->number || shm_bcache->uptime > uptime)) { ght_finalize(p_table); p_table = NULL; } if (p_table == NULL) { num = 0; p_table = ght_create(MAXBOARD); for (i = 0; i < MAXBOARD && i < shm_bcache->number; i++) { num++; if (!shm_bcache->bcache[i].header.filename[0]) continue; strsncpy(upperstr, shm_bcache->bcache[i].header.filename, sizeof (upperstr)); for (j = 0; upperstr[j]; j++) upperstr[j] = toupper(upperstr[j]); ght_insert(p_table, &shm_bcache->bcache[i], j, upperstr); } uptime = now_t; } strsncpy(upperstr, board, sizeof (upperstr)); for (j = 0; upperstr[j]; j++) upperstr[j] = toupper(upperstr[j]); ptr = ght_get(p_table, j, upperstr); if (!ptr) return numboard(board); return ptr; }
static int process_command(sub_client *c) { srv_log(LOG_DEBUG, "c->argv[0]: %s", c->argv[0]); sds name = sdsnew(c->argv[0]); sdstolower(name); sub_command *cmd = ght_get(server.sub_commands, sdslen(name), name); if (!cmd) { add_reply_error_fmt(c, "unknown command '%s'", name); } else if ((cmd->arity > 0 && cmd->arity != c->argc) || (c->argc < -cmd->arity)) { add_reply_error_fmt(c, "wrong number of arguments for '%s' command", name); } else { srv_log(LOG_DEBUG, "cmd name: %s arity: %d", cmd->name, cmd->arity); cmd->proc(c); } sdsfree(name); return SUBCLI_OK; }
int expireevent() { struct event *e; int *count; time_t now_t = time(NULL); while (eventhead) { e = eventhead; if (e->t > now_t - 600) break; eventhead = e->next; count = ght_get(passerrtable, sizeof (e->from), &e->from); (*count)--; if (!*count) { ght_remove(passerrtable, sizeof (e->from), &e->from); free(count); } free(e); } if (!eventhead) eventtail = NULL; return 0; }
/* * This is an example program that reads words from a text-file (a * book or something like that) and uses those as keys in a hash table * (the actual data stored is unimportant). The words are case * sensitive. * * After this, the program opens another text-file and tries to match * the words in that with the words stored in the table. * * The meaning with this program is to test the speed of the table and * to provide an example of its use. */ int main(int argc, char *argv[]) { FILE *p_file; char *p_dict_name; char *p_text_name; ght_hash_table_t *p_table; ght_iterator_t iterator; struct stat stat_struct; int i_found; int i_cnt; char *p_buf; char *p_tok; const void *p_key; void *p_e; /* Create a new hash table */ if ( !(p_table = ght_create(1000)) ) { return 1; } ght_set_rehash(p_table, TRUE); /* Parse the arguments */ if (argc < 3) { printf("Usage: dict_example [-m|-t|-b] dictfile textfile\n\n" "Reads words from `dictfile' and looks up these words in `textfile'.\n" "Options:\n" " -m Use move-to-front heuristics\n" " -t Use transpose heuristics\n" " -b Use bounded buckets (use the hash table as a cache)\n" ); return 0; } else if (argc > 3) { if(strcmp(argv[1], "-m") == 0) ght_set_heuristics(p_table, GHT_HEURISTICS_MOVE_TO_FRONT); else if(strcmp(argv[1], "-t") == 0) ght_set_heuristics(p_table, GHT_HEURISTICS_TRANSPOSE); else if (strcmp(argv[1], "-b") == 0) { /* Rehashing makes no sense in "cache" mode */ ght_set_rehash(p_table, FALSE); ght_set_bounded_buckets(p_table, 3, bucket_free_callback); } p_dict_name = argv[2]; p_text_name = argv[3]; } else { /* 2 arguments */ p_dict_name = argv[1]; p_text_name = argv[2]; } /* Open the dictionary file (first check its size) */ if (stat(p_dict_name, &stat_struct) < 0) { perror("stat"); return 1; } if (!(p_buf = (char*)malloc(stat_struct.st_size))) { perror("malloc"); return 1; } /* Open the dictionary file and read that into the buffer. */ if (! (p_file = fopen(p_dict_name, "r")) ) { perror("fopen"); return 1; } fread(p_buf, sizeof(char), stat_struct.st_size, p_file); fclose(p_file); /* For each word in the dictionary file, insert it into the hash table. */ p_tok = strtok(p_buf, DELIMS); i_cnt = 0; i_found = 0; while (p_tok) { int *p_data; if ( !(p_data = (int*)malloc(sizeof(int))) ) { perror("malloc"); return 1; } *p_data = i_cnt++; /* Insert the word into the table */ if (ght_insert(p_table, p_data, strlen(p_tok), p_tok) < 0) free(p_data); /* Could not insert the item (already exists), free it. */ else i_found++; p_tok = strtok(NULL, DELIMS); } printf("Done reading %d unique words from the wordlist.\n" "Total number of words is %d.\n\n", i_found, i_cnt); free(p_buf); /* Check the size of the text file. */ if (stat(p_text_name, &stat_struct) < 0) { perror("stat"); return 1; } if (!(p_buf = (char*)malloc(stat_struct.st_size))) { perror("malloc"); return 1; } /* Open the text file and read that into the buffer. */ if (! (p_file = fopen(p_text_name, "r")) ) { perror("fopen"); return 1; } fread(p_buf, sizeof(char), stat_struct.st_size, p_file); fclose(p_file); /* For each word in the text file, check if it exists in the hash table. */ p_tok = strtok(p_buf, DELIMS); i_cnt = 0; i_found = 0; while (p_tok) { printf(" searching %s ;", p_tok); if (ght_get(p_table, strlen(p_tok), p_tok)) { i_found++; } i_cnt++; p_tok = strtok(NULL, DELIMS); } free(p_buf); printf("Found %d words out of %d words\n", i_found, i_cnt); /* Free the entry data in the table */ for(p_e = ght_first(p_table, &iterator, &p_key); p_e; p_e = ght_next(p_table, &iterator, &p_key)) { free(p_e); } /* Free the table */ ght_finalize(p_table); return 0; }
/* 按照Dijkstra算法寻找从from到to的最短路径。对fidx只读。 * 由于子进程执行完该函数很快结束,因此就不一一释放内存了。 */ static void query_path(char *from, char *to, int distance) { ght_iterator_t it; void *key; UserNode *pun_from, *pun_to, *tmp; PathNode *pn; pLinkList S; Path *dist, *ptr; int nu, i; PathParam pp; FILE *fp; char tmpf[256], fpath[256]; pun_from = ght_get(fidx, strlen(from), from); if(pun_from == NULL) return; pun_to = ght_get(fidx, strlen(to), to); if(to == NULL) return; sprintf(tmpf, FRIENDS_TMPDIR "/%s.%s.path.tmp", from ,to); fp = fopen(tmpf, "w+"); if(fp == NULL) return; //节省起见, 如果不在一个圈子或者还没有划分,就不找了 if(pun_from->div != pun_to->div || pun_from->div == 0) { fprintf(fp, "Query return null result."); goto END_WITH_RESULT; } if((S = init_queue()) == NULL) //待查找集 goto END_WITH_ERROR; nu = 1; for(tmp = ght_first(fidx, &it, &key); tmp; tmp = ght_next(fidx, &it, &key)) { if(tmp->div == pun_from->div && tmp != pun_from) { pn = malloc(sizeof(PathNode)); if(pn == NULL) goto END_WITH_ERROR; pn->pun = tmp; pn->midx = pn->pidx = 0; if(insert_node(S, pn) == -1) goto END_WITH_ERROR; nu++; } } if(nu > 1024) { fprintf(fp, "朋友圈过于庞大,查询被拒绝。\n"); goto END_WITH_RESULT; } dist = malloc(sizeof(Path)*nu); if(dist == NULL) goto END_WITH_ERROR; pn = malloc(sizeof(PathNode)); if(pn == NULL) goto END_WITH_ERROR; pn->pun = pun_from; //put "from" in dist[0] pn->midx = pn->pidx = 0; dist[0].me = pn; dist[0].prev = pn; dist[0].len = 0; //myself pp.dist = dist; pp.curr = 1; //curr=0 is "from" pp.distance = distance; //limited distance pp.nu = nu; //num friends pp.pn = pn; apply_queue(S, init_dist, &pp); //init dist array while(!is_empty(S)) { //S是未计算完毕的集合 pp.pn = NULL; pp.len = INFINITY; apply_queue(S, find_min, &pp); //找出距离值最小的,放在pp.pn if(pp.pn == NULL) goto END_WITH_ERROR; apply_queue(S, renew_dist, &pp); //用pp.pn更新距离值 delete_node2(S, (void*)pp.pn, 0); //只从队列中删除,pp.pn不释放 } //find "to" for(i = 0; i < nu; i++) { if(dist[i].me->pun == pun_to) break; } if(i == nu) goto END_WITH_ERROR; ptr = &dist[i]; for(i = 0; ptr->me && ptr->me->pun != pun_from && i < nu; i++) { fprintf(fp, "%s <--%c", ptr->me->pun->userid, (i%6==5) ? '\n' : ' '); ptr = &dist[ptr->prev->midx]; } fprintf(fp, "%s", dist[0].me->pun->userid); END_WITH_RESULT: fclose(fp); sprintf(fpath, FRIENDS_TMPDIR "/%s.%s.path", from ,to); rename(tmpf, fpath); return; END_WITH_ERROR: fclose(fp); unlink(tmpf); return; }
static bstring tr_evalKey(TextResource tr, const char* key) { trnode_t* node = ght_get(tr->strings,strlen(key),key); if (!node) return bformat("<'%s' not found>",key); return tr_eval(tr,node); }
int main(int argc,char *argv[]) { int rc; char *k, *v, *line, buf[BUFSIZ]; ght_hash_table_t *p_table=NULL; /* create hash table of size 256 */ p_table=ght_create(256); if (p_table == NULL) { print_it("Error: Could not create hash table\n"); return(1); } print_menu(); for (;;) { print_prompt(); line=fgets(buf,sizeof(buf)-1,stdin); if (line == NULL) break; switch(*line) { case 'i': { k=read_data("Enter key: "); v=read_data("Enter value: "); if (k && v) { /* insert to hash table */ rc=ght_insert(p_table, v, strlen(k), k); if (rc == 0) { print_it("Inserted: Key=%s, Value=%s\n", k,v); free(k); } else { print_it("Error: ght_insert() failed\n"); (void) free((char *) k); (void) free((char *) v); } } else { if (k) (void) free((char *) k); if (v) (void) free((char *) v); } break; } case 'r': /* replace */ { k=read_data("Enter key: "); v=read_data("Enter new value: "); if (k && v) { char * old_val; /* Replace a key in the hash table */ old_val = (char*)ght_replace(p_table, v, strlen(k), k); if (old_val != NULL) { print_it("Replaced: Key=%s, Old Value=%s, Value=%s\n", k,old_val, v); free(old_val); free(k); } else { print_it("Error: ght_replace() failed\n"); (void) free((char *) k); (void) free((char *) v); } } else { if (k) (void) free((char *) k); if (v) (void) free((char *) v); } break; } case 'h': { print_menu(); break; } case 'n': /* number of elements */ { print_it("Number elements in hash table: %d\n", ght_size(p_table)); break; } case 's': /* size of hash table */ { print_it("Hash table size: %d\n", ght_table_size(p_table)); break; } case 't': /* dump */ { const void *pk, *pv; ght_iterator_t iterator; for (pv=(char *) ght_first(p_table,&iterator, &pk); pv; pv=(char *) ght_next(p_table,&iterator, &pk)) { print_it("%s => %s\n",(char *) pk,(char *) pv); } break; } case 'd': { k=read_data("Enter key to delete: "); if (k) { v=ght_remove(p_table, strlen(k), k); if (v) { print_it("Removed %s => %s",k,v); (void) free((char *) v); } else { print_it("Error: could not find data for key %s\n", k); } (void) free((char *) k); } break; } case 'l': { k=read_data("Enter key: "); if (k) { v=(char *) ght_get(p_table,strlen(k),k); if (v) { print_it("Found: %s => %s\n",k,v); } else { print_it("No data found for key: %s\n",k); } (void) free((char *) k); } break; } case 'q': { if (p_table) { const void *pv, *pk; ght_iterator_t iterator; for (pv=(char *) ght_first(p_table,&iterator, &pk); pv; pv=(char *) ght_next(p_table,&iterator, &pk)) { (void) free((char *) pv); } ght_finalize(p_table); } return(0); break; } default: { print_it("Unknown option\n"); break; } } } return(0); }
/******************************************************* * WriteMmdModelMaterials関数 * * PMDとPMXのテクスチャ画像データを書き出す * * 引数 * * model : テクスチャ画像データを書き出すモデル * * out_data_size : 書き出したデータのバイト数格納先 * * 返り値 * * 書き出したデータ * *******************************************************/ uint8* WriteMmdModelMaterials( MODEL_INTERFACE* model, size_t* out_data_size ) { // 画像データをまとめて書き出すバッファ MEMORY_STREAM *stream = CreateMemoryStream(1024 * 1024); // 作成結果のストリーム MEMORY_STREAM result_stream = {0}; // 作成結果データ uint8 *result; // テクスチャ画像配列へのポインタ MATERIAL_INTERFACE **materials; // 画像データの格納先 uint8 *image_data = NULL; // 画像データ格納バッファのサイズ size_t image_data_buffer_size = 0; // UTF-8での画像ファイルへのパス char utf8_path[8192]; // OSでの画像ファイルへのパス char *system_path; // 画像ファイルの読み込み、ファイルサイズ、存在確認用 FILE *fp; // 画像ファイルの数 int num_images = 0; // テクスチャ画像配列のサイズ int num_materials; // 32ビット書き出し用 uint32 data32; // 画像データの開始位置 long image_start = sizeof(data32); // 画像データの合計サイズ long total_image_size = 0; int counter; // 書き出す画像ファイルの名前・サイズ配列 MATERIAL_ARCHIVE_DATA *names; // 重複書き出し防止用 ght_hash_table_t *name_table; unsigned int name_length; uint32 diff; // for文用のカウンタ int i; // モデルに設定されているテクスチャ画像を取得 materials = (MATERIAL_INTERFACE**)model->get_materials(model, &num_materials); name_table = ght_create(num_materials+1); ght_set_hash(name_table, (ght_fn_hash_t)GetStringHash); // それぞれの画像ファイルのファイル名サイズを取得 for(i=0; i<num_materials; i++) { MATERIAL_INTERFACE *material = materials[i]; if(material->main_texture != NULL) { name_length = (unsigned int)strlen(material->main_texture); if(ght_get(name_table, name_length, material->main_texture) == NULL) { (void)ght_insert(name_table, (void*)1, name_length, material->main_texture); image_start += (long)name_length+1; image_start += sizeof(uint32) + sizeof(uint32) + sizeof(uint32); num_images++; } } if(material->sphere_texture != NULL) { name_length = (unsigned int)strlen(material->sphere_texture); if(ght_get(name_table, name_length, material->sphere_texture) == NULL) { (void)ght_insert(name_table, (void*)1, name_length, material->sphere_texture); image_start += (long)name_length+1; image_start += sizeof(uint32) + sizeof(uint32) + sizeof(uint32); num_images++; } } if(material->toon_texture != NULL) { // トゥーンテクスチャの場合はモデルのディレクトリに画像があるか確認 (void)sprintf(utf8_path, "%s/%s", model->model_path, material->toon_texture); system_path = LocaleFromUTF8(utf8_path); if((fp = fopen(system_path, "rb")) != NULL) { // 画像有 name_length = (unsigned int)strlen(material->toon_texture); if(ght_get(name_table, name_length, material->toon_texture) == NULL) { (void)ght_insert(name_table, (void*)1, name_length, material->toon_texture); image_start += (long)name_length+1; image_start += sizeof(uint32) + sizeof(uint32) + sizeof(uint32); num_images++; (void)fclose(fp); } } MEM_FREE_FUNC(system_path); } } ght_finalize(name_table); // 画像ファイルを一つのデータにまとめる name_table = ght_create(num_materials+1); ght_set_hash(name_table, (ght_fn_hash_t)GetStringHash); names = (MATERIAL_ARCHIVE_DATA*)MEM_ALLOC_FUNC(sizeof(*names)*num_images); counter = 0; for(i=0; i<num_materials; i++) { MATERIAL_INTERFACE *material = materials[i]; if(material->main_texture != NULL) { name_length = (unsigned int)strlen(material->main_texture); if(ght_get(name_table, name_length, material->main_texture) == NULL) { (void)ght_insert(name_table, (void*)1, name_length, material->main_texture); names[counter].data_start = image_start + total_image_size; (void)sprintf(utf8_path, "%s/%s", model->model_path, material->main_texture); system_path = LocaleFromUTF8(utf8_path); if((fp = fopen(system_path, "rb")) != NULL) { (void)fseek(fp, 0, SEEK_END); names[counter].name = material->main_texture; names[counter].data_size = ftell(fp); names[counter].data_start = total_image_size + image_start; total_image_size += names[counter].data_size; rewind(fp); if(image_data_buffer_size < names[counter].data_size) { image_data = (uint8*)MEM_REALLOC_FUNC(image_data, names[counter].data_size); image_data_buffer_size = names[counter].data_size; } (void)fread(image_data, 1, names[counter].data_size, fp); (void)MemWrite(image_data, 1, names[counter].data_size, stream); counter++; (void)fclose(fp); } else { char sp_path[8192] = {0}; char *extention = sp_path; char *p = extention; (void)strcpy(sp_path, system_path); while(*p != '\0') { if(*p == '.') { extention = p; } p++; } extention[1] = 's'; extention[2] = 'p'; extention[3] = 'a'; extention[4] = '\0'; if((fp = fopen(sp_path, "rb")) != NULL) { (void)fseek(fp, 0, SEEK_END); names[counter].name = material->main_texture; names[counter].data_size = ftell(fp); names[counter].data_start = total_image_size + image_start; total_image_size += names[counter].data_size; rewind(fp); if(image_data_buffer_size < names[counter].data_size) { image_data = (uint8*)MEM_REALLOC_FUNC(image_data, names[counter].data_size); image_data_buffer_size = names[counter].data_size; } (void)fread(image_data, 1, names[counter].data_size, fp); (void)MemWrite(image_data, 1, names[counter].data_size, stream); counter++; (void)fclose(fp); } else { extention[3] = 'h'; if((fp = fopen(sp_path, "rb")) != NULL) { (void)fseek(fp, 0, SEEK_END); names[counter].name = material->main_texture; names[counter].data_size = ftell(fp); names[counter].data_start = total_image_size + image_start; total_image_size += names[counter].data_size; rewind(fp); if(image_data_buffer_size < names[counter].data_size) { image_data = (uint8*)MEM_REALLOC_FUNC(image_data, names[counter].data_size); image_data_buffer_size = names[counter].data_size; } (void)fread(image_data, 1, names[counter].data_size, fp); (void)MemWrite(image_data, 1, names[counter].data_size, stream); counter++; (void)fclose(fp); } } } MEM_FREE_FUNC(system_path); } } if(material->sphere_texture != NULL) { name_length = (unsigned int)strlen(material->sphere_texture); if(ght_get(name_table, name_length, material->sphere_texture) == NULL) { (void)ght_insert(name_table, (void*)1, name_length, material->sphere_texture); names[counter].data_start = image_start + total_image_size; (void)sprintf(utf8_path, "%s/%s", model->model_path, material->sphere_texture); system_path = LocaleFromUTF8(utf8_path); if((fp = fopen(system_path, "rb")) != NULL) { (void)fseek(fp, 0, SEEK_END); names[counter].name = material->sphere_texture; names[counter].data_size = ftell(fp); names[counter].data_start = total_image_size + image_start; total_image_size += names[counter].data_size; rewind(fp); if(image_data_buffer_size < names[counter].data_size) { image_data = (uint8*)MEM_REALLOC_FUNC(image_data, names[counter].data_size); image_data_buffer_size = names[counter].data_size; } (void)fread(image_data, 1, names[counter].data_size, fp); (void)MemWrite(image_data, 1, names[counter].data_size, stream); counter++; (void)fclose(fp); } MEM_FREE_FUNC(system_path); } } if(material->toon_texture != NULL) { // トゥーンテクスチャの場合はモデルのディレクトリに画像があるか確認 (void)sprintf(utf8_path, "%s/%s", model->model_path, material->toon_texture); system_path = LocaleFromUTF8(utf8_path); name_length = (unsigned int)strlen(material->toon_texture); if(ght_get(name_table, name_length, material->toon_texture) == NULL) { if((fp = fopen(system_path, "rb")) != NULL) { // 画像有 (void)ght_insert(name_table, (void*)1, name_length, material->toon_texture); (void)fseek(fp, 0, SEEK_END); names[counter].name = material->toon_texture; names[counter].data_size = ftell(fp); names[counter].data_start = total_image_size + image_start; total_image_size += names[counter].data_size; rewind(fp); if(image_data_buffer_size < names[counter].data_size) { image_data = (uint8*)MEM_REALLOC_FUNC(image_data, names[counter].data_size); image_data_buffer_size = names[counter].data_size; } (void)fread(image_data, 1, names[counter].data_size, fp); (void)MemWrite(image_data, 1, names[counter].data_size, stream); counter++; (void)fclose(fp); } } MEM_FREE_FUNC(system_path); } } num_images = counter; ght_finalize(name_table); result = (uint8*)MEM_ALLOC_FUNC(image_start + total_image_size + sizeof(uint32)); result_stream.buff_ptr = result; result_stream.data_size = image_start + total_image_size; result_stream.block_size = 1; data32 = num_images; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); for(i=0; i<num_images; i++) { data32 = (uint32)strlen(names[i].name)+1; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); (void)MemWrite(names[i].name, 1, data32, &result_stream); data32 = names[i].data_start; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); data32 = names[i].data_size; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); } if((diff = (uint32)(image_start - result_stream.data_point)) > 0) { (void)MemSeek(&result_stream, sizeof(data32), SEEK_SET); for(i=0; i<num_images; i++) { data32 = (uint32)strlen(names[i].name)+1; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); (void)MemWrite(names[i].name, 1, data32, &result_stream); data32 = names[i].data_start - diff; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); data32 = names[i].data_start - diff; (void)MemWrite(&data32, sizeof(data32), 1, &result_stream); } image_start -= diff; } (void)MemWrite(stream->buff_ptr, 1, stream->data_point, &result_stream); if(out_data_size != NULL) { *out_data_size = image_start + total_image_size; } MEM_FREE_FUNC(image_data); MEM_FREE_FUNC(names); MEM_FREE_FUNC(materials); (void)DeleteMemoryStream(stream); return result; }
/*! * \em Get the \em Data Pointer stored at \p key_data of size \p key_data. * \return the data pointer upon success, nullptr if no data was * indexed by \p key. */ void* get(unsigned int key_size, const void *key_data) const { return m_ht ? ght_get(m_ht, key_size, key_data) : nullptr; }
static bstring tr_eval(TextResource tr, trnode_t* node) { //internally we work with bstrings trnode_t* tmpNode; switch(node->type) { case TRNODE_TEXT: return bstrcpy(node->textData); case TRNODE_REPR: ; int match=0; if (node->condKey) { assert(node->condValue); //conditional char* condkey = bstr2cstr(node->condKey,'\0'); bstring val = ght_get(tr->parameters,strlen(condkey),condkey); bcstrfree(condkey); if (val && !bstrcmp(node->condValue, val)) { //matches match = 1; } } else { //unconditional, so go too match=1; } if (match) { return tr_evalKey(tr,node->reprKey->data); } else return bfromcstr(""); case TRNODE_STRING: //these guys have a blob of nodes that needs to be catted together smartly tmpNode = node->children_list; bstring tmpStr = bfromcstralloc(32,""); while(tmpNode) { bstring childStr = tr_eval(tr,tmpNode); bconchar(tmpStr,' '); bconcat(tmpStr,childStr); bdestroy(childStr); tmpNode = tmpNode->next; } return tmpStr; case TRNODE_SWITCH: //look through the children for matching choice ; char* switchVar = bstr2cstr(node->switchVar,'\0'); bstring val = ght_get(tr->parameters,strlen(switchVar),switchVar); bcstrfree(switchVar); tmpNode = node->children_list; while(tmpNode) { assert(tmpNode->type == TRNODE_STRING); assert(tmpNode->caseValue); if (!bstrcmp(tmpNode->caseValue,val)) { //we match, return this return tr_eval(tr,tmpNode); } //try next tmpNode = tmpNode->next; } return bfromcstr(""); default: assert(0); } assert(0); return NULL; }
void* get(const T & key) const { return m_ht ? ght_get(m_ht, sizeof(key), &key) : nullptr; }
int logfile_refresh(logfile *log) { int rowcount = 0; char *line = NULL; logerror *err; logerror *err_in_table; logerror *newlist = NULL; logerror *newlist_filtered = NULL; unsigned int filtered_count = 0; while((line = linereader_getline(log->file)) != NULL) { err = parse_error_line(log->logformat, line); if (err == NULL) continue; update_top_errortype(&log->worstNewLine, err); //Get a possible duplicate entry in the hashtable err_in_table = ght_get(log->errortypes, err->keylength, err->key); if (err_in_table == NULL) { //Insert a completely new error ght_insert(log->errortypes, err, err->keylength, err->key); newlist = errorlist_insert(newlist, err); update_top_errortype(&log->worstNewType, err); } else { //Merge the two duplicate errors logerror_merge(err_in_table, err); if (err_in_table->is_new == 0) { log->errors = errorlist_remove_error(log->errors, err_in_table); newlist = errorlist_insert(newlist, err_in_table); } err_in_table->is_new = 1; } ++rowcount; } if (newlist != NULL) { //First we reset the is_new bits so that next refreshes work correctly err = newlist; while (err != NULL) { err->is_new = 0; err = err->next; } if (log->filter) { filtered_count = loglist_filter(&newlist, &newlist_filtered, log->filter, log->filter_data, FILTER_REMOVE_FAILED); newlist_filtered = errorlist_sort(newlist_filtered, log->sorting); } newlist = errorlist_sort(newlist, log->sorting); //printf("Sorted, final merge"); log->errors = errorlist_merge(log->errors, newlist, log->sorting); log->filtered_errors = errorlist_merge(log->filtered_errors, newlist_filtered, log->sorting); log->filtered_entries += filtered_count; } return rowcount; }