tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Sprintf.h (2544B)


      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 /* Provides a safer sprintf for printing to fixed-size character arrays. */
      8 
      9 #ifndef mozilla_Sprintf_h_
     10 #define mozilla_Sprintf_h_
     11 
     12 #include <stdio.h>
     13 #include <stdarg.h>
     14 #include <algorithm>
     15 
     16 #include "mozilla/Assertions.h"
     17 #include "mozilla/Attributes.h"
     18 #include "mozilla/Printf.h"
     19 
     20 #ifdef __cplusplus
     21 
     22 #  ifndef SPRINTF_H_USES_VSNPRINTF
     23 namespace mozilla {
     24 namespace detail {
     25 
     26 struct MOZ_STACK_CLASS SprintfAppend final : public mozilla::PrintfTarget {
     27  explicit SprintfAppend(char* aBuf, size_t aBufLen)
     28      : mBuf(aBuf), mBufLen(aBufLen) {}
     29 
     30  bool append(const char* aStr, size_t aLen) override {
     31    if (aLen == 0) {
     32      return true;
     33    }
     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;
     40    }
     41    return true;
     42  }
     43 
     44 private:
     45  char* mBuf;
     46  size_t mBufLen;
     47 };
     48 
     49 }  // namespace detail
     50 }  // namespace mozilla
     51 #  endif  // SPRINTF_H_USES_VSNPRINTF
     52 
     53 MOZ_FORMAT_PRINTF(3, 0)
     54 [[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
     69 }
     70 
     71 MOZ_FORMAT_PRINTF(3, 4)
     72 [[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;
     79 }
     80 
     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);
     85 }
     86 
     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;
     95 }
     96 
     97 #endif
     98 #endif /* mozilla_Sprintf_h_ */