implementation module EnDecode; import StdEnv; import DefaultElem; import DynamicUtilities; // non-unique, straight-forward conversions class EnDecode a where { to_size :: a -> !Int; to_string :: a !Int !*{#Char} -> (!Int,!*{#Char}); from_string :: !Int !{#Char} -> (a,!Int); encode :: a -> !*{#Char} | EnDecode a; encode a :== snd (to_string a 0 (createArray (to_size a) '@')); decode :: !{#Char} -> a | EnDecode a; decode buffer :== fst (from_string 0 buffer) }; ENDECODE_BOOL_SIZE :== 1; ENDECODE_BOOL_TRUE :== 0; ENDECODE_BOOL_FALSE :== 1; instance EnDecode Bool where { to_size _ = ENDECODE_BOOL_SIZE; to_string b offset buffer = (offset + ENDECODE_BOOL_SIZE, { buffer & [offset] = toChar (if b ENDECODE_BOOL_TRUE ENDECODE_BOOL_FALSE) }); from_string offset buffer # c = buffer.[offset]; = (if ((toInt c) == ENDECODE_BOOL_TRUE) True False,offset + ENDECODE_BOOL_SIZE); }; ENDECODE_INT_SIZE :== 4; instance EnDecode Int where { to_size _ = ENDECODE_INT_SIZE; to_string i offset buffer = (offset + ENDECODE_INT_SIZE, WriteLong buffer offset i); from_string offset buffer # i = FromStringToInt buffer offset; = (i,offset + ENDECODE_INT_SIZE); }; ENDECODE_CHAR_SIZE :== 1; instance EnDecode Char where { to_size _ = ENDECODE_CHAR_SIZE; to_string i offset buffer = (offset + ENDECODE_CHAR_SIZE, { buffer & [offset] = i }); from_string offset buffer # c = buffer.[offset]; = (c,offset + ENDECODE_CHAR_SIZE); }; ENDECODE_LIST_SIZE :== 4; /*2.0 instance EnDecode [b] | EnDecode, DefaultElem b & Array {#} b 0.2*/ //1.3 instance EnDecode [b] | EnDecode b //3.1 where { to_size list = ENDECODE_LIST_SIZE + (to_size_list list 0); where { to_size_list [x:xs] total_size = to_size_list xs (to_size x + total_size); to_size_list [] total_size = total_size; }; to_string list offset buffer # (last_offset,buffer,n_elements) = to_string2 list (ENDECODE_LIST_SIZE + offset) buffer 0; # buffer = WriteLong buffer offset n_elements; = (last_offset,buffer); where { to_string2 [x:xs] offset buffer i # (offset,buffer) = to_string x offset buffer; = to_string2 xs offset buffer (inc i); to_string2 [] offset buffer i = (offset,buffer,i); }; from_string offset buffer # s_list = FromStringToInt buffer offset; = from_string2 0 s_list [] buffer (ENDECODE_LIST_SIZE + offset); where { from_string2 i limit accu buffer offset | i == limit = (reverse accu,offset); # (x,offset) = from_string offset buffer; = from_string2 (inc i) limit [x:accu] buffer offset; }; }; ENDECODE_ARRAY_SIZE :== 4; //1.3 instance EnDecode {#b} | EnDecode b & DefaultElem b & ArrayElem b //3.1 /*2.0 instance EnDecode {#a} | EnDecode, DefaultElem a & Array {#} a 0.2*/ where { to_size array = ENDECODE_ARRAY_SIZE + (to_size_array 0 (size array) 0); where { to_size_array :: !Int !Int !Int -> !Int; to_size_array i limit total_size | i == limit = total_size; = to_size_array (inc i) limit (total_size + (to_size array.[i])); }; to_string array offset buffer # buffer = WriteLong buffer offset s_array; = to_string_array 0 s_array (offset + ENDECODE_ARRAY_SIZE) buffer; where { to_string_array i limit offset buffer | i == limit = (offset,buffer); # (offset,buffer) = to_string array.[i] offset buffer; = to_string_array (inc i) limit offset buffer; s_array = size array }; from_string offset buffer # s_array = FromStringToInt buffer offset; # a = createArray s_array default_elem; = from_string_array 0 s_array a (offset + ENDECODE_ARRAY_SIZE) buffer; where { from_string_array i limit array offset buffer | i == limit = (array,offset); # (elem,offset) = from_string offset buffer; = from_string_array (inc i) limit {array & [i] = elem} offset buffer; } }; // copy of above but without # //1.3 instance EnDecode {b} | EnDecode b & DefaultElem b & ArrayElem b //3.1 /*2.0 instance EnDecode {a} | EnDecode, DefaultElem a & Array {} a 0.2*/ where { to_size array = ENDECODE_ARRAY_SIZE + (to_size_array 0 (size array) 0); where { to_size_array :: !Int !Int !Int -> !Int; to_size_array i limit total_size | i == limit = total_size; = to_size_array (inc i) limit (total_size + (to_size array.[i])); }; to_string array offset buffer # buffer = WriteLong buffer offset s_array; = to_string_array 0 s_array (offset + ENDECODE_ARRAY_SIZE) buffer; where { to_string_array i limit offset buffer | i == limit = (offset,buffer); # (offset,buffer) = to_string array.[i] offset buffer; = to_string_array (inc i) limit offset buffer; s_array = size array }; from_string offset buffer # s_array = FromStringToInt buffer offset; # a = createArray s_array default_elem; = from_string_array 0 s_array a (offset + ENDECODE_ARRAY_SIZE) buffer; where { from_string_array i limit array offset buffer | i == limit = (array,offset); # (elem,offset) = from_string offset buffer; = from_string_array (inc i) limit {array & [i] = elem} offset buffer; } }; /*2.0 instance EnDecode (a,b) | EnDecode a & EnDecode b; 0.2*/ //1.3 instance EnDecode (a,b) | EnDecode b & EnDecode a //3.1 where { to_size (a,b) = to_size a + to_size b; to_string (a,b) offset buffer # (offset,buffer) = to_string a offset buffer; # (offset,buffer) = to_string b offset buffer; = (offset,buffer); from_string offset buffer # (a,offset) = from_string offset buffer; # (b,offset) = from_string offset buffer; = ((a,b),offset); }; /*2.0 instance EnDecode (a,b,c,d) | EnDecode a & EnDecode b & EnDecode c & EnDecode d; 0.2*/ //1.3 instance EnDecode (a,b,c,d) | EnDecode a & EnDecode b & EnDecode c & EnDecode d //3.1 where { to_size (a,b,c,d) = to_size a + to_size b + to_size c + to_size d; to_string (a,b,c,d) offset buffer # (offset,buffer) = to_string a offset buffer; # (offset,buffer) = to_string b offset buffer; # (offset,buffer) = to_string c offset buffer; # (offset,buffer) = to_string d offset buffer; = (offset,buffer); from_string offset buffer # (a,offset) = from_string offset buffer; # (b,offset) = from_string offset buffer; # (c,offset) = from_string offset buffer; # (d,offset) = from_string offset buffer; = ((a,b,c,d),offset); }; /*2.0 instance EnDecode (a,b,c,d,e) | EnDecode a & EnDecode b & EnDecode c & EnDecode d & EnDecode e 0.2*/ //1.3 instance EnDecode (a,b,c,d,e) | EnDecode a & EnDecode b & EnDecode c & EnDecode d & EnDecode e //3.1 where { to_size (a,b,c,d,e) = to_size a + to_size b + to_size c + to_size d + to_size e; to_string (a,b,c,d,e) offset buffer # (offset,buffer) = to_string a offset buffer; # (offset,buffer) = to_string b offset buffer; # (offset,buffer) = to_string c offset buffer; # (offset,buffer) = to_string d offset buffer; # (offset,buffer) = to_string e offset buffer; = (offset,buffer); from_string offset buffer # (a,offset) = from_string offset buffer; # (b,offset) = from_string offset buffer; # (c,offset) = from_string offset buffer; # (d,offset) = from_string offset buffer; # (e,offset) = from_string offset buffer; = ((a,b,c,d,e),offset); };