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"
10 //----------------------------------------------------------------------
13 nsSMILValue::nsSMILValue(const nsISMILType
* aType
)
14 : mType(nsSMILNullType::Singleton())
17 NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
21 InitAndCheckPostcondition(aType
);
24 nsSMILValue::nsSMILValue(const nsSMILValue
& aVal
)
25 : mType(nsSMILNullType::Singleton())
27 InitAndCheckPostcondition(aVal
.mType
);
28 mType
->Assign(*this, aVal
);
32 nsSMILValue::operator=(const nsSMILValue
& aVal
)
37 if (mType
!= aVal
.mType
) {
38 DestroyAndReinit(aVal
.mType
);
41 mType
->Assign(*this, aVal
);
47 nsSMILValue::operator==(const nsSMILValue
& aVal
) const
52 return mType
== aVal
.mType
&& mType
->IsEqual(*this, aVal
);
56 nsSMILValue::Swap(nsSMILValue
& aOther
)
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();
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
);
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
);
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
);
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 //----------------------------------------------------------------------
122 // Wrappers for nsISMILType::Init & ::Destroy that verify their postconditions
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");
132 nsSMILValue::DestroyAndCheckPostcondition()
134 mType
->Destroy(*this);
135 NS_ABORT_IF_FALSE(IsNull(), "Post-condition of Destroy failed. "
136 "nsSMILValue not null after destroying");
140 nsSMILValue::DestroyAndReinit(const nsISMILType
* aNewType
)
142 DestroyAndCheckPostcondition();
143 InitAndCheckPostcondition(aNewType
);