You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@etch.apache.org by Michael Fitzner <Mi...@bmw-carit.de> on 2012/03/05 10:18:15 UTC

AW: Etch c-binding array question

Hi Thomas,
If you specify a byte[][] in your IDL file, there are different possibilities how to create the array data. In Java it is possible to create a regular multi-dimensional or ragged array. The binding-c should also support this kind of arrays. See following examples:

// client

    {
      // option 1 with fixed length
      // like in Java
      // byte[][] mda1 = new byte[4][10];

      char data_org[4][10] = {"this", "is", "a", "test1"};
      //byte[4][10]
      etch_nativearray* data = new_etch_nativearray(CLASSID_ARRAY_BYTE, 1, 2, 10, 4, 0);
      // put "this" string
      data->put2(data, &data_org[0][0], 0, 0);
      data->put2(data, &data_org[0][1], 0, 1);
      data->put2(data, &data_org[0][2], 0, 2);
      data->put2(data, &data_org[0][3], 0, 3);
      data->put2(data, &data_org[0][4], 0, 4);
      // put "is" string
      data->put2(data, &data_org[1][0], 1, 0);
      data->put2(data, &data_org[1][1], 1, 1);
      // put "a" string
      data->put2(data, &data_org[2][0], 2, 0);
      // put "test1" string
      data->put2(data, &data_org[3][0], 3, 0);
      data->put2(data, &data_org[3][1], 3, 1);
      data->put2(data, &data_org[3][2], 3, 2);
      data->put2(data, &data_org[3][3], 3, 3);
      data->put2(data, &data_org[3][4], 3, 4);
      // do call
      remote->arrayExample(remote, (etch_arraytype*)data);
    }

    {
      // option 2 with fixed length
      // like in Java
      // byte[][] mda1 = new byte[4][10];

      char data_org[4][10] = {"this", "is", "a", "test2"};
      //byte[4][10]
      etch_nativearray* data = new_etch_nativearray_from(data_org, CLASSID_ARRAY_BYTE, 1, 2, 10, 4, 0);
      // do call
      remote->arrayExample(remote, (etch_arraytype*)data);
    }

    {
      // option 3 with dynamic array length
      // like in Java
      // byte[][] mda1 = new byte[4];
      // mda1[0] = new byte[10];
      // mda1[1] = new byte[5];
      // .
      char data_org[4][10] = {"this", "is", "a", "test3"};
      etch_arrayvalue* av = new_arrayvalue(ETCH_XTRNL_TYPECODE_BYTE, NULL, 2, 4, 1, 1, 1);

      etch_nativearray* na1 = new_etch_nativearray_from(data_org[0], CLASSID_ARRAY_BYTE, 1, 1, 5, 0, 0);
      etch_nativearray* na2 = new_etch_nativearray_from(data_org[1], CLASSID_ARRAY_BYTE, 1, 1, 3, 0, 0);
      etch_nativearray* na3 = new_etch_nativearray_from(data_org[2], CLASSID_ARRAY_BYTE, 1, 1, 2, 0, 0);
      etch_nativearray* na4 = new_etch_nativearray_from(data_org[3], CLASSID_ARRAY_BYTE, 1, 1, 6, 0, 0);

      arrayvalue_add(av, (etch_object*)na1);
      arrayvalue_add(av, (etch_object*)na2);
      arrayvalue_add(av, (etch_object*)na3);
      arrayvalue_add(av, (etch_object*)na4);

      // do call
      remote->arrayExample(remote, (etch_arraytype*)av);
    }

// server
  if(is_etch_arrayvalue(data)) {
    int i;
    int count;
    etch_arrayvalue* av = (etch_arrayvalue*)data;
    // get count of second dim
    count = arrayvalue_count(av);
    for(i = 0; i < count; i++) {
      etch_nativearray* na = (etch_nativearray*)arrayvalue_get(av, i);
      printf("[%d]=%s\n", i, na->values);
    }
    etch_object_destroy(data);
  }

In my opinion the array handling is currently inconsistent (nativearray, arrayvalue, arraylist etc.) I would recommend a refactoring of this code parts.

The implementation of the array handling inside the binding-c is still from the initial contribution and we didn't change these. The new binding-cpp will provide a much cleaner API and we should to switch over to it later!

Regards
Michael

-----Ursprüngliche Nachricht-----
Von: Thomas Marsh [mailto:ThomasMarsh@gamestop.com] 
Gesendet: Freitag, 20. Januar 2012 19:58
An: etch-dev@incubator.apache.org
Betreff: Etch c-binding array question

Hello all,

I am having trouble understanding the array usage in the C binding, and I hope someone can point out the error in my understanding. I am trying to implement a service method with the signature "void test(byte[][] data)". Unfortunately, I seem unable to provide a value from a native char** pointer that successfully passes the validator.

After trying several implementations, I have a naïve implementation which does the following:

char **s = .; // array of variable length strings, like { "this", "is", "a", "test" } int nelts = .; // length of 's'

etch_arrayvalue * av = new_arrayvalue(ETCHTYPEB_BYTE, NULL, 2, nelts, 1, 0, 0);

int i, j;
for (i=0; i < nelts; i++) {
int len = strlen(s[i]);
etch_arrayvalue *elt = new_arrayvalue(ETCHTYPEB_BYTE, NULL, 1, len, 1, 0, 0); for (j=0; j < len; j++) { etch_byte *b = new_byte(s[i][j]); arrayvalue_add(elt, b); } arrayvalue_add(av, let); }
remote->test(remote, av);

I also tried variations on arrayvalue_from with native arrays, etc., but could not get it to work. The only thing I could get to work was to send a native array with fixed dimensions, but that does not work for our case.

Thanks for any assistance!

--thomas