1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 *     Copyright 2015 Couchbase, Inc
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 */
17 
18 #include "util.h"
19 #include <stdexcept>
20 
21 using namespace Subdoc;
22 using std::string;
23 
24 string
match_match(const Match& m)25 Util::match_match(const Match& m)
26 {
27     return m.loc_deepest.to_string();
28 }
29 
30 string
match_key(const Match& m)31 Util::match_key(const Match& m)
32 {
33     if (m.has_key()) {
34         return m.loc_key.to_string();
35     } else {
36         return string();
37     }
38 }
39 
40 string
match_parent(const Match& m)41 Util::match_parent(const Match& m)
42 {
43     return m.loc_deepest.to_string();
44 }
45 
46 void
dump_newdoc(const Result& op, std::ostream& os)47 Util::dump_newdoc(const Result& op, std::ostream& os)
48 {
49     auto newdoc = op.newdoc();
50     os << "Dumping doc with "
51        << std::dec << newdoc.size() << " segments" << std::endl;
52     for (size_t ii = 0; ii < newdoc.size(); ++ii) {
53         os << "[" << std::dec << ii << "]: ";
54         os.write(newdoc[ii].at, newdoc[ii].length);
55         os << std::endl;
56     }
57 }
58 
59 const char *
jsonerr(jsonsl_error_t err)60 Util::jsonerr(jsonsl_error_t err)
61 {
62 #define X(n) if (err == JSONSL_ERROR_##n) { return #n; }
63     JSONSL_XERR;
64 #undef X
65     return "UNKNOWN";
66 }
67 
68 namespace std {
69 ostream&
operator <<(ostream& os, const Subdoc::Error::Code& err)70 operator<<(ostream& os, const Subdoc::Error::Code& err) {
71     os << "0x" << std::hex << static_cast<int>(err)
72        << " (" << Subdoc::Error(err).description() << ")";
73     return os;
74 }
75 }
76 
77 void
do_assert(const char *e, const char *func, const char *file, int line)78 Util::do_assert(const char *e, const char *func, const char *file,
79         int line)
80 {
81     std::string ss;
82     ss.append("Assertion failed (").append(e).append(") ");
83     ss.append("function ").append(func).append(", ");
84     ss.append("file ").append(file).append(", line").append(std::to_string(line));
85     throw std::runtime_error(ss);
86 }
87 
88 jsonsl_type_t
get_root_type(Command command, const char *path, size_t len)89 Util::get_root_type(Command command, const char *path, size_t len)
90 {
91     char c = 0;
92     // Find first non-whitespace character
93     for (size_t ii = 0; ii < len; ++ii) {
94         if (!isspace(path[ii])) {
95             c = path[ii];
96             break;
97         }
98     }
99 
100     if (!c) {
101         switch (command.base()) {
102         case Command::ARRAY_APPEND:
103         case Command::ARRAY_PREPEND:
104         case Command::ARRAY_ADD_UNIQUE:
105             return JSONSL_T_LIST;
106         default:
107             return JSONSL_T_UNKNOWN;
108         }
109     }
110 
111     if (c == '[') {
112         return JSONSL_T_LIST;
113     } else {
114         return JSONSL_T_OBJECT;
115     }
116 }
117 
118