1 /// My old csv code. Extremely basic functionality. 2 module arsd.csv; 3 4 import std.string; 5 import std.array; 6 7 /// Returns the array of csv rows from the given in-memory data (the argument is NOT a filename). 8 string[][] readCsv(string data) { 9 data = data.replace("\r\n", "\n"); 10 data = data.replace("\r", ""); 11 12 //auto idx = data.indexOf("\n"); 13 //data = data[idx + 1 .. $]; // skip headers 14 15 string[] fields; 16 string[][] records; 17 18 string[] current; 19 20 int state = 0; 21 string field; 22 foreach(c; data) { 23 tryit: switch(state) { 24 default: assert(0); 25 case 0: // normal 26 if(c == '"') 27 state = 1; 28 else if(c == ',') { 29 // commit field 30 current ~= field; 31 field = null; 32 } else if(c == '\n') { 33 // commit record 34 current ~= field; 35 36 records ~= current; 37 current = null; 38 field = null; 39 } else 40 field ~= c; 41 break; 42 case 1: // in quote 43 if(c == '"') { 44 state = 2; 45 } else 46 field ~= c; 47 break; 48 case 2: // is it a closing quote or an escaped one? 49 if(c == '"') { 50 field ~= c; 51 state = 1; 52 } else { 53 state = 0; 54 goto tryit; 55 } 56 } 57 } 58 59 if(field !is null) 60 current ~= field; 61 if(current !is null) 62 records ~= current; 63 64 65 return records; 66 } 67 68 /// Formats the given rows into csv format. Use like `std.file.write(toCsv(...));` 69 string toCsv(string[][] rows) { 70 string data; 71 72 foreach(ridx, row; rows) { 73 if(ridx) data ~= "\n"; 74 foreach(idx, cell; row) { 75 if(idx) data ~= ","; 76 77 if(cell.indexOf(",") != -1 || cell.indexOf("\"") != -1 || cell.indexOf("\n") != -1) { 78 data ~= "\""; 79 data ~= cell.replace(`"`, `""`); 80 data ~= "\""; 81 } else { 82 data ~= cell; 83 } 84 } 85 } 86 87 return data; 88 }