1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef ProfileBufferEntrySerializationGeckoExtensions_h
8 #define ProfileBufferEntrySerializationGeckoExtensions_h
10 #include "mozilla/ProfileBufferEntrySerialization.h"
12 #include "js/AllocPolicy.h"
13 #include "js/Utility.h"
18 // ----------------------------------------------------------------------------
21 // nsString or nsCString contents are serialized as the number of bytes (encoded
22 // as ULEB128) and all the characters in the string. The terminal '\0' is
24 // Make sure you write and read with the same character type!
26 // Usage: `nsCString s = ...; aEW.WriteObject(s);`
27 template <typename CHAR
>
28 struct ProfileBufferEntryWriter::Serializer
<nsTString
<CHAR
>> {
29 static Length
Bytes(const nsTString
<CHAR
>& aS
) {
30 const auto length
= aS
.Length();
31 return ProfileBufferEntryWriter::ULEB128Size(length
) +
32 static_cast<Length
>(length
* sizeof(CHAR
));
35 static void Write(ProfileBufferEntryWriter
& aEW
, const nsTString
<CHAR
>& aS
) {
36 const auto length
= aS
.Length();
37 aEW
.WriteULEB128(length
);
38 // Copy the bytes from the string's buffer.
39 aEW
.WriteBytes(aS
.Data(), length
* sizeof(CHAR
));
43 template <typename CHAR
>
44 struct ProfileBufferEntryReader::Deserializer
<nsTString
<CHAR
>> {
45 static void ReadInto(ProfileBufferEntryReader
& aER
, nsTString
<CHAR
>& aS
) {
49 static nsTString
<CHAR
> Read(ProfileBufferEntryReader
& aER
) {
50 const Length length
= aER
.ReadULEB128
<Length
>();
52 // BulkWrite is the most efficient way to copy bytes into the target string.
53 auto writerOrErr
= s
.BulkWrite(length
, 0, true);
54 MOZ_RELEASE_ASSERT(!writerOrErr
.isErr());
56 auto writer
= writerOrErr
.unwrap();
58 aER
.ReadBytes(writer
.Elements(), length
* sizeof(CHAR
));
59 writer
.Finish(length
, true);
64 // ----------------------------------------------------------------------------
67 // nsAuto[C]String contents are serialized as the number of bytes (encoded as
68 // ULEB128) and all the characters in the string. The terminal '\0' is omitted.
69 // Make sure you write and read with the same character type!
71 // Usage: `nsAutoCString s = ...; aEW.WriteObject(s);`
72 template <typename CHAR
, size_t N
>
73 struct ProfileBufferEntryWriter::Serializer
<nsTAutoStringN
<CHAR
, N
>> {
74 static Length
Bytes(const nsTAutoStringN
<CHAR
, N
>& aS
) {
75 const auto length
= aS
.Length();
76 return ProfileBufferEntryWriter::ULEB128Size(length
) +
77 static_cast<Length
>(length
* sizeof(CHAR
));
80 static void Write(ProfileBufferEntryWriter
& aEW
,
81 const nsTAutoStringN
<CHAR
, N
>& aS
) {
82 const auto length
= aS
.Length();
83 aEW
.WriteULEB128(length
);
84 // Copy the bytes from the string's buffer.
85 aEW
.WriteBytes(aS
.BeginReading(), length
* sizeof(CHAR
));
89 template <typename CHAR
, size_t N
>
90 struct ProfileBufferEntryReader::Deserializer
<nsTAutoStringN
<CHAR
, N
>> {
91 static void ReadInto(ProfileBufferEntryReader
& aER
,
92 nsTAutoStringN
<CHAR
, N
>& aS
) {
96 static nsTAutoStringN
<CHAR
, N
> Read(ProfileBufferEntryReader
& aER
) {
97 const auto length
= aER
.ReadULEB128
<Length
>();
98 nsTAutoStringN
<CHAR
, N
> s
;
99 // BulkWrite is the most efficient way to copy bytes into the target string.
100 auto writerOrErr
= s
.BulkWrite(length
, 0, true);
101 MOZ_RELEASE_ASSERT(!writerOrErr
.isErr());
103 auto writer
= writerOrErr
.unwrap();
104 aER
.ReadBytes(writer
.Elements(), length
* sizeof(CHAR
));
105 writer
.Finish(length
, true);
110 // ----------------------------------------------------------------------------
113 // JS::UniqueChars contents are serialized as the number of bytes (encoded as
114 // ULEB128) and all the characters in the string. The terminal '\0' is omitted.
115 // Note: A nullptr pointer will be serialized like an empty string, so when
116 // deserializing it will result in an allocated buffer only containing a
117 // single null terminator.
119 // Usage: `JS::UniqueChars s = ...; aEW.WriteObject(s);`
121 struct ProfileBufferEntryWriter::Serializer
<JS::UniqueChars
> {
122 static Length
Bytes(const JS::UniqueChars
& aS
) {
124 return ProfileBufferEntryWriter::ULEB128Size
<Length
>(0);
126 const auto len
= static_cast<Length
>(strlen(aS
.get()));
127 return ProfileBufferEntryWriter::ULEB128Size(len
) + len
;
130 static void Write(ProfileBufferEntryWriter
& aEW
, const JS::UniqueChars
& aS
) {
132 aEW
.WriteULEB128
<Length
>(0);
135 const auto len
= static_cast<Length
>(strlen(aS
.get()));
136 aEW
.WriteULEB128(len
);
137 aEW
.WriteBytes(aS
.get(), len
);
142 struct ProfileBufferEntryReader::Deserializer
<JS::UniqueChars
> {
143 static void ReadInto(ProfileBufferEntryReader
& aER
, JS::UniqueChars
& aS
) {
147 static JS::UniqueChars
Read(ProfileBufferEntryReader
& aER
) {
148 const auto len
= aER
.ReadULEB128
<Length
>();
149 // Use the same allocation policy as JS_smprintf.
151 static_cast<char*>(js::SystemAllocPolicy
{}.pod_malloc
<char>(len
+ 1));
152 aER
.ReadBytes(buffer
, len
);
154 return JS::UniqueChars(buffer
);
158 } // namespace mozilla
160 #endif // ProfileBufferEntrySerializationGeckoExtensions_h