Пример #1
0
static void
write_metadata_for_file (GString *out,
			 MetaFile *file,
			 GList **stringvs,
			 GHashTable *strings,
			 GHashTable *key_hash)
{
  GList *l;
  MetaData *data;
  guint32 key;

  g_assert (file->metadata_pointer != 0);
  set_uint32 (out, file->metadata_pointer, out->len);

  append_uint32 (out, g_list_length (file->data), NULL);

  for (l = file->data; l != NULL; l = l->next)
    {
      data = l->data;

      key = GPOINTER_TO_UINT (g_hash_table_lookup (key_hash, data->key));
      if (data->is_list)
	key |= KEY_IS_LIST_MASK;
      append_uint32 (out, key, NULL);
      if (data->is_list)
	append_stringv (out, data->values, stringvs);
      else
	append_string (out, data->value, strings);
    }
}
Пример #2
0
static void
write_children (GString *out,
		MetaBuilder *builder)
{
  GHashTable *strings;
  MetaFile *child, *file;
  GList *l;
  GList *files;

  files = g_list_prepend (NULL, builder->root);

  while (files != NULL)
    {
      file = files->data;
      files = g_list_remove_link (files, files);

      if (file->children == NULL)
	continue; /* No children, skip file */

      strings = string_block_begin ();

      if (file->children_pointer != 0)
	set_uint32 (out, file->children_pointer, out->len);

      append_uint32 (out, g_list_length (file->children), NULL);

      for (l = file->children; l != NULL; l = l->next)
	{
	  child = l->data;

	  /* No mtime, children or metadata, no need for this
	     to be in the file */
	  if (child->last_changed == 0 &&
	      child->children == NULL &&
	      child->data == NULL)
	    continue;

	  append_string (out, child->name, strings);
	  append_uint32 (out, 0, &child->children_pointer);
	  append_uint32 (out, 0, &child->metadata_pointer);
	  append_time_t (out, child->last_changed, builder);

	  if (file->children)
	    files = g_list_append (files, child);
	}

      string_block_end (out, strings);
    }
}
Пример #3
0
void
hstcpcli::request_buf_open_index(size_t pst_id, const char *dbn,
  const char *tbl, const char *idx, const char *retflds, const char *filflds)
{
  if (num_req_sent > 0 || num_req_rcvd > 0) {
    close();
    set_error(-1, "request_buf_open_index: protocol out of sync");
    return;
  }
  const string_ref dbn_ref(dbn, strlen(dbn));
  const string_ref tbl_ref(tbl, strlen(tbl));
  const string_ref idx_ref(idx, strlen(idx));
  const string_ref rfs_ref(retflds, strlen(retflds));
  writebuf.append_literal("P\t");
  append_uint32(writebuf, pst_id); // FIXME size_t ?
  writebuf.append_literal("\t");
  writebuf.append(dbn_ref.begin(), dbn_ref.end());
  writebuf.append_literal("\t");
  writebuf.append(tbl_ref.begin(), tbl_ref.end());
  writebuf.append_literal("\t");
  writebuf.append(idx_ref.begin(), idx_ref.end());
  writebuf.append_literal("\t");
  writebuf.append(rfs_ref.begin(), rfs_ref.end());
  if (filflds != 0) {
    const string_ref fls_ref(filflds, strlen(filflds));
    writebuf.append_literal("\t");
    writebuf.append(fls_ref.begin(), fls_ref.end());
  }
  writebuf.append_literal("\n");
  ++num_req_bufd;
}
Пример #4
0
static void
stringv_block_end (GString *out,
		   GHashTable *string_block,
		   GList *stringv_block)
{
  guint32 table_offset;
  StringvInfo *info;
  GList *l, *s;


  for (l = stringv_block; l != NULL; l = l->next)
    {
      info = l->data;

      table_offset = out->len;

      append_uint32 (out, g_list_length (info->strings), NULL);
      for (s = info->strings; s != NULL; s = s->next)
	append_string (out, s->data, string_block);

      set_uint32 (out, info->offset, table_offset);

      g_free (info);
    }

  g_list_free (stringv_block);

  /* Pad to 32bit */
  while (out->len % 4 != 0)
    g_string_append_c (out, 0);
}
Пример #5
0
static gboolean
create_new_journal (const char *filename, guint32 random_tag)
{
  char *journal_name;
  guint32 size_offset;
  GString *out;
  gsize pos;
  gboolean res;

  journal_name = get_journal_filename (filename, random_tag);

  out = g_string_new (NULL);

  /* HEADER */
  g_string_append_c (out, 0xda);
  g_string_append_c (out, 0x1a);
  g_string_append_c (out, 'j');
  g_string_append_c (out, 'o');
  g_string_append_c (out, 'u');
  g_string_append_c (out, 'r');

  /* VERSION */
  g_string_append_c (out, MAJOR_JOURNAL_VERSION);
  g_string_append_c (out, MINOR_JOURNAL_VERSION);

  append_uint32 (out, random_tag, NULL);
  append_uint32 (out, 0, &size_offset);
  append_uint32 (out, 0, NULL); /* Num entries, none so far */

  pos = out->len;

  g_string_set_size (out, NEW_JOURNAL_SIZE);
  memset (out->str + pos, 0, out->len - pos);

  set_uint32 (out, size_offset, out->len);

  res = g_file_set_contents (journal_name,
			     out->str, out->len,
			     NULL);

  g_free (journal_name);
  g_string_free (out, TRUE);

  return res;
}
Пример #6
0
static GString *
append_time_t (GString *s, gint64 val, MetaBuilder *builder)
{
  guint32 offset;

  if (val == 0)
    offset = 0;
  else if (val <= builder->time_t_base)
    offset = 1;
  else
    offset = val - builder->time_t_base;

  return append_uint32 (s, offset, NULL);
}
Пример #7
0
static void
append_stringv (GString *out,
		GList *strings,
		GList **stringv_block)
{
  guint32 offset;
  StringvInfo *info;

  append_uint32 (out, 0xdeaddead, &offset);

  info = g_new (StringvInfo, 1);
  info->offset = offset;
  info->strings = strings;

  *stringv_block = g_list_prepend (*stringv_block, info);
}
Пример #8
0
static void
append_string (GString *out,
	       const char *string,
	       GHashTable *string_block)
{
  guint32 offset;
  GList *offsets;

  append_uint32 (out, 0xdeaddead, &offset);

  if (g_hash_table_lookup_extended (string_block,
				    string, NULL,
				    (gpointer *)&offsets))
    {
      offsets = g_list_append (offsets, GUINT_TO_POINTER (offset));
    }
  else
    {
      g_hash_table_insert (string_block,
			   (char *)string,
			   g_list_prepend (NULL, GUINT_TO_POINTER (offset)));
    }
}
Пример #9
0
void
hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
  const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
  const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
  const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
  const string_ref *invalues, size_t invalueslen)
{
  if (num_req_sent > 0 || num_req_rcvd > 0) {
    close();
    set_error(-1, "request_buf_exec_generic: protocol out of sync");
    return;
  }
  append_uint32(writebuf, pst_id); // FIXME size_t ?
  writebuf.append_literal("\t");
  writebuf.append(op.begin(), op.end());
  writebuf.append_literal("\t");
  append_uint32(writebuf, kvslen); // FIXME size_t ?
  for (size_t i = 0; i < kvslen; ++i) {
    const string_ref& kv = kvs[i];
    append_delim_value(writebuf, kv.begin(), kv.end());
  }
  if (limit != 0 || skip != 0 || invalues_keypart >= 0 ||
    mod_op.size() != 0 || filslen != 0) {
    /* has more option */
    writebuf.append_literal("\t");
    append_uint32(writebuf, limit); // FIXME size_t ?
    if (skip != 0 || invalues_keypart >= 0 ||
      mod_op.size() != 0 || filslen != 0) {
      writebuf.append_literal("\t");
      append_uint32(writebuf, skip); // FIXME size_t ?
    }
    if (invalues_keypart >= 0) {
      writebuf.append_literal("\t@\t");
      append_uint32(writebuf, invalues_keypart);
      writebuf.append_literal("\t");
      append_uint32(writebuf, invalueslen);
      for (size_t i = 0; i < invalueslen; ++i) {
	const string_ref& s = invalues[i];
	append_delim_value(writebuf, s.begin(), s.end());
      }
    }
    for (size_t i = 0; i < filslen; ++i) {
      const hstcpcli_filter& f = fils[i];
      writebuf.append_literal("\t");
      writebuf.append(f.filter_type.begin(), f.filter_type.end());
      writebuf.append_literal("\t");
      writebuf.append(f.op.begin(), f.op.end());
      writebuf.append_literal("\t");
      append_uint32(writebuf, f.ff_offset);
      append_delim_value(writebuf, f.val.begin(), f.val.end());
    }
    if (mod_op.size() != 0) {
      writebuf.append_literal("\t");
      writebuf.append(mod_op.begin(), mod_op.end());
      for (size_t i = 0; i < mvslen; ++i) {
	const string_ref& mv = mvs[i];
	append_delim_value(writebuf, mv.begin(), mv.end());
      }
    }
  }
  writebuf.append_literal("\n");
  ++num_req_bufd;
}
Пример #10
0
static GString *
metadata_create_static (MetaBuilder *builder,
			guint32 *random_tag_out)
{
  GString *out;
  GHashTable *hash, *key_hash;
  GHashTableIter iter;
  char *key;
  GList *keys, *l;
  GHashTable *strings;
  guint32 index;
  guint32 attributes_pointer;
  gint64 time_t_min;
  gint64 time_t_max;
  guint32 random_tag, root_name;

  out = g_string_new (NULL);

  /* HEADER */
  g_string_append_c (out, 0xda);
  g_string_append_c (out, 0x1a);
  g_string_append_c (out, 'm');
  g_string_append_c (out, 'e');
  g_string_append_c (out, 't');
  g_string_append_c (out, 'a');

  /* VERSION */
  g_string_append_c (out, MAJOR_VERSION);
  g_string_append_c (out, MINOR_VERSION);

  append_uint32 (out, 0, NULL); /* Rotated */
  random_tag = g_random_int ();
  *random_tag_out = random_tag;
  append_uint32 (out, random_tag, NULL);
  append_uint32 (out, 0, &builder->root_pointer);
  append_uint32 (out, 0, &attributes_pointer);

  time_t_min = 0;
  time_t_max = 0;
  metafile_collect_times (builder->root, &time_t_min, &time_t_max);

  /* Store the base as the min value in use minus one so that
     0 is free to mean "not defined" */
  time_t_min = time_t_min - 1;

  /* Pick the base as the minimum, unless that leads to
     a 32bit overflow */
  if (time_t_max - time_t_min > G_MAXUINT32)
    time_t_min = time_t_max - G_MAXUINT32;
  builder->time_t_base = time_t_min;
  append_int64 (out, builder->time_t_base);

  /* Collect and sort all used keys */
  hash = g_hash_table_new (g_str_hash, g_str_equal);
  metafile_collect_keywords (builder->root, hash);
  g_hash_table_iter_init (&iter, hash);
  keys = NULL;
  while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
    keys = g_list_prepend (keys, key);
  g_hash_table_destroy (hash);
  keys = g_list_sort (keys, (GCompareFunc)strcmp);

  /* Write keys to file and collect mapping for keys */
  set_uint32 (out, attributes_pointer, out->len);
  key_hash = g_hash_table_new (g_str_hash, g_str_equal);
  strings = string_block_begin ();
  append_uint32 (out, g_list_length (keys), NULL);
  for (l = keys, index = 0; l != NULL; l = l->next, index++)
    {
      key = l->data;
      append_string (out, key, strings);
      g_hash_table_insert (key_hash, key, GUINT_TO_POINTER (index));
    }
  string_block_end (out, strings);

  /* update root pointer */
  set_uint32 (out, builder->root_pointer, out->len);

  /* Root name */
  append_uint32 (out, 0, &root_name);

  /* Root child pointer */
  append_uint32 (out, 0, &builder->root->children_pointer);

  /* Root metadata pointer */
  append_uint32 (out, 0, &builder->root->metadata_pointer);

  /* Root last changed */
  append_uint32 (out, builder->root->last_changed, NULL);

  /* Root name */
  set_uint32 (out, root_name, out->len);
  g_string_append_len (out, "/", 2);

  /* Pad to 32bit */
  while (out->len % 4 != 0)
    g_string_append_c (out, 0);

  write_children (out, builder);
  write_metadata (out, builder, key_hash);

  g_hash_table_destroy (key_hash);
  g_list_free (keys);

  return out;
}