let lift_base x =
Labeled (Base x)
-let u8 n = lift_base @@ U8 n
-let u16 n = lift_base @@ U16 n
+let u8 n =
+ if 0 <=n && n <= 0xFF then lift_base @@ U8 n
+ else invalid_arg "Bytes.u8"
+
+let u16 n =
+ if 0 <= n && n <= 0xFFFF then lift_base @@ U16 n
+ else invalid_arg "Bytes.u16"
+
let u30 n = lift_base @@ U30 (Int32.of_int n)
let u32 n = lift_base @@ U32 (Int32.of_int n)
let s32 n = lift_base @@ S32 (Int32.of_int n)
List.map Int64.to_int @@ split_byte (fun n i->(Int64.logand (Int64.shift_right_logical n i) 0xFFL)) value size
let rec encode_base = function
- U8 x when x <= 0xFF ->
+ U8 x ->
split_byte_int x 1
- | U16 x when x <= 0xFFFF ->
+ | U16 x ->
split_byte_int x 2
| S24 x ->
split_byte_int x 3
+(**
+ ABC primitive data type.
+
+ Provide the type of ABC primitive data type and byte encodeing function.
+
+ @author mzp
+ @see <http://www.adobe.com/devnet/actionscript/articles/avm2overview.pdf> AVM2 Overview(pdf)
+*)
+
+(** the type of a primitive data type *)
type t
+(** {6 Create data type }*)
+
+(** create u8
+
+@raise InvalidArgumnet If n > 0xFF or n < 0. *)
val u8 : int -> t
+
+(** create u16
+
+@raise InvalidArgumnet If n > 0xFFFF or n < 0. *)
val u16 : int -> t
+
+(** create u30 *)
val u30 : int -> t
+
+(** create u32 *)
val u32 : int -> t
+
+(** create d64 *)
val d64 : float -> t
+
+(** create s32 *)
val s32 : int -> t
+
+(** create s24 *)
val s24 : int -> t
+(**{6 Label}*)
+
+(**
+ [label l] create label. This label is refered by [lable_ref l].
+
+ This value is removed when encode.
+*)
val label : Label.t -> t
+
+(**
+ [label_ref l] refer to [label l] position.
+
+ This value become s24 when encode.
+*)
val label_ref : Label.t -> t
+(**{6 Block}*)
+
+(**
+ [block xs] create block.
+
+ Block become [(u30 size_of_xs)::xs ] when encode.
+*)
val block : t list -> t
-val output_bytes: out_channel -> t list -> unit
+(**{6 Encode}*)
+
+(**
+ [to_int_list xs] encode [xs] to [int list].
+*)
val to_int_list : t list -> int list
+(**
+ [output_bytes ch xs] output encoded [xs] to [ch]
+*)
+val output_bytes: out_channel -> t list -> unit
assert_equal [50] @@ encode (u8 50);
assert_equal [0] @@ encode (u8 0);
assert_equal [0xFF] @@ encode (u8 0xFF);
- assert_raises (Invalid_argument "Bytes.to_int_list") @@ fun () -> encode (u8 0x100)
+ assert_raises (Invalid_argument "Bytes.u8") @@ fun () -> u8 0x100;
+ assert_raises (Invalid_argument "Bytes.u8") @@ fun () -> u8 ~-1
test u16 =
(* little endian *)
assert_equal [0xfe;0xca] @@ encode (u16 0xcafe);
assert_equal [0;0] @@ encode (u16 0);
assert_equal [0xFF;0xFF] @@ encode (u16 0xFFFF);
- assert_raises (Invalid_argument "Bytes.to_int_list") @@ fun () -> encode (u8 0x10000)
+ assert_raises (Invalid_argument "Bytes.u16") @@ fun () -> u16 0x10000;
+ assert_raises (Invalid_argument "Bytes.u16") @@ fun () -> u16 ~-1
test s24 =
assert_equal [0xcb;0xfe;0xca;] @@ encode (s24 0xcafecb);
assert_equal [0x20] @@ encode (s32 0x20);
assert_equal [0xF6;0xFF;0xFF;0xFF;0xF] @@ encode (s32 ~-10);
+test d64 =
+ assert_equal [0;0;0;0;0;0;0xe8;0x3f] @@ encode (d64 0.75)
+
test label =
let l =
Label.make () in
to_int_list [block [u8 0; u30 0xFF]] in
assert_equal [3; 0; 0xFF;0x01] bytes
-test d64 =
- assert_equal [0;0;0;0;0;0;0xe8;0x3f] @@ encode (d64 0.75)