here is implementation with 1SM and about 2 times faster than previous
implementation.
tips: select./case. implementation slower than usage of ". for dispatching..
#!/bin/j
require 'jpm socket strings'
IFNAME =: 'headers'
OFNAME =: 'records'
HCNT =: 0
LHN =: , 1{::sdgethostname_jsocket_''
NB. ================== parse ====================
SFs =: 154 4 $ ' s0 '
SFs =: (' s1 ')(8 12 13)}SFs
SFs =: (' s2 ')(22 24 25 26 27 50 52 53 54 55)}SFs
SFs =: (' s3 ')(29 32 33 34)}SFs
SFs =: (' s4 ')(35 36 39 40 41)}SFs
SFs =: (' s5 ')(38)}SFs
SFs =: (' s6 ')(64 67 68 69)}SFs
SFs =: (' s7 ')(78 82 83)}SFs
SFs =: (' s8 ')(92 96 97)}SFs
SFs =: (' s9 ')(114)}SFs
SFs =: (' sA ')(133 139)}SFs
SFs =: (' sB ')(146)}SFs
s0 =: dyad : ''''''
s1 =: dyad : '''''[AVs=:(<(x.+i.y.){SRC)(0)}AVs'
s2 =: dyad : '''''[AVs=:(<(x.+i.y.){SRC)(3)}AVs'
s3 =: dyad : '''''[AVs=:(<(x.+i.<:y.){SRC)(3)}AVs'
s4 =: dyad : '''''[AVs=:(<(x.+i.<:<:y.){SRC)(3)}AVs'
s5 =: dyad : '''''[AVs=:(<(x.+i.<:<:y.){SRC)(2)}AVs'
s6 =: dyad : '''''[AVs=:(<(x.+i.y.){SRC)(5)}AVs'
s7 =: dyad : '''''[AVs=:(<(x.+i.y.){SRC)(6)}AVs'
s8 =: dyad : '''''[AVs=:(<(x.+i.y.){SRC)(1)}AVs'
s9 =: dyad : '''''[AN=:<(toupper(x.+i.y.){SRC),'':'''
sA =: dyad define
s =. ((>:x.)+i.<:<:y.){SRC
if. #s do.
i =. ANs i.AN
if. i<#ANs do.
AVs =: (<s)(i)}AVs
else.
ANs =: ANs,AN
AVs =: AVs,<s
end.
end.
''return.
)
sB =: dyad define
v =. 3{::AVs
i =. v i.':'
if. i<#v do.
h =. deb i{.v
if. 0=#h do. h =. LHN end.
p =. ((>:i)}.v)-.LF
if. 0=#p do. p =. '80' end.
AVs =: (h;p)(3 4)}AVs
end.
AVs =: (' '&,@:,&LF)each AVs
TEXT =: TEXT,(;ANs,.AVs),LF
ANs =:
'METHOD:';'HTTP-PROTOCOL-VERSION:';'PROTOCOL:';'HOST:';'PORT:';'RESOURCE:';'QUERY:'
AVs =: 'GET';'HTTP/0.9';'http';LHN;'80';'';''
HCNT =: >:HCNT
''return.
)
cm =: 256$0
cm =: (1)(a.i.' ')}cm
cm =: (2)(a.i.':')}cm
cm =: (3)(a.i.'/')}cm
cm =: (4)(a.i.'?')}cm
cm =: (5)(a.i.TAB)}cm
cm =: (6)(a.i. LF)}cm
NB. other SP : / ? TAB LF
NB. 0 1 2 3 4 5 6
NB.
sm =: 1 1 0 6 0 6 0 6 0 6 0 6 20 1 NB. 0: wait for METHOD
sm =: sm, 1 0 2 3 0 6 0 6 0 6 2 3 21 3 NB. 1: read METHOD
sm =: sm, 3 1 12 0 7 1 8 0 10 0 12 0 15 0 NB. 2: wait for
[protocol://][host[:[port]]][/[path]][?[query]]
sm =: sm, 3 0 12 3 4 0 8 3 10 3 12 3 15 3 NB. 3: read PROTOCOL or HOST
sm =: sm, 7 0 12 3 0 6 5 0 10 3 12 3 15 3 NB. 4: current is PROTOCOL:
or HOST:
sm =: sm, 9 2 12 3 0 6 6 3 10 3 12 3 15 3 NB. 5: current PROTOCOL:/
or HOST:/
sm =: sm, 7 1 12 0 7 1 8 0 10 0 12 0 15 0 NB. 6: wait for
[HOST[:[PORT]]][/[PATH]][?[QUERY]]
sm =: sm, 7 0 12 3 7 0 8 3 10 3 12 3 15 3 NB. 7: read HOST
sm =: sm, 9 1 12 0 0 6 9 1 10 0 12 0 15 0 NB. 8: wait for
[PATH][?[QUERY]]
sm =: sm, 9 0 12 3 0 6 9 0 10 3 12 3 15 3 NB. 9: read PATH
sm =: sm, 11 1 12 0 11 1 11 1 11 1 12 0 15 0 NB. 10: wait for QUERY
sm =: sm, 11 0 12 3 11 0 11 0 11 0 12 3 15 3 NB. 11: read QUERY
sm =: sm, 13 1 12 0 0 6 0 6 0 6 12 0 15 0 NB. 12: wait for VERSION or
LF
sm =: sm, 13 0 14 3 13 0 13 0 13 0 14 3 15 3 NB. 13: read VERSION
sm =: sm, 14 0 14 0 14 0 14 0 14 0 14 0 15 0 NB. 14: wait for end of
'method url version' line
sm =: sm, 16 1 0 6 0 6 0 6 0 6 0 6 20 1 NB. 15: wait for ATTRNAME
sm =: sm, 16 0 0 6 17 3 0 6 0 6 0 6 0 6 NB. 16: read ATTRNAME
sm =: sm, 18 1 18 1 18 1 18 1 18 1 18 1 19 1 NB. 17: wait for ATTRVALUE
sm =: sm, 18 0 18 0 18 0 18 0 18 0 18 0 19 0 NB. 18: read ATTRVALUE
sm =: sm, 16 2 18 0 18 0 18 0 18 0 18 0 20 2 NB. 19: continue read
ATTRVALUE or start read ATTRNAME?
sm =: sm, 0 6 0 6 0 6 0 6 0 6 0 6 0 3 NB. 20: wait for end of
header (second LF from LF,LF)
sm =: sm, 0 6 0 6 0 6 0 6 0 6 0 6 20 1 NB. 21: wait for first LF
from LF,LF
sm =: 22 7 2 $ sm
process =: monad define
ANs =:
'METHOD:';'HTTP-PROTOCOL-VERSION:';'PROTOCOL:';'HOST:';'PORT:';'RESOURCE:';'QUERY:'
AVs =: 'GET';'HTTP/0.9';'http';LHN;'80';'';''
t =. (4;sm;cm);:SRC
'i l f' =. |:t
".(":,.i),.(f{SFs),.":,.l
i =. (2{|:t)i:146
i =. i{0{|:t
i =. i+2
i return.
)
NB. ================== read =====================
main =: monad define
TEXT =: ''
fn =. IFNAME
fs =. 1!:4<fn
fp =. 0
fss =. 1e7
buf =. ''
'' 1!:2 <OFNAME
while. 1 do.
if. fp<fs do.
NB. read chunk
n =. fss<.fs-fp
SRC =: (buf, 1!:11 fn;fp,n)-.CR
fp =. fp+n
i =. process''
buf =. i}.SRC
else.
if. #buf do.
SRC =: buf
process''
end.
break.
end.
end.
TEXT 1!:3<OFNAME
''return.
)
NB.start_jpm_''
main''
NB.echo (0 0 100 showtotal_jpm_'')
NB.echo showdetail_jpm_ 'process_url'
echo HCNT
exit''
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm