DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (8c5f9b08938e)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * This code was copied from xpcom/ds/nsTextFormatter r1.3
 *           Memory model and Frozen linkage changes only.
 *                           -- Prasad <prasad@medhas.org>
 */

#ifndef nsTextFormatter_h___
#define nsTextFormatter_h___

/*
 ** API for PR printf like routines. Supports the following formats
 **	%d - decimal
 **	%u - unsigned decimal
 **	%x - unsigned hex
 **	%X - unsigned uppercase hex
 **	%o - unsigned octal
 **	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
 **	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
 **	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
 **	%s - utf8 string
 **	%S - char16_t string
 **	%c - character
 **	%p - pointer (deals with machine dependent pointer size)
 **	%f - float
 **	%g - float
 */
#include <stdio.h>
#include <stdarg.h>
#include "nscore.h"
#include "nsString.h"
#include "mozilla/Span.h"
#include "mozilla/TypeTraits.h"

#ifdef XPCOM_GLUE
#  error \
      "nsTextFormatter is not available in the standalone glue due to NSPR dependencies."
#endif

class nsTextFormatter {
 public:
  /*
   * sprintf into a fixed size buffer. Guarantees that the buffer is null
   * terminated. Returns the length of the written output, NOT including the
   * null terminator, or (uint32_t)-1 if an error occurs.
   */
  template <typename... T>
  static uint32_t snprintf(char16_t* aOut, uint32_t aOutLen,
                           const char16_t* aFmt, T... aArgs) {
    BoxedValue values[] = {BoxedValue(aArgs)...};
    return vsnprintf(aOut, aOutLen, aFmt,
                     mozilla::MakeSpan(values, sizeof...(aArgs)));
  }

  /*
   * sprintf into an existing nsAString, overwriting any contents it already
   * has. Infallible.
   */
  template <typename... T>
  static void ssprintf(nsAString& aOut, const char16_t* aFmt, T... aArgs) {
    BoxedValue values[] = {BoxedValue(aArgs)...};
    vssprintf(aOut, aFmt, mozilla::MakeSpan(values, sizeof...(aArgs)));
  }

 private:
  enum ArgumentKind {
    INT,
    UINT,
    POINTER,
    DOUBLE,
    STRING,
    STRING16,
    INTPOINTER,
  };

  union ValueUnion {
    int64_t mInt;
    uint64_t mUInt;
    void const* mPtr;
    double mDouble;
    char const* mString;
    char16_t const* mString16;
    int* mIntPtr;
  };

  struct BoxedValue {
    ArgumentKind mKind;
    ValueUnion mValue;

    explicit BoxedValue(int aArg) : mKind(INT) { mValue.mInt = aArg; }

    explicit BoxedValue(unsigned int aArg) : mKind(UINT) {
      mValue.mUInt = aArg;
    }

    explicit BoxedValue(long aArg) : mKind(INT) { mValue.mInt = aArg; }

    explicit BoxedValue(unsigned long aArg) : mKind(UINT) {
      mValue.mUInt = aArg;
    }

    explicit BoxedValue(long long aArg) : mKind(INT) { mValue.mInt = aArg; }

    explicit BoxedValue(unsigned long long aArg) : mKind(UINT) {
      mValue.mUInt = aArg;
    }

    explicit BoxedValue(const void* aArg) : mKind(POINTER) {
      mValue.mPtr = aArg;
    }

    explicit BoxedValue(double aArg) : mKind(DOUBLE) { mValue.mDouble = aArg; }

    explicit BoxedValue(const char* aArg) : mKind(STRING) {
      mValue.mString = aArg;
    }

    explicit BoxedValue(const char16_t* aArg) : mKind(STRING16) {
      mValue.mString16 = aArg;
    }

#if defined(MOZ_USE_CHAR16_WRAPPER)
    explicit BoxedValue(const char16ptr_t aArg) : mKind(STRING16) {
      mValue.mString16 = aArg;
    }

#endif

    explicit BoxedValue(int* aArg) : mKind(INTPOINTER) {
      mValue.mIntPtr = aArg;
    }

    bool IntCompatible() const { return mKind == INT || mKind == UINT; }

    bool PointerCompatible() const {
      return mKind == POINTER || mKind == STRING || mKind == STRING16 ||
             mKind == INTPOINTER;
    }
  };

  struct SprintfStateStr;

  static int fill2(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen,
                   int aWidth, int aFlags);
  static int fill_n(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen,
                    int aWidth, int aPrec, int aFlags);
  static int cvt_ll(SprintfStateStr* aState, uint64_t aNum, int aWidth,
                    int aPrec, int aRadix, int aFlags, const char16_t* aHexStr);
  static int cvt_f(SprintfStateStr* aState, double aDouble, int aWidth,
                   int aPrec, const char16_t aType, int aFlags);
  static int cvt_S(SprintfStateStr* aState, const char16_t* aStr, int aWidth,
                   int aPrec, int aFlags);
  static int cvt_s(SprintfStateStr* aState, const char* aStr, int aWidth,
                   int aPrec, int aFlags);
  static int dosprintf(SprintfStateStr* aState, const char16_t* aFmt,
                       mozilla::Span<BoxedValue> aValues);
  static int StringStuff(SprintfStateStr* aState, const char16_t* aStr,
                         uint32_t aLen);
  static int LimitStuff(SprintfStateStr* aState, const char16_t* aStr,
                        uint32_t aLen);
  static uint32_t vsnprintf(char16_t* aOut, uint32_t aOutLen,
                            const char16_t* aFmt,
                            mozilla::Span<BoxedValue> aValues);
  static void vssprintf(nsAString& aOut, const char16_t* aFmt,
                        mozilla::Span<BoxedValue> aValues);
};

#endif /* nsTextFormatter_h___ */