tor-browser

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

SMILValue.cpp (4203B)


      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 #include "SMILValue.h"
      8 
      9 #include <string.h>
     10 
     11 #include "nsDebug.h"
     12 
     13 namespace mozilla {
     14 
     15 //----------------------------------------------------------------------
     16 // Public methods
     17 
     18 SMILValue::SMILValue(const SMILType* aType) : mType(SMILNullType::Singleton()) {
     19  mU.mBool = false;
     20  if (!aType) {
     21    NS_ERROR("Trying to construct SMILValue with null mType pointer");
     22    return;
     23  }
     24 
     25  InitAndCheckPostcondition(aType);
     26 }
     27 
     28 SMILValue::SMILValue(const SMILValue& aVal) : mType(SMILNullType::Singleton()) {
     29  InitAndCheckPostcondition(aVal.mType);
     30  mType->Assign(*this, aVal);
     31 }
     32 
     33 const SMILValue& SMILValue::operator=(const SMILValue& aVal) {
     34  if (&aVal == this) return *this;
     35 
     36  if (mType != aVal.mType) {
     37    DestroyAndReinit(aVal.mType);
     38  }
     39 
     40  mType->Assign(*this, aVal);
     41 
     42  return *this;
     43 }
     44 
     45 // Move constructor / reassignment operator:
     46 SMILValue::SMILValue(SMILValue&& aVal) noexcept
     47    : mU(aVal.mU),  // Copying union is only OK because we clear aVal.mType
     48                    // below.
     49      mType(aVal.mType) {
     50  // Leave aVal with a null type, so that it's safely destructible (and won't
     51  // mess with anything referenced by its union, which we've copied).
     52  aVal.mType = SMILNullType::Singleton();
     53 }
     54 
     55 SMILValue& SMILValue::operator=(SMILValue&& aVal) noexcept {
     56  if (!IsNull()) {
     57    // Clean up any data we're currently tracking.
     58    DestroyAndCheckPostcondition();
     59  }
     60 
     61  // Copy the union (which could include a pointer to external memory) & mType:
     62  mU = aVal.mU;
     63  mType = aVal.mType;
     64 
     65  // Leave aVal with a null type, so that it's safely destructible (and won't
     66  // mess with anything referenced by its union, which we've now copied).
     67  aVal.mType = SMILNullType::Singleton();
     68 
     69  return *this;
     70 }
     71 
     72 bool SMILValue::operator==(const SMILValue& aVal) const {
     73  if (&aVal == this) return true;
     74 
     75  return mType == aVal.mType && mType->IsEqual(*this, aVal);
     76 }
     77 
     78 nsresult SMILValue::Add(const SMILValue& aValueToAdd, uint32_t aCount) {
     79  if (aValueToAdd.mType != mType) {
     80    NS_ERROR("Trying to add incompatible types");
     81    return NS_ERROR_FAILURE;
     82  }
     83 
     84  return mType->Add(*this, aValueToAdd, aCount);
     85 }
     86 
     87 nsresult SMILValue::SandwichAdd(const SMILValue& aValueToAdd) {
     88  if (aValueToAdd.mType != mType) {
     89    NS_ERROR("Trying to add incompatible types");
     90    return NS_ERROR_FAILURE;
     91  }
     92 
     93  return mType->SandwichAdd(*this, aValueToAdd);
     94 }
     95 
     96 nsresult SMILValue::ComputeDistance(const SMILValue& aTo,
     97                                    double& aDistance) const {
     98  if (aTo.mType != mType) {
     99    NS_ERROR("Trying to calculate distance between incompatible types");
    100    return NS_ERROR_FAILURE;
    101  }
    102 
    103  return mType->ComputeDistance(*this, aTo, aDistance);
    104 }
    105 
    106 nsresult SMILValue::Interpolate(const SMILValue& aEndVal, double aUnitDistance,
    107                                SMILValue& aResult) const {
    108  if (aEndVal.mType != mType) {
    109    NS_ERROR("Trying to interpolate between incompatible types");
    110    return NS_ERROR_FAILURE;
    111  }
    112 
    113  if (aResult.mType != mType) {
    114    // Outparam has wrong type
    115    aResult.DestroyAndReinit(mType);
    116  }
    117 
    118  return mType->Interpolate(*this, aEndVal, aUnitDistance, aResult);
    119 }
    120 
    121 //----------------------------------------------------------------------
    122 // Helper methods
    123 
    124 // Wrappers for SMILType::InitValue & ::DestroyValue that verify their
    125 // postconditions.
    126 void SMILValue::InitAndCheckPostcondition(const SMILType* aNewType) {
    127  aNewType->InitValue(*this);
    128  MOZ_ASSERT(mType == aNewType,
    129             "Post-condition of Init failed. SMILValue is invalid");
    130 }
    131 
    132 void SMILValue::DestroyAndCheckPostcondition() {
    133  mType->DestroyValue(*this);
    134  MOZ_ASSERT(IsNull(),
    135             "Post-condition of Destroy failed. "
    136             "SMILValue not null after destroying");
    137 }
    138 
    139 void SMILValue::DestroyAndReinit(const SMILType* aNewType) {
    140  DestroyAndCheckPostcondition();
    141  InitAndCheckPostcondition(aNewType);
    142 }
    143 
    144 }  // namespace mozilla