xpcom/string/nsTextFormatter.h
author Chris Pearce <cpearce@mozilla.com>
Mon, 12 Mar 2018 13:05:04 +1300
changeset 407747 09d7852a968dbc0d25ba6e299b78f53ee5ba8ca9
parent 395657 f6ef04a022f3c5aa861e438298302a989308369e
child 448947 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1434804 - Pause autoplayed media if they become audible. r=kamidphish Our autoplay blocking is trivial to defeat; just mute or volume=0 a video, play(), and then unmute, and then you're playing audibly. So this patch makes us pause() media that become audible atfter playback has started. MozReview-Commit-ID: 2RAtbohMGJO

/* -*- 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___ */