[m-rev.] for review: add conversion fucntions from bytes to 16-bit integers
Julien Fischer
jfischer at opturion.com
Tue Oct 10 12:06:54 AEDT 2017
For review by anyone.
Note: I will add the 32-bit versions of these after this change has been
reviewed.
-----------------------
Add conversion functions from bytes (uint8s) to 16-bit integers.
library/int16.m:
library/uint16.m:
As above.
tests/hard_coded/Mmakefile:
tests/hard_coded/int16_from_bytes.{m,exp}:
tests/hard_coded/uint16_from_bytes.{m,exp}:
Test the new functions.
Julien.
diff --git a/library/int16.m b/library/int16.m
index 4399830..4ce54cf 100644
--- a/library/int16.m
+++ b/library/int16.m
@@ -37,6 +37,18 @@
:- func to_int(int16) = int.
+ % from_bytes_le(LSB, MSB) = I16:
+ % I16 is the int16 whose least and most significant bytes are given by the
+ % uint8s LSB and MSB respectively.
+ %
+:- func from_bytes_le(uint8, uint8) = int16.
+
+ % from_bytes_be(MSB, LSB) = I16:
+ % I16 is the int16 whose least and most significant bytes are given by the
+ % uint8s LSB and MSB respectively.
+ %
+:- func from_bytes_be(uint8, uint8) = int16.
+
%---------------------------------------------------------------------------%
% Less than.
@@ -316,6 +328,44 @@ cast_from_uint16(_) = _ :-
%---------------------------------------------------------------------------%
+:- pragma foreign_proc("C",
+ from_bytes_le(LSB::in, MSB::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ unsigned char *int16_bytes = (unsigned char *) &I16;
+#if defined(MR_BIG_ENDIAN)
+ int16_bytes[0] = MSB;
+ int16_bytes[1] = LSB;
+#else
+ int16_bytes[0] = LSB;
+ int16_bytes[1] = MSB;
+#endif
+").
+
+:- pragma foreign_proc("Java",
+ from_bytes_le(LSB::in, MSB::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) (MSB << java.lang.Byte.SIZE | (LSB & 0x00ff));
+").
+
+:- pragma foreign_proc("C#",
+ from_bytes_le(LSB::in, MSB::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) (MSB << 8 | (LSB & 0x00ff));
+").
+
+from_bytes_le(_, _) = _ :-
+ sorry($module, "int16.from_bytes_le/2 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+from_bytes_be(MSB, LSB) =
+ from_bytes_le(LSB, MSB).
+
+%---------------------------------------------------------------------------%
+
max(X, Y) =
( if X > Y then X else Y ).
diff --git a/library/uint16.m b/library/uint16.m
index 5a592a2..9d2c6e8 100644
--- a/library/uint16.m
+++ b/library/uint16.m
@@ -37,6 +37,18 @@
:- func to_int(uint16) = int.
+ % from_bytes_le(LSB, MSB) = U16:
+ % U16 is the uint16 whose least and most significant bytes are given by the
+ % uint8s LSB and MSB respectively.
+ %
+:- func from_bytes_le(uint8, uint8) = uint16.
+
+ % from_bytes_be(MSB, LSB) = U16:
+ % U16 is the uint16 whose least and most significant bytes are given by the
+ % uint8s LSB and MSB respectively.
+ %
+:- func from_bytes_be(uint8, uint8) = uint16.
+
%--------------------------------------------------------------------------%
% Less than.
@@ -304,6 +316,44 @@ to_int(_) = _ :-
%---------------------------------------------------------------------------%
+:- pragma foreign_proc("C",
+ from_bytes_le(LSB::in, MSB::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ unsigned char *uint16_bytes = (unsigned char *) &U16;
+#if defined(MR_BIG_ENDIAN)
+ uint16_bytes[0] = MSB;
+ uint16_bytes[1] = LSB;
+#else
+ uint16_bytes[0] = LSB;
+ uint16_bytes[1] = MSB;
+#endif
+").
+
+:- pragma foreign_proc("Java",
+ from_bytes_le(LSB::in, MSB::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U16 = (short) (MSB << java.lang.Byte.SIZE | (LSB & 0x00ff));
+").
+
+:- pragma foreign_proc("C#",
+ from_bytes_le(LSB::in, MSB::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U16 = (ushort) (MSB << 8 | (LSB & 0x00ff));
+").
+
+from_bytes_le(_, _) = _ :-
+ sorry($module, "uint16.from_bytes_le/2 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+from_bytes_be(MSB, LSB) =
+ from_bytes_le(LSB, MSB).
+
+%---------------------------------------------------------------------------%
+
X div Y = X // Y.
:- pragma inline('//'/2).
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 52758f2..55854fb 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -172,6 +172,7 @@ ORDINARY_PROGS = \
inst_alias \
int_fold_up_down \
int_range_ops \
+ int16_from_bytes \
integer_int16_conv \
integer_int32_conv \
integer_int8_conv \
@@ -373,6 +374,7 @@ ORDINARY_PROGS = \
type_to_term_bug \
uc_export_enum \
uint16_switch_test \
+ uint16_from_bytes \
uint32_switch_test \
uint8_switch_test \
uint_switch_test \
diff --git a/tests/hard_coded/int16_from_bytes.exp b/tests/hard_coded/int16_from_bytes.exp
index e69de29..62a8cd0 100644
--- a/tests/hard_coded/int16_from_bytes.exp
+++ b/tests/hard_coded/int16_from_bytes.exp
@@ -0,0 +1,4 @@
+-256i16
+255i16
+255i16
+-256i16
diff --git a/tests/hard_coded/int16_from_bytes.m b/tests/hard_coded/int16_from_bytes.m
index e69de29..0dc6eaf 100644
--- a/tests/hard_coded/int16_from_bytes.m
+++ b/tests/hard_coded/int16_from_bytes.m
@@ -0,0 +1,20 @@
+:- module int16_from_bytes.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module int16.
+
+main(!IO) :-
+ Test1 = int16.from_bytes_le(0x00u8, 0xffu8),
+ io.write_line(Test1, !IO),
+ Test2 = int16.from_bytes_le(0xffu8, 0x00u8),
+ io.write_line(Test2, !IO),
+ Test3 = int16.from_bytes_be(0x00u8, 0xffu8),
+ io.write_line(Test3, !IO),
+ Test4 = int16.from_bytes_be(0xffu8, 0x00u8),
+ io.write_line(Test4, !IO).
diff --git a/tests/hard_coded/uint16_from_bytes.exp b/tests/hard_coded/uint16_from_bytes.exp
index e69de29..e57f651 100644
--- a/tests/hard_coded/uint16_from_bytes.exp
+++ b/tests/hard_coded/uint16_from_bytes.exp
@@ -0,0 +1,4 @@
+65280u16
+255u16
+255u16
+65280u16
diff --git a/tests/hard_coded/uint16_from_bytes.m b/tests/hard_coded/uint16_from_bytes.m
index e69de29..1bb34bf 100644
--- a/tests/hard_coded/uint16_from_bytes.m
+++ b/tests/hard_coded/uint16_from_bytes.m
@@ -0,0 +1,20 @@
+:- module uint16_from_bytes.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module uint16.
+
+main(!IO) :-
+ Test1 = uint16.from_bytes_le(0x00u8, 0xffu8),
+ io.write_line(Test1, !IO),
+ Test2 = uint16.from_bytes_le(0xffu8, 0x00u8),
+ io.write_line(Test2, !IO),
+ Test3 = uint16.from_bytes_be(0x00u8, 0xffu8),
+ io.write_line(Test3, !IO),
+ Test4 = uint16.from_bytes_be(0xffu8, 0x00u8),
+ io.write_line(Test4, !IO).
More information about the reviews
mailing list