Coverage Report

Created: 2018-09-25 14:53

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