Blender  V3.3
obj_import_string_utils.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
4 
5 /* NOTE: we could use C++17 <charconv> from_chars to parse
6  * floats, but even if some compilers claim full support,
7  * their standard libraries are not quite there yet.
8  * LLVM/libc++ only has a float parser since LLVM 14,
9  * and gcc/libstdc++ since 11.1. So until at least these are
10  * the minimum spec, use an external library. */
11 #include "fast_float.h"
12 #include <charconv>
13 
14 namespace blender::io::obj {
15 
17 {
18  const char *start = buffer.begin();
19  const char *end = buffer.end();
20  size_t len = 0;
21  const char *ptr = start;
22  while (ptr < end) {
23  char c = *ptr++;
24  if (c == '\n') {
25  break;
26  }
27  ++len;
28  }
29 
30  buffer = StringRef(ptr, end);
31  return StringRef(start, len);
32 }
33 
34 static bool is_whitespace(char c)
35 {
36  return c <= ' ';
37 }
38 
39 void fixup_line_continuations(char *p, char *end)
40 {
41  while (true) {
42  /* Find next backslash, if any. */
43  char *backslash = std::find(p, end, '\\');
44  if (backslash == end)
45  break;
46  /* Skip over possible whitespace right after it. */
47  p = backslash + 1;
48  while (p < end && is_whitespace(*p) && *p != '\n')
49  ++p;
50  /* If then we have a newline, turn both backslash
51  * and the newline into regular spaces. */
52  if (p < end && *p == '\n') {
53  *backslash = ' ';
54  *p = ' ';
55  }
56  }
57 }
58 
59 const char *drop_whitespace(const char *p, const char *end)
60 {
61  while (p < end && is_whitespace(*p)) {
62  ++p;
63  }
64  return p;
65 }
66 
67 const char *drop_non_whitespace(const char *p, const char *end)
68 {
69  while (p < end && !is_whitespace(*p)) {
70  ++p;
71  }
72  return p;
73 }
74 
75 static const char *drop_plus(const char *p, const char *end)
76 {
77  if (p < end && *p == '+') {
78  ++p;
79  }
80  return p;
81 }
82 
83 const char *parse_float(const char *p,
84  const char *end,
85  float fallback,
86  float &dst,
87  bool skip_space,
88  bool require_trailing_space)
89 {
90  if (skip_space) {
91  p = drop_whitespace(p, end);
92  }
93  p = drop_plus(p, end);
94  fast_float::from_chars_result res = fast_float::from_chars(p, end, dst);
95  if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
96  dst = fallback;
97  }
98  else if (require_trailing_space && res.ptr < end && !is_whitespace(*res.ptr)) {
99  /* If there are trailing non-space characters, do not eat up the number. */
100  dst = fallback;
101  return p;
102  }
103  return res.ptr;
104 }
105 
106 const char *parse_floats(const char *p,
107  const char *end,
108  float fallback,
109  float *dst,
110  int count,
111  bool require_trailing_space)
112 {
113  for (int i = 0; i < count; ++i) {
114  p = parse_float(p, end, fallback, dst[i], true, require_trailing_space);
115  }
116  return p;
117 }
118 
119 const char *parse_int(const char *p, const char *end, int fallback, int &dst, bool skip_space)
120 {
121  if (skip_space) {
122  p = drop_whitespace(p, end);
123  }
124  p = drop_plus(p, end);
125  std::from_chars_result res = std::from_chars(p, end, dst);
126  if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
127  dst = fallback;
128  }
129  return res.ptr;
130 }
131 
132 } // namespace blender::io::obj
int len
Definition: draw_manager.c:108
int count
ccl_global float * buffer
static unsigned c
Definition: RandGen.cpp:83
static bool is_whitespace(char c)
const char * parse_floats(const char *p, const char *end, float fallback, float *dst, int count, bool require_trailing_space)
void fixup_line_continuations(char *p, char *end)
const char * drop_non_whitespace(const char *p, const char *end)
const char * parse_int(const char *p, const char *end, int fallback, int &dst, bool skip_space)
static const char * drop_plus(const char *p, const char *end)
const char * drop_whitespace(const char *p, const char *end)
StringRef read_next_line(StringRef &buffer)
const char * parse_float(const char *p, const char *end, float fallback, float &dst, bool skip_space, bool require_trailing_space)
PointerRNA * ptr
Definition: wm_files.c:3480