[ocaml] fix uint32 parsing

Don't use int32 to represent uint32 so we don't get overflows...
When extracting an uint32 from a bytestream, copy it to a C uint32 first,
then convert that to an int64 for usage in OCaml (since it doesn't have unsigned ints)

This addresses #793 at least for unsigned 32bit values.
Only tested on 64bit system so far...
This commit is contained in:
Felix Ruess
2014-08-25 18:24:06 +02:00
parent d575430dde
commit c95b2a23a8
5 changed files with 24 additions and 3 deletions
+2
View File
@@ -44,6 +44,7 @@ let fvalue = fun x ->
match x with
Pprz.Float x -> x
| Pprz.Int32 x -> Int32.to_float x
| Pprz.Int64 x -> Int64.to_float x
| Pprz.Int x -> float_of_int x
| _ -> failwith (sprintf "Receive.log_and_parse: float expected, got '%s'" (Pprz.string_of_value x))
@@ -52,6 +53,7 @@ let ivalue = fun x ->
match x with
Pprz.Int x -> x
| Pprz.Int32 x -> Int32.to_int x
| Pprz.Int64 x -> Int64.to_int x
| _ -> failwith "Receive.log_and_parse: int expected"
let format_string_field = fun s ->
@@ -44,6 +44,7 @@ let fvalue = fun x ->
match x with
Pprz.Float x -> x
| Pprz.Int32 x -> Int32.to_float x
| Pprz.Int64 x -> Int64.to_float x
| Pprz.Int x -> float_of_int x
| _ -> failwith (sprintf "Receive.log_and_parse: float expected, got '%s'" (Pprz.string_of_value x))
@@ -52,6 +53,7 @@ let ivalue = fun x ->
match x with
Pprz.Int x -> x
| Pprz.Int32 x -> Int32.to_int x
| Pprz.Int64 x -> Int64.to_int x
| _ -> failwith "Receive.log_and_parse: int expected"
(*
+13
View File
@@ -29,6 +29,7 @@
#include <stdio.h>
#include "caml/mlvalues.h"
#include "caml/alloc.h"
#include "inttypes.h"
#ifdef ARCH_ALIGN_DOUBLE
value
@@ -145,6 +146,18 @@ c_int32_of_indexed_bytes(value s, value index)
return copy_int32(*x);
}
value
c_uint32_of_indexed_bytes(value s, value index)
{
uint32_t *x = (uint32_t*)(String_val(s) + Int_val(index));
/* since OCaml doesn't have unsigned integers,
* we represent it as 64bit signed int to make sure it doesn't overflow
*/
int64_t y = *x;
return copy_int64(y);
}
#ifdef ARCH_ALIGN_INT64
value
c_int64_of_indexed_bytes(value s, value index)
+6 -3
View File
@@ -76,9 +76,10 @@ let units_file = Env.paparazzi_src // "conf" // "units.xml"
external float_of_bytes : string -> int -> float = "c_float_of_indexed_bytes"
external double_of_bytes : string -> int -> float = "c_double_of_indexed_bytes"
external int32_of_bytes : string -> int -> int32 = "c_int32_of_indexed_bytes"
external int8_of_bytes : string -> int -> int = "c_int8_of_indexed_bytes"
external int16_of_bytes : string -> int -> int = "c_int16_of_indexed_bytes"
external int32_of_bytes : string -> int -> int32 = "c_int32_of_indexed_bytes"
external uint32_of_bytes : string -> int -> int64 = "c_uint32_of_indexed_bytes"
external int64_of_bytes : string -> int -> int64 = "c_int64_of_indexed_bytes"
external sprint_float : string -> int -> float -> unit = "c_sprint_float"
external sprint_double : string -> int -> float -> unit = "c_sprint_double"
@@ -141,7 +142,8 @@ let int_of_string = fun x ->
let rec value = fun t v ->
match t with
Scalar ("uint8" | "uint16" | "int8" | "int16") -> Int (int_of_string v)
| Scalar ("uint32" | "int32") -> Int32 (Int32.of_string v)
| Scalar "int32" -> Int32 (Int32.of_string v)
| Scalar "uint32" -> Int64 (Int64.of_string v)
| Scalar ("uint64" | "int64") -> Int64 (Int64.of_string v)
| Scalar ("float" | "double") -> Float (float_of_string v)
| Scalar "string" -> String v
@@ -351,7 +353,8 @@ let rec value_of_bin = fun buffer index _type ->
| Scalar "int16" -> Int (int16_of_bytes buffer index), sizeof _type
| Scalar "float" -> Float (float_of_bytes buffer index), sizeof _type
| Scalar "double" -> Float (double_of_bytes buffer index), sizeof _type
| Scalar ("int32" | "uint32") -> Int32 (int32_of_bytes buffer index), sizeof _type
| Scalar "int32" -> Int32 (int32_of_bytes buffer index), sizeof _type
| Scalar "uint32" -> Int64 (uint32_of_bytes buffer index), sizeof _type
| Scalar ("int64" | "uint64") -> Int64 (int64_of_bytes buffer index), sizeof _type
| ArrayType t ->
(** First get the number of values *)
+1
View File
@@ -51,6 +51,7 @@ type message = {
external int32_of_bytes : string -> int -> int32 = "c_int32_of_indexed_bytes"
external uint32_of_bytes : string -> int -> int64 = "c_uint32_of_indexed_bytes"
external int64_of_bytes : string -> int -> int64 = "c_int64_of_indexed_bytes"
(** [int32_of_bytes buffer offset] *)