Coverage Report

Created: 2025-01-15 06:18

/src/oatpp/src/oatpp/data/mapping/ObjectMapper.hpp
Line
Count
Source
1
/***************************************************************************
2
 *
3
 * Project         _____    __   ____   _      _
4
 *                (  _  )  /__\ (_  _)_| |_  _| |_
5
 *                 )(_)(  /(__)\  )( (_   _)(_   _)
6
 *                (_____)(__)(__)(__)  |_|    |_|
7
 *
8
 *
9
 * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 *     http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 *
23
 ***************************************************************************/
24
25
#ifndef oatpp_data_mapping_ObjectMapper_hpp
26
#define oatpp_data_mapping_ObjectMapper_hpp
27
28
#include <utility>
29
30
#include "oatpp/Types.hpp"
31
32
#include "oatpp/data/stream/Stream.hpp"
33
34
#include "oatpp/utils/parser/Caret.hpp"
35
#include "oatpp/utils/parser/ParsingError.hpp"
36
37
namespace oatpp { namespace data { namespace mapping {
38
39
/**
40
 * Error stack
41
 */
42
struct ErrorStack {
43
44
  /**
45
   * stack
46
   */
47
  std::list<oatpp::String> stack;
48
49
  /**
50
   * Push error
51
   * @param error
52
   */
53
  void push(const oatpp::String& error);
54
55
  /**
56
   * Push all errors from other error stack.
57
   * @param errorStack
58
   */
59
  void splice(ErrorStack& errorStack);
60
61
  /**
62
   * Stacktrace as string.
63
   * @return
64
   */
65
  oatpp::String stacktrace() const;
66
67
  /**
68
   * Check if error stack is empty.
69
   * @return
70
   */
71
  bool empty() const;
72
73
};
74
75
/**
76
 * Mapping error
77
 */
78
class MappingError : public std::runtime_error {
79
private:
80
  ErrorStack m_stack;
81
public:
82
83
  /**
84
   * Constructor.
85
   * @param errorStack
86
   */
87
  MappingError(const ErrorStack& errorStack);
88
89
  /**
90
   * Constructor.
91
   * @param errorStack
92
   */
93
  MappingError(ErrorStack&& errorStack);
94
95
  /**
96
   * Get error stack
97
   * @return - See &id:oatpp::data::mapping::ErrorStack;.
98
   */
99
  const ErrorStack& errorStack() const;
100
101
  /**
102
   * Get error stack
103
   * @return - See &id:oatpp::data::mapping::ErrorStack;.
104
   */
105
  ErrorStack& errorStack();
106
107
};
108
109
/**
110
 * Abstract ObjectMapper class.
111
 */
112
class ObjectMapper {
113
public:
114
115
  /**
116
   * Metadata for ObjectMapper.
117
   */
118
  class Info {
119
  public:
120
121
    /**
122
     * Constructor
123
     */
124
    Info(const oatpp::String& pMimeType, const oatpp::String& pMimeSubtype)
125
2.63k
      : httpContentType(pMimeType + "/" + pMimeSubtype)
126
2.63k
      , mimeType(pMimeType)
127
2.63k
      , mimeSubtype(pMimeSubtype)
128
2.63k
    {}
129
130
    /**
131
     * Value for Content-Type http header when DTO is serialized via specified ObjectMapper.
132
     */
133
    const oatpp::String httpContentType;
134
135
    /**
136
     * Mime type
137
     */
138
    const oatpp::String mimeType;
139
140
    /**
141
     * Mime subtype
142
     */
143
    const oatpp::String mimeSubtype;
144
145
  };
146
private:
147
  Info m_info;
148
public:
149
150
  /**
151
   * Constructor.
152
   * @param info - Metadata for ObjectMapper.
153
   */
154
  ObjectMapper(const Info& info);
155
156
  /**
157
   * Get ObjectMapper metadata.
158
   * @return - ObjectMapper metadata.
159
   */
160
  const Info& getInfo() const;
161
162
  /**
163
   * Serialize object to stream. Implement this method.
164
   * @param stream - &id:oatpp::data::stream::ConsistentOutputStream; to serialize object to.
165
   * @param errorStack - See &id:oatpp::data::mapping::ErrorStack;.
166
   * @param variant - Object to serialize.
167
   */
168
  virtual void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant, ErrorStack& errorStack) const = 0;
169
170
  /**
171
   * Deserialize object. Implement this method.
172
   * @param caret - &id:oatpp::utils::parser::Caret; over serialized buffer.
173
   * @param type - pointer to object type. See &id:oatpp::data::type::Type;.
174
   * @param errorStack - See &id:oatpp::data::mapping::ErrorStack;.
175
   * @return - deserialized object wrapped in &id:oatpp::Void;.
176
   */
177
  virtual oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::Type* type, ErrorStack& errorStack) const = 0;
178
179
  /**
180
   * Serialize object to String.
181
   * @param variant - Object to serialize.
182
   * @return - serialized object as &id:oatpp::String;.
183
   * @throws - &id:oatpp::data::mapping::MappingError;
184
   * @throws - depends on implementation.
185
   */
186
  oatpp::String writeToString(const oatpp::Void& variant) const;
187
188
  /**
189
   * Deserialize object.
190
   * If nullptr is returned - check caret.getError()
191
   * @tparam Wrapper - ObjectWrapper type.
192
   * @param caret - &id:oatpp::utils::parser::Caret; over serialized buffer.
193
   * @return - deserialized Object.
194
   * @throws - &id:oatpp::data::mapping::MappingError;
195
   * @throws - depends on implementation.
196
   */
197
  template<class Wrapper>
198
  Wrapper readFromCaret(oatpp::utils::parser::Caret& caret) const {
199
    auto type = Wrapper::Class::getType();
200
    ErrorStack errorStack;
201
    const auto& result = read(caret, type, errorStack).template cast<Wrapper>();
202
    if(!errorStack.empty()) {
203
      throw MappingError(std::move(errorStack));
204
    }
205
    return result;
206
  }
207
208
  /**
209
   * Deserialize object.
210
   * @tparam Wrapper - ObjectWrapper type.
211
   * @param str - serialized data.
212
   * @return - deserialized Object.
213
   * @throws - &id:oatpp::data::mapping::MappingError;
214
   * @throws - depends on implementation.
215
   */
216
  template<class Wrapper>
217
2.63k
  Wrapper readFromString(const oatpp::String& str) const {
218
2.63k
    auto type = Wrapper::Class::getType();
219
2.63k
    oatpp::utils::parser::Caret caret(str);
220
2.63k
    ErrorStack errorStack;
221
2.63k
    const auto& result = read(caret, type, errorStack).template cast<Wrapper>();
222
2.63k
    if(!errorStack.empty()) {
223
1.75k
      throw MappingError(std::move(errorStack));
224
1.75k
    }
225
878
    return result;
226
2.63k
  }
227
  
228
};
229
  
230
}}}
231
232
#endif /* oatpp_data_mapping_ObjectMapper_hpp */