dom/smil/nsSMILValue.cpp

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:fac31c40e4ce
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/. */
5
6 #include "nsSMILValue.h"
7 #include "nsDebug.h"
8 #include <string.h>
9
10 //----------------------------------------------------------------------
11 // Public methods
12
13 nsSMILValue::nsSMILValue(const nsISMILType* aType)
14 : mType(nsSMILNullType::Singleton())
15 {
16 if (!aType) {
17 NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
18 return;
19 }
20
21 InitAndCheckPostcondition(aType);
22 }
23
24 nsSMILValue::nsSMILValue(const nsSMILValue& aVal)
25 : mType(nsSMILNullType::Singleton())
26 {
27 InitAndCheckPostcondition(aVal.mType);
28 mType->Assign(*this, aVal);
29 }
30
31 const nsSMILValue&
32 nsSMILValue::operator=(const nsSMILValue& aVal)
33 {
34 if (&aVal == this)
35 return *this;
36
37 if (mType != aVal.mType) {
38 DestroyAndReinit(aVal.mType);
39 }
40
41 mType->Assign(*this, aVal);
42
43 return *this;
44 }
45
46 bool
47 nsSMILValue::operator==(const nsSMILValue& aVal) const
48 {
49 if (&aVal == this)
50 return true;
51
52 return mType == aVal.mType && mType->IsEqual(*this, aVal);
53 }
54
55 void
56 nsSMILValue::Swap(nsSMILValue& aOther)
57 {
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
62
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();
66 }
67
68 nsresult
69 nsSMILValue::Add(const nsSMILValue& aValueToAdd, uint32_t aCount)
70 {
71 if (aValueToAdd.mType != mType) {
72 NS_ERROR("Trying to add incompatible types");
73 return NS_ERROR_FAILURE;
74 }
75
76 return mType->Add(*this, aValueToAdd, aCount);
77 }
78
79 nsresult
80 nsSMILValue::SandwichAdd(const nsSMILValue& aValueToAdd)
81 {
82 if (aValueToAdd.mType != mType) {
83 NS_ERROR("Trying to add incompatible types");
84 return NS_ERROR_FAILURE;
85 }
86
87 return mType->SandwichAdd(*this, aValueToAdd);
88 }
89
90 nsresult
91 nsSMILValue::ComputeDistance(const nsSMILValue& aTo, double& aDistance) const
92 {
93 if (aTo.mType != mType) {
94 NS_ERROR("Trying to calculate distance between incompatible types");
95 return NS_ERROR_FAILURE;
96 }
97
98 return mType->ComputeDistance(*this, aTo, aDistance);
99 }
100
101 nsresult
102 nsSMILValue::Interpolate(const nsSMILValue& aEndVal,
103 double aUnitDistance,
104 nsSMILValue& aResult) const
105 {
106 if (aEndVal.mType != mType) {
107 NS_ERROR("Trying to interpolate between incompatible types");
108 return NS_ERROR_FAILURE;
109 }
110
111 if (aResult.mType != mType) {
112 // Outparam has wrong type
113 aResult.DestroyAndReinit(mType);
114 }
115
116 return mType->Interpolate(*this, aEndVal, aUnitDistance, aResult);
117 }
118
119 //----------------------------------------------------------------------
120 // Helper methods
121
122 // Wrappers for nsISMILType::Init & ::Destroy that verify their postconditions
123 void
124 nsSMILValue::InitAndCheckPostcondition(const nsISMILType* aNewType)
125 {
126 aNewType->Init(*this);
127 NS_ABORT_IF_FALSE(mType == aNewType,
128 "Post-condition of Init failed. nsSMILValue is invalid");
129 }
130
131 void
132 nsSMILValue::DestroyAndCheckPostcondition()
133 {
134 mType->Destroy(*this);
135 NS_ABORT_IF_FALSE(IsNull(), "Post-condition of Destroy failed. "
136 "nsSMILValue not null after destroying");
137 }
138
139 void
140 nsSMILValue::DestroyAndReinit(const nsISMILType* aNewType)
141 {
142 DestroyAndCheckPostcondition();
143 InitAndCheckPostcondition(aNewType);
144 }

mercurial