Esempio n. 1
0
void
games_scores_backend_discard_scores (GamesScoresBackend * self)
{
#ifdef ENABLE_SETGID
  games_scores_backend_release_lock (self);
#endif
}
Esempio n. 2
0
gboolean
games_scores_backend_set_scores (GamesScoresBackend * self, GList * list)
{
  GList *s;
  GamesScore *d;
  gchar *buffer;
  gint output_length = 0;
  gchar dtostrbuf[G_ASCII_DTOSTR_BUF_SIZE];

  if (!games_scores_backend_get_lock (self))
    return FALSE;

  self->priv->scores_list = list;

  s = list;
  while (s != NULL) {
    gdouble rscore;
    guint64 rtime;

    d = (GamesScore *) s->data;
    rscore = 0.0;
    switch (self->priv->style) {
    case GAMES_SCORES_STYLE_PLAIN_DESCENDING:
    case GAMES_SCORES_STYLE_PLAIN_ASCENDING:
      rscore = games_score_get_value_as_plain (d);
      break;
    case GAMES_SCORES_STYLE_TIME_DESCENDING:
    case GAMES_SCORES_STYLE_TIME_ASCENDING:
      rscore = games_score_get_value_as_time (d);
      break;
    default:
      g_assert_not_reached ();
    }
    rtime = games_score_get_time (d);

    buffer = g_strdup_printf ("%s %"G_GUINT64_FORMAT"\n",
                              g_ascii_dtostr (dtostrbuf, sizeof (dtostrbuf),
                                              rscore), rtime);
    write (self->priv->fd, buffer, strlen (buffer));
    output_length += strlen (buffer);
    /* Ignore any errors and blunder on. */
    g_free (buffer);

    s = g_list_next (s);
  }

  /* Remove any content in the file that hasn't yet been overwritten. */
  ftruncate (self->priv->fd, output_length--);

  /* Update the timestamp so we don't reread the scores unnecessarily. */
  self->priv->timestamp = time (NULL);

  games_scores_backend_release_lock (self);

  return TRUE;
}
Esempio n. 3
0
void
games_scores_backend_discard_scores (GamesScoresBackend * self)
{
  games_scores_backend_release_lock (self);
}
Esempio n. 4
0
/**
 * games_scores_backend_get_scores:
 * @self: the backend to get the scores from
 * 
 * You can alter the list returned by this function, but you must
 * make sure you set it again with the _set_scores method or discard it
 * with with the _discard_scores method. Otherwise deadlocks will ensue.
 *
 * Return value: (transfer none) (allow-none) (element-type GnomeGamesSupport.Score): The list of scores
 */
GList *
games_scores_backend_get_scores (GamesScoresBackend * self)
{
  gchar *buffer;
  gchar *eol;
  gchar *scorestr;
  gchar *timestr;
  GamesScore *newscore;
  struct stat info;
  int error;
  ssize_t length, target;
  GList *t;
  
  /* Check for a change in the scores file and update if necessary. */
  error = stat (self->priv->filename, &info);

  /* If an error occurs then we give up on the file and return NULL. */
  if (error != 0) {
    return NULL;
  }

  if ((info.st_mtime > self->priv->timestamp) || (self->priv->scores_list == NULL)) {
    self->priv->timestamp = info.st_mtime;

    /* Dump the old list of scores. */
    t = self->priv->scores_list;
    while (t != NULL) {
      g_object_unref (t->data);
      t = g_list_next (t);
    }
    g_list_free (self->priv->scores_list);
    self->priv->scores_list = NULL;

    /* Lock the file and get the list. */
    if (!games_scores_backend_get_lock (self))
      return NULL;

    buffer = g_malloc (info.st_size + 1);
    if (buffer == NULL) {
      games_scores_backend_release_lock (self);
      return NULL;
    }

    target = info.st_size;
    length = 0;
    do {
      target -= length;
      length = read (self->priv->fd, buffer, info.st_size);
      if (length == -1) {
        games_scores_backend_release_lock (self);
        g_free (buffer);
        return NULL;
      }
    } while (length < target);

    buffer[info.st_size] = '\0';

    /* FIXME: These details should be in a sub-class. */

    /* Parse the list. We start by breaking it into lines. */
    /* Since the buffer is null-terminated 
     * we can do the string stuff reasonably safely. */
    eol = strchr (buffer, '\n');
    scorestr = buffer;
    while (eol != NULL) {
      *eol++ = '\0';
      timestr = strchr (scorestr, ' ');
      if (timestr == NULL)
        break;
      *timestr++ = '\0';
      /* At this point we have two strings, both null terminated. All
       * part of the original buffer. */
      switch (self->priv->style) {
      case GAMES_SCORES_STYLE_PLAIN_DESCENDING:
      case GAMES_SCORES_STYLE_PLAIN_ASCENDING:
        newscore = games_score_new_plain (g_ascii_strtod (scorestr, NULL));
        break;
      case GAMES_SCORES_STYLE_TIME_DESCENDING:
      case GAMES_SCORES_STYLE_TIME_ASCENDING:
        newscore = games_score_new_time (g_ascii_strtod (scorestr, NULL));
        break;
      default:
        g_assert_not_reached ();
      }
      games_score_set_time (newscore, g_ascii_strtoull (timestr, NULL, 10));
      self->priv->scores_list = g_list_append (self->priv->scores_list, newscore);
      /* Setup again for the next time around. */
      scorestr = eol;
      eol = strchr (eol, '\n');
    }

    g_free (buffer);
  }

  /* FIXME: Sort the scores! We shouldn't rely on the file being sorted. */

  return self->priv->scores_list;
}