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

Reply via email to