Bug 1842999 - Part 25: Support testing elements are present in resizable typed arrays...
[gecko.git] / mozglue / misc / Sprintf.h
blob4b459de82d7e653595824531e4cfdbcd6ac02933
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/. */
7 /* Provides a safer sprintf for printing to fixed-size character arrays. */
9 #ifndef mozilla_Sprintf_h_
10 #define mozilla_Sprintf_h_
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include <algorithm>
16 #include "mozilla/Assertions.h"
17 #include "mozilla/Attributes.h"
18 #include "mozilla/Printf.h"
20 #ifdef __cplusplus
22 # ifndef SPRINTF_H_USES_VSNPRINTF
23 namespace mozilla {
24 namespace detail {
26 struct MOZ_STACK_CLASS SprintfAppend final : public mozilla::PrintfTarget {
27 explicit SprintfAppend(char* aBuf, size_t aBufLen)
28 : mBuf(aBuf), mBufLen(aBufLen) {}
30 bool append(const char* aStr, size_t aLen) override {
31 if (aLen == 0) {
32 return true;
34 // Don't copy more than what's left to use.
35 size_t copy = std::min(mBufLen, aLen);
36 if (copy > 0) {
37 memcpy(mBuf, aStr, copy);
38 mBuf += copy;
39 mBufLen -= copy;
41 return true;
44 private:
45 char* mBuf;
46 size_t mBufLen;
49 } // namespace detail
50 } // namespace mozilla
51 # endif // SPRINTF_H_USES_VSNPRINTF
53 MOZ_FORMAT_PRINTF(3, 0)
54 MOZ_MAYBE_UNUSED
55 static int VsprintfBuf(char* buffer, size_t bufsize, const char* format,
56 va_list args) {
57 MOZ_ASSERT(format != buffer);
58 # ifdef SPRINTF_H_USES_VSNPRINTF
59 int result = vsnprintf(buffer, bufsize, format, args);
60 buffer[bufsize - 1] = '\0';
61 return result;
62 # else
63 mozilla::detail::SprintfAppend ss(buffer, bufsize);
64 ss.vprint(format, args);
65 size_t len = ss.emitted();
66 buffer[std::min(len, bufsize - 1)] = '\0';
67 return len;
68 # endif
71 MOZ_FORMAT_PRINTF(3, 4)
72 MOZ_MAYBE_UNUSED
73 static int SprintfBuf(char* buffer, size_t bufsize, const char* format, ...) {
74 va_list args;
75 va_start(args, format);
76 int result = VsprintfBuf(buffer, bufsize, format, args);
77 va_end(args);
78 return result;
81 template <size_t N>
82 MOZ_FORMAT_PRINTF(2, 0)
83 int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args) {
84 return VsprintfBuf(buffer, N, format, args);
87 template <size_t N>
88 MOZ_FORMAT_PRINTF(2, 3)
89 int SprintfLiteral(char (&buffer)[N], const char* format, ...) {
90 va_list args;
91 va_start(args, format);
92 int result = VsprintfLiteral(buffer, format, args);
93 va_end(args);
94 return result;
97 #endif
98 #endif /* mozilla_Sprintf_h_ */