Exemple #1
0
int
sexp_iterator_check_type(struct sexp_iterator *iterator,
			 const uint8_t *type)
{
  return (sexp_iterator_enter_list(iterator)
	  && iterator->type == SEXP_ATOM
	  && !iterator->display
	  && strlen(type) == iterator->atom_length
	  && !memcmp(type, iterator->atom, iterator->atom_length)
	  && sexp_iterator_next(iterator));
}
Exemple #2
0
const uint8_t *
sexp_iterator_check_types(struct sexp_iterator *iterator,
			  unsigned ntypes,
			  const uint8_t * const *types)
{
  if (sexp_iterator_enter_list(iterator)
      && iterator->type == SEXP_ATOM
      && !iterator->display)
    {
      unsigned i;
      for (i = 0; i<ntypes; i++)
	if (strlen(types[i]) == iterator->atom_length
	    && !memcmp(types[i], iterator->atom,
		       iterator->atom_length))
	  return sexp_iterator_next(iterator) ? types[i] : NULL;
    }
  return NULL;
}
Exemple #3
0
int
sexp_iterator_next(struct sexp_iterator *iterator)
{
  switch (iterator->type)
    {
    case SEXP_END:
      return 1;
    case SEXP_LIST:
      /* Skip this list */
      return sexp_iterator_enter_list(iterator)
	&& sexp_iterator_exit_list(iterator);
    case SEXP_ATOM:
      /* iterator->pos should already point at the start of the next
       * element. */
      return sexp_iterator_parse(iterator);
    }
  /* If we get here, we have a bug. */
  abort();
}
Exemple #4
0
int
sexp_iterator_assoc(struct sexp_iterator *iterator,
		    unsigned nkeys,
		    const uint8_t * const *keys,
		    struct sexp_iterator *values)
{
  TMP_DECL(found, int, NETTLE_MAX_SEXP_ASSOC);
  unsigned nfound;
  unsigned i;

  TMP_ALLOC(found, nkeys);
  for (i = 0; i<nkeys; i++)
    found[i] = 0;

  nfound = 0;
  
  for (;;)
    {
      switch (iterator->type)
	{
	case SEXP_LIST:

	  /* FIXME: Use sexp_iterator_check_type? Problem is to
	   * distinguish syntax errors from unkown keys (which we want
	   * to just ignore). */
	  if (!sexp_iterator_enter_list(iterator))
	    return 0;
	  
	  if (iterator->type == SEXP_ATOM
	      && !iterator->display)
	    {
	      /* Compare to the given keys */
	      for (i = 0; i<nkeys; i++)
		{
		  /* NOTE: The strlen could be put outside of the
		   * loop */
		  if (strlen(keys[i]) == iterator->atom_length
		      && !memcmp(keys[i], iterator->atom,
				 iterator->atom_length))
		    {
		      if (found[i])
			/* We don't allow duplicates */
			return 0;

		      /* Advance to point to value */
		      if (!sexp_iterator_next(iterator))
			return 0;

		      found[i] = 1;
		      nfound++;
		      
		      /* Record this position. */
		      values[i] = *iterator;
		      
		      break;
		    }
		}
	    }
	  if (!sexp_iterator_exit_list(iterator))
	    return 0;
	  break;
	case SEXP_ATOM:
	  /* Just ignore */
	  if (!sexp_iterator_next(iterator))
	    return 0;
	  break;
	  
	case SEXP_END:
	  return sexp_iterator_exit_list(iterator)
	    && (nfound == nkeys);

	default:
	  abort();
	}
    }
}
Exemple #5
0
void
test_main(void)
{
    struct sexp_iterator i;
    uint32_t x;

    ASSERT(sexp_iterator_first(&i, LDATA("")));
    ASSERT(i.type == SEXP_END);

    ASSERT(sexp_iterator_first(&i, LDATA("()")));
    ASSERT(i.type == SEXP_LIST
           && sexp_iterator_enter_list(&i)
           && i.type == SEXP_END
           && sexp_iterator_exit_list(&i)
           && i.type == SEXP_END);

    ASSERT(sexp_iterator_first(&i, LDATA("(")));
    ASSERT(i.type == SEXP_LIST
           && !sexp_iterator_enter_list(&i));

    /* Check integers. */
    ASSERT(sexp_iterator_first(&i, LDATA("1:\0"
                                         "1:\x11"
                                         "2:\x00\x11"
                                         "2:\x00\x80"
                                         "5:\x00\xaa\xbb\xcc\xdd")));
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x80);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0xaabbccdd);

    ASSERT(sexp_iterator_first(&i, LDATA("3:foo0:[3:bar]12:xxxxxxxxxxxx")));
    ASSERT(i.type == SEXP_ATOM
           && !i.display_length && !i.display
           && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)

           && sexp_iterator_next(&i) && i.type == SEXP_ATOM
           && !i.display_length && !i.display
           && !i.atom_length && i.atom

           && sexp_iterator_next(&i) && i.type == SEXP_ATOM
           && i.display_length == 3 && MEMEQ(3, "bar", i.display)
           && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)

           && sexp_iterator_next(&i) && i.type == SEXP_END);

    /* Same data, transport encoded. */

    {
        struct tstring *s
            = tstring_data(LDATA("{Mzpmb28=} {MDo=} {WzM6YmFyXTEyOnh4eHh4eHh4eHh4eA==}"));
        ASSERT(sexp_transport_iterator_first (&i, s->length, s->data));
        ASSERT(i.type == SEXP_ATOM
               && !i.display_length && !i.display
               && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)

               && sexp_iterator_next(&i) && i.type == SEXP_ATOM
               && !i.display_length && !i.display
               && !i.atom_length && i.atom

               && sexp_iterator_next(&i) && i.type == SEXP_ATOM
               && i.display_length == 3 && MEMEQ(3, "bar", i.display)
               && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)

               && sexp_iterator_next(&i) && i.type == SEXP_END);

    }
    {
        static const uint8_t *keys[2] = { "n", "e" };
        struct sexp_iterator v[2];

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)0:(1:y)(1:e))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && sexp_iterator_assoc(&i, 2, keys, v));

        ASSERT(v[0].type == SEXP_ATOM
               && !v[0].display_length && !v[0].display
               && v[0].atom_length == 2 && MEMEQ(2, "xx", v[0].atom)

               && sexp_iterator_next(&v[0]) && v[0].type == SEXP_ATOM
               && !v[0].display_length && !v[0].display
               && v[0].atom_length == 3 && MEMEQ(3, "foo", v[0].atom)

               && sexp_iterator_next(&v[0]) && v[0].type == SEXP_END);

        ASSERT(v[1].type == SEXP_END);

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && !sexp_iterator_assoc(&i, 2, keys, v));

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n)(1:n3:foo))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && !sexp_iterator_assoc(&i, 2, keys, v));
    }
}