The OpenD Programming Language

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 }