static void giblorb_qsort( giblorb_resdesc_t **list, int len ) { int ix, jx, res; giblorb_resdesc_t *tmpptr, *pivot; if ( len < 6 ) { /* The list is short enough for a bubble-sort. */ for ( jx = len - 1; jx > 0; jx-- ) { for ( ix = 0; ix < jx; ix++ ) { res = sortsplot( list[ix], list[ix + 1] ); if ( res > 0 ) { tmpptr = list[ix]; list[ix] = list[ix + 1]; list[ix + 1] = tmpptr; } } } } else { /* Split the list. */ pivot = list[len / 2]; ix = 0; jx = len; while ( 1 ) { while ( ix < jx - 1 && sortsplot( list[ix], pivot ) < 0 ) ix++; while ( ix < jx - 1 && sortsplot( list[jx - 1], pivot ) > 0 ) jx--; if ( ix >= jx - 1 ) break; tmpptr = list[ix]; list[ix] = list[jx - 1]; list[jx - 1] = tmpptr; } ix++; /* Sort the halves. */ giblorb_qsort( list + 0, ix ); giblorb_qsort( list + ix, len - ix ); } }
static giblorb_err_t giblorb_initialize_map(giblorb_map_t *map) { /* It is important that the map structure be kept valid during this function. If this returns an error, giblorb_destroy_map() will be called. */ int ix, jx; giblorb_result_t chunkres; giblorb_err_t err; char *ptr; glui32 len; glui32 numres; int gotindex = FALSE; for (ix=0; ix<map->numchunks; ix++) { giblorb_chunkdesc_t *chu = &map->chunks[ix]; switch (chu->type) { case giblorb_ID_RIdx: /* Resource index chunk: build the resource list and sort it. */ if (gotindex) return giblorb_err_Format; /* duplicate index chunk */ err = giblorb_load_chunk_by_number(map, giblorb_method_Memory, &chunkres, ix); if (err) return err; ptr = chunkres.data.ptr; len = chunkres.length; numres = giblorb_native4(ptr+0); if (numres) { int ix2; giblorb_resdesc_t *resources; giblorb_resdesc_t **ressorted; if (len != numres*12+4) return giblorb_err_Format; /* bad length field */ resources = (giblorb_resdesc_t *)giblorb_malloc(numres * sizeof(giblorb_resdesc_t)); ressorted = (giblorb_resdesc_t **)giblorb_malloc(numres * sizeof(giblorb_resdesc_t *)); if (!ressorted || !resources) return giblorb_err_Alloc; ix2 = 0; for (jx=0; jx<numres; jx++) { giblorb_resdesc_t *res = &(resources[jx]); glui32 respos; res->usage = giblorb_native4(ptr+jx*12+4); res->resnum = giblorb_native4(ptr+jx*12+8); respos = giblorb_native4(ptr+jx*12+12); while (ix2 < map->numchunks && map->chunks[ix2].startpos < respos) ix2++; if (ix2 >= map->numchunks || map->chunks[ix2].startpos != respos) return giblorb_err_Format; /* start pos does not match a real chunk */ res->chunknum = ix2; ressorted[jx] = res; } /* Sort a resource list (actually a list of pointers to structures in map->resources.) This makes it easy to find resources by usage and resource number. */ giblorb_qsort(ressorted, numres); map->numresources = numres; map->resources = resources; map->ressorted = ressorted; } giblorb_unload_chunk(map, ix); gotindex = TRUE; break; } } return giblorb_err_None; }