GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — src: move BlobSerializerDeserializer to a separate header file · nodejs/node@0c06bfd

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • node.gyp
  • src
    • blob_serializer_deserializer-inl.h
    • blob_serializer_deserializer.h
    • node_snapshotable.cc
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@
174174
'src/base_object_types.h',
175175
'src/base64.h',
176176
'src/base64-inl.h',
177+
'src/blob_serializer_deserializer.h',
178+
'src/blob_serializer_deserializer-inl.h',
177179
'src/callback_queue.h',
178180
'src/callback_queue-inl.h',
179181
'src/cleanup_queue.h',
Collapse file

‎src/blob_serializer_deserializer-inl.h‎

Copy file name to clipboard
+359Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
#ifndef SRC_BLOB_SERIALIZER_DESERIALIZER_INL_H_
2+
#define SRC_BLOB_SERIALIZER_DESERIALIZER_INL_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include "blob_serializer_deserializer.h"
7+
8+
#include <ostream>
9+
#include <sstream>
10+
#include <string>
11+
#include <type_traits>
12+
#include <utility>
13+
14+
#include "debug_utils-inl.h"
15+
16+
// This is related to the blob that is used in snapshots and has nothing to do
17+
// with `node_blob.h`.
18+
19+
namespace node {
20+
21+
struct EnvSerializeInfo;
22+
struct PropInfo;
23+
struct RealmSerializeInfo;
24+
25+
namespace builtins {
26+
struct CodeCacheInfo;
27+
} // namespace builtins
28+
29+
// These operator<< overload declarations are needed because
30+
// BlobSerializerDeserializer::ToStr() uses these.
31+
32+
std::ostream& operator<<(std::ostream& output,
33+
const builtins::CodeCacheInfo& info);
34+
35+
std::ostream& operator<<(std::ostream& output,
36+
const std::vector<builtins::CodeCacheInfo>& vec);
37+
38+
std::ostream& operator<<(std::ostream& output, const std::vector<uint8_t>& vec);
39+
40+
std::ostream& operator<<(std::ostream& output,
41+
const std::vector<PropInfo>& vec);
42+
43+
std::ostream& operator<<(std::ostream& output, const PropInfo& info);
44+
45+
std::ostream& operator<<(std::ostream& output,
46+
const std::vector<std::string>& vec);
47+
48+
std::ostream& operator<<(std::ostream& output, const RealmSerializeInfo& i);
49+
50+
std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i);
51+
52+
template <typename... Args>
53+
void BlobSerializerDeserializer::Debug(const char* format,
54+
Args&&... args) const {
55+
if (is_debug) {
56+
FPrintF(stderr, format, std::forward<Args>(args)...);
57+
}
58+
}
59+
60+
template <typename T>
61+
std::string BlobSerializerDeserializer::ToStr(const T& arg) const {
62+
std::stringstream ss;
63+
ss << arg;
64+
return ss.str();
65+
}
66+
67+
template <typename T>
68+
std::string BlobSerializerDeserializer::GetName() const {
69+
#define TYPE_LIST(V) \
70+
V(builtins::CodeCacheInfo) \
71+
V(PropInfo) \
72+
V(std::string)
73+
74+
#define V(TypeName) \
75+
if constexpr (std::is_same_v<T, TypeName>) { \
76+
return #TypeName; \
77+
} else // NOLINT(readability/braces)
78+
TYPE_LIST(V)
79+
#undef V
80+
81+
if constexpr (std::is_arithmetic_v<T>) {
82+
return (std::is_unsigned_v<T> ? "uint"
83+
: std::is_integral_v<T> ? "int"
84+
: "float") +
85+
std::to_string(sizeof(T) * 8) + "_t";
86+
}
87+
return "";
88+
}
89+
90+
// Helper for reading numeric types.
91+
template <typename Impl>
92+
template <typename T>
93+
T BlobDeserializer<Impl>::ReadArithmetic() {
94+
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
95+
T result;
96+
ReadArithmetic(&result, 1);
97+
return result;
98+
}
99+
100+
// Layout of vectors:
101+
// [ 4/8 bytes ] count
102+
// [ ... ] contents (count * size of individual elements)
103+
template <typename Impl>
104+
template <typename T>
105+
std::vector<T> BlobDeserializer<Impl>::ReadVector() {
106+
if (is_debug) {
107+
std::string name = GetName<T>();
108+
Debug("\nReadVector<%s>()(%d-byte)\n", name.c_str(), sizeof(T));
109+
}
110+
size_t count = static_cast<size_t>(ReadArithmetic<size_t>());
111+
if (count == 0) {
112+
return std::vector<T>();
113+
}
114+
if (is_debug) {
115+
Debug("Reading %d vector elements...\n", count);
116+
}
117+
std::vector<T> result;
118+
if constexpr (std::is_arithmetic_v<T>) {
119+
result = ReadArithmeticVector<T>(count);
120+
} else {
121+
result = ReadNonArithmeticVector<T>(count);
122+
}
123+
if (is_debug) {
124+
std::string str = std::is_arithmetic_v<T> ? "" : ToStr(result);
125+
std::string name = GetName<T>();
126+
Debug("ReadVector<%s>() read %s\n", name.c_str(), str.c_str());
127+
}
128+
return result;
129+
}
130+
131+
template <typename Impl>
132+
std::string BlobDeserializer<Impl>::ReadString() {
133+
size_t length = ReadArithmetic<size_t>();
134+
135+
if (is_debug) {
136+
Debug("ReadString(), length=%d: ", length);
137+
}
138+
139+
CHECK_GT(length, 0); // There should be no empty strings.
140+
MallocedBuffer<char> buf(length + 1);
141+
memcpy(buf.data, sink.data() + read_total, length + 1);
142+
std::string result(buf.data, length); // This creates a copy of buf.data.
143+
144+
if (is_debug) {
145+
Debug("\"%s\", read %zu bytes\n", result.c_str(), length + 1);
146+
}
147+
148+
read_total += length + 1;
149+
return result;
150+
}
151+
152+
// Helper for reading an array of numeric types.
153+
template <typename Impl>
154+
template <typename T>
155+
void BlobDeserializer<Impl>::ReadArithmetic(T* out, size_t count) {
156+
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
157+
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
158+
if (is_debug) {
159+
std::string name = GetName<T>();
160+
Debug("Read<%s>()(%d-byte), count=%d: ", name.c_str(), sizeof(T), count);
161+
}
162+
163+
size_t size = sizeof(T) * count;
164+
memcpy(out, sink.data() + read_total, size);
165+
166+
if (is_debug) {
167+
std::string str =
168+
"{ " + std::to_string(out[0]) + (count > 1 ? ", ... }" : " }");
169+
Debug("%s, read %zu bytes\n", str.c_str(), size);
170+
}
171+
read_total += size;
172+
}
173+
174+
// Helper for reading numeric vectors.
175+
template <typename Impl>
176+
template <typename Number>
177+
std::vector<Number> BlobDeserializer<Impl>::ReadArithmeticVector(size_t count) {
178+
static_assert(std::is_arithmetic_v<Number>, "Not an arithmetic type");
179+
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
180+
std::vector<Number> result(count);
181+
ReadArithmetic(result.data(), count);
182+
return result;
183+
}
184+
185+
// Helper for reading non-numeric vectors.
186+
template <typename Impl>
187+
template <typename T>
188+
std::vector<T> BlobDeserializer<Impl>::ReadNonArithmeticVector(size_t count) {
189+
static_assert(!std::is_arithmetic_v<T>, "Arithmetic type");
190+
DCHECK_GT(count, 0); // Should not read contents for vectors of size 0.
191+
std::vector<T> result;
192+
result.reserve(count);
193+
bool original_is_debug = is_debug;
194+
is_debug = original_is_debug && !std::is_same_v<T, std::string>;
195+
for (size_t i = 0; i < count; ++i) {
196+
if (is_debug) {
197+
Debug("\n[%d] ", i);
198+
}
199+
result.push_back(ReadElement<T>());
200+
}
201+
is_debug = original_is_debug;
202+
203+
return result;
204+
}
205+
206+
template <typename Impl>
207+
template <typename T>
208+
T BlobDeserializer<Impl>::ReadElement() {
209+
if constexpr (std::is_arithmetic_v<T>) {
210+
return ReadArithmetic<T>();
211+
} else if constexpr (std::is_same_v<T, std::string>) {
212+
return ReadString();
213+
} else {
214+
return impl()->template Read<T>();
215+
}
216+
}
217+
218+
// Helper for writing numeric types.
219+
template <typename Impl>
220+
template <typename T>
221+
size_t BlobSerializer<Impl>::WriteArithmetic(const T& data) {
222+
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
223+
return WriteArithmetic(&data, 1);
224+
}
225+
226+
// Layout of vectors:
227+
// [ 4/8 bytes ] count
228+
// [ ... ] contents (count * size of individual elements)
229+
template <typename Impl>
230+
template <typename T>
231+
size_t BlobSerializer<Impl>::WriteVector(const std::vector<T>& data) {
232+
if (is_debug) {
233+
std::string str = std::is_arithmetic_v<T> ? "" : ToStr(data);
234+
std::string name = GetName<T>();
235+
Debug("\nWriteVector<%s>() (%d-byte), count=%d: %s\n",
236+
name.c_str(),
237+
sizeof(T),
238+
data.size(),
239+
str.c_str());
240+
}
241+
242+
size_t written_total = WriteArithmetic<size_t>(data.size());
243+
if (data.size() == 0) {
244+
return written_total;
245+
}
246+
247+
if constexpr (std::is_arithmetic_v<T>) {
248+
written_total += WriteArithmeticVector<T>(data);
249+
} else {
250+
written_total += WriteNonArithmeticVector<T>(data);
251+
}
252+
253+
if (is_debug) {
254+
std::string name = GetName<T>();
255+
Debug("WriteVector<%s>() wrote %d bytes\n", name.c_str(), written_total);
256+
}
257+
258+
return written_total;
259+
}
260+
261+
// The layout of a written string:
262+
// [ 4/8 bytes ] length
263+
// [ |length| bytes ] contents
264+
template <typename Impl>
265+
size_t BlobSerializer<Impl>::WriteString(const std::string& data) {
266+
CHECK_GT(data.size(), 0); // No empty strings should be written.
267+
size_t written_total = WriteArithmetic<size_t>(data.size());
268+
if (is_debug) {
269+
std::string str = ToStr(data);
270+
Debug("WriteString(), length=%zu: \"%s\"\n", data.size(), data.c_str());
271+
}
272+
273+
// Write the null-terminated string.
274+
size_t length = data.size() + 1;
275+
sink.insert(sink.end(), data.c_str(), data.c_str() + length);
276+
written_total += length;
277+
278+
if (is_debug) {
279+
Debug("WriteString() wrote %zu bytes\n", written_total);
280+
}
281+
282+
return written_total;
283+
}
284+
285+
// Helper for writing an array of numeric types.
286+
template <typename Impl>
287+
template <typename T>
288+
size_t BlobSerializer<Impl>::WriteArithmetic(const T* data, size_t count) {
289+
static_assert(std::is_arithmetic_v<T>, "Arithmetic type");
290+
DCHECK_GT(count, 0); // Should not write contents for vectors of size 0.
291+
if (is_debug) {
292+
std::string str =
293+
"{ " + std::to_string(data[0]) + (count > 1 ? ", ... }" : " }");
294+
std::string name = GetName<T>();
295+
Debug("Write<%s>() (%zu-byte), count=%zu: %s",
296+
name.c_str(),
297+
sizeof(T),
298+
count,
299+
str.c_str());
300+
}
301+
302+
size_t size = sizeof(T) * count;
303+
const char* pos = reinterpret_cast<const char*>(data);
304+
sink.insert(sink.end(), pos, pos + size);
305+
306+
if (is_debug) {
307+
Debug(", wrote %zu bytes\n", size);
308+
}
309+
return size;
310+
}
311+
312+
// Helper for writing numeric vectors.
313+
template <typename Impl>
314+
template <typename Number>
315+
size_t BlobSerializer<Impl>::WriteArithmeticVector(
316+
const std::vector<Number>& data) {
317+
static_assert(std::is_arithmetic_v<Number>, "Arithmetic type");
318+
return WriteArithmetic(data.data(), data.size());
319+
}
320+
321+
// Helper for writing non-numeric vectors.
322+
template <typename Impl>
323+
template <typename T>
324+
size_t BlobSerializer<Impl>::WriteNonArithmeticVector(
325+
const std::vector<T>& data) {
326+
static_assert(!std::is_arithmetic_v<T>, "Arithmetic type");
327+
DCHECK_GT(data.size(),
328+
0); // Should not write contents for vectors of size 0.
329+
size_t written_total = 0;
330+
bool original_is_debug = is_debug;
331+
is_debug = original_is_debug && !std::is_same_v<T, std::string>;
332+
for (size_t i = 0; i < data.size(); ++i) {
333+
if (is_debug) {
334+
Debug("\n[%d] ", i);
335+
}
336+
written_total += WriteElement<T>(data[i]);
337+
}
338+
is_debug = original_is_debug;
339+
340+
return written_total;
341+
}
342+
343+
template <typename Impl>
344+
template <typename T>
345+
size_t BlobSerializer<Impl>::WriteElement(const T& data) {
346+
if constexpr (std::is_arithmetic_v<T>) {
347+
return WriteArithmetic<T>(data);
348+
} else if constexpr (std::is_same_v<T, std::string>) {
349+
return WriteString(data);
350+
} else {
351+
return impl()->template Write<T>(data);
352+
}
353+
}
354+
355+
} // namespace node
356+
357+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
358+
359+
#endif // SRC_BLOB_SERIALIZER_DESERIALIZER_INL_H_

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.