• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2021, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 #ifndef __GENERIC_PAYLOAD_H__
31 #define __GENERIC_PAYLOAD_H__
32 
33 #include <errno.h>
34 #include <debug_handler.h>
35 #include <assert.h>
36 #include <functional>
37 #include <cstring>
38 
39 // Do not define __CLASS__ for logging in shared utility header like this one
40 
41 namespace sdm {
42 
43 struct GenericPayload {
44  public:
GenericPayloadGenericPayload45   GenericPayload():
46     type_size(0), payload(nullptr), array_size(0) {}
47 
GenericPayloadGenericPayload48   GenericPayload(const GenericPayload &in) {
49     type_size = 0;
50     payload = nullptr;
51     array_size = 0;
52     if (in.payload) {
53       display::DebugHandler::Get()->Error("GenericPayload::%s:New GenericPayload will not copy"
54                "payload data! Use CopyPayload on a new GenericPayload instance.", __FUNCTION__);
55     }
56     copy_constructed = true;
57   }
58 
59   GenericPayload& operator=(const GenericPayload &) = delete;
60 
CopyPayloadGenericPayload61   template<typename A> int CopyPayload(const GenericPayload &in) {
62     if (sizeof(A) != in.type_size) {
63       return -EINVAL;
64     }
65     A* p = reinterpret_cast<A *>(in.payload);
66     type_size = sizeof(A);
67     array_size = in.array_size;
68 
69     if (payload != nullptr) {
70       release();
71     }
72     A* p2 = nullptr;
73     if (array_size > 1) {
74       p2 = new A[array_size];
75     } else {
76       p2 = new A();
77     }
78     if (p2 == nullptr) {
79       return -ENOMEM;
80     }
81     *p2 = *p;
82     payload = reinterpret_cast<uint8_t *>(p2);
83     if (array_size > 1) {
84       release = std::function<void(void)>([p2]() -> void {delete [] p2;});
85     } else {
86       release = std::function<void(void)>([p2]() -> void {delete p2;});
87     }
88     return 0;
89   }
90 
CreatePayloadGenericPayload91   template<typename A> int CreatePayload(A *&p) {
92     if (payload) {
93       p = nullptr;
94       return -EALREADY;
95     }
96 
97     p = new A();
98     if (p == nullptr) {
99       return -ENOMEM;
100     }
101 
102     type_size = sizeof(A);
103     array_size = 1;
104     payload = reinterpret_cast<uint8_t *>(p);
105     release = std::function<void(void)>([p]() -> void {delete p;});
106 
107     return 0;
108   }
109 
CreatePayloadGenericPayload110   template<typename A> int CreatePayload(A *&p, uint32_t sz) {
111     if (payload) {
112       p = nullptr;
113       return -EALREADY;
114     }
115 
116     if (!sz) {
117       return -EINVAL;
118     }
119 
120     p = new A[sz];
121     if (p == nullptr) {
122       return -ENOMEM;
123     }
124 
125     type_size = sizeof(A);
126     array_size = sz;
127     payload = reinterpret_cast<uint8_t *>(p);
128     release = std::function<void(void)>([p]() -> void {delete [] p;});
129 
130     return 0;
131   }
132 
GetPayloadGenericPayload133   template<typename A> int GetPayload(A *&p, uint32_t *sz) const {
134     if ((sz == nullptr) || (sizeof(A) != type_size)) {
135       p = nullptr;
136       return -EINVAL;
137     }
138 
139     p = reinterpret_cast<A *>(payload);
140     *sz = 0;
141     if (p == nullptr && copy_constructed) {
142       display::DebugHandler::Get()->Error("GenericPayload::%s:Payload was not properly"
143                                           "copied via CopyPayload", __FUNCTION__);
144       return -ENOMEM;
145     } else if (p == nullptr) {
146       display::DebugHandler::Get()->Error("GenericPayload::%s:Payload was not properly"
147                                           "created via CreatePayload", __FUNCTION__);
148       return -ENOMEM;
149     }
150     *sz = array_size;
151 
152     return 0;
153   }
154 
DeletePayloadGenericPayload155   void DeletePayload() {
156     if (payload != nullptr) {
157       release();
158     }
159 
160     type_size = 0;
161     payload = nullptr;
162     array_size = 0;
163   }
164 
~GenericPayloadGenericPayload165   ~GenericPayload() {
166     DeletePayload();
167   }
168 
169  private:
170   uint32_t type_size;
171   uint8_t *payload;
172   uint32_t array_size;
173   std::function<void(void)> release;
174   bool copy_constructed = false;
175 };
176 
177 }  // namespace sdm
178 
179 #endif  // __GENERIC_PAYLOAD_H__
180 
181