Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/string/nsTextFormatter.h
Line
Count
Source (jump to first uncovered line)
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
/*
8
 * This code was copied from xpcom/ds/nsTextFormatter r1.3
9
 *           Memory model and Frozen linkage changes only.
10
 *                           -- Prasad <prasad@medhas.org>
11
 */
12
13
#ifndef nsTextFormatter_h___
14
#define nsTextFormatter_h___
15
16
/*
17
 ** API for PR printf like routines. Supports the following formats
18
 ** %d - decimal
19
 ** %u - unsigned decimal
20
 ** %x - unsigned hex
21
 ** %X - unsigned uppercase hex
22
 ** %o - unsigned octal
23
 ** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
24
 ** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
25
 ** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
26
 ** %s - utf8 string
27
 ** %S - char16_t string
28
 ** %c - character
29
 ** %p - pointer (deals with machine dependent pointer size)
30
 ** %f - float
31
 ** %g - float
32
 */
33
#include <stdio.h>
34
#include <stdarg.h>
35
#include "nscore.h"
36
#include "nsString.h"
37
#include "mozilla/Span.h"
38
#include "mozilla/TypeTraits.h"
39
40
#ifdef XPCOM_GLUE
41
#error "nsTextFormatter is not available in the standalone glue due to NSPR dependencies."
42
#endif
43
44
class nsTextFormatter
45
{
46
public:
47
48
  /*
49
   * sprintf into a fixed size buffer. Guarantees that the buffer is null
50
   * terminated. Returns the length of the written output, NOT including the
51
   * null terminator, or (uint32_t)-1 if an error occurs.
52
   */
53
  template<typename ...T>
54
  static uint32_t snprintf(char16_t* aOut, uint32_t aOutLen, const char16_t* aFmt, T... aArgs) {
55
    BoxedValue values[] = { BoxedValue(aArgs)... };
56
    return vsnprintf(aOut, aOutLen, aFmt, mozilla::MakeSpan(values, sizeof...(aArgs)));
57
  }
58
59
  /*
60
   * sprintf into an existing nsAString, overwriting any contents it already
61
   * has. Infallible.
62
   */
63
  template<typename ...T>
64
  static void ssprintf(nsAString& aOut, const char16_t* aFmt, T... aArgs) {
65
    BoxedValue values[] = { BoxedValue(aArgs)... };
66
    vssprintf(aOut, aFmt, mozilla::MakeSpan(values, sizeof...(aArgs)));
67
  }
68
69
private:
70
71
  enum ArgumentKind {
72
    INT,
73
    UINT,
74
    POINTER,
75
    DOUBLE,
76
    STRING,
77
    STRING16,
78
    INTPOINTER,
79
  };
80
81
  union ValueUnion {
82
    int64_t mInt;
83
    uint64_t mUInt;
84
    void const* mPtr;
85
    double mDouble;
86
    char const* mString;
87
    char16_t const* mString16;
88
    int* mIntPtr;
89
  };
90
91
  struct BoxedValue {
92
    ArgumentKind mKind;
93
    ValueUnion mValue;
94
95
    explicit BoxedValue(int aArg)
96
      : mKind(INT)
97
    {
98
      mValue.mInt = aArg;
99
    }
100
101
    explicit BoxedValue(unsigned int aArg)
102
      : mKind(UINT)
103
    {
104
      mValue.mUInt = aArg;
105
    }
106
107
    explicit BoxedValue(long aArg)
108
      : mKind(INT)
109
    {
110
      mValue.mInt = aArg;
111
    }
112
113
    explicit BoxedValue(unsigned long aArg)
114
      : mKind(UINT)
115
    {
116
      mValue.mUInt = aArg;
117
    }
118
119
    explicit BoxedValue(long long aArg)
120
      : mKind(INT)
121
0
    {
122
0
      mValue.mInt = aArg;
123
0
    }
124
125
    explicit BoxedValue(unsigned long long aArg)
126
      : mKind(UINT)
127
0
    {
128
0
      mValue.mUInt = aArg;
129
0
    }
130
131
    explicit BoxedValue(const void* aArg)
132
      : mKind(POINTER)
133
0
    {
134
0
      mValue.mPtr = aArg;
135
0
    }
136
137
    explicit BoxedValue(double aArg)
138
      : mKind(DOUBLE)
139
    {
140
      mValue.mDouble = aArg;
141
    }
142
143
    explicit BoxedValue(const char* aArg)
144
      : mKind(STRING)
145
    {
146
      mValue.mString = aArg;
147
    }
148
149
    explicit BoxedValue(const char16_t* aArg)
150
      : mKind(STRING16)
151
3
    {
152
3
      mValue.mString16 = aArg;
153
3
    }
154
155
#if defined(MOZ_USE_CHAR16_WRAPPER)
156
    explicit BoxedValue(const char16ptr_t aArg)
157
      : mKind(STRING16)
158
    {
159
      mValue.mString16 = aArg;
160
    }
161
162
#endif
163
164
    explicit BoxedValue(int* aArg)
165
      : mKind(INTPOINTER)
166
0
    {
167
0
      mValue.mIntPtr = aArg;
168
0
    }
169
170
0
    bool IntCompatible() const {
171
0
      return mKind == INT || mKind == UINT;
172
0
    }
173
174
0
    bool PointerCompatible() const {
175
0
      return mKind == POINTER || mKind == STRING || mKind == STRING16 || mKind == INTPOINTER;
176
0
    }
177
  };
178
179
  struct SprintfStateStr;
180
181
  static int fill2(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen, int aWidth,
182
                   int aFlags);
183
  static int fill_n(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen, int aWidth,
184
                    int aPrec, int aFlags);
185
  static int cvt_ll(SprintfStateStr* aState, uint64_t aNum, int aWidth, int aPrec, int aRadix,
186
                    int aFlags, const char16_t* aHexStr);
187
  static int cvt_f(SprintfStateStr* aState, double aDouble, int aWidth, int aPrec,
188
                   const char16_t aType, int aFlags);
189
  static int cvt_S(SprintfStateStr* aState, const char16_t* aStr, int aWidth, int aPrec,
190
                   int aFlags);
191
  static int cvt_s(SprintfStateStr* aState, const char* aStr, int aWidth, int aPrec,
192
                   int aFlags);
193
  static int dosprintf(SprintfStateStr* aState, const char16_t* aFmt,
194
                       mozilla::Span<BoxedValue> aValues);
195
  static int StringStuff(SprintfStateStr* aState, const char16_t* aStr, uint32_t aLen);
196
  static int LimitStuff(SprintfStateStr* aState, const char16_t* aStr, uint32_t aLen);
197
  static uint32_t vsnprintf(char16_t* aOut, uint32_t aOutLen, const char16_t* aFmt,
198
                            mozilla::Span<BoxedValue> aValues);
199
  static void vssprintf(nsAString& aOut, const char16_t* aFmt,
200
                        mozilla::Span<BoxedValue> aValues);
201
};
202
203
#endif /* nsTextFormatter_h___ */