- - - - - - - - - - - - - - - - - - arrayvalue - nativearray discussion - - - - - - - - - - - - - - - - - - 1. when reading arrays off the wire (tagdata input) the binding creates arrayvalue objects. 2. question whether we can substitute our nativearray across the board. a. probably best not, since code up the line that is now mostly ported, would instead have to be rewritten for nativearray. 3. should we however plan to always use 1-dim nativearray as the base of our arrayvalue, since if we need to be able to access elements, we can't simply reflect to an array as does java, we need the subscripting and primitive object instantiation facilities of the nativearray. a. however the arrayvalue is an arraylist under the covers. perhaps we should let the arrayvalue have either or both backing store types, arraylist or nativearray. b. that could create inconsistencies of access, in that accessing nativearray always returns a disposable, and accessing arrayvalue always returns a non-disposable. c. however we could well want to not store an object for every array element, a large byte array case in point. d. let's store only as arraylist for now, leaving the option open to store as nativearray if we need it. e. another possibility is to "lazy-load" the arraylist from the natarray. in this way, we always return a non-disposable from arrayvalue.get(). when item[i] is requested, we look in the arraylist, lazy-allocating it if needed. if arraylist[i] is null, we populate it from natarray[i]. in either case we return the non-disposable arraylist[i]. 4. our arrayvalue has *both* an arraylist *and* a nativearray member. the natarray member currently is saved there when an arrayvalue was created *from* a nativearray. the natarray can be owned by the arrayvalue or not. a. arrayvalue has from() and to() nativearray methods b. arrayvalue_to_nativearray is limited to three dimensions of course. 5. java code freely references the native array or the array value and expects both to be available. ArrayValue has getArray() which returns ArrayValue.array, the native array. TaggedData has Object fromArrayValue(ArrayValue) which returns the native array representation of the ArrayValue. So we really need to keep the 1-dim nativearray in the c arrayvalue. let's do it the lazy load way descibed above. the arrayvalue then handles the multi-dimensional aspect. - - - - - - - - - - - - - - - - - - serialization notes 1 - - - - - - - - - - - - - - - - - - let's walk through writing some arrays. first, a 2-dimensional array. int x[2][3] = { {1,2,3}, {4,5,6} }; 0. we start with a nativearray, and call writeValue(ARRAY, nativearray); 1. writeValue always puts the supplied byte typecode to the buffer first. so in this case, that is ARRAY. (1) 2. next, switch(typecode) to ARRAY. a. convert the nativearray to an arrayvalue, passing ownership of na to av: etch_arrayvalue* av = new_arrayvalue_from (nativearray, typecode, customtype, size(?), 0, TRUE); b. call writeArray(av, vtor); 3. writeArray calls startArray(arrayvalue); a. put the arrayvalue's content type byte. (2) b. if content type is custom, put array's custom struct type. (3) c. put intval arrayvalue's dimensions (4) d. put intval arrayvalue's itemcount (5) 4. writeArray calls writeValues(arrayvalue); a. elementVtor ev = av.eltvtor; b. foreach entry val in ev writeValue(ev, val); 5. writeValue writes each value in the arrayvalue. this will be recursive for multidim arrays. a. in our case, the first arravalue has dim 2 and has 2 entries, which are the two 3-integer dimensions of x so writeValue(arravalue.value[i]); goes back to step 0. b. our inner recursion of writeValue (arravalue.value[i]) writes the int content (6) 6. writeArray calls endArray(arrayvalue); a. endArray writes the EOD marker. (7) ARRAY INTEGER 2 2 (a1) (a2) (a4) (a5) ARRAY INTEGER 1 3 (a6):(b1) (b2) (b4) (b5) 1 (b6) 2 (b6) 3 (b6) EOD (b7) ARRAY INTEGER 1 3 (a6):(b1) (b2) (b4) (b5) 4 (b6) 5 (b6) 6 (b6) EOD (b7) EOD (a7) - - - - - - - - - - - - - - - - - - deserialization notes 1 - - - - - - - - - - - - - - - - - - looking at the serialization, it seems as if we should do things a bit differently from the java version. when java creates an arrayvalue in which to read an array off the wire, it first allocates a java native array, and then wraps an arrayvalue around that. with the scanty information available, and without lookahead, we can't allocate our version of a nativearray, since (a) ours is top down, i.e. we need the entire byte blob first, and (b) we don't know the item count up front (we know the itemcount for the serialized *array*, in our example above that would be 2, i.e. 2 arrays of type and length not yet read. all we know at the time of array container allocation is the number of dimensions, and the actual serialized item count for that dimension. if it turns out we need data not yet read, we could conceivably look ahead for it. however the better approach might be to read into arrayvalues, and when done, construct the nativearray. lets explore that avenue here. 0. we start with a serialized arrayvalue of dim 2, type int, whose members are 2 arrayvalues of dim 1. 1. readValue finds ARRAY (a1) a. calls readArray() 2. readArray a. calls startArray() getting a new arrayvalue back. 3. startArray() a. reads the content type byte = INTEGER (a2) b. reads the dimensions count = 2 (a4) c. reads the item count = 2 (a5) d. allocates an arrayvalue (java code is lost) e. returns the new arrayvalue. 4. readArray receives arrayvalue from startArray. readArray calls readValues(arrayvalue, vtor) 5. readValues gets the element vtor for this dimension count value = readValue(arrayvalue); (a6) until value is EOD arrayvalue.add(value) value = readValue() ; 6. readValue a. ARRAY (b1) 7. readArray() arrayvalb = startArray(); 8. startArray() a. reads the content type byte INTEGER (b2) b. reads the dimensions count = 1 (b4) c. reads the item count = 3 (b5) d. allocates an arrayvalue (java code is lost) e. returns the new arrayvalb. 9. readArray() a. readValues(arrayvalb); 10. readValues gets the element vtor for this dimension count value = readValue(arrayvalb) = tiny 1; (b6) arrayvalb.add(value) value = readValue(arrayvalb) = tiny 2; (b6) arrayvalb.add(value) value = readValue(arrayvalb) = tiny 3; (b6) arrayvalb.add(value) value = readValue(arrayvalb) = EOD (b7) return; 10. readArray() calls endArray which is a nop and returns arrayvalb. 11. readValues (a) gets back Object arrayvalb and puts it to arrayvalue[0] (repeat 5-10) readValues (a) gets back Object arrayvalc and puts it to arrayvalue[1] 999. readValue processing ARRAY receives arrayvalue result of readArray(), presumably an arrayvalue with 2 members, each member being an array dim1 with 3 members. and converts the arrayValue to nativearray.