From 96ba8f8b062bff48fc6462c35973c03418bd7c6e Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Fri, 21 Nov 2008 22:10:58 -0600 Subject: [PATCH] add multipart stream, actual multipart parsing to follow soon --- basis/mime/multipart/authors.txt | 1 + basis/mime/multipart/multipart-tests.factor | 248 ++++++++++++++++++++ basis/mime/multipart/multipart.factor | 68 ++++++ 3 files changed, 317 insertions(+) create mode 100644 basis/mime/multipart/authors.txt create mode 100644 basis/mime/multipart/multipart-tests.factor create mode 100644 basis/mime/multipart/multipart.factor diff --git a/basis/mime/multipart/authors.txt b/basis/mime/multipart/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/basis/mime/multipart/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/basis/mime/multipart/multipart-tests.factor b/basis/mime/multipart/multipart-tests.factor new file mode 100644 index 0000000000..e8a12eeea4 --- /dev/null +++ b/basis/mime/multipart/multipart-tests.factor @@ -0,0 +1,248 @@ +USING: accessors io io.streams.string kernel mime.multipart +tools.test make multiline ; +IN: mime.multipart.tests + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + +[ { "a" "a" f } ] [ + [ + "aazzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "aa" f } ] [ + [ + "aazzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + + +[ { "a" f } ] [ + [ + "azzbzzczzdzz" "zz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [ + [ + "azzbzzczzdzz" "zzz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 1 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "az" "zb" "zz" "cz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 2 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "a" "zzb" "zzc" "zzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 3 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "az" "zbzz" "czzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 4 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + +[ { "azz" "bzzcz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 5 >>n + [ , ] [ ] multipart-step-loop drop + ] { } make +] unit-test + + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "azzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + + +[ { "a" "a" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "aa" f f "b" f f "c" f f "d" f f } ] [ + [ + "aazzbzzczzdzz" "z" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + + + +[ { "a" f "b" f "c" f "d" f } ] [ + [ + "azzbzzczzdzz" "zz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" "zz" } ] [ + [ + "azzbzzczzdzz" "zzz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "z" "z" "b" "z" "z" "c" "z" "z" "d" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 1 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "az" "zb" "zz" "cz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 2 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "a" "zzb" "zzc" "zzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 3 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "az" "zbzz" "czzd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 4 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test + +[ { "azz" "bzzcz" "zd" f } ] [ + [ + "azzbzzczzdzzz" "zzz" 5 >>n + [ , ] [ ] multipart-loop-all + ] { } make +] unit-test diff --git a/basis/mime/multipart/multipart.factor b/basis/mime/multipart/multipart.factor new file mode 100644 index 0000000000..433e89ed41 --- /dev/null +++ b/basis/mime/multipart/multipart.factor @@ -0,0 +1,68 @@ +! Copyright (C) 2008 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors combinators io kernel locals math multiline +sequences splitting ; +IN: mime.multipart + +TUPLE: multipart-stream stream n leftover separator ; + +: ( stream separator -- multipart-stream ) + multipart-stream new + swap >>separator + swap >>stream + 16 2^ >>n ; + +> ] [ stream>> ] bi stream-read [ ?append ] keep not ; + +: multipart-split ( bytes separator -- before after ? empty? ) + #! first boolean: return true if found + #! second boolean: true if sequence= + 2dup sequence= [ + 2drop f f f t + ] [ + split1 dup >boolean f + ] if ; + +PRIVATE> + +:: multipart-step ( stream bytes end-stream? separator quot: ( bytes -- ) -- ? end-stream? ) + #! return t to loop again + bytes separator multipart-split [ + ! separator == input + 3drop f quot call f + ] [ + [ + ! found + [ [ quot call ] unless-empty ] + [ + stream (>>leftover) + [ quot call ] unless-empty + ] if-empty f quot call f + ] [ + ! not found + drop + end-stream? [ + [ quot call ] unless-empty f + ] [ + separator length 1- ?cut* stream (>>leftover) + [ quot call ] unless-empty t + ] if + ] if + ] if stream leftover>> end-stream? not or ; + +:: multipart-step-loop ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ? ) + stream dup [ read-n ] [ separator>> ] bi quot1 multipart-step + swap [ drop stream quot1 quot2 multipart-step-loop ] quot2 if ; + +: multipart-loop-all ( stream quot1: ( bytes -- ) quot2: ( -- ) -- ) + 3dup multipart-step-loop [ multipart-loop-all ] [ 3drop ] if ;