zOs/REXX.O13/CSV

/* copy csv begin *****************************************************/
csvIni: procedure expose m.
    if m.csv.ini == 1 then
        return
    m.csv.ini = 1
    call jIni
    call classNew "n CsvRdr u JRWO, f RDR r", "m",
        , "jReset m.m.rdr = arg",
        , "jOpen call csvRdrOpen m, opt",
        , "jClose call jClose m.m.rdr; call oMutatName m, 'CsvRdr'"
    call classNew "n CsvRdrR u CsvRdr", "m",
        , "jReadO return csvRdrReadO(m)"
    call classNew "n CsvWrt u JRW, f RDR r", "m",
        , "jReset m.m.rdr = arg",
        , "jOpen call csvWrtOpen m, opt",
        , "jClose call jClose m.m.rdr; call oMutatName m, 'CsvWrt'"
    call classNew "n CsvWrtR u CsvWrt", "m",
        , "jRead return csvWrtRead(m, var)"
    return
endProcedure csvIni

/*--- create a new csvRdr --------------------------------------------*/
csvRdr: procedure expose m.
parse arg rdr
    return jReset(oNew('CsvRdr'), rdr)
endProcedure csvRdr

/*--- open csvRdr: read first line and create dataClass --------------*/
csvRdrOpen: procedure expose m.
parse arg m
    call jOpen m.m.rdr, '<'
    if jRead(m.m.rdr, m'.LINE') then do
        ff = 'f' repAll(m.m.line, ',', ' v, f ') 'v'
        m.m.class = classNew("n* CsvF u" ff)
        end
    call oMutatName m, 'CsvRdrR'
    return
endProcedure csvRdrOpen

/*--- read next line and return derived object -----------------------*/
csvRdrReadO: procedure expose m.
parse arg m
    do until m.m.line <> ''

        if \ jRead(m.m.rdr, m'.LINE') then
            return ''
        end
    var = oNew(m.m.class)
    ff = oClaMet(m.m.class, 'oFlds')
    s = m'.SCAN'
    call scanSrc s, m.m.line
    do fx=1
        f1 = substr(m.ff.fx, 2)
        if scanString(s, '"') then
            m.var.f1 = m.s.val
        else do
            call scanUntil s, ','
            m.var.f1 = m.s.tok
            end
        if scanEnd(s) then
            leave
        if \ scanLit(s, ',') then
            call scanErr s, ',' expected
        end
    if fx <> m.ff.0 then
        call scanerr s, 'csv cla' m.ff.0 'fields but' cx 'in line'
    return var
endProcedure csvRdrReadO

/*--- create a new csvRdr --------------------------------------------*/
csvWrt: procedure expose m.
parse arg rdr
    return jReset(oNew('CsvWrt'), rdr)
endProcedure csvWrt

/*--- open csvRdr: read first line and create dataClass --------------*/
csvWrtOpen: procedure expose m.
parse arg m
    call jOpen m.m.rdr, '<'
    m.m.class = ''
    m.m.o1    = ''
    call oMutatName m, 'CsvWrtR'
    return
endProcedure csvWrtOpen

/*--- read next line and return derived object -----------------------*/
csvWrtRead: procedure expose m.
parse arg m, var
    if m.m.o1 == '' then
        i1 = jReadO(m.m.rdr)
    else do
        i1 = m.m.o1
        m.m.o1 = ''
        end
    if i1 == '' then
        return 0
    if m.m.class == '' then do
        m.m.class = objClass(i1)
        m.m.o1 = i1
        t = ''
        ff = oFlds(i1)
        do fx=1 to m.ff.0
            t = t','substr(m.ff.fx, 2)
            end
        m.var = substr(t, 2)
        return 1
        end
    else do
        t = ''
        ff = oFlds(i1)
        do fx=1 to m.ff.0
            f1 = i1 || m.ff.fx
            val = m.f1
            if pos(',', val) > 0 | pos('"', val) > 0 then
                t = t','quote(val, '"')
            else
                t = t','val
            end
        m.var = substr(t, 2)
        return 1
        end
endProcedure csvWrtRead

/* copy csv end   *****************************************************/