aboutsummaryrefslogtreecommitdiff
path: root/odb/statement-processing-common.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/statement-processing-common.hxx')
-rw-r--r--odb/statement-processing-common.hxx174
1 files changed, 174 insertions, 0 deletions
diff --git a/odb/statement-processing-common.hxx b/odb/statement-processing-common.hxx
new file mode 100644
index 0000000..4c12791
--- /dev/null
+++ b/odb/statement-processing-common.hxx
@@ -0,0 +1,174 @@
+// file : odb/statement-processingc-common.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_STATEMENT_PROCESSING_COMMON_HXX
+#define ODB_STATEMENT_PROCESSING_COMMON_HXX
+
+#include <odb/pre.hxx>
+
+//#define LIBODB_DEBUG_STATEMENT_PROCESSING 1
+//#define LIBODB_TRACE_STATEMENT_PROCESSING 1
+
+#include <string>
+#include <cstddef> // std::size_t
+
+namespace odb
+{
+ typedef std::char_traits<char> traits;
+
+ static inline const char*
+ find (const char* b, const char* e, char c)
+ {
+ return traits::find (b, e - b, c);
+ }
+
+ static inline const char*
+ rfind (const char* b, const char* e, char c)
+ {
+ for (--e; b != e; --e)
+ if (*e == c)
+ return e;
+
+ return 0;
+ }
+
+ // Iterate over INSERT column/value list, UPDATE SET expression list,
+ // or SELECT column/join list.
+ //
+ // for (const char* b (columns_begin), *e (begin (b, end));
+ // e != 0;
+ // next (b, e, end))
+ // {
+ // // b points to the beginning of the value (i.e., one past '(').
+ // // e points one past the end of the value (i.e., to ',', ')', or '\n').
+ // }
+ //
+ // // b points one past the last value.
+ //
+ static inline const char*
+ paren_begin (const char*& b, const char* end)
+ {
+ // Note that the list may not end with '\n'.
+
+ b++; // Skip '('.
+ const char* e (find (b, end, '\n'));
+ return (e != 0 ? e : end) - 1; // Skip ',' or ')'.
+ }
+
+ static inline void
+ paren_next (const char*& b, const char*& e, const char* end)
+ {
+ if (*e == ',')
+ {
+ b = e + 2; // Skip past '\n'.
+ e = find (b, end, '\n');
+ e = (e != 0 ? e : end) - 1; // Skip ',' or ')'.
+ }
+ else
+ {
+ b = (e + 1 != end ? e + 2 : end); // Skip past '\n'.
+ e = 0;
+ }
+ }
+
+ static inline const char*
+ comma_begin (const char* b, const char* end)
+ {
+ // Note that the list may not end with '\n'.
+
+ const char* e (find (b, end, '\n'));
+ return e != 0 ? e - (*(e - 1) == ',' ? 1 : 0) : end; // Skip ','.
+ }
+
+ static inline void
+ comma_next (const char*& b, const char*& e, const char* end)
+ {
+ if (*e == ',')
+ {
+ b = e + 2; // Skip past '\n'.
+ e = find (b, end, '\n');
+ e = (e != 0 ? e - (*(e - 1) == ',' ? 1 : 0) : end); // Skip ','.
+ }
+ else
+ {
+ b = (e != end ? e + 1 : end); // Skip past '\n'.
+ e = 0;
+ }
+ }
+
+ static inline const char*
+ newline_begin (const char* b, const char* end)
+ {
+ // Note that the list may not end with '\n'.
+
+ const char* e (find (b, end, '\n'));
+ return e != 0 ? e : end;
+ }
+
+ static inline void
+ newline_next (const char*& b,
+ const char*& e,
+ const char* end,
+ const char* prefix,
+ std::size_t prefix_size)
+ {
+ if (e != end)
+ e++; // Skip past '\n'.
+
+ b = e;
+
+ // Do we have another element?
+ //
+ if (static_cast<std::size_t> (end - b) > prefix_size &&
+ traits::compare (b, prefix, prefix_size) == 0)
+ {
+ e = find (b, end, '\n');
+ if (e == 0)
+ e = end;
+ }
+ else
+ e = 0;
+ }
+
+ // Note that end must point to the beginning of the list.
+ //
+ static inline const char*
+ newline_rbegin (const char* e, const char* end)
+ {
+ const char* b (rfind (end, e - 1, '\n'));
+ return b != 0 ? b + 1 : end; // Skip past '\n'.
+ }
+
+ static inline void
+ newline_rnext (const char*& b, const char*& e, const char* end)
+ {
+ if (b != end)
+ {
+ e = b - 1; // Skip to previous '\n'.
+ b = rfind (end, e - 1, '\n');
+ b = (b != 0 ? b + 1 : end); // Skip past '\n'.
+ }
+ else
+ {
+ e = end - 1; // One before the first element.
+ b = 0;
+ }
+ }
+
+ // Fast path: just remove the "structure".
+ //
+ static inline void
+ process_fast (const char* s, std::string& r)
+ {
+ r = s;
+ for (std::size_t i (r.find ('\n'));
+ i != std::string::npos;
+ i = r.find ('\n', i))
+ r[i++] = ' ';
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_STATEMENT_PROCESSING_COMMON_HXX