[Gd-chatter] r11603 - in trunk/libraries/packetizer: . packetizer-test
hannes at gwydiondylan.org
hannes at gwydiondylan.org
Fri Jan 4 03:22:14 CET 2008
Author: hannes
Date: Fri Jan 4 03:22:13 2008
New Revision: 11603
Modified:
trunk/libraries/packetizer/module.dylan
trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
trunk/libraries/packetizer/packetizer.dylan
trunk/libraries/packetizer/protocol-definer-macro.dylan
Log:
Job: 7299
fix parsing of container-frames with a dynamic length expression
assembling those is still broken, added a testcase which shows that
it is broken (no padding support!)
Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan (original)
+++ trunk/libraries/packetizer/module.dylan Fri Jan 4 03:22:13 2008
@@ -126,7 +126,9 @@
<decoded-header-frame>,
payload, payload-setter;
- export <variably-typed-container-frame>,
+ export <inline-layering-error>,
+ <missing-inline-layering-error>,
+ <variably-typed-container-frame>,
<unparsed-variably-typed-container-frame>,
<decoded-variably-typed-container-frame>;
Modified: trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan (original)
+++ trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan Fri Jan 4 03:22:13 2008
@@ -405,15 +405,59 @@
define protocol dyn-length-in-container (container-frame)
length frame.mylength * 8;
field foo :: <unsigned-byte> = 0;
- field mylength :: <unsigned-byte> = 3;
+ field mylength :: <unsigned-byte>,
+ fixup: byte-offset(frame-size(frame));
end;
define test dynlength ()
+ let f = parse-frame(<dyn-length-in-container>, #(#x00, #x02));
+ check-equal("length frame.my-length; size of simple frame is correct", 16, f.frame-size);
+ let field-list = fields(f);
+ static-checker(field-list[0], 0, 8, 8);
+ static-checker(field-list[1], 8, 8, 16);
+ frame-field-checker(0, f, 0, 8, 8);
+ frame-field-checker(1, f, 8, 8, 16);
+ let g = parse-frame(<dyn-length-in-container>, #(#x00, #x03, #x02));
+ check-equal("length frame.my-length; size of frame with padding is correct", 24, g.frame-size);
+ frame-field-checker(0, g, 0, 8, 8);
+ frame-field-checker(1, g, 8, 8, 16);
+ //this tells us: we need padding frame fields!
+end;
+
+define test dynlength-assemble ()
let f = make(<dyn-length-in-container>);
- check-equal("size of frame with length is correct", 24, f.frame-size);
let as = assemble-frame(f);
- check-equal("size of assembled frame is correct", 3, as.packet.size);
+ check-equal("assembling of dynlength[1] works correct", 2, as.packet[1]);
+ let g = make(<dyn-length-in-container>);
+ let as = assemble-frame(g);
+ check-equal("assembly of dynlength[0] works correct", 0, as.packet[0]);
+ //hah, no padding support!
+ check-equal("assembly of dynlength[1] works correct", 3, as.packet[1]);
+ check-equal("assembly of dynlength[2] works correct", 0, as.packet[2]);
end;
+
+define protocol dyn-length-as-client-field (container-frame)
+ field first-foo :: <dyn-length-in-container>;
+ field second-foo :: <dyn-length-in-container>;
+end;
+
+define test dyn-length-client ()
+ let f = parse-frame(<dyn-length-as-client-field>, #(#x00, #x02, #x00, #x02));
+ check-equal("size of dyn-length-client is correct", 32, f.frame-size);
+ let field-list = fields(f);
+ static-checker(field-list[0], 0, $unknown-at-compile-time, $unknown-at-compile-time);
+ static-checker(field-list[1], $unknown-at-compile-time, $unknown-at-compile-time, $unknown-at-compile-time);
+ frame-field-checker(0, f, 0, 16, 16);
+ frame-field-checker(1, f, 16, 16, 32);
+end;
+
+define test dyn-length-client2 ()
+ let f = parse-frame(<dyn-length-as-client-field>, #(#x00, #x03, #x04, #x00, #x04, #x01, #x02));
+ check-equal("size of dyn-length-client2 is correct", 56, f.frame-size);
+ frame-field-checker(0, f, 0, 24, 24);
+ frame-field-checker(1, f, 24, 32, 56);
+end;
+
define suite packetizer-suite ()
test packetizer-parser;
test packetizer-dynamic-parser;
@@ -430,6 +474,8 @@
test half-byte-parsing;
test dns-foo-parsing;
test dynlength;
+ test dyn-length-client;
+ test dyn-length-client2;
end;
define suite packetizer-assemble-suite ()
@@ -448,10 +494,11 @@
test half-bytes-assembling;
test bits-assemble;
test dns-foo-assemble;
+ test dynlength-assemble;
end;
begin
- run-test-application(packetizer-suite, arguments: #("-debug"));
- run-test-application(packetizer-assemble-suite, arguments: #("-debug"));
+ run-test-application(packetizer-suite); //, arguments: #("-debug"));
+ run-test-application(packetizer-assemble-suite); //, arguments: #("-debug"));
end;
Modified: trunk/libraries/packetizer/packetizer.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer.dylan (original)
+++ trunk/libraries/packetizer/packetizer.dylan Fri Jan 4 03:22:13 2008
@@ -151,10 +151,6 @@
define open generic container-frame-size (frame :: <container-frame>) => (length :: false-or(<integer>));
-define method container-frame-size (frame :: <container-frame>) => (res :: false-or(<integer>))
- #f
-end;
-
define open generic frame-size (frame :: type-union(<frame>, subclass(<fixed-size-frame>)))
=> (length :: <integer>);
@@ -281,6 +277,12 @@
end;
end;
+define class <inline-layering-error> (<error>)
+end;
+
+define class <missing-inline-layering-error> (<error>)
+end;
+
define inline method fixup-protocol-magic (frame :: <variably-typed-container-frame>) => (magic)
let layer-table = recursive-reverse-layer(frame.object-class);
if (layer-table)
@@ -288,10 +290,10 @@
if (res)
res
else
- error("Inline layering not found for %=", frame);
+ signal(make(<inline-layering-error>));
end;
else
- error("No non-empty layering table not found for %=", frame);
+ signal(make(<missing-inline-layering-error>));
end;
end;
@@ -397,7 +399,11 @@
define open generic payload-setter (value /* :: false-or(<frame>) */, object :: <header-frame>)
=> (res /* :: false-or(<frame>) */);
define method frame-size (frame :: <container-frame>) => (res :: <integer>)
- reduce1(\+, map(curry(get-field-size-aux, frame), frame.fields));
+ block()
+ container-frame-size(frame);
+ exception (e :: <error>)
+ reduce1(\+, map(curry(get-field-size-aux, frame), frame.fields));
+ end;
end;
define method assemble-frame (frame :: <unparsed-container-frame>) => (packet :: <unparsed-container-frame>);
Modified: trunk/libraries/packetizer/protocol-definer-macro.dylan
==============================================================================
--- trunk/libraries/packetizer/protocol-definer-macro.dylan (original)
+++ trunk/libraries/packetizer/protocol-definer-macro.dylan Fri Jan 4 03:22:13 2008
@@ -2,8 +2,6 @@
Author: Andreas Bogk, Hannes Mehnert
Copyright: (C) 2005, 2006, All rights reserved. Free for non-commercial use.
-
-
define macro protocol-module-definer
{ protocol-module-definer (?:name; ?super:name; ?fields:*) }
=> { define module ?name
@@ -90,7 +88,7 @@
end;
end;
define inline method field-size (frame :: subclass(?name)) => (res :: <number>)
- if (?#"attrs" = #"abstract")
+ if (find-method(container-frame-size, list(?name)))
$unknown-at-compile-time;
else
static-end(last("$" ## ?name ## "-fields"));
@@ -419,12 +417,14 @@
parent: parent);
let length = field-size(frame-type);
if (length = $unknown-at-compile-time)
- let fr-length = container-frame-size(frame);
- if (fr-length)
- frame.packet := subsequence(frame.packet, length: fr-length);
- values(frame, fr-length);
- else
- frame
+ block (ret)
+ let fr-length = container-frame-size(frame);
+ if (fr-length)
+ frame.packet := subsequence(frame.packet, length: fr-length);
+ ret(apply(values, frame, fr-length));
+ end;
+ exception (e :: <error>)
+ frame;
end;
else
values(frame, length)
More information about the chatter
mailing list