コード例 #1
0
ファイル: test-checksum.c プロジェクト: davebenson/dsk
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;
}
コード例 #2
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;
}
コード例 #3
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);
    }
}
コード例 #4
0
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);

}
コード例 #5
0
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;
      }
  }
}
コード例 #6
0
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;
      }
  }
}
コード例 #7
0
/**
 * 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);
}
コード例 #8
0
/**
 * 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;
}
コード例 #9
0
ファイル: dsk-http-proxy.c プロジェクト: davebenson/dsk
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;
}
コード例 #10
0
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));
}
コード例 #11
0
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));
}
コード例 #12
0
/**
 * 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);
}
コード例 #13
0
ファイル: dsk-main.c プロジェクト: davebenson/dsk
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);
}
コード例 #14
0
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);
}
コード例 #15
0
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);
}
コード例 #16
0
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);
}
コード例 #17
0
ファイル: test-table-file-0.c プロジェクト: davebenson/dsk
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);
}
コード例 #18
0
/* 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);
    }
}
コード例 #19
0
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);
}
コード例 #20
0
/**
 * 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;
}
コード例 #21
0
ファイル: server.c プロジェクト: davebenson/snipez
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;
}
コード例 #22
0
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;
}
コード例 #23
0
ファイル: server.c プロジェクト: davebenson/snipez
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;
}
コード例 #24
0
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;
    }
}
コード例 #25
0
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;
}
コード例 #26
0
ファイル: dsk-main.c プロジェクト: davebenson/dsk
void              dsk_main_remove_ref      (void)
{
  dsk_assert (main_n_refs > 0);
  if (--main_n_refs == 0)
    dsk_main_quit ();
}
コード例 #27
0
ファイル: server.c プロジェクト: davebenson/snipez
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;
}
コード例 #28
0
ファイル: server.c プロジェクト: davebenson/snipez
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);
}
コード例 #29
0
ファイル: test-table-file-0.c プロジェクト: davebenson/dsk
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);
}
コード例 #30
0
ファイル: test-table-file-0.c プロジェクト: davebenson/dsk
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);
  }
}