int main () { DskChecksum *h; unsigned i; for (i = 0; i < TEST_COUNT; i++) { uint8_t buf[32]; h = dsk_checksum_new (DSK_CHECKSUM_MD5); dsk_checksum_feed_str (h, tests[i].str); dsk_checksum_done (h); dsk_checksum_get (h, buf); dsk_assert (memcmp (buf, tests[i].md5, 16) == 0); dsk_checksum_destroy (h); h = dsk_checksum_new (DSK_CHECKSUM_SHA1); dsk_checksum_feed_str (h, tests[i].str); dsk_checksum_done (h); dsk_checksum_get (h, buf); dsk_assert (memcmp (buf, tests[i].sha1, 20) == 0); dsk_checksum_destroy (h); h = dsk_checksum_new (DSK_CHECKSUM_SHA256); dsk_checksum_feed_str (h, tests[i].str); dsk_checksum_done (h); dsk_checksum_get (h, buf); dsk_assert (memcmp (buf, tests[i].sha256, 32) == 0); dsk_checksum_destroy (h); } return 0; }
int main() { /* TEST: dsk_ascii_isupper */ dsk_assert (dsk_ascii_isupper ('A')); dsk_assert (dsk_ascii_isupper ('Z')); dsk_assert (!dsk_ascii_isupper ('a')); dsk_assert (!dsk_ascii_isupper ('z')); dsk_assert (!dsk_ascii_isupper ('0')); return 0; }
void decount(DskBuffer* buf, int start, int end) { char b[1024]; while (start <= end) { char *rv; sprintf (b, "%d", start++); rv = dsk_buffer_read_line (buf); dsk_assert (rv != NULL); dsk_assert (strcmp (b, rv) == 0); dsk_free (rv); } }
static void test_parse_request_0 (void) { DskHttpRequest *r; r = parse_request_from_string ("GET /f HTTP/1.0\r\n" "Host: example.com\r\n"); dsk_assert (r->verb == DSK_HTTP_VERB_GET); dsk_assert (strcmp (r->path, "/f") == 0); dsk_assert (strcmp (r->host, "example.com") == 0); dsk_assert (strcmp (dsk_http_request_get (r, "host"), "example.com") == 0); dsk_assert (strcmp (dsk_http_request_get (r, "path"), "/f") == 0); dsk_object_unref (r); }
static void nfa_state_tree_foreach_1 (struct NFA_State *state, NFA_StateCallback callback, void *callback_data) { struct NFA_Transition *trans; restart: dsk_assert (!state->flag); state->flag = DSK_TRUE; callback (state, callback_data); { struct NFA_State *tail = NULL; for (trans = state->transitions; trans; trans = trans->next_in_state) if (!trans->next_state->flag) { if (tail == NULL) { tail = trans->next_state; tail->flag = DSK_TRUE; } else nfa_state_tree_foreach_1 (trans->next_state, callback, callback_data); } if (tail) { tail->flag = DSK_FALSE; state = tail; goto restart; } } }
static void clear_nfa_flags (struct NFA_State *state) { struct NFA_Transition *trans; restart: dsk_assert (state->flag); state->flag = 0; { struct NFA_State *tail = NULL; for (trans = state->transitions; trans; trans = trans->next_in_state) if (trans->next_state->flag) { if (tail == NULL) { tail = trans->next_state; tail->flag = 0; } else clear_nfa_flags (trans->next_state); } if (tail) { tail->flag = 1; state = tail; goto restart; } } }
/** * dsk_checksum_get: * @checksum: the checksum to query. * @data_out: binary buffer to fill with the checksum value. * * Get a binary checksum value. This should be of the * size returned by dsk_checksum_get_size(). */ void dsk_checksum_get (DskChecksum *checksum, uint8_t *data_out) { dsk_assert ((checksum->flags & 1) == 1); memcpy (data_out, checksum + 1, checksum->size); }
/** * dsk_checksum_done: * @checksum: the checksum to finish. * * Finish processing loose data for the checksum. * This may only be called once in * the lifetime of the checksum. */ void dsk_checksum_done (DskChecksum *checksum) { dsk_assert ((checksum->flags & 1) == 0); (*(checksum)->done) (checksum); checksum->flags |= 1; }
static dsk_boolean handle_incoming_connection (DskOctetListener *listener) { DskHttpServerStream *stream; /* accept connection */ switch (dsk_octet_listener_accept (listener, NULL, &source, &sink, &error)) { case DSK_IO_RESULT_SUCCESS: /* create http-server stream */ stream = dsk_http_server_stream_new (sink, source, &server_stream_options); dsk_assert (stream != NULL); dsk_hook_trap (&stream->request_available, (DskHookFunc) handle_http_stream_request_available, stream, dsk_object_unref); break; case DSK_IO_RESULT_AGAIN: break; case DSK_IO_RESULT_ERROR: dsk_main_exit (1); dsk_warning ("cannot accept a new socket: %s", error->message); dsk_error_unref (error); error = NULL; return DSK_FALSE; case DSK_IO_RESULT_EOF: dsk_assert_not_reached (); } /* invoke this handler when the next incoming connection is available. */ return DSK_TRUE; }
static void dsk_ssl_source_set_poll (void *object, dsk_boolean is_trapped) { DskOctetSource *source = DSK_OCTET_SOURCE (object); dsk_assert (dsk_hook_is_trapped (&source->readable_hook) == is_trapped); dsk_ssl_stream_update_traps (DSK_SSL_STREAM (source->stream)); }
static void dsk_ssl_sink_set_poll (void *object, dsk_boolean is_trapped) { DskOctetSink *sink = DSK_OCTET_SINK (object); dsk_assert (dsk_hook_is_trapped (&sink->writable_hook) == is_trapped); dsk_ssl_stream_update_traps (DSK_SSL_STREAM (sink->stream)); }
/** * dsk_checksum_destroy: * @checksum: the checksum function. * * Free memory used by the checksum object. */ void dsk_checksum_destroy (DskChecksum *checksum) { /* This assert verifies that the checksum was created with dsk_checksum_new() */ dsk_assert (checksum->flags & 2); dsk_free (checksum); }
void dsk_main_watch_fd (DskFileDescriptor fd, unsigned events, DskFDFunc callback, void *callback_data) { dsk_assert (fd >= 0); dsk_dispatch_watch_fd (dsk_dispatch_default (), fd, events, callback, callback_data); }
static void handle_fd_connected (DskClientStream *stream) { stream_do_watch_fd (stream); dsk_assert (stream->idle_disconnect_timer == NULL); if (stream->idle_disconnect_time_ms >= 0) stream->idle_disconnect_timer = dsk_dispatch_add_timer_millis (dsk_dispatch_default (), stream->idle_disconnect_time_ms, handle_idle_too_long, stream); }
static void maybe_set_autoreconnect_timer (DskClientStream *stream) { dsk_assert (stream->reconnect_timer == NULL); if (stream->reconnect_time_ms >= 0) stream->reconnect_timer = dsk_dispatch_add_timer_millis (dsk_dispatch_default (), stream->reconnect_time_ms, handle_reconnect_timer_expired, stream); }
void random_slice(DskBuffer* buf) { DskBuffer tmpbuf; char *copy, *copy_at; unsigned orig_size = buf->size; dsk_buffer_init (&tmpbuf); copy = dsk_malloc (buf->size); copy_at = copy; while (1) { int r; r = (rand () % 16384) + 1; r = dsk_buffer_read (buf, r, copy_at); dsk_buffer_append (&tmpbuf, r, copy_at); if (r == 0) break; } dsk_assert (copy_at == copy + orig_size); dsk_assert (buf->size == 0); dsk_assert (tmpbuf.size == orig_size); copy_at = dsk_malloc (orig_size); dsk_assert (dsk_buffer_read (&tmpbuf, orig_size, copy_at) == orig_size); dsk_assert (dsk_buffer_read (&tmpbuf, orig_size, copy_at) == 0); dsk_assert (memcmp (copy, copy_at, orig_size) == 0); dsk_free (copy); dsk_free (copy_at); }
static void test_various_read_write_1 (const char *name, unsigned n_entries, TestEntry *entries, uint64_t n_write) { DskError *error = NULL; DskTableFileInterface *iface = &dsk_table_file_interface_trivial; uint64_t big_i; /* index from 0..n_write-1 */ uint32_t small_i; /* index from 0..n_entries-1 */ DskTableFileWriter *writer; DskTableReader *reader; if (cmdline_verbose) fprintf (stderr, "running dataset %s [%llu]\n", name, (unsigned long long) n_write); else fprintf (stderr, "."); writer = iface->new_writer (iface, location, "base", &error); if (writer == NULL) dsk_die ("%s", error->message); for (big_i = small_i = 0; big_i < n_write; big_i++) { TestEntry *e = entries + small_i++; if (small_i == n_entries) small_i = 0; if (!writer->write (writer, strlen (e->key), (uint8_t*) e->key, strlen (e->value), (uint8_t*) e->value, &error)) dsk_die ("error writing: %s", error->message); } if (!writer->close (writer, &error)) dsk_die ("error closing writer: %s", error->message); writer->destroy (writer); reader = iface->new_reader (iface, location, "base", &error); if (reader == NULL) dsk_die ("error creating reader: %s", error->message); small_i = 0; for (big_i = 0; big_i < n_write; big_i++) { TestEntry *e = entries + small_i++; if (small_i == n_entries) small_i = 0; dsk_assert (!reader->at_eof); dsk_assert (reader->key_length == strlen (e->key)); dsk_assert (reader->value_length == strlen (e->value)); dsk_assert (memcmp (reader->key_data, e->key, reader->key_length) == 0); dsk_assert (memcmp (reader->value_data, e->value, reader->value_length) == 0); if (!reader->advance (reader, &error)) dsk_die ("error reading file: %s", error->message); if (big_i + 1 == n_write) break; } dsk_assert (reader->at_eof); reader->destroy (reader); }
/* use -1 to disable these timeouts */ void dsk_client_stream_set_reconnect_time (DskClientStream *client, int millis) { /* short-circuit no-op cases */ if (millis < 0) { if (client->reconnect_time_ms == -1) return; millis = -1; } else if (client->reconnect_time_ms == millis) return; /* if we have a valid file-descriptor or we are resolving the name, there then the reconnect_time_ms is not currently relevant: set it and go */ if (client->fd != -1 || client->is_resolving_name) { client->reconnect_time_ms = millis; return; } if (millis == -1) { /* handle timer removal */ if (client->reconnect_timer) { dsk_dispatch_remove_timer (client->reconnect_timer); client->reconnect_timer = NULL; } else dsk_warn_if_reached ("no reconnect timer?"); } else { if (client->reconnect_time_ms >= 0) dsk_dispatch_remove_timer (client->reconnect_timer); else dsk_assert (client->reconnect_timer == NULL); client->reconnect_time_ms = millis; /* TODO: subtract elapsed time from last disconnect / failed to connect */ client->reconnect_timer = dsk_dispatch_add_timer_millis (dsk_dispatch_default (), millis, handle_reconnect_timer_expired, client); } }
static void dsk_ssl_stream_finalize (DskSslStream *stream) { dsk_assert (stream->ssl); SSL_free (stream->ssl); stream->ssl = NULL; if (stream->underlying_read) dsk_hook_trap_free (stream->underlying_read); if (stream->underlying_write) dsk_hook_trap_free (stream->underlying_write); if (stream->underlying_sink) dsk_object_unref (stream->underlying_sink); if (stream->underlying_source) dsk_object_unref (stream->underlying_source); dsk_object_unref (stream->context); }
/** * dsk_checksum_get_hex: * @checksum: the checksum to query. * @hex_out: buffer to fill with a NUL-terminated hex checksum value. * * Get a hex checksum value. This should be of the * size returned by (dsk_checksum_get_size() * 2 + 1). */ void dsk_checksum_get_hex (DskChecksum *checksum, char *hex_out) { static const char hex_digits[] = "0123456789abcdef"; unsigned i; const uint8_t *checksum_value = (const uint8_t *) (checksum + 1); dsk_assert ((checksum->flags & 1) == 1); for (i = 0; i < checksum->size; i++) { uint8_t h = checksum_value[i]; *hex_out++ = hex_digits[h >> 4]; *hex_out++ = hex_digits[h & 15]; } *hex_out = 0; }
static void remove_tmp_wall (TmpWall *tmp_walls, unsigned index, TmpWall **wall_list_inout) { TmpWall *remove = tmp_walls + index; /* ignore previously deleted elements */ if (remove->prev == (void*) 1) return; if (remove->prev == NULL) { dsk_assert (*wall_list_inout == remove); (*wall_list_inout) = remove->next; } else remove->prev->next = remove->next; if (remove->next != NULL) remove->next->prev = remove->prev; remove->prev = remove->next = (void*) 1; }
static dsk_boolean handle_underlying_writable (DskOctetSink *underlying, DskSslStream *stream) { dsk_assert (stream->underlying_sink == underlying); if (stream->handshaking) { DskError *error = NULL; if (!do_handshake (stream, &error)) { dsk_octet_stream_set_error (DSK_OCTET_STREAM (stream), error); dsk_error_unref (error); return DSK_FALSE; } return DSK_TRUE; } else if (stream->write_needed_to_read) dsk_hook_notify (&stream->base_instance.source->readable_hook); else dsk_hook_notify (&stream->base_instance.sink->writable_hook); return DSK_TRUE; }
static void remove_object_from_cell_list (Object *object) { unsigned idx = (object->x/CELL_SIZE) + (object->y/CELL_SIZE) * object->game->universe_width; Cell *cell = object->game->cells + idx; #if 0 // Assert: the object is in the list */ {Object*tmp;for(tmp=cell->objects[object->type];tmp;tmp=tmp->next_in_cell)if (tmp==object)break;dsk_assert (tmp != NULL);} #endif if (object->prev_in_cell != NULL) object->prev_in_cell->next_in_cell = object->next_in_cell; else { dsk_assert (cell->objects[object->type] == object); cell->objects[object->type] = object->next_in_cell; } if (object->next_in_cell != NULL) object->next_in_cell->prev_in_cell = object->prev_in_cell; }
static void dump_token_list (struct Token *token) { while (token) { printf ("token %p: ", token); switch (token->type) { case TOKEN_LPAREN: printf ("("); break; case TOKEN_RPAREN: printf (")"); break; case TOKEN_ALTER: printf ("|"); break; case TOKEN_STAR: printf ("*"); break; case TOKEN_PLUS: printf ("+"); break; case TOKEN_QUESTION_MARK: printf ("?"); break; case TOKEN_PATTERN: dsk_assert (token->pattern->type == PATTERN_LITERAL); print_char_class (token->pattern->info.literal); break; } printf ("\n"); token = token->next; } }
int main(int argc, char** argv) { DskBuffer gskbuffer; char buf[1024]; char *str; dsk_cmdline_init ("test dsk-buffer code", "test DskBuffer", NULL, 0); dsk_cmdline_process_args (&argc, &argv); dsk_buffer_init (&gskbuffer); dsk_assert (gskbuffer.size == 0); dsk_buffer_append (&gskbuffer, 5, "hello"); dsk_assert (gskbuffer.size == 5); dsk_assert (dsk_buffer_read (&gskbuffer, sizeof (buf), buf) == 5); dsk_assert (memcmp (buf, "hello", 5) == 0); dsk_assert (gskbuffer.size == 0); dsk_buffer_clear (&gskbuffer); dsk_buffer_init (&gskbuffer); count (&gskbuffer, 1, 100000); decount (&gskbuffer, 1, 100000); dsk_assert (gskbuffer.size == 0); dsk_buffer_clear (&gskbuffer); dsk_buffer_init (&gskbuffer); dsk_buffer_append_string (&gskbuffer, "hello\na\nb"); str = dsk_buffer_read_line (&gskbuffer); dsk_assert (str); dsk_assert (strcmp (str, "hello") == 0); dsk_free (str); str = dsk_buffer_read_line (&gskbuffer); dsk_assert (str); dsk_assert (strcmp (str, "a") == 0); dsk_free (str); dsk_assert (gskbuffer.size == 1); dsk_assert (dsk_buffer_read_line (&gskbuffer) == NULL); dsk_buffer_append_byte (&gskbuffer, '\n'); str = dsk_buffer_read_line (&gskbuffer); dsk_assert (str); dsk_assert (strcmp (str, "b") == 0); dsk_free (str); dsk_assert (gskbuffer.size == 0); dsk_buffer_clear (&gskbuffer); dsk_buffer_init (&gskbuffer); dsk_buffer_append (&gskbuffer, 5, "hello"); dsk_buffer_append_foreign (&gskbuffer, 4, "test", NULL, NULL); dsk_buffer_append (&gskbuffer, 5, "hello"); dsk_assert (gskbuffer.size == 14); dsk_assert (dsk_buffer_read (&gskbuffer, sizeof (buf), buf) == 14); dsk_assert (memcmp (buf, "hellotesthello", 14) == 0); dsk_assert (gskbuffer.size == 0); /* Test that the foreign data really is not being stored in the DskBuffer */ { char test_str[5]; strcpy (test_str, "test"); dsk_buffer_init (&gskbuffer); dsk_buffer_append (&gskbuffer, 5, "hello"); dsk_buffer_append_foreign (&gskbuffer, 4, test_str, NULL, NULL); dsk_buffer_append (&gskbuffer, 5, "hello"); dsk_assert (gskbuffer.size == 14); dsk_assert (dsk_buffer_peek (&gskbuffer, sizeof (buf), buf) == 14); dsk_assert (memcmp (buf, "hellotesthello", 14) == 0); test_str[1] = '3'; dsk_assert (gskbuffer.size == 14); dsk_assert (dsk_buffer_read (&gskbuffer, sizeof (buf), buf) == 14); dsk_assert (memcmp (buf, "hellot3sthello", 14) == 0); dsk_buffer_clear (&gskbuffer); } /* Test str_index_of */ { DskBuffer buffer = DSK_BUFFER_INIT; dsk_buffer_append_foreign (&buffer, 3, "abc", NULL, NULL); dsk_buffer_append_foreign (&buffer, 3, "def", NULL, NULL); dsk_buffer_append_foreign (&buffer, 3, "gad", NULL, NULL); #if 0 dsk_assert (dsk_buffer_str_index_of (&buffer, "cdefg") == 2); dsk_assert (dsk_buffer_str_index_of (&buffer, "ad") == 7); dsk_assert (dsk_buffer_str_index_of (&buffer, "ab") == 0); dsk_assert (dsk_buffer_str_index_of (&buffer, "a") == 0); dsk_assert (dsk_buffer_str_index_of (&buffer, "g") == 6); #endif dsk_buffer_clear (&buffer); } static const char *before_strs[] = { "", "foo", NULL, NULL }; before_strs[2] = generate_str (100, 1000); before_strs[3] = generate_str (10000, 100000); static const char *placeholder_strs[] = { "", "bar", NULL, NULL, NULL }; placeholder_strs[2] = generate_str (100, 1000); placeholder_strs[3] = generate_str (10000, 100000); placeholder_strs[4] = generate_str (100000, 1000000); static const char *after_strs[] = { "", "foo", NULL, NULL }; after_strs[2] = generate_str (100, 1000); after_strs[3] = generate_str (10000, 100000); unsigned bi, pi, ai; for (bi = 0; bi < DSK_N_ELEMENTS (before_strs); bi++) for (pi = 0; pi < DSK_N_ELEMENTS (placeholder_strs); pi++) for (ai = 0; ai < DSK_N_ELEMENTS (after_strs); ai++) { DskBuffer buffer = DSK_BUFFER_INIT; const char *pi_str = placeholder_strs[pi]; DskBufferPlaceholder placeholder; dsk_buffer_append_string (&buffer, before_strs[bi]); dsk_buffer_append_placeholder (&buffer, strlen (pi_str), &placeholder); dsk_buffer_append_string (&buffer, after_strs[ai]); dsk_buffer_placeholder_set (&placeholder, pi_str); dsk_assert (try_initial_remove (&buffer, before_strs[bi])); dsk_assert (try_initial_remove (&buffer, pi_str)); dsk_assert (try_initial_remove (&buffer, after_strs[ai])); dsk_assert (buffer.size == 0); } return 0; }
void dsk_main_remove_ref (void) { dsk_assert (main_n_refs > 0); if (--main_n_refs == 0) dsk_main_quit (); }
static Game * create_game (const char *name, unsigned width, unsigned height) { Game *game = dsk_malloc (sizeof (Game)); unsigned usize; unsigned i; game->name = dsk_strdup (name); game->next_game = all_games; all_games = game; game->universe_width = width; game->universe_height = height; usize = width * height; game->h_walls = generate_ones (usize); game->v_walls = generate_ones (usize); for (i = 0; i < N_OBJECT_TYPES; i++) game->objects[i] = NULL; game->generators = NULL; game->cells = dsk_malloc0 (sizeof (Cell) * width * height); game->latest_update = 0; game->wrap = DSK_TRUE; game->diag_bullets_bounce = DSK_TRUE; game->bullet_kills_player = DSK_TRUE; game->bullet_kills_generator = DSK_TRUE; game->pending_updates = NULL; /* Generate with Modified Kruskals Algorithm, see * http://en.wikipedia.org/wiki/Maze_generation_algorithm */ TmpWall *tmp_walls = dsk_malloc (sizeof (TmpWall) * usize * 2); TmpSetInfo *sets = dsk_malloc (sizeof (TmpSetInfo) * usize); /* connect the walls together in random order */ unsigned *scramble; scramble = dsk_malloc (sizeof (unsigned) * usize * 2); for (i = 0; i < usize * 2; i++) scramble[i] = i; for (i = 0; i < usize * 2; i++) swap_ints (scramble + random_int_range (usize * 2), scramble + random_int_range (usize * 2)); TmpWall *wall_list = NULL; for (i = 0; i < usize * 2; i++) { unsigned e = scramble[i]; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); if (!game->wrap) { if ((h && y == 0) || (!h && x == 0)) continue; } tmp_walls[e].prev = NULL; tmp_walls[e].next = wall_list; if (wall_list) wall_list->prev = tmp_walls + e; wall_list = tmp_walls + e; } for (i = 0; i < usize; i++) { sets[i].set_number = i; sets[i].next_in_set = sets + i; } while (wall_list != NULL) { /* Invariants: - the sets are in a ring by set number. - The wall_list only consists of walls that separate distinct sets. */ /* remove wall */ unsigned e = wall_list - tmp_walls; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); TmpSetInfo *si = sets + e / 2; TmpSetInfo *osi; if (h) { if (y == 0) osi = si + (height - 1) * width; else osi = si - width; game->h_walls[x + y * width] = 0; } else { if (x == 0) osi = si + width - 1; else osi = si - 1; game->v_walls[x + y * width] = 0; } dsk_assert (osi->set_number != si->set_number); TmpSetInfo *kring = osi->set_number < si->set_number ? osi : si; /* ring to keep */ TmpSetInfo *dring = osi->set_number < si->set_number ? si : osi; /* ring to change */ TmpSetInfo *dring_start = dring; /* combine sets (removing any walls that no longer separate different sets from the list of walls to remove) */ unsigned set = kring->set_number; do { unsigned x = (dring - sets) % width; unsigned y = (dring - sets) / width; int wall_idx; dring->set_number = set; #if 0 if (wall_list) { dsk_assert (wall_list->prev == NULL); TmpWall *t; for (t = wall_list; t; t = t->next) if (t->next) dsk_assert (t->next->prev == t); } #endif /* Maybe remove left wall from candidate set of walls. */ wall_idx = -1; if (x > 0 && (dring-1)->set_number == set) wall_idx = 2 * (x + y * width); else if (x == 0 && game->wrap && (dring+width-1)->set_number == set) wall_idx = 2 * (x + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove right wall from candidate set of walls. */ wall_idx = -1; if (x < width - 1 && (dring+1)->set_number == set) wall_idx = 2 * ((x+1) + y * width); else if (x == width - 1 && game->wrap && (dring-width+1)->set_number == set) wall_idx = 2 * (0 + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove top wall from candidate set of walls. */ wall_idx = -1; if (y > 0 && (dring-width)->set_number == dring->set_number) wall_idx = 2 * (x + y * width) + 1; else if (y == 0 && game->wrap && (dring+width*(height-1))->set_number == set) wall_idx = 2 * (x + y * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove bottom wall from candidate set of walls. */ wall_idx = -1; if (y < height - 1 && (dring+width)->set_number == set) wall_idx = 2 * (x + (y+1) * width) + 1; else if (y == height - 1 && game->wrap && (dring-(height-1)*width)->set_number == set) wall_idx = 2 * (x + 0 * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); dring = dring->next_in_set; } while (dring != dring_start); /* Merge the rings */ TmpSetInfo *old_dring_next = dring->next_in_set; dring->next_in_set = kring->next_in_set; kring->next_in_set = old_dring_next; } dsk_free (tmp_walls); dsk_free (sets); dsk_free (scramble); /* generate generators */ unsigned n_generators = 12 + rand () % 6; dsk_warning ("%u generators", n_generators); i = 0; while (i < n_generators) { unsigned idx = random_int_range (usize); Cell *cell = game->cells + idx; if (cell->generator == NULL) { cell->generator = dsk_malloc (sizeof (Generator)); cell->generator->game = game; cell->generator->x = (idx % width) * CELL_SIZE + CELL_SIZE/2; cell->generator->y = (idx / width) * CELL_SIZE + CELL_SIZE/2; dsk_warning ("created generator at %u,%u",cell->generator->x ,cell->generator->y); cell->generator->generator_prob = 0.01; cell->generator->next_in_game = game->generators; cell->generator->prev_in_game = NULL; if (game->generators) game->generators->prev_in_game = cell->generator; game->generators = cell->generator; i++; } } game->timer = dsk_main_add_timer_millis (update_period_msecs, (DskTimerFunc) game_update_timer_callback, game); return game; }
static void game_update_timer_callback (Game *game) { /* run players */ Object *object; for (object = game->objects[OBJECT_TYPE_USER]; object != NULL; ) { User *user = (User *) object; dsk_boolean destroy_user = DSK_FALSE; if (user->dead_count > 0) { user->dead_count -= 1; if (user->dead_count == 0) { teleport_object (&user->base); add_object_to_cell_list (object); } object = object->next_in_game; continue; } if (user->move_x || user->move_y) { int new_x = object->x + user->move_x; int new_y = object->y + user->move_y; void *obj; if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); break; case OCC_WALL: case OCC_USER: /* move blocked harmlessly */ break; case OCC_ENEMY: destroy_user = DSK_TRUE; break; case OCC_BULLET: destroy_user = DSK_TRUE; remove_object_from_cell_list (obj); remove_object_from_game_list (obj); break; case OCC_GENERATOR: destroy_user = DSK_TRUE; break; } } if (user->bullet_block > 0) user->bullet_block--; else if (user->bullet_x || user->bullet_y) { /* create bullet */ Bullet *bullet = dsk_malloc (sizeof (Bullet)); bullet->base.type = OBJECT_TYPE_BULLET; bullet->base.game = game; /* create bullet on top of the user, we'll move it in the next loop */ bullet->base.x = user->base.x; bullet->base.y = user->base.y; add_object_to_cell_list (&bullet->base); add_object_to_game_list (&bullet->base); bullet->move_x = user->bullet_x; bullet->move_y = user->bullet_y; user->bullet_block = BULLET_BLOCK_PERIOD; } if (destroy_user) { remove_object_from_cell_list (object); user->dead_count = DEAD_TIME; } object = object->next_in_game; } /* update bullets, kill stuff */ { unsigned bi; for (bi = 0; bi < BULLET_SPEED; bi++) { for (object = game->objects[OBJECT_TYPE_BULLET]; object != NULL; ) { Bullet *bullet = (Bullet *) object; int new_x, new_y; dsk_boolean destroy_bullet; retry: new_x = object->x + bullet->move_x; new_y = object->y + bullet->move_y; if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } destroy_bullet = DSK_TRUE; void *obj; switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); destroy_bullet = DSK_FALSE; break; case OCC_WALL: if (bullet->move_x && bullet->move_y && game->diag_bullets_bounce) { void *dummy; dsk_boolean xflip = get_occupancy (game, new_x, object->y, &dummy) == OCC_WALL; dsk_boolean yflip = get_occupancy (game, object->x, new_y, &dummy) == OCC_WALL; if (!xflip && !yflip) xflip = yflip = DSK_TRUE; if (xflip) bullet->move_x = -bullet->move_x; if (yflip) bullet->move_y = -bullet->move_y; goto retry; } break; case OCC_USER: if (game->bullet_kills_player) { /* user dies */ User *user = obj; remove_object_from_cell_list (obj); user->dead_count = DEAD_TIME; } break; case OCC_ENEMY: /* destroy enemy */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); break; case OCC_BULLET: /* destroy other bullet */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); break; case OCC_GENERATOR: if (game->bullet_kills_generator) { Generator *gen = obj; Cell *cell = game->cells + (gen->x/CELL_SIZE) + (gen->y/CELL_SIZE) * game->universe_width; dsk_assert (cell->generator == gen); cell->generator = NULL; /* remove generator from list */ if (gen->prev_in_game) gen->prev_in_game->next_in_game = gen->next_in_game; else game->generators = gen->next_in_game; if (gen->next_in_game) gen->next_in_game->prev_in_game = gen->prev_in_game; cell->generator = NULL; dsk_free (gen); } break; } if (destroy_bullet) { Object *next = object->next_in_game; remove_object_from_cell_list (object); remove_object_from_game_list (object); dsk_free (bullet); object = next; } else object = object->next_in_game; } } } /* update enemies */ for (object = game->objects[OBJECT_TYPE_ENEMY]; object != NULL; ) { //Enemy *enemy = (Enemy *) object; int new_x, new_y; new_x = object->x; new_y = object->y; if (random_double () < ENEMY_MOVE_FRACTION) { new_x += random_int_range (3) - 1; new_y += random_int_range (3) - 1; } if (game->wrap) { new_x = mod (new_x, game->universe_width * CELL_SIZE); new_y = mod (new_y, game->universe_height * CELL_SIZE); } dsk_boolean destroy_enemy = DSK_FALSE; void *obj; switch (get_occupancy (game, new_x, new_y, &obj)) { case OCC_EMPTY: move_object (object, new_x, new_y); break; case OCC_WALL: break; case OCC_USER: /* enemy kills user */ remove_object_from_game_list (obj); remove_object_from_cell_list (obj); ((User*)obj)->dead_count = DEAD_TIME; break; case OCC_ENEMY: /* move suppressed */ break; case OCC_BULLET: /* destroy bullet */ remove_object_from_cell_list (obj); remove_object_from_game_list (obj); dsk_free (obj); destroy_enemy = DSK_TRUE; break; case OCC_GENERATOR: break; } if (destroy_enemy) { Object *next = object->next_in_game; remove_object_from_cell_list (object); remove_object_from_game_list (object); dsk_free (object); object = next; } else object = object->next_in_game; } /* run generators */ Generator *gen; for (gen = game->generators; gen; gen = gen->next_in_game) { if (random_double () < gen->generator_prob) { /* try generating enemy */ int positions[12][2] = { {-1,-1}, {-1,0}, {-1,1}, {-1,2}, {0,2}, {1,2}, {2,2}, {2,1}, {2,0}, {2,-1}, {1,-1}, {0,-1} }; unsigned p = random_int_range (12); int dx = positions[p][0]; int dy = positions[p][1]; unsigned x = gen->x + dx; unsigned y = gen->y + dy; void *dummy; if (get_occupancy (game, x, y, &dummy) == OCC_EMPTY) { /* create enemy */ Enemy *enemy = dsk_malloc (sizeof (Enemy)); enemy->base.type = OBJECT_TYPE_ENEMY; enemy->base.x = x; enemy->base.y = y; enemy->base.game = game; add_object_to_cell_list (&enemy->base); add_object_to_game_list (&enemy->base); } } } /* finish any requests that were waiting for a new frame */ while (game->pending_updates != NULL) { DskJsonValue *state_json; PendingUpdate *pu = game->pending_updates; game->pending_updates = pu->next; state_json = create_user_update (pu->user); respond_take_json (pu->request, state_json); dsk_free (pu); } game->latest_update += 1; game->timer = dsk_main_add_timer_millis (update_period_msecs, (DskTimerFunc) game_update_timer_callback, game); }
static void test_simple_write_read (void) { DskError *error = NULL; DskTableFileInterface *iface = &dsk_table_file_interface_trivial; DskTableFileWriter *writer = iface->new_writer (iface, location, "base", &error); DskTableReader *reader; if (writer == NULL) dsk_die ("%s", error->message); if (!writer->write (writer, 1, (uint8_t*) "a", 1, (uint8_t*) "A", &error) || !writer->write (writer, 1, (uint8_t*) "b", 1, (uint8_t*) "B", &error) || !writer->write (writer, 1, (uint8_t*) "c", 1, (uint8_t*) "C", &error)) dsk_die ("error writing: %s", error->message); if (!writer->close (writer, &error)) dsk_die ("error closing writer: %s", error->message); writer->destroy (writer); reader = iface->new_reader (iface, location, "base", &error); if (reader == NULL) dsk_die ("error creating reader: %s", error->message); dsk_assert (!reader->at_eof); dsk_assert (reader->key_length == 1); dsk_assert (reader->key_data[0] == 'a'); dsk_assert (reader->value_length == 1); dsk_assert (reader->value_data[0] == 'A'); if (!reader->advance (reader, &error)) dsk_die ("error advancing reader: %s", error->message); dsk_assert (!reader->at_eof); dsk_assert (reader->key_length == 1); dsk_assert (reader->key_data[0] == 'b'); dsk_assert (reader->value_length == 1); dsk_assert (reader->value_data[0] == 'B'); if (!reader->advance (reader, &error)) dsk_die ("error advancing reader: %s", error->message); dsk_assert (!reader->at_eof); dsk_assert (reader->key_length == 1); dsk_assert (reader->key_data[0] == 'c'); dsk_assert (reader->value_length == 1); dsk_assert (reader->value_data[0] == 'C'); if (!reader->advance (reader, &error)) dsk_die ("error advancing reader: %s", error->message); dsk_assert (reader->at_eof); reader->destroy (reader); }
static void test_various_write_seek_1 (const char *name, unsigned n_entries, TestEntry *entries, unsigned n_negative, TestEntry *neg_entries) { DskError *error = NULL; unsigned i; DskTableFileInterface *iface = &dsk_table_file_interface_trivial; DskTableFileWriter *writer; DskTableFileSeeker *seeker; if (cmdline_verbose) fprintf (stderr, "running dataset %s [%u]\n", name, n_entries); else fprintf (stderr, "."); writer = iface->new_writer (iface, location, "base", &error); if (writer == NULL) dsk_die ("%s", error->message); for (i = 0; i < n_entries; i++) { TestEntry *e = entries + i; if (!writer->write (writer, strlen (e->key), (uint8_t*) e->key, strlen (e->value), (uint8_t*) e->value, &error)) dsk_die ("error writing: %s", error->message); } if (!writer->close (writer, &error)) dsk_die ("error closing writer: %s", error->message); writer->destroy (writer); /* --- now test seeker --- */ /* pick the step size. */ { static unsigned prime_table[] = { 29, 31, 37, 41, 43, 47, 53, 59, 61, 67 }; unsigned *p_ptr = prime_table + DSK_N_ELEMENTS (prime_table) - 1; unsigned max_test, n_test, test_i, step; while (n_entries % *p_ptr == 0) p_ptr--; step = *p_ptr % n_entries; /* create seeker */ seeker = iface->new_seeker (iface, location, "base", &error); if (seeker == NULL) dsk_die ("error creating seeker from newly finished writer: %s", error->message); max_test = cmdline_slow ? 100000 : 1000; n_test = DSK_MIN (n_entries, max_test); test_i = step; for (i = 0; i < n_test; i++) { unsigned key_len, value_len; const uint8_t *key_data, *value_data; /* do the seek */ if (!seeker->find (seeker, str_test_func, (void*) entries[test_i].key, DSK_TABLE_FILE_FIND_ANY, &key_len, &key_data, &value_len, &value_data, &error)) { if (error) dsk_die ("error doing find that should have succeeded: %s", error->message); else dsk_die ("not found doing find that should have succeeded"); } #if 0 dsk_warning ("test=%s, got result %.*s", entries[test_i].key, (int) key_len, key_data); #endif dsk_assert (key_len == strlen (entries[test_i].key)); dsk_assert (value_len == strlen (entries[test_i].value)); dsk_assert (memcmp (key_data, entries[test_i].key, key_len) == 0); dsk_assert (memcmp (value_data, entries[test_i].value, value_len) == 0); /* advance test_i */ test_i += step; if (test_i >= n_entries) test_i -= n_entries; } /* do negative tests */ for (i = 0; i < n_negative; i++) { unsigned key_len, value_len; const uint8_t *key_data, *value_data; /* do the seek */ if (!seeker->find (seeker, str_test_func, (void*) neg_entries[i].key, DSK_TABLE_FILE_FIND_ANY, &key_len, &key_data, &value_len, &value_data, &error)) { if (error) dsk_die ("error doing find that should have returned nothing: %s", error->message); } else if (key_len == strlen (neg_entries[i].key) && memcmp (key_data, neg_entries[i].key, key_len) == 0) { dsk_die ("found result when none expected"); } } seeker->destroy (seeker); } }