Browse Source

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

zhibog 5 years ago
parent
commit
803f6a6651
1 changed files with 44 additions and 12 deletions
  1. 44 12
      core/encoding/csv/csv.odin

+ 44 - 12
core/encoding/csv/csv.odin

@@ -2,7 +2,7 @@ package csv
 
 // @note(zh): Encoding utility for csv files
 // 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 
 // a bool parameter to the proc as shown down below.
 // Example useage:
@@ -15,20 +15,33 @@ main :: proc() {
     file_name := "test.csv";
 
     // Write file and read with the headers omitted
-    if isOkWrite := write(file_name, &ctx); isOkWrite {
-        if content, row_count, isOkRead := read(file_name, DELIMITER, true); isOkRead {
-            fmt.println("Column count(no headers): ", row_count);
+    if isOkWrite := write_file(file_name, &ctx); isOkWrite {
+        if content, row_count, isOkRead := read_file(file_name, DELIMITER, true); isOkRead {
+            fmt.println("Row count(no headers): ", row_count);
             fmt.println(content);
         }
     }
 
     // Write file and read with the headers being read as well
-    if isOkWrite := write(file_name, &ctx); isOkWrite {
-        if content, row_count, isOkRead := read(file_name); isOkRead {
-            fmt.println("Column count(with headers): ", row_count);
+    if isOkWrite := write_file(file_name, &ctx); isOkWrite {
+        if content, row_count, isOkRead := read_file(file_name); isOkRead {
+            fmt.println("Row count(with headers): ", row_count);
             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";
 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();
     defer strings.destroy_builder(&b);
 
@@ -59,10 +82,10 @@ write :: proc(path: string, ctx: ^CSV) -> bool {
         }
         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);
     if err != os.ERROR_NONE do return false;
     defer os.close(file);
@@ -71,13 +94,14 @@ write_raw :: proc(path: string, data: []byte) -> bool {
     return true;
 }
 
-read :: 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 {
+read_string ::proc(data: string, delimiter := DELIMITER, skip_header := false) -> (content: []string, row_count: int, is_ok: bool) {
+    if data != "" {
         cols: [dynamic]string;
         defer delete(cols);
         content: [dynamic]string;
         row_count := 0;
         prev_index := 0;
+        bytes := ([]byte)(data);
         for i := 0; i < len(bytes); i += 1 {
             if bytes[i] == '\n' {
                 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));
         if skip_header  do return content[row_count:], row_count - 1, 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;
 }