Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / xpcom / string / nsTextFormatter.h
blobf571043da2cef0e8ef614877ab0bb313fdaa9e10
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 /*
8 * This code was copied from xpcom/ds/nsTextFormatter r1.3
9 * Memory model and Frozen linkage changes only.
10 * -- Prasad <prasad@medhas.org>
13 #ifndef nsTextFormatter_h___
14 #define nsTextFormatter_h___
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
33 #include <stdio.h>
34 #include <stdarg.h>
35 #include "nscore.h"
36 #include "nsString.h"
37 #include "mozilla/Span.h"
39 #ifdef XPCOM_GLUE
40 # error \
41 "nsTextFormatter is not available in the standalone glue due to NSPR dependencies."
42 #endif
44 class nsTextFormatter {
45 public:
47 * sprintf into a fixed size buffer. Guarantees that the buffer is null
48 * terminated. Returns the length of the written output, NOT including the
49 * null terminator, or (uint32_t)-1 if an error occurs.
51 template <typename... T>
52 static uint32_t snprintf(char16_t* aOut, uint32_t aOutLen,
53 const char16_t* aFmt, T... aArgs) {
54 BoxedValue values[] = {BoxedValue(aArgs)...};
55 return vsnprintf(aOut, aOutLen, aFmt,
56 mozilla::Span(values, sizeof...(aArgs)));
60 * sprintf into an existing nsAString, overwriting any contents it already
61 * has. Infallible.
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::Span(values, sizeof...(aArgs)));
69 private:
70 enum ArgumentKind {
71 INT,
72 UINT,
73 POINTER,
74 DOUBLE,
75 STRING,
76 STRING16,
77 INTPOINTER,
80 union ValueUnion {
81 int64_t mInt;
82 uint64_t mUInt;
83 void const* mPtr;
84 double mDouble;
85 char const* mString;
86 char16_t const* mString16;
87 int* mIntPtr;
90 struct BoxedValue {
91 ArgumentKind mKind;
92 ValueUnion mValue;
94 explicit BoxedValue(int aArg) : mKind(INT) { mValue.mInt = aArg; }
96 explicit BoxedValue(unsigned int aArg) : mKind(UINT) {
97 mValue.mUInt = aArg;
100 explicit BoxedValue(long aArg) : mKind(INT) { mValue.mInt = aArg; }
102 explicit BoxedValue(unsigned long aArg) : mKind(UINT) {
103 mValue.mUInt = aArg;
106 explicit BoxedValue(long long aArg) : mKind(INT) { mValue.mInt = aArg; }
108 explicit BoxedValue(unsigned long long aArg) : mKind(UINT) {
109 mValue.mUInt = aArg;
112 explicit BoxedValue(const void* aArg) : mKind(POINTER) {
113 mValue.mPtr = aArg;
116 explicit BoxedValue(double aArg) : mKind(DOUBLE) { mValue.mDouble = aArg; }
118 explicit BoxedValue(const char* aArg) : mKind(STRING) {
119 mValue.mString = aArg;
122 explicit BoxedValue(const char16_t* aArg) : mKind(STRING16) {
123 mValue.mString16 = aArg;
126 #if defined(MOZ_USE_CHAR16_WRAPPER)
127 explicit BoxedValue(const char16ptr_t aArg) : mKind(STRING16) {
128 mValue.mString16 = aArg;
131 #endif
133 explicit BoxedValue(int* aArg) : mKind(INTPOINTER) {
134 mValue.mIntPtr = aArg;
137 bool IntCompatible() const { return mKind == INT || mKind == UINT; }
139 bool PointerCompatible() const {
140 return mKind == POINTER || mKind == STRING || mKind == STRING16 ||
141 mKind == INTPOINTER;
145 struct SprintfStateStr;
147 static int fill2(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen,
148 int aWidth, int aFlags);
149 static int fill_n(SprintfStateStr* aState, const char16_t* aSrc, int aSrcLen,
150 int aWidth, int aPrec, int aFlags);
151 static int cvt_ll(SprintfStateStr* aState, uint64_t aNum, int aWidth,
152 int aPrec, int aRadix, int aFlags, const char16_t* aHexStr);
153 static int cvt_f(SprintfStateStr* aState, double aDouble, int aWidth,
154 int aPrec, const char16_t aType, int aFlags);
155 static int cvt_S(SprintfStateStr* aState, const char16_t* aStr, int aWidth,
156 int aPrec, int aFlags);
157 static int cvt_s(SprintfStateStr* aState, const char* aStr, int aWidth,
158 int aPrec, int aFlags);
159 static int dosprintf(SprintfStateStr* aState, const char16_t* aFmt,
160 mozilla::Span<BoxedValue> aValues);
161 static int StringStuff(SprintfStateStr* aState, const char16_t* aStr,
162 uint32_t aLen);
163 static int LimitStuff(SprintfStateStr* aState, const char16_t* aStr,
164 uint32_t aLen);
165 static uint32_t vsnprintf(char16_t* aOut, uint32_t aOutLen,
166 const char16_t* aFmt,
167 mozilla::Span<BoxedValue> aValues);
168 static void vssprintf(nsAString& aOut, const char16_t* aFmt,
169 mozilla::Span<BoxedValue> aValues);
172 #endif /* nsTextFormatter_h___ */