Archived

This forum has been archived. Please start a new discussion on GitHub.

effects of C++ Array Mapping for Sequences

Hello all,
I'm concerned about the impact of metadata directives.

Suppose my server has a method defined as

interface File {
void write(["cpp:array"] Ice::ByteSeq contents);
};

my questions are:

1. If my client application is also written in C++, does that mean my client program has to pass an array when invoking this method? Can my client use a separate slice definition without the "cpp:array" directive to make the call? I.e., can my client use the C++ code generated from the slice definition
void write(Ice::ByteSeq contents) ?

2. What if my client application is written in other languages? If the answer to the previous question is no problem, I guess there's no problem here either.

3. can I have multiple metadata directives for different languages? for example,
void write(["cpp:array"]["java:type:java.util.ArrayList"] Ice::ByteSeq contents);

4. If the answer to the first question is no problem, can my server just use a derived interface with an overidden method in implementation without changing the overall slice interface definition? What I mean is:

interface File {
void write(Ice::ByteSeq contents);
};

interface ServerIFile extends File
{
void write(["cpp:type:std::list"] Ice::ByteSeq contents);
};

interface ServerIIFile extends File
{
void write(["cpp:array"] Ice::ByteSeq contents);
};

while my client program only know the first definition.
I guess the answer would be no for my last question.

Comments

  • marc
    marc Florida
    smu wrote: »
    1. If my client application is also written in C++, does that mean my client program has to pass an array when invoking this method? Can my client use a separate slice definition without the "cpp:array" directive to make the call? I.e., can my client use the C++ code generated from the slice definition
    void write(Ice::ByteSeq contents) ?

    No, you don't have to use the array mapping. Just use the same Slice definition without the cpp:array metadata for your client (either by making a copy of your Slice file and modifying the metadata in this copy, or with #ifdefs).
    smu wrote: »
    2. What if my client application is written in other languages? If the answer to the previous question is no problem, I guess there's no problem here either.

    Other language mappings are not affected by metadata that starts with "cpp:".
    smu wrote: »
    3. can I have multiple metadata directives for different languages? for example,
    void write(["cpp:array"]["java:type:java.util.ArrayList"] Ice::ByteSeq contents);

    Sure, no problem. (Except that the syntax would be ["cpp:array", "java:type:java.util.ArrayList"].)
    smu wrote: »
    4. If the answer to the first question is no problem, can my server just use a derived interface with an overidden method in implementation without changing the overall slice interface definition? What I mean is:

    interface File {
    void write(Ice::ByteSeq contents);
    };

    interface ServerIFile extends File
    {
    void write(["cpp:type:std::list"] Ice::ByteSeq contents);
    };

    interface ServerIIFile extends File
    {
    void write(["cpp:array"] Ice::ByteSeq contents);
    };

    while my client program only know the first definition.
    I guess the answer would be no for my last question.

    No, you cannot overload operations in Slice.

    Metadata doesn't change the client/server contract. Your clients and servers must use the same Slice definitions, but they don't have to use the same metadata.
  • Thanks Marc! That helps a lot.

    Actually the reason I asked those question is that I saw the following paragraph on page 344 of Ice 3.1.1 Documentation. I'm not familiar with java but it seemed like the client needed to follow the metadata directive of server interface definition:
    interface I {
    ...
    void modifiedInParam(
    ["java:type:java.util.ArrayList"] StringSeq seq);
    ...
    };

    As you might expect, modifying the mapping for an operation’s parameters or
    return value may require the application to manually convert values from the original mapping to the modified mapping. For example, suppose we want to invoke the modifiedInParam operation. The signature of its proxy operation is shown below:
    void modifiedInParam(java.util.List seq, Ice.Current curr)
    The metadata changes the mapping of the seq parameter to java.util.List,
    which is the default abstract type. If a caller has a StringSeq value in the original
    mapping, it must convert the array as shown in the following example:
    String[] seq = new String[2];
    seq[0] = "hi";
    seq[1] = "there";
    IPrx proxy = ...;
    proxy.modifiedInParam(java.util.Arrays.asList(seq));


    By the way, a non-technical issue of your forum registration form:
    "If you were referred to this site by an existing member of ZeroC Forums, enter their name here." I though it was cool that you could directly look up the name for me:cool: , but it turns out I should input their username here, not the actual name.

    Thanks again,
    Shang
  • The client and server contract is not affected by Slice metadata. In general, given a Slice definition, you can add, change, or delete whatever metadata you like on just the client side, just the server side, or both, and the data that is sent over the wire does not change. In other words, changes to metadata never invalidate the client-server contract.

    However, many metadata directives affect the APIs. So, for example, if you use metadata to change the type of a parameter from an array to a list, you will need to pass the correct type. However, the client choose to pass the parameter as an array, and the server can choose to receive as a list. To do that, simply compile client and server with the same Slice definitions, except with the metadata directive changed as appropriate.

    Cheers,

    Michi.
  • Another question:
    can array mapping be nested in other definitions?

    sequence<byte> ImageData;
    sequence<["cpp:array"]ImageData> MultiImages;

    interface I
    {
    MultiImages GetImages();
    }

    Is that legal? in the sense of nesting and in the sense of "array mapping for sequences applies to input parameters and to out parameters of AMI and AMD operations"


    Thank you all!
    Shang
  • dwayne
    dwayne St. John's, Newfoundland
    smu wrote: »
    Another question:
    can array mapping be nested in other definitions?

    sequence<byte> ImageData;
    sequence<["cpp:array"]ImageData> MultiImages;

    interface I
    {
    MultiImages GetImages();
    }

    No, you cannot nest the array (or range) mapping. You can nest other alternative mappings, but not using the syntax you use above. It would instead have to be something like
        ["cpp:type:std::list< ::Ice::Byte>"] sequence<byte> ImageData;
        sequence<ImageData> MultiImages;
    

    Regards,
    Dwayne
  • The reason for disallowing such nested definitions is that it greatly complicates language mappings. There are all sorts of corner cases that need to be dealt with, such as anonymous types, scoping conflicts, etc. The bottom line is that the feature simply isn't worth the trouble.

    Cheers,

    Michi.