1 /* -*- Mode: C++; tab-width: 8; 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/. */
6
7 #ifndef mozilla_ArenaAllocatorExtensions_h
8 #define mozilla_ArenaAllocatorExtensions_h
9
10 #include "mozilla/ArenaAllocator.h"
11 #include "mozilla/CheckedInt.h"
12 #include "nsAString.h"
13
14 /**
15 * Extensions to the ArenaAllocator class.
16 */
17 namespace mozilla {
18
19 namespace detail {
20
21 template <typename T, size_t ArenaSize, size_t Alignment>
22 T* DuplicateString(const T* aSrc, const CheckedInt<size_t>& aLen,
23 ArenaAllocator<ArenaSize, Alignment>& aArena);
24
25 } // namespace detail
26
27 /**
28 * Makes an arena allocated null-terminated copy of the source string. The
29 * source string must be null-terminated.
30 *
31 * @param aSrc String to copy.
32 * @param aArena The arena to allocate the string copy out of.
33 * @return An arena allocated null-terminated string.
34 */
35 template <typename T, size_t ArenaSize, size_t Alignment>
ArenaStrdup(const T * aStr,ArenaAllocator<ArenaSize,Alignment> & aArena)36 T* ArenaStrdup(const T* aStr, ArenaAllocator<ArenaSize, Alignment>& aArena) {
37 return detail::DuplicateString(aStr, nsCharTraits<T>::length(aStr), aArena);
38 }
39
40 /**
41 * Makes an arena allocated null-terminated copy of the source string.
42 *
43 * @param aSrc String to copy.
44 * @param aArena The arena to allocate the string copy out of.
45 * @return An arena allocated null-terminated string.
46 */
47 template <typename T, size_t ArenaSize, size_t Alignment>
ArenaStrdup(const detail::nsTStringRepr<T> & aStr,ArenaAllocator<ArenaSize,Alignment> & aArena)48 T* ArenaStrdup(const detail::nsTStringRepr<T>& aStr,
49 ArenaAllocator<ArenaSize, Alignment>& aArena) {
50 return detail::DuplicateString(aStr.BeginReading(), aStr.Length(), aArena);
51 }
52
53 /**
54 * Copies the source string and adds a null terminator. Source string does not
55 * have to be null terminated.
56 */
57 template <typename T, size_t ArenaSize, size_t Alignment>
DuplicateString(const T * aSrc,const CheckedInt<size_t> & aLen,ArenaAllocator<ArenaSize,Alignment> & aArena)58 T* detail::DuplicateString(const T* aSrc, const CheckedInt<size_t>& aLen,
59 ArenaAllocator<ArenaSize, Alignment>& aArena) {
60 const auto byteLen = (aLen + 1) * sizeof(T);
61 if (!byteLen.isValid()) {
62 return nullptr;
63 }
64
65 T* p = static_cast<T*>(aArena.Allocate(byteLen.value(), mozilla::fallible));
66 if (p) {
67 memcpy(p, aSrc, byteLen.value() - sizeof(T));
68 p[aLen.value()] = T(0);
69 }
70
71 return p;
72 }
73
74 } // namespace mozilla
75
76 #endif // mozilla_ArenaAllocatorExtensions_h
77