Skip to content

Commit b41477e

Browse files
committed
Merge pull request #12 from avsm/master
Add hexdumping pretty printing functions
2 parents 554f6a8 + df28df9 commit b41477e

File tree

6 files changed

+55
-3
lines changed

6 files changed

+55
-3
lines changed

CHANGES

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
0.7.2 (trunk):
22
* Improved ocamldoc for BE/LE modules.
33
* Add Travis-CI test scripts and fix `test.sh` script compilation.
4+
* Support int32/int64 constant values in cenum like `VAL = 0xffffffffl`, useful for 32-bit hosts.
45
* Check and raise error in case of negative offsets for blits (#4).
56
* Correctly preserve the sequence after a constant constructor is set during a `cenum` definition.
67
* Do not repeat the `sizeof_<field>` binding for every get/set field (should be no externally observable change).
8+
* Add `Cstruct.hexdump_to_buffer` to make spooling hexdump output easier.
9+
* Generate `hexdump_foo` and `hexdump_foo_to_buffer` prettyprinting functions for a `cstruct foo`.
710

811
0.7.1 (06-Mar-2013):
912
* Add `Async_cstruct.Pipe` to map pipes of `Cstruct` buffers to strings or `Bigsubstring`.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ val get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32
8282
val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unit
8383
val get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32
8484
val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unit
85+
val hexdump_pcap_packet_to_buffer : Buffer.t -> pcap_packet -> unit
86+
val hexdump_pcap_packet : Cstruct.t -> unit
8587
8688
val sizeof_ethernet : int
8789
val get_ethernet_dst : Cstruct.t -> Cstruct.t
@@ -94,7 +96,13 @@ val set_ethernet_src : string -> int -> Cstruct.t -> unit
9496
val blit_ethernet_src : Cstruct.t -> int -> Cstruct.t -> unit
9597
val get_ethernet_ethertype : Cstruct.t -> Cstruct.uint16
9698
val set_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 -> unit
99+
val hexdump_ethernet_to_buffer : Buffer.t -> Cstruct.t -> unit
100+
val hexdump_ethernet : Cstruct.t -> unit
97101
```
102+
103+
The `hexdump` functions above are convenient pretty-printing functions
104+
to help you debug, and aren't intended to be high performance.
105+
98106
You can also declare C-like enums:
99107

100108
```

lib/cstruct.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,15 @@ let hexdump t =
234234
done;
235235
print_endline ""
236236

237+
let hexdump_to_buffer buf t =
238+
let c = ref 0 in
239+
for i = 0 to len t - 1 do
240+
if !c mod 16 = 0 then Buffer.add_char buf '\n';
241+
bprintf buf "%.2x " (Char.code (Bigarray.Array1.get t.buffer (t.off+i)));
242+
incr c;
243+
done;
244+
Buffer.add_char buf '\n'
245+
237246
let split ?(start=0) t off =
238247
let header = sub t start off in
239248
let body = sub t (start+off) (len t - off - start) in

lib/cstruct.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ val split: ?start:int -> t -> int -> t * t
133133
val to_string: t -> string
134134

135135
val hexdump: t -> unit
136+
val hexdump_to_buffer: Buffer.t -> t -> unit
136137
val debug: t -> string
137138

138139
module BE : sig

lib_test/basic.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,6 @@ let _ =
8585
assert(Cstruct.BE.get_uint32 be2 0 = 0xbeef_l);
8686
assert(Cstruct.BE.get_uint32 be 3 = 0xbeef_l);
8787
assert(get_foo_b be = 44);
88-
assert(get_foo_a be = 7)
88+
assert(get_foo_a be = 7);
89+
hexdump_foo be
8990

syntax/pa_cstruct.ml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,36 @@ let output_sizeof_sig _loc s =
193193
value $lid:"sizeof_"^s.name$ : int
194194
>>
195195

196+
let output_hexdump _loc s =
197+
let hexdump =
198+
List.fold_left (fun a f ->
199+
<:expr<
200+
$a$; Buffer.add_string _buf $str:" "^f.field^" = "$;
201+
$match f.ty with
202+
|UInt8 |UInt16 -> <:expr< Printf.bprintf _buf "0x%x\n" ($lid:getter_name s f$ v) >>
203+
|UInt32 -> <:expr< Printf.bprintf _buf "0x%lx\n" ($lid:getter_name s f$ v) >>
204+
|UInt64 -> <:expr< Printf.bprintf _buf "0x%Lx\n" ($lid:getter_name s f$ v) >>
205+
|Buffer len -> <:expr< Printf.bprintf _buf "<buffer length %d>" $int:string_of_int len$; Cstruct.hexdump_to_buffer _buf ($lid:getter_name s f$ v) >>
206+
$ >>
207+
) <:expr< >> s.fields
208+
in
209+
<:str_item<
210+
value $lid:"hexdump_"^s.name^"_to_buffer"$ _buf v = do { $hexdump$ };
211+
value $lid:"hexdump_"^s.name$ v =
212+
let _buf = Buffer.create 128 in
213+
do {
214+
Buffer.add_string _buf $str:s.name ^ " = {\n"$;
215+
$lid:"hexdump_"^s.name^"_to_buffer"$ _buf v;
216+
print_endline (Buffer.contents _buf);
217+
print_endline "}"
218+
} >>
219+
220+
let output_hexdump_sig _loc s =
221+
<:sig_item<
222+
value $lid:"hexdump_"^s.name^"_to_buffer"$ : Buffer.t -> Cstruct.t -> unit;
223+
value $lid:"hexdump_"^s.name$ : Cstruct.t -> unit;
224+
>>
225+
196226
let output_struct _loc s =
197227
(* Generate functions of the form {get/set}_<struct>_<field> *)
198228
let expr = List.fold_left (fun a f ->
@@ -202,7 +232,7 @@ let output_struct _loc s =
202232
$output_set _loc s f$
203233
>>
204234
) <:str_item< $output_sizeof _loc s$ >> s.fields
205-
in expr
235+
in <:str_item< $expr$; $output_hexdump _loc s$ >>
206236

207237
let output_struct_sig _loc s =
208238
(* Generate signaturs of the form {get/set}_<struct>_<field> *)
@@ -213,7 +243,7 @@ let output_struct_sig _loc s =
213243
$output_set_sig _loc s f$ ;
214244
>>
215245
) <:sig_item< $output_sizeof_sig _loc s$ >> s.fields
216-
in expr
246+
in <:sig_item< $expr$; $output_hexdump_sig _loc s$ >>
217247

218248
let output_enum _loc name fields width =
219249
let intfn,pattfn = match ty_of_string width with

0 commit comments

Comments
 (0)