Bumping manifests a=b2g-bump
[gecko.git] / dom / smil / nsSMILValue.cpp
blob319fa4e2eed27cbe6a356291e21b91cd2c8003b0
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsSMILValue.h"
7 #include "nsDebug.h"
8 #include <string.h>
10 //----------------------------------------------------------------------
11 // Public methods
13 nsSMILValue::nsSMILValue(const nsISMILType* aType)
14 : mType(nsSMILNullType::Singleton())
16 if (!aType) {
17 NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
18 return;
21 InitAndCheckPostcondition(aType);
24 nsSMILValue::nsSMILValue(const nsSMILValue& aVal)
25 : mType(nsSMILNullType::Singleton())
27 InitAndCheckPostcondition(aVal.mType);
28 mType->Assign(*this, aVal);
31 const nsSMILValue&
32 nsSMILValue::operator=(const nsSMILValue& aVal)
34 if (&aVal == this)
35 return *this;
37 if (mType != aVal.mType) {
38 DestroyAndReinit(aVal.mType);
41 mType->Assign(*this, aVal);
43 return *this;
46 bool
47 nsSMILValue::operator==(const nsSMILValue& aVal) const
49 if (&aVal == this)
50 return true;
52 return mType == aVal.mType && mType->IsEqual(*this, aVal);
55 void
56 nsSMILValue::Swap(nsSMILValue& aOther)
58 nsSMILValue tmp;
59 memcpy(&tmp, &aOther, sizeof(nsSMILValue)); // tmp = aOther
60 memcpy(&aOther, this, sizeof(nsSMILValue)); // aOther = this
61 memcpy(this, &tmp, sizeof(nsSMILValue)); // this = tmp
63 // |tmp| is about to die -- we need to clear its mType, so that its
64 // destructor doesn't muck with the data we just transferred out of it.
65 tmp.mType = nsSMILNullType::Singleton();
68 nsresult
69 nsSMILValue::Add(const nsSMILValue& aValueToAdd, uint32_t aCount)
71 if (aValueToAdd.mType != mType) {
72 NS_ERROR("Trying to add incompatible types");
73 return NS_ERROR_FAILURE;
76 return mType->Add(*this, aValueToAdd, aCount);
79 nsresult
80 nsSMILValue::SandwichAdd(const nsSMILValue& aValueToAdd)
82 if (aValueToAdd.mType != mType) {
83 NS_ERROR("Trying to add incompatible types");
84 return NS_ERROR_FAILURE;
87 return mType->SandwichAdd(*this, aValueToAdd);
90 nsresult
91 nsSMILValue::ComputeDistance(const nsSMILValue& aTo, double& aDistance) const
93 if (aTo.mType != mType) {
94 NS_ERROR("Trying to calculate distance between incompatible types");
95 return NS_ERROR_FAILURE;
98 return mType->ComputeDistance(*this, aTo, aDistance);
101 nsresult
102 nsSMILValue::Interpolate(const nsSMILValue& aEndVal,
103 double aUnitDistance,
104 nsSMILValue& aResult) const
106 if (aEndVal.mType != mType) {
107 NS_ERROR("Trying to interpolate between incompatible types");
108 return NS_ERROR_FAILURE;
111 if (aResult.mType != mType) {
112 // Outparam has wrong type
113 aResult.DestroyAndReinit(mType);
116 return mType->Interpolate(*this, aEndVal, aUnitDistance, aResult);
119 //----------------------------------------------------------------------
120 // Helper methods
122 // Wrappers for nsISMILType::Init & ::Destroy that verify their postconditions
123 void
124 nsSMILValue::InitAndCheckPostcondition(const nsISMILType* aNewType)
126 aNewType->Init(*this);
127 NS_ABORT_IF_FALSE(mType == aNewType,
128 "Post-condition of Init failed. nsSMILValue is invalid");
131 void
132 nsSMILValue::DestroyAndCheckPostcondition()
134 mType->Destroy(*this);
135 NS_ABORT_IF_FALSE(IsNull(), "Post-condition of Destroy failed. "
136 "nsSMILValue not null after destroying");
139 void
140 nsSMILValue::DestroyAndReinit(const nsISMILType* aNewType)
142 DestroyAndCheckPostcondition();
143 InitAndCheckPostcondition(aNewType);