1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include <cstring>
34 #include <type_traits>
35 
36 #include "mongo/config.h"
37 
38 #include "mongo/base/data_type.h"
39 
40 namespace mongo {
41 
42 class ConstDataView {
43 public:
44     typedef const char* bytes_type;
45 
ConstDataView(bytes_type bytes)46     ConstDataView(bytes_type bytes) : _bytes(bytes) {}
47 
48     bytes_type view(std::size_t offset = 0) const {
49         return _bytes + offset;
50     }
51 
52     template <typename T>
53     const ConstDataView& read(T* t, size_t offset = 0) const {
54         DataType::unsafeLoad(t, view(offset), nullptr);
55 
56         return *this;
57     }
58 
59     template <typename T>
60     T read(std::size_t offset = 0) const {
61         T t(DataType::defaultConstruct<T>());
62 
63         read(&t, offset);
64 
65         return t;
66     }
67 
68 private:
69     bytes_type _bytes;
70 };
71 
72 class DataView : public ConstDataView {
73 public:
74     typedef char* bytes_type;
75 
DataView(bytes_type bytes)76     DataView(bytes_type bytes) : ConstDataView(bytes) {}
77 
78     bytes_type view(std::size_t offset = 0) const {
79         // It is safe to cast away const here since the pointer stored in our base class was
80         // originally non-const by way of our constructor.
81         return const_cast<bytes_type>(ConstDataView::view(offset));
82     }
83 
84     template <typename T>
85     DataView& write(const T& value, std::size_t offset = 0) {
86         DataType::unsafeStore(value, view(offset), nullptr);
87 
88         return *this;
89     }
90 };
91 
92 }  // namespace mongo
93