Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-02-26 10:01:42 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-02-26 10:01:42 +0300
commit5f83495e4c21d8c2297e9f15ac1a81657a992855 (patch)
tree37508c644072b4692961eec71f7ed81c72ab60fc
parent66af6e4f32148e254a3dc64e442b4b6f389259d8 (diff)
BLI_fileops: add utility to read text with newlines set to nil
-rw-r--r--source/blender/blenlib/BLI_fileops.h4
-rw-r--r--source/blender/blenlib/intern/storage.c57
2 files changed, 61 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 3ee22e4ad0a..74e6c32b288 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -158,6 +158,10 @@ bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESUL
/* read ascii file as lines, empty list if reading fails */
struct LinkNode *BLI_file_read_as_lines(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size);
+void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath,
+ bool trim_trailing_space,
+ size_t pad_bytes,
+ size_t *r_size);
void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size);
void BLI_file_free_lines(struct LinkNode *lines);
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index d1d8c4fa2e0..e267c061b2b 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -449,6 +449,63 @@ void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t
}
/**
+ * Return the text file data with:
+
+ * - Newlines replaced with '\0'.
+ * - Optionally trim whitespace, replacing trailing ' ' & '\t' with '\0'.
+ *
+ * This is an alternative to using #BLI_file_read_as_lines,
+ * allowing us to loop over lines without converting it into a linked list
+ * with individual allocations.
+ *
+ * \param trim_trailing_space: Replace trailing spaces & tabs with nil.
+ * This arguments prevents the caller from counting blank lines (if that's important).
+ * \param pad_bytes: When this is non-zero, the first byte is set to nil,
+ * to simplify parsing the file.
+ * It's recommended to pass in 1, so all text is nil terminated.
+ *
+ * Example looping over lines:
+ *
+ * \code{.c}
+ * size_t data_len;
+ * char *data = BLI_file_read_text_as_mem_with_newline_as_nil(filepath, true, 1, &data_len);
+ * char *data_end = data + data_len;
+ * for (char *line = data; line != data_end; line = strlen(line) + 1) {
+ * printf("line='%s'\n", line);
+ * }
+ * \endcode
+ */
+void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath,
+ bool trim_trailing_space,
+ size_t pad_bytes,
+ size_t *r_size)
+{
+ char *mem = BLI_file_read_text_as_mem(filepath, pad_bytes, r_size);
+ if (mem != NULL) {
+ char *mem_end = mem + *r_size;
+ if (pad_bytes != 0) {
+ *mem_end = '\0';
+ }
+ for (char *p = mem, *p_next; p != mem_end; p = p_next) {
+ p_next = memchr(p, '\n', mem_end - p);
+ if (p_next != NULL) {
+ if (trim_trailing_space) {
+ for (char *p_trim = p_next - 1; p_trim > p && ELEM(*p_trim, ' ', '\t'); p_trim--) {
+ *p_trim = '\0';
+ }
+ }
+ *p_next = '\0';
+ p_next++;
+ }
+ else {
+ p_next = mem_end;
+ }
+ }
+ }
+ return mem;
+}
+
+/**
* Reads the contents of a text file and returns the lines in a linked list.
*/
LinkNode *BLI_file_read_as_lines(const char *name)