Парсинг CSV-файла


//////////////////////////////////////////////////////////////////////
//
// CSV Parser
//
// Artix, sun-doctor@7masterov.ru
//
//////////////////////////////////////////////////////////////////////
function CSVArray(a) {
    this.it = [];
    for(var k in a) this.it[this.it.length]=a[k];
    this.get = CSVArray_get;
    this.getSize = CSVArray_getSize;
}

function CSVArray_get(i) { return this.it[i]; }

function CSVArray_getSize() { return this.it.length; }

function CSVParser(filename,create) {
    this.trim = 0;
    this.close = CSVParser_close;
    this.eof = CSVParser_eof;
    this.line = 0;
    this.raw = "";
    this.delim = ";";
    this.readLine = CSVParser_readLine;
    this.writeLine = CSVParser_writeLine;
    this.writeArray = CSVParser_writeArray;
    this.readArray = CSVParser_readArray;
    this.quote = CSVParser_quote;
    this.unquote = CSVParser_unquote;
    this.filename = filename;
    this.fso = new ActiveXObject("Scripting.FileSystemObject");
    this.file = null;
    this.ready = false;

    if (create) {
        this.file = this.fso.CreateTextFile(filename, true);
        this.ready = true;
    }
    else if (this.fso.FileExists(filename)) {
        this.file = this.fso.OpenTextFile(filename, 1);
        this.ready = true;
    }
}

function CSVParser_close() {
    if (!this.ready) return;
    this.file.close();
}

function CSVParser_eof() {
    //if (!this.ready) return 1;
    return (this.file.atEndOfStream?1:0);
}

function CSVParser_readLine() {
    if (!this.ready) return null;
    this.line++;
    this.raw = this.file.readLine();
    return this.raw;
}

function CSVParser_writeLine(s) {
    if (!this.ready) return null;
    this.line++;
    return this.file.writeLine(s);
}

function CSVParser_readArray() {
    if (!this.ready) return null;    
    var dict = new ActiveXObject("Scripting.Dictionary");
    var row = ""+this.readLine();
    var s = ""+row;
    var stack = "";
    var idx=0;
    while(true && idx<100) {
        var p1 = s.indexOf(this.delim);
        var p2 = s.indexOf('"');
        if (p1<0 && p2<0) break;
        if (p1<0) p1=s.length+10;
        if (p2<0) p2=s.length+10;
        //MsgBox(s+"\n"+stack+"\n"+p1 + ':'+p2);
        if (p1 < p2) {
            if (stack.length==0) {
                it = ""+s.substr(0,p1);
                dict.add(idx++,this.unquote(it));
            } else {
                if (stack=='""') {
                   dict.add(idx++,"");
                   stack = "";
		} else 
                   stack+=""+s.substr(0,p1+1);
            }
            s = s.substr(p1+1,s.length);
        } else {
            if (s.substr(p2+1,2)=='""') {
                if (stack=="") {
                    stack+=""+s.substr(0,p2+3);
                    s = s.substr(p2+3,s.length);
                } else {
                    it = stack+s.substr(0,p2+2);
                    stack="";
                    dict.add(idx++,this.unquote(it));
                    s = s.substr(p2+4,s.length);
                }
            }
            else if (s.substr(p2,2)=='""') {
                stack+=""+s.substr(0,p2+2);
                s = s.substr(p2+2,s.length);
            } else {
                if (stack!="") {
                    it = stack+s.substr(0,p2+1);
                    stack="";
                    dict.add(idx++,this.unquote(it));
                }
                else {
                    stack+=s.substr(0,p2+1);
                }
                s = s.substr(p2+1,s.length);
                if (s.indexOf(this.delim)==0) s=s.substr(1,s.length);
            }
        }
    }
    if (s!="") dict.add(idx++,this.unquote(stack+s));
    return dict;
}

function CSVParser_writeArray(s) {
    var n="";
    for(var i=0; i<arguments.length; i++) {
       n += (n==""?"":this.delim)+this.quote(arguments[i]);
    }
    return this.writeLine(n);
}

function CSVParser_quote(s) {
    s=""+s;
    if (this.trim) s=""+trim(s);
    if (s.indexOf('"') >= 0 || s.indexOf(this.delim) >= 0 || s.indexOf("\n") >= 0) {
        var ss=""+s.replace(/\n/g,"\\n");
        return '"'+ss.replace(/\\"/g,'""')+'"';
    }
    return s;
}

function CSVParser_unquote(s) {
    s=""+s;
    if (s.indexOf('"')==0 && s.lastIndexOf('"')==(s.length-1)) {
        var ss=s.substr(1,s.length-2);
        ss=""+ss.replace(/\\\\n/g,"\n");
        return ""+ss.replace(/\\"\\"/g,'"');
    }
    return s;
}