List of List using DynamicList

15 views
Skip to first unread message

Carlo Contavalli

unread,
Jan 21, 2023, 12:30:45 PM1/21/23
to capn...@googlegroups.com
Hello,

How do you create and use a DynamicList() to parse a serialized List(List(struct)) object?
I have a schema::Type::Reader object representing the type, but not sure how to instantiate the ListSchema correctly, and from there create the DynamicList.

Is there an example of code I can look at? I could not find any unit test for DynamicList with List of List.

I see I can use SchemaLoader.get() to get a capnp::Type out of a schema::Type::Reader, and from there I can get the ListSchema, and DynamicList. But the .get() method recurses on the Type, so it'll return the type of the inner struct, rather than outer List, and I suspect the returned DynamicList will iterate on the inner struct, rather than the outer list.

(If you see a duplicate, apologies - it seemed like the message was first blocked as spam)

Carlo

Kenton Varda

unread,
Jan 24, 2023, 4:10:56 PM1/24/23
to Carlo Contavalli, capn...@googlegroups.com
Hi Carlo,

It seems like you've figured out what everything represents and than you need to use SchemaLoader here. I'm not sure I understand the problem you're getting at.

On Sat, Jan 21, 2023 at 11:30 AM Carlo Contavalli <ca...@enfabrica.net> wrote:
I see I can use SchemaLoader.get() to get a capnp::Type out of a schema::Type::Reader, and from there I can get the ListSchema, and DynamicList. But the .get() method recurses on the Type, so it'll return the type of the inner struct, rather than outer List, and I suspect the returned DynamicList will iterate on the inner struct, rather than the outer list.

You mean SchemaLoader::getType(), right? Sure, the code "recurses" to convert the list's element type, but it then wraps that type in `ListSchema::of()`:

case schema::Type::LIST:
return ListSchema::of(getType(proto.getList().getElementType(), scope));

So the returned type should not lose the fact that the type represents a list (or list-of-lists, or list-of-list-of-lists, etc.).

Do you have some code that doesn't work as you expect, that you could share?

Sorry, I don't know of any example code off the top of my head, though perhaps there is something in schema-test.c++, schema-loader-test.c++, or dynamic-test.c++.

-Kenton

Carlo Contavalli

unread,
Jan 24, 2023, 7:11:45 PM1/24/23
to Kenton Varda, capn...@googlegroups.com
Hello,

On Tue, Jan 24, 2023 at 1:10 PM Kenton Varda <ken...@cloudflare.com> wrote:
You mean SchemaLoader::getType(), right?

Correct.
 
case schema::Type::LIST:
return ListSchema::of(getType(proto.getList().getElementType(), scope));

So the returned type should not lose the fact that the type represents a list (or list-of-lists, or list-of-list-of-lists, etc.).

Do you have some code that doesn't work as you expect, that you could share?

When looking at the code above, the recursion seemed to pretty much return a type representing List(struct) rather than
List(List(struct)), I am not sure iterating over the DynamicList is doing the right thing. My code is crashing, so assumed I was doing something wrong.

Let me work on a self contained example, don't have one handy.

Fundamentally... Once getType() returns, I have a capnp::Type that I can use to build a DynamicList, which I can use to iterate over the elements.
Iterating over the elements is moving through the outer list, and returns a DynamicValue. Now I need to iterate over the elements on the inner list.

To go from DynamicValue to another DynamicList... use getType() passing in getList().getElementType() (recursing inside once), and then DynamicValue.of<DynamicList<...>>?

Thanks,
Carlo

Kenton Varda

unread,
Jan 25, 2023, 5:16:39 PM1/25/23
to Carlo Contavalli, capn...@googlegroups.com
On Tue, Jan 24, 2023 at 6:11 PM Carlo Contavalli <ca...@enfabrica.net> wrote:
Hello,

On Tue, Jan 24, 2023 at 1:10 PM Kenton Varda <ken...@cloudflare.com> wrote:
You mean SchemaLoader::getType(), right?

Correct.
 
case schema::Type::LIST:
return ListSchema::of(getType(proto.getList().getElementType(), scope));

So the returned type should not lose the fact that the type represents a list (or list-of-lists, or list-of-list-of-lists, etc.).

Do you have some code that doesn't work as you expect, that you could share?

When looking at the code above, the recursion seemed to pretty much return a type representing List(struct) rather than
List(List(struct)),

I don't think that's true. If you give it a representation of List(List(struct)), it'll return ListSchema::of(ListSchema::of(struct type)), which seems correct?
 
I am not sure iterating over the DynamicList is doing the right thing. My code is crashing, so assumed I was doing something wrong.

Let me work on a self contained example, don't have one handy.

Yes, I think that would help.
 
Fundamentally... Once getType() returns, I have a capnp::Type that I can use to build a DynamicList, which I can use to iterate over the elements.
Iterating over the elements is moving through the outer list, and returns a DynamicValue. Now I need to iterate over the elements on the inner list.

To go from DynamicValue to another DynamicList... use getType() passing in getList().getElementType() (recursing inside once), and then DynamicValue.of<DynamicList<...>>?

You would use `dynamicValue.as<DynamicList>()`, which returns a DynamicList::Reader for the inner list, which you can then iterate over.

-Kenton
Reply all
Reply to author
Forward
0 new messages