mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-28 09:58:23 +08:00
[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:
@@ -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"
|
||||
|
||||
(*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 *)
|
||||
|
||||
@@ -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] *)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user