Esempio n. 1
0
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 );
    }
}
Esempio n. 2
0
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;
}