Added procs to read and write just the data, without any file loading / writing

This commit is contained in:
zhibog
2019-11-08 22:17:24 +01:00
parent 672cfd51c3
commit 803f6a6651
+44 -12
View File
@@ -2,7 +2,7 @@ package csv
// @note(zh): Encoding utility for csv files // @note(zh): Encoding utility for csv files
// You may use the provided struct to build your csv dynamically. // You may use the provided struct to build your csv dynamically.
// If you have a string with the whole content already, just use write_raw. // If you have a string with the whole content already, just use write_file_raw to write it to a file.
// You are able to read the csv with the headers included in the data or omitted by providing // You are able to read the csv with the headers included in the data or omitted by providing
// a bool parameter to the proc as shown down below. // a bool parameter to the proc as shown down below.
// Example useage: // Example useage:
@@ -15,20 +15,33 @@ main :: proc() {
file_name := "test.csv"; file_name := "test.csv";
// Write file and read with the headers omitted // Write file and read with the headers omitted
if isOkWrite := write(file_name, &ctx); isOkWrite { if isOkWrite := write_file(file_name, &ctx); isOkWrite {
if content, row_count, isOkRead := read(file_name, DELIMITER, true); isOkRead { if content, row_count, isOkRead := read_file(file_name, DELIMITER, true); isOkRead {
fmt.println("Column count(no headers): ", row_count); fmt.println("Row count(no headers): ", row_count);
fmt.println(content); fmt.println(content);
} }
} }
// Write file and read with the headers being read as well // Write file and read with the headers being read as well
if isOkWrite := write(file_name, &ctx); isOkWrite { if isOkWrite := write_file(file_name, &ctx); isOkWrite {
if content, row_count, isOkRead := read(file_name); isOkRead { if content, row_count, isOkRead := read_file(file_name); isOkRead {
fmt.println("Column count(with headers): ", row_count); fmt.println("Row count(with headers): ", row_count);
fmt.println(content); fmt.println(content);
} }
} }
// Write slice to a csv string
csv_string_data: [9]string = {"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii"};
col_count := 3;
csv_string := write_string(csv_string_data[:], col_count);
fmt.println(csv_string);
// Read data into a slice when you have read the csv file yourself
csv_data := "aaa, bbb, ccc\n ddd, eee, fff\n ggg, hhh, iii";
if content, row_count, isOkRead := read_string(csv_data); isOkRead {
fmt.println("Row count(from string): ", row_count);
fmt.println(content);
}
} }
*/ */
@@ -45,7 +58,17 @@ LF :: "\n";
CRLF :: "\r\n"; CRLF :: "\r\n";
DELIMITER :: ","; DELIMITER :: ",";
write :: proc(path: string, ctx: ^CSV) -> bool { write_string :: proc(data: []string, col_count: int, delimiter := DELIMITER, line_ending := LF) -> string {
b := strings.make_builder();
for i := 0; i < len(data); i += 1 {
if i >= col_count && i % col_count == 0 do strings.write_string(&b, line_ending);
strings.write_string(&b, data[i]);
if len(data) - i > 1 do strings.write_string(&b, delimiter);
}
return strings.to_string(b);
}
write_file :: proc(path: string, ctx: ^CSV) -> bool {
b := strings.make_builder(); b := strings.make_builder();
defer strings.destroy_builder(&b); defer strings.destroy_builder(&b);
@@ -59,10 +82,10 @@ write :: proc(path: string, ctx: ^CSV) -> bool {
} }
strings.write_string(&b, ctx.line_ending); strings.write_string(&b, ctx.line_ending);
} }
return write_raw(path, b.buf[:]); return write_file_raw(path, b.buf[:]);
} }
write_raw :: proc(path: string, data: []byte) -> bool { write_file_raw :: proc(path: string, data: []byte) -> bool {
file, err := os.open(path, os.O_RDWR | os.O_CREATE | os.O_TRUNC); file, err := os.open(path, os.O_RDWR | os.O_CREATE | os.O_TRUNC);
if err != os.ERROR_NONE do return false; if err != os.ERROR_NONE do return false;
defer os.close(file); defer os.close(file);
@@ -71,13 +94,14 @@ write_raw :: proc(path: string, data: []byte) -> bool {
return true; return true;
} }
read :: proc(path: string, delimiter := DELIMITER, skip_header := false) -> (content: []string, row_count: int, is_ok: bool) { read_string ::proc(data: string, delimiter := DELIMITER, skip_header := false) -> (content: []string, row_count: int, is_ok: bool) {
if bytes, isOk := os.read_entire_file(path); isOk { if data != "" {
cols: [dynamic]string; cols: [dynamic]string;
defer delete(cols); defer delete(cols);
content: [dynamic]string; content: [dynamic]string;
row_count := 0; row_count := 0;
prev_index := 0; prev_index := 0;
bytes := ([]byte)(data);
for i := 0; i < len(bytes); i += 1 { for i := 0; i < len(bytes); i += 1 {
if bytes[i] == '\n' { if bytes[i] == '\n' {
append(&cols, string(bytes[prev_index:i])); append(&cols, string(bytes[prev_index:i]));
@@ -101,6 +125,14 @@ read :: proc(path: string, delimiter := DELIMITER, skip_header := false) -> (con
for col in cols do append(&content, ..strings.split(col, delimiter)); for col in cols do append(&content, ..strings.split(col, delimiter));
if skip_header do return content[row_count:], row_count - 1, true; if skip_header do return content[row_count:], row_count - 1, true;
else do return content[:], row_count, true; else do return content[:], row_count, true;
} else {
return nil, -1, false;
}
}
read_file :: proc(path: string, delimiter := DELIMITER, skip_header := false) -> (content: []string, row_count: int, is_ok: bool) {
if bytes, isOk := os.read_entire_file(path); isOk {
return read_string(string(bytes), delimiter, skip_header);
} }
return nil, -1, false; return nil, -1, false;
} }