Beispiel #1
0
static bool remove_slot(qhasharr_t *tbl, int idx) {
    qhasharr_slot_t *tblslots = get_slots(tbl);
    assert(tblslots[idx].count != 0);

    tblslots[idx].count = 0;
    return true;
}
Beispiel #2
0
/**
 * qhasharr->remove_by_idx(): Remove an object from this table by index number.
 *
 * @param tbl       qhasharr_t container pointer.
 * @param idx       slot index number
 *
 * @return true if successful, otherwise(not found) returns false
 * @retval errno will be set in error condition.
 *  - ENOENT    : Index is not pointing a valid object.
 *  - EINVAL    : Invald argument.
 *  - EFAULT    : Unexpected error. Data structure is not constant.
 *
 * @code
 *  int idx = 0;
 *  qhasharr_obj_t obj;
 *  while(tbl->getnext(tbl, &obj, &idx) == true) {
 *    if (condition_to_remove) {
 *      idx--;  // adjust index by -1
 *      remove_by_idx(idx);
 *    }
 *    free(obj.name);
 *    free(obj.data);
 *  }
 * @endcode
 *
 * @note
 * This function is to remove an object in getnext() traversal loop without
 * knowing the object name but index value. When key names are longer than
 * defined size, the keys are stored with truncation with their fingerprint,
 * so this method provides a way to remove those keys.
 * getnext() returns actual index + 1(pointing next slot of current finding),
 * so you need to adjust it by -1 for the valid index number. And once you
 * remove object by this method, rewind idx by -1 before calling getnext()
 * because collision objects can be moved back to removed index again, so
 * by adjusting index by -1, getnext() can continue search from the removed
 * slot index again. Please refer an example code.
 */
bool qhasharr_remove_by_idx(qhasharr_t *tbl, int idx) {
    if (idx < 0) {
        errno = EINVAL;
        return false;
    }

    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (tblslots[idx].count == 1) {
        // just remove
        remove_data(tbl, idx);
    } else if (tblslots[idx].count > 1) {  // leading slot and has collision
        // find the collision key
        int idx2;
        for (idx2 = idx + 1;; idx2++) {
            if (idx2 >= tbldata->maxslots)
                idx2 = 0;
            if (idx2 == idx) {
                errno = EFAULT;
                return false;
            }
            if (tblslots[idx2].count == COLLISION_MARK
                    && tblslots[idx2].hash == tblslots[idx].hash) {
                break;
            }
        }

        // move to leading slot
        int backupcount = tblslots[idx].count;
        remove_data(tbl, idx);  // remove leading data
        copy_slot(tbl, idx, idx2);  // copy slot
        remove_slot(tbl, idx2);  // remove moved slot

        tblslots[idx].count = backupcount - 1;  // adjust collision counter
        if (tblslots[idx].link != -1) {
            tblslots[tblslots[idx].link].hash = idx;
        }

    } else if (tblslots[idx].count == COLLISION_MARK) {  // collision key
        // decrease counter from leading slot
        if (tblslots[tblslots[idx].hash].count <= 1) {
            errno = EFAULT;
            return false;
        }
        tblslots[tblslots[idx].hash].count--;

        // remove data
        remove_data(tbl, idx);
    } else {
        errno = ENOENT;
        return false;
    }

    return true;
}
Beispiel #3
0
void* tss::get() const
{
    tss_slots* slots = get_slots(false);

    if (!slots)
        return 0;

    if (m_slot >= slots->size())
        return 0;

    return (*slots)[m_slot];
}
Beispiel #4
0
static int get_idx(qhasharr_t *tbl, const void *name, size_t namesize,
                   uint32_t hash) {
    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (tblslots[hash].count > 0) {
        int count, idx;
        for (count = 0, idx = hash; count < tblslots[hash].count;) {
            if (tblslots[idx].hash == hash
                    && (tblslots[idx].count > 0 || tblslots[idx].count == COLLISION_MARK)) {
                // same hash
                count++;

                // is same key?
                // first check key length
                if (namesize == tblslots[idx].data.pair.namesize) {
                    if (namesize <= Q_HASHARR_NAMESIZE) {
                        // original key is stored
                        if (!memcmp(name, tblslots[idx].data.pair.name,
                                    namesize)) {
                            return idx;
                        }
                    } else {
                        // key is truncated, compare MD5 also.
                        unsigned char namemd5[16];
                        qhashmd5(name, namesize, namemd5);
                        if (!memcmp(name, tblslots[idx].data.pair.name,
                        Q_HASHARR_NAMESIZE)
                                && !memcmp(namemd5,
                                           tblslots[idx].data.pair.namemd5,
                                           16)) {
                            return idx;
                        }
                    }
                }
            }

            // increase idx
            idx++;
            if (idx >= tbldata->maxslots)
                idx = 0;

            // check loop
            if (idx == hash)
                break;

            continue;
        }
    }

    return -1;
}
Beispiel #5
0
static int dialog_loadgame_load(gg_widget_t *widget, gg_widget_t *emitter, void *data, void *extra_data)
{
    int slot = saveload_selected;

    if (get_slots() & (1 << slot))
    {
        set_pgn_slot(slot);
        set_set_loading(TRUE);
        gg_dialog_close();
        gg_dialog_close();
    }
    return 1;
}
Beispiel #6
0
static bool copy_slot(qhasharr_t *tbl, int idx1, int idx2) {
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (tblslots[idx1].count != 0 || tblslots[idx2].count == 0) {
        errno = EFAULT;
        return false;
    }

    memcpy((void *) (&tblslots[idx1]), (void *) (&tblslots[idx2]),
           sizeof(qhasharr_slot_t));

    return true;
}
Beispiel #7
0
static void *get_data(qhasharr_t *tbl, int idx, size_t *size) {
    if (idx < 0) {
        errno = ENOENT;
        return NULL;
    }

    qhasharr_slot_t *tblslots = get_slots(tbl);

    int newidx;
    size_t datasize;
    for (newidx = idx, datasize = 0;; newidx = tblslots[newidx].link) {
        datasize += tblslots[newidx].datasize;
        if (tblslots[newidx].link == -1)
            break;
    }

    void *data, *dp;
    if ((data = malloc(datasize)) == NULL) {
        errno = ENOMEM;
        return NULL;
    }

    for (newidx = idx, dp = data;; newidx = tblslots[newidx].link) {
        if (tblslots[newidx].count == EXTBLOCK_MARK) {
            // extended data block
            memcpy(dp, (void *) tblslots[newidx].data.ext.data,
                   tblslots[newidx].datasize);
        } else {
            // key/value pair data block
            memcpy(dp, (void *) tblslots[newidx].data.pair.data,
                   tblslots[newidx].datasize);
        }

        dp += tblslots[newidx].datasize;
        if (tblslots[newidx].link == -1)
            break;
    }

    if (size != NULL)
        *size = datasize;
#ifdef QHASHARR_TIMESTAMP
    time(&tblslots[idx].timestamp);
#endif
    return data;
}
Beispiel #8
0
/**
 * qhasharr->clear(): Clears this table so that it contains no keys.
 *
 * @param tbl       qhasharr_t container pointer.
 *
 * @return true if successful, otherwise returns false.
 */
void qhasharr_clear(qhasharr_t *tbl) {
    if (tbl == NULL) {
        errno = EINVAL;
        return;
    }

    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (tbldata->usedslots == 0)
        return;

    tbldata->usedslots = 0;
    tbldata->num = 0;

    // clear memory
    memset((void *) tblslots, '\0',
           (tbldata->maxslots * sizeof(qhasharr_slot_t)));
}
Beispiel #9
0
/**
 * qhasharr->getnext(): Get next element.
 *
 * @param tbl       qhasharr_t container pointer.
 * @param idx       index pointer
 *
 * @return key name string if successful, otherwise(end of table) returns NULL
 * @retval errno will be set in error condition.
 *  - ENOENT    : No next element.
 *  - EINVAL    : Invald argument.
 *  - ENOMEM    : Memory allocation failed.
 *
 * @code
 *  int idx = 0;
 *  qhasharr_obj_t obj;
 *  while(tbl->getnext(tbl, &obj, &idx) == true) {
 *    printf("NAMESIZE=%zu, DATASIZE=%zu\n",
 *           obj.namesize, obj.datasize);
 *    free(obj.name);  // key name
 *    free(obj.data);  // value data
 *  }
 * @endcode
 *
 * @note
 *  Please be aware a key name will be returned with truncated length
 *  because key name gets truncated if it doesn't fit into slot size,
 *  Q_HASHARR_NAMESIZE.
 */
bool qhasharr_getnext(qhasharr_t *tbl, qhasharr_obj_t *obj, int *idx) {
    if (tbl == NULL || obj == NULL || idx == NULL) {
        errno = EINVAL;
        return NULL;
    }

    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    for (; *idx < tbldata->maxslots; (*idx)++) {
        if (tblslots[*idx].count == 0 || tblslots[*idx].count == EXTBLOCK_MARK) {
            continue;
        }

        size_t namesize = tblslots[*idx].data.pair.namesize;
        if (namesize > Q_HASHARR_NAMESIZE)
            namesize = Q_HASHARR_NAMESIZE;

        obj->name = malloc(namesize + 1);
        if (obj->name == NULL) {
            errno = ENOMEM;
            return false;
        }
        memcpy(obj->name, tblslots[*idx].data.pair.name, namesize);
        memcpy(obj->name + namesize, "", 1); // for truncated case
        obj->namesize = namesize;

        obj->data = get_data(tbl, *idx, &obj->datasize);
        if (obj->data == NULL) {
            free(obj->name);
            errno = ENOMEM;
            return false;
        }

        *idx += 1;
        return true;
    }

    errno = ENOENT;
    return false;
}
Beispiel #10
0
void tss::set(void* value)
{
    tss_slots* slots = get_slots(true);

    if (!slots)
        throw boost::thread_resource_error();

    if (m_slot >= slots->size())
    {
        try
        {
            slots->resize(m_slot + 1);
        }
        catch (...)
        {
            throw boost::thread_resource_error();
        }
    }

    (*slots)[m_slot] = value;
}
Beispiel #11
0
static bool remove_data(qhasharr_t *tbl, int idx) {
    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);
    assert(tblslots[idx].count != 0);

    while (true) {
        int link = tblslots[idx].link;
        remove_slot(tbl, idx);
        tbldata->usedslots--;

        if (link == -1)
            break;

        idx = link;
    }

    // decrease stored key counter
    tbldata->num--;

    return true;
}
Beispiel #12
0
// find empty slot : return empty slow number, otherwise returns -1.
static int find_avail(qhasharr_t *tbl, int startidx) {
    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (startidx >= tbldata->maxslots)
        startidx = 0;

    int idx = startidx;
    while (true) {
        if (tblslots[idx].count == 0)
            return idx;

        idx++;
        if (idx >= tbldata->maxslots)
            idx = 0;
        if (idx == startidx)
            break;
    }

    return -1;
}
Beispiel #13
0
/**
 * qhasharr->getts_by_obj(): Get an timestamp of object by key object from
 *                              this table 
 *
 * @param tbl       qhasharr_t container pointer.
 * @param name      key data
 * @param namesize  size of key
 * @param ts        if not NULL, timestamp of object will be stored
 *
 * @return malloced object pointer if successful, otherwise(not found)
 *  returns NULL
 * @retval errno will be set in error condition.
 *  - ENOENT    : No such key found.
 *  - EINVAL    : Invalid argument.
 *
 * @note
 * timestamp must be pre-allocated.
 */
bool qhasharr_getts_by_obj(qhasharr_t *tbl, const void *name, size_t namesize,
        time_t *ts) {
    if (tbl == NULL || name == NULL || namesize == 0) {
        errno = EINVAL;
        return false;
    }

    qhasharr_data_t *tbldata = tbl->data;

    // get hash integer
    uint32_t hash = qhashmurmur3_32(name, namesize) % tbldata->maxslots;
    int idx = get_idx(tbl, name, namesize, hash);
    if (idx < 0) {
        errno = ENOENT;
        return false;
    }

    if (ts) {
        qhasharr_slot_t *tblslots = get_slots(tbl);
        *ts = tblslots[idx].timestamp;
    }

    return true;
}
Beispiel #14
0
int main(int argc, char **argv)
{
    pid_t id;
    pid_t childs[ANZAHL_JOBS];
    int i = 0;
    int slot = 0;
    int delay = 0;
    char command[32] = "";

    /* array initialisieren */
    for (i=0; i<ANZAHL_JOBS; ++i)
        childs[i] = 0;

    while (1)
    {
        printf("Nr, Wartezeit und Befehl eingeben: ");

        if ((i = scanf("%d, %d, %31s", &slot, &delay, command)) < 2)
        {
            fprintf(stderr, "Usage: %s <slot>, <delay>, <command>\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        /* zombies terminieren */
        get_zombies(childs);

        /* check for correct input */
        if ((i == 2 && delay != -1 ) || slot > 9)
        {
            fprintf(stderr, "Usage: %s <slot>, <delay>, <command>\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        /* job loeschen */
        else if (i == 2)
        {
            /* job vorhanden? */
            if (childs[slot] != 0)
            {
                kill(childs[slot], 9);
                childs[slot] = 0;
            }
            else
            {
                printf("Slot %d schon frei.\n", slot);
                continue;
            }
        }
        /* job hinzufuegen */
        else if (i == 3)
        {
            if (childs[slot] != 0)
            {
                printf("Slot %d belegt.\n", slot);
                continue;
            }

            /* job anlegen */
            id = fork();

            /* fork fehlgeschlagen */
            if (id == -1)
            {
                perror("fork failed");
                exit(EXIT_FAILURE);
            }
            /* child-prozess */
            else if (id == 0)
            {
                sleep(delay);

                printf("Child: %d\n", getpid());

                /* command ausfuehren */
                if (execlp(command, command, NULL) == -1)
                {
                    perror("execlp");
                    exit(EXIT_FAILURE);
                }
                exit(0);
            }
            /* parent-prozess */
            else if (id > 0)
            {
                printf("Parent: %d erzeugt.\n", id);

                childs[slot] = id;

                get_zombies(childs);
                get_slots(childs);
            }
        }
    }
    
    return 0;
}
Beispiel #15
0
static int _mwrite_one(Stream_t *Dir,
		       char *argname,
		       char *shortname,
		       write_data_callback *cb,
		       void *arg,
		       ClashHandling_t *ch)
{
	char longname[VBUFSIZE];
	const char *dstname;
	dos_name_t dosname;
	int expanded;
	struct scan_state scan;
	clash_action ret;
	doscp_t *cp = GET_DOSCONVERT(Dir);

	expanded = 0;

	if(isSpecial(argname)) {
		fprintf(stderr, "Cannot create entry named . or ..\n");
		return -1;
	}

	if(ch->name_converter == dos_name) {
		if(shortname)
			stripspaces(shortname);
		if(argname)
			stripspaces(argname);
	}

	if(shortname){
		convert_to_shortname(cp, ch, shortname, &dosname);
		if(ch->use_longname & 1){
			/* short name mangled, treat it as a long name */
			argname = shortname;
			shortname = 0;
		}
	}

	if (argname[0] && (argname[1] == ':')) {
		/* Skip drive letter */
		dstname = argname + 2;
	} else {
		dstname = argname;
	}

	/* Copy original argument dstname to working value longname */
	strncpy(longname, dstname, VBUFSIZE-1);

	if(shortname) {
		ch->use_longname =
			convert_to_shortname(cp, ch, shortname, &dosname);
		if(strcmp(shortname, longname))
			ch->use_longname |= 1;
	} else {
		ch->use_longname =
			convert_to_shortname(cp, ch, longname, &dosname);
	}

	ch->action[0] = ch->namematch_default[0];
	ch->action[1] = ch->namematch_default[1];

	while (1) {
		switch((ret=get_slots(Dir, &dosname, longname, &scan, ch))){
			case NAMEMATCH_ERROR:
				return -1;	/* Non-file-specific error,
						 * quit */
				
			case NAMEMATCH_SKIP:
				return -1;	/* Skip file (user request or
						 * error) */

			case NAMEMATCH_PRENAME:
				ch->use_longname =
					convert_to_shortname(cp, ch,
							     longname,
							     &dosname);
				continue;
			case NAMEMATCH_RENAME:
				continue;	/* Renamed file, loop again */

			case NAMEMATCH_GREW:
				/* No collision, and not enough slots.
				 * Try to grow the directory
				 */
				if (expanded) {	/* Already tried this
						 * once, no good */
					fprintf(stderr,
						"%s: No directory slots\n",
						progname);
					return -1;
				}
				expanded = 1;
				
				if (dir_grow(Dir, scan.max_entry))
					return -1;
				continue;
			case NAMEMATCH_OVERWRITE:
			case NAMEMATCH_SUCCESS:
				return write_slots(Dir, &dosname, longname,
						   &scan, cb, arg,
						   ch->use_longname);
			default:
				fprintf(stderr,
					"Internal error: clash_action=%d\n",
					ret);
				return -1;
		}

	}
}
Beispiel #16
0
/**
 * qhasharr->put_by_obj(): ut an object into this table by key object.
 *
 * @param tbl       qhasharr_t container pointer.
 * @param name      key data
 * @param namesize  size of key
 * @param data      data
 * @param datasize  size of data
 *
 * @return true if successful, otherwise returns false
 * @retval errno will be set in error condition.
 *  - ENOBUFS   : Table doesn't have enough space to store the object.
 *  - EINVAL    : Invalid argument.
 *  - EFAULT    : Unexpected error. Data structure is not constant.
 */
bool qhasharr_put_by_obj(qhasharr_t *tbl, const void *name, size_t namesize,
                         const void *data, size_t datasize) {
    if (tbl == NULL || name == NULL || namesize == 0 || data == NULL
            || datasize == 0) {
        errno = EINVAL;
        return false;
    }

    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    // check full
    if (tbldata->usedslots >= tbldata->maxslots) {
        errno = ENOBUFS;
        return false;
    }

    // get hash integer
    uint32_t hash = qhashmurmur3_32(name, namesize) % tbldata->maxslots;

    // check, is slot empty
    if (tblslots[hash].count == 0) {  // empty slot
        // put data
        if (put_data(tbl, hash, hash, name, namesize, data, datasize,
                     1) == false) {
            return false;
        }
    } else if (tblslots[hash].count > 0) {  // same key or hash collision
        // check same key;
        int idx = get_idx(tbl, name, namesize, hash);
        if (idx >= 0) {  // same key
            // remove and recall
            qhasharr_remove_by_idx(tbl, idx);
            return qhasharr_put_by_obj(tbl, name, namesize, data, datasize);
        } else {  // no same key but hash collision
            // find empty slot
            int idx = find_avail(tbl, hash);
            if (idx < 0) {
                errno = ENOBUFS;
                return false;
            }

            // put data. -1 is used for collision resolution (idx != hash);
            if (put_data(tbl, idx, hash, name, namesize, data, datasize,
                         COLLISION_MARK) == false) {
                return false;
            }

            // increase counter from leading slot
            tblslots[hash].count++;
        }
    } else {
        // collision key or extended block

        // find empty slot
        int idx = find_avail(tbl, hash + 1);
        if (idx < 0) {
            errno = ENOBUFS;
            return false;
        }

        // move the slot
        copy_slot(tbl, idx, hash);
        remove_slot(tbl, hash);

        // adjust the link chain
        if (tblslots[idx].link != -1) {
            tblslots[tblslots[idx].link].hash = idx;
        }
        if (tblslots[idx].count == EXTBLOCK_MARK) {
            tblslots[tblslots[idx].hash].link = idx;
        }

        // store data
        if (put_data(tbl, hash, hash, name, namesize, data, datasize,
                     1) == false) {
            return false;
        }
    }

    return true;
}
Beispiel #17
0
gg_dialog_t *dialog_saveload_create(gg_dialog_t *parent, int saving)
{
    gg_widget_t *dialog;
    gg_widget_t *rootvbox = gg_vbox_create(0);
    gg_widget_t *vbox = gg_vbox_create(0);
    gg_widget_t *hbox = gg_vbox_create(0);
    gg_widget_t *hboxtemp;
    gg_widget_t *widget;
    char temp[80];
    char whiteis[80], blackis[80];
    int i=0,j=0;
    int padding=0;

    change_saving=saving;

    if ( !changing_slot )
        saveload_selected=0;

    /*DBG_LOG( "dialog opened with saveselected of %i", saveload_selected );*/

    /* Right side.. */
    if (!changing_slot)
    {
#ifdef _arch_dreamcast
        dc_restore_savegames();
#endif
        for ( i=0; i<SAVEGAME_SLOTS; i++ )
            load_save_xml( i );
    }

    if ( get_slots() & (1 << saveload_selected) )
    {
        gg_widget_t *board_box = gg_vbox_create(0);

        sprintf( temp, "Saved: %s", get_time_save(saveload_selected) );
        widget = gg_label_create(temp);
        gg_container_append(GG_CONTAINER(vbox), widget);

        switch ( get_config_save(saveload_selected)->player[WHITE] )
        {
        case PLAYER_ENGINE:
            sprintf( whiteis, "CPU" );
            break;
        case PLAYER_UI:
            sprintf( whiteis, "Human" );
            break;
        default:
            /* Whoops */
            sprintf( whiteis, "Oh no.." );
            break;
        }

        switch ( get_config_save(saveload_selected)->player[BLACK] )
        {
        case PLAYER_ENGINE:
            sprintf( blackis, "CPU" );
            break;
        case PLAYER_UI:
            sprintf( blackis, "Human" );
            break;
        default:
            /* Whoops */
            sprintf( blackis, "Oh no.." );
            break;
        }

        sprintf( temp, "%s vs %s", whiteis, blackis );
        widget = gg_label_create(temp);
        gg_container_append(GG_CONTAINER(vbox), widget);

        sprintf( temp, "Difficulty: %s",
            get_config_save(saveload_selected)->difficulty ? "Normal" : "Easy" );
        widget = gg_label_create(temp);
        gg_container_append(GG_CONTAINER(vbox), widget);

        sprintf( temp, "Level: %i",
            get_config_save(saveload_selected)->cpu_level );
        widget = gg_label_create(temp);
        gg_container_append(GG_CONTAINER(vbox), widget);

        widget = gg_label_create(" ");
        gg_container_append(GG_CONTAINER(vbox), widget);

        /* create board.. */

        for ( i=7; i>=0; i-- )
        {
            gg_widget_t *hboxtemp2;
            gg_colour_t col_white =
                {
                    1.0f, 1.0f, 1.0f, 1.0f
                };
            /*gg_colour_t col_grey =
                {
                    0.3f, 0.3f, 0.3f, 1.0f
                };*/
            hboxtemp = gg_hbox_create(0);
            hboxtemp2 = gg_hbox_create(0);
            gg_set_requested_size(hboxtemp2, 20, 20);
            gg_container_append(GG_CONTAINER(hboxtemp), hboxtemp2);

            for ( j=0; j<8; j++ )
            {
                gg_colour_t col_green = {0.5, 0.6, 0.5, 1.0};
                gg_colour_t col_yellow = {0.8, 0.7, 0.4, 1.0};
                gg_colour_t front, *back;
                int square = get_saved_board(saveload_selected)->square[i * 8 + j];

                sprintf(temp, "%c", xmlsquaretofont(square));
                widget = gg_label_create( temp );
                gg_set_requested_size(widget, 20, 20);
                gg_align_set_alignment(GG_ALIGN(widget), 0.5, 0.5);

                if (COLOUR(square) == WHITE)
                    front = col_white;
                else
                    front = *get_col(COL_BLACK);

                if ((i + j) % 2 == 0)
                    back = &col_green;
                else
                    back = &col_yellow;

                /* FIXME Hack to turn off shadow */
                front.a = 2.0f;

                gg_label_set_colour(GG_LABEL(widget), &front, back);
                gg_container_append(GG_CONTAINER(hboxtemp), widget);
            }
            gg_container_append(GG_CONTAINER(board_box), hboxtemp);
        }
        gg_container_append(GG_CONTAINER(vbox), board_box);
    }
    else
    {
        sprintf( temp, "Empty slot" );
        widget = gg_label_create(temp);
        gg_container_append(GG_CONTAINER(vbox), widget);

        for ( i=0; i<12; i++ )
        {
            widget = gg_label_create(" ");
            gg_container_append(GG_CONTAINER(vbox), widget);
        }
    }
    gg_set_requested_size(vbox, 201, 0);
    gg_container_append(GG_CONTAINER(hbox), gg_frame_create(vbox));

    /* left side */
    vbox = gg_vbox_create(0);
    /* padding.. */
    for ( i=0; i<padding; i++ )
    {
        widget = gg_label_create(" ");
        gg_container_append(GG_CONTAINER(vbox), widget);
    }

    widget = gg_option_create();
    for ( i=0; i<SAVEGAME_SLOTS; i++ )
    {
        sprintf( temp, "Save slot: %i", i+1 );
        gg_option_append_label(GG_OPTION(widget), temp, 0.5f, 0.0f);
    }
    gg_widget_subscribe_signal_name(widget, widget->id, "option_changed", 
        dialog_saveload_change, widget);
    gg_container_append(GG_CONTAINER(vbox), widget);

    if ( changing_slot )
        gg_option_set_selected(GG_OPTION(widget), saveload_selected);

    if ( saving )
    {
        widget = gg_action_create_with_label("Save Game", 0.5f, 0.0f);
        gg_widget_subscribe_signal_name(widget, widget->id, "action_pressed", 
            dialog_savegame_save, vbox);
    }
    else
    {
        widget = gg_action_create_with_label("Load Game", 0.5f, 0.0f);
        gg_widget_subscribe_signal_name(widget, widget->id, "action_pressed", 
            dialog_loadgame_load, vbox);
    }
    gg_container_append(GG_CONTAINER(vbox), widget);

    widget = gg_action_create_with_label("Cancel", 0.5f, 0.0f);
    gg_widget_subscribe_signal_name(widget, widget->id, "action_pressed", 
        dialog_close_cb, NULL);
    gg_container_append(GG_CONTAINER(vbox), widget);

    /*for ( i=0; i<SAVEGAME_SLOTS; i++ )
    {
        sprintf( temp, "%i:  ", i );
        widget = gg_action_create_with_label(temp, 0.0f, 0.0f);

        gg_action_set_callback(GG_ACTION(widget), dialog_saveload_change, vbox);

        gg_container_append(GG_CONTAINER(vbox), widget);
    }*/

    gg_container_append(GG_CONTAINER(hbox), vbox );

    if ( changing_slot )
        gg_vbox_set_selected(vbox, padding );

    /* Dialog stuff */
    gg_container_append(GG_CONTAINER(rootvbox), hbox);
    dialog = gg_dialog_create(rootvbox, NULL, parent, GG_DIALOG_AUTOHIDE_PARENT);

    if ( saving )
        gg_dialog_set_style(GG_DIALOG(dialog), get_ingame_style());
    else
        gg_dialog_set_style(GG_DIALOG(dialog), get_menu_style());

    return GG_DIALOG(dialog);
}
Beispiel #18
0
/**
 * qhasharr->debug(): Print hash table for debugging purpose
 *
 * @param tbl       qhasharr_t container pointer.
 * @param out       output stream
 *
 * @return true if successful, otherwise returns false
 * @retval errno will be set in error condition.
 *  - EIO       : Invalid output stream.
 */
bool qhasharr_debug(qhasharr_t *tbl, FILE *out) {
    if (tbl == NULL) {
        errno = EINVAL;
        return false;
    }

    if (out == NULL) {
        errno = EIO;
        return false;
    }

    qhasharr_slot_t *tblslots = get_slots(tbl);

    int idx = 0;
    qhasharr_obj_t obj;
    while (tbl->getnext(tbl, &obj, &idx) == true) {
        uint16_t namesize = tblslots[idx - 1].data.pair.namesize;
        _q_textout(out, obj.name, obj.namesize, MAX_HUMANOUT);
        fprintf(out, "%s(%d)=", (namesize > Q_HASHARR_NAMESIZE) ? "..." : "",
                namesize);
        _q_textout(out, obj.data, obj.datasize, MAX_HUMANOUT);
        fprintf(out, " (%zu)\n", obj.datasize);

        free(obj.name);
        free(obj.data);
    }

#ifdef BUILD_DEBUG
    qhasharr_data_t *tbldata = tbl->data;
    fprintf(out, "%d elements (slot %d used/%d total)\n",
            tbldata->num, tbldata->usedslots, tbldata->maxslots);
    for (idx = 0; idx < tbldata->maxslots; idx++) {
        if (tblslots[idx].count == 0) continue;

        fprintf(out, "slot=%d,type=", idx);
        if (tblslots[idx].count == EXTBLOCK_MARK) {
            fprintf(out, "EXTEND");
            fprintf(out, ",prev=%d", tblslots[idx].hash);
            fprintf(out, ",next=%d", tblslots[idx].link);
            fprintf(out, ",datasize=%d", tblslots[idx].datasize);
            fprintf(out, ",data=");
            _q_textout(out,
                    tblslots[idx].data.ext.data,
                    tblslots[idx].datasize,
                    MAX_HUMANOUT);
        } else {
            fprintf(out, "%s", (tblslots[idx].count == COLLISION_MARK)?"COLISN":"NORMAL");
            fprintf(out, ",next=%d", tblslots[idx].link);
            fprintf(out, ",count=%d", tblslots[idx].count);
            fprintf(out, ",hash=%u", tblslots[idx].hash);
            fprintf(out, ",namesize=%d", tblslots[idx].data.pair.namesize);
            fprintf(out, ",datasize=%d", tblslots[idx].datasize);
            fprintf(out, ",name=");
            _q_textout(out,
                    tblslots[idx].data.pair.name,
                    (tblslots[idx].data.pair.namesize>Q_HASHARR_NAMESIZE)
                    ? Q_HASHARR_NAMESIZE
                    : tblslots[idx].data.pair.namesize,
                    MAX_HUMANOUT);
            fprintf(out, ",data=");
            _q_textout(out,
                    tblslots[idx].data.pair.data,
                    tblslots[idx].datasize,
                    MAX_HUMANOUT);
        }
        fprintf(out, "\n");
    }
#endif

    return true;
}
Beispiel #19
0
static bool put_data(qhasharr_t *tbl, int idx, uint32_t hash, const void *name,
                     size_t namesize, const void *data, size_t datasize,
                     int count) {
    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    assert(tblslots[idx].count == 0);

    unsigned char namemd5[16];
    qhashmd5(name, namesize, namemd5);

    // store name
    tblslots[idx].count = count;
    tblslots[idx].hash = hash;
    memcpy(tblslots[idx].data.pair.name, name,
           (namesize < Q_HASHARR_NAMESIZE) ? namesize : Q_HASHARR_NAMESIZE);
    memcpy((char *) tblslots[idx].data.pair.namemd5, (char *) namemd5, 16);
    tblslots[idx].data.pair.namesize = namesize;
    tblslots[idx].link = -1;

    // store data
    int newidx;
    size_t savesize;
    for (newidx = idx, savesize = 0; savesize < datasize;) {
        if (savesize > 0) {  // find next empty slot
            int tmpidx = find_avail(tbl, newidx + 1);
            if (tmpidx < 0) {
                remove_data(tbl, idx);
                errno = ENOBUFS;
                return false;
            }

            // clear & set
            memset((void *) (&tblslots[tmpidx]), '\0', sizeof(qhasharr_slot_t));

            tblslots[tmpidx].count = EXTBLOCK_MARK; // extended data block
            tblslots[tmpidx].hash = newidx;   // previous link
            tblslots[tmpidx].link = -1;       // end block mark
            tblslots[tmpidx].datasize = 0;
            tblslots[newidx].link = tmpidx;   // link chain

            newidx = tmpidx;
        }

        // copy data
        size_t copysize = datasize - savesize;
        if (tblslots[newidx].count == EXTBLOCK_MARK) {
            // extended value
            if (copysize > sizeof(struct Q_HASHARR_SLOT_EXT)) {
                copysize = sizeof(struct Q_HASHARR_SLOT_EXT);
            }
            memcpy(tblslots[newidx].data.ext.data, data + savesize, copysize);
        } else {
            // first slot
            if (copysize > Q_HASHARR_DATASIZE) {
                copysize = Q_HASHARR_DATASIZE;
            }
            memcpy(tblslots[newidx].data.pair.data, data + savesize, copysize);

            // increase stored key counter
            tbldata->num++;
        }
        tblslots[newidx].datasize = copysize;
        savesize += copysize;

        // increase used slot counter
        tbldata->usedslots++;
    }

#ifdef QHASHARR_TIMESTAMP
    time(&tblslots[idx].timestamp);
#endif

    return true;
}