diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index cd28081f766b9..0032c4317985b 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -1754,9 +1754,9 @@ String _File::get_line() const { return f->get_line(); } -Vector _File::get_csv_line(String delim) const { +Vector _File::get_csv_line(const String &p_delim) const { ERR_FAIL_COND_V(!f, Vector()); - return f->get_csv_line(delim); + return f->get_csv_line(p_delim); } /**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) @@ -1853,6 +1853,11 @@ void _File::store_line(const String &p_string) { f->store_line(p_string); } +void _File::store_csv_line(const Vector &p_values, const String &p_delim) { + ERR_FAIL_COND(!f); + f->store_csv_line(p_values, p_delim); +} + void _File::store_buffer(const PoolVector &p_buffer) { ERR_FAIL_COND(!f); @@ -1936,6 +1941,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real); ClassDB::bind_method(D_METHOD("get_buffer", "len"), &_File::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line); + ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text); ClassDB::bind_method(D_METHOD("get_md5", "path"), &_File::get_md5); ClassDB::bind_method(D_METHOD("get_sha256", "path"), &_File::get_sha256); @@ -1943,7 +1949,6 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap); ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error); ClassDB::bind_method(D_METHOD("get_var"), &_File::get_var); - ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8); ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16); @@ -1954,6 +1959,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("store_real", "value"), &_File::store_real); ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &_File::store_buffer); ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line); + ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string); ClassDB::bind_method(D_METHOD("store_var", "value"), &_File::store_var); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 437d7515c68c0..720b14bf564c1 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -455,6 +455,7 @@ class _File : public Reference { PoolVector get_buffer(int p_length) const; ///< get an array of bytes String get_line() const; + Vector get_csv_line(const String &p_delim = ",") const; String get_as_text() const; String get_md5(const String &p_path) const; String get_sha256(const String &p_path) const; @@ -480,12 +481,11 @@ class _File : public Reference { void store_string(const String &p_string); void store_line(const String &p_string); + void store_csv_line(const Vector &p_values, const String &p_delim = ","); virtual void store_pascal_string(const String &p_string); virtual String get_pascal_string(); - Vector get_csv_line(String delim = ",") const; - void store_buffer(const PoolVector &p_buffer); ///< store an array of bytes void store_var(const Variant &p_var); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index e09e5e16ad213..8f4fae9eb1a0c 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -346,9 +346,9 @@ String FileAccess::get_line() const { return String::utf8(line.get_data()); } -Vector FileAccess::get_csv_line(String delim) const { +Vector FileAccess::get_csv_line(const String &p_delim) const { - ERR_FAIL_COND_V(delim.length() != 1, Vector()); + ERR_FAIL_COND_V(p_delim.length() != 1, Vector()); String l; int qc = 0; @@ -376,7 +376,7 @@ Vector FileAccess::get_csv_line(String delim) const { CharType c = l[i]; CharType s[2] = { 0, 0 }; - if (!in_quote && c == delim[0]) { + if (!in_quote && c == p_delim[0]) { strings.push_back(current); current = String(); } else if (c == '"') { @@ -525,6 +525,28 @@ void FileAccess::store_line(const String &p_line) { store_8('\n'); } +void FileAccess::store_csv_line(const Vector &p_values, const String &p_delim) { + + ERR_FAIL_COND(p_delim.length() != 1); + + String line = ""; + int size = p_values.size(); + for (int i = 0; i < size; ++i) { + String value = p_values[i]; + + if (value.find("\"") != -1 || value.find(p_delim) != -1 || value.find("\n")) { + value = "\"" + value.replace("\"", "\"\"") + "\""; + } + if (i < size - 1) { + value += p_delim; + } + + line += value; + } + + store_line(line); +} + void FileAccess::store_buffer(const uint8_t *p_src, int p_length) { for (int i = 0; i < p_length; i++) diff --git a/core/os/file_access.h b/core/os/file_access.h index b7d93e9f5d8c3..f1f3005dd9997 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -112,7 +112,7 @@ class FileAccess { virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes virtual String get_line() const; virtual String get_token() const; - virtual Vector get_csv_line(String delim = ",") const; + virtual Vector get_csv_line(const String &p_delim = ",") const; /**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac) * It's not about the current CPU type but file formats. @@ -136,6 +136,7 @@ class FileAccess { virtual void store_string(const String &p_string); virtual void store_line(const String &p_line); + virtual void store_csv_line(const Vector &p_values, const String &p_delim = ","); virtual void store_pascal_string(const String &p_string); virtual String get_pascal_string(); diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 6c900385f7070..17453898338d9 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -100,7 +100,7 @@ - Returns the next value of the file in CSV (Comma Separated Values) format. You can pass a different delimiter to use other than the default "," (comma). + Returns the next value of the file in CSV (Comma Separated Values) format. You can pass a different delimiter to use other than the default "," (comma), it should be one character long. @@ -327,6 +327,17 @@ Stores the given array of bytes in the file. + + + + + + + + + Store the given [PoolStringArray] in the file as a line formatted in the CSV (Comma Separated Values) format. You can pass a different delimiter to use other than the default "," (comma), it should be one character long. + +