content/base/src/nsMappedAttributes.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/src/nsMappedAttributes.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,263 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * A unique per-element set of attributes that is used as an
    1.11 + * nsIStyleRule; used to implement presentational attributes.
    1.12 + */
    1.13 +
    1.14 +#include "nsMappedAttributes.h"
    1.15 +#include "nsHTMLStyleSheet.h"
    1.16 +#include "nsRuleWalker.h"
    1.17 +#include "mozilla/HashFunctions.h"
    1.18 +#include "mozilla/MemoryReporting.h"
    1.19 +
    1.20 +using namespace mozilla;
    1.21 +
    1.22 +nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
    1.23 +                                       nsMapRuleToAttributesFunc aMapRuleFunc)
    1.24 +  : mAttrCount(0),
    1.25 +    mSheet(aSheet),
    1.26 +    mRuleMapper(aMapRuleFunc)
    1.27 +{
    1.28 +}
    1.29 +
    1.30 +nsMappedAttributes::nsMappedAttributes(const nsMappedAttributes& aCopy)
    1.31 +  : mAttrCount(aCopy.mAttrCount),
    1.32 +    mSheet(aCopy.mSheet),
    1.33 +    mRuleMapper(aCopy.mRuleMapper)
    1.34 +{
    1.35 +  NS_ASSERTION(mBufferSize >= aCopy.mAttrCount, "can't fit attributes");
    1.36 +
    1.37 +  uint32_t i;
    1.38 +  for (i = 0; i < mAttrCount; ++i) {
    1.39 +    new (&Attrs()[i]) InternalAttr(aCopy.Attrs()[i]);
    1.40 +  }
    1.41 +}
    1.42 +
    1.43 +nsMappedAttributes::~nsMappedAttributes()
    1.44 +{
    1.45 +  if (mSheet) {
    1.46 +    mSheet->DropMappedAttributes(this);
    1.47 +  }
    1.48 +
    1.49 +  uint32_t i;
    1.50 +  for (i = 0; i < mAttrCount; ++i) {
    1.51 +    Attrs()[i].~InternalAttr();
    1.52 +  }
    1.53 +}
    1.54 +
    1.55 +
    1.56 +nsMappedAttributes*
    1.57 +nsMappedAttributes::Clone(bool aWillAddAttr)
    1.58 +{
    1.59 +  uint32_t extra = aWillAddAttr ? 1 : 0;
    1.60 +
    1.61 +  // This will call the overridden operator new
    1.62 +  return new (mAttrCount + extra) nsMappedAttributes(*this);
    1.63 +}
    1.64 +
    1.65 +void* nsMappedAttributes::operator new(size_t aSize, uint32_t aAttrCount) CPP_THROW_NEW
    1.66 +{
    1.67 +  NS_ASSERTION(aAttrCount > 0, "zero-attribute nsMappedAttributes requested");
    1.68 +
    1.69 +  // aSize will include the mAttrs buffer so subtract that.
    1.70 +  void* newAttrs = ::operator new(aSize - sizeof(void*[1]) +
    1.71 +                                  aAttrCount * sizeof(InternalAttr));
    1.72 +
    1.73 +#ifdef DEBUG
    1.74 +  static_cast<nsMappedAttributes*>(newAttrs)->mBufferSize = aAttrCount;
    1.75 +#endif
    1.76 +
    1.77 +  return newAttrs;
    1.78 +}
    1.79 +
    1.80 +NS_IMPL_ISUPPORTS(nsMappedAttributes,
    1.81 +                  nsIStyleRule)
    1.82 +
    1.83 +void
    1.84 +nsMappedAttributes::SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue)
    1.85 +{
    1.86 +  NS_PRECONDITION(aAttrName, "null name");
    1.87 +
    1.88 +  uint32_t i;
    1.89 +  for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) {
    1.90 +    if (Attrs()[i].mName.Equals(aAttrName)) {
    1.91 +      Attrs()[i].mValue.Reset();
    1.92 +      Attrs()[i].mValue.SwapValueWith(aValue);
    1.93 +      return;
    1.94 +    }
    1.95 +  }
    1.96 +
    1.97 +  NS_ASSERTION(mBufferSize >= mAttrCount + 1, "can't fit attributes");
    1.98 +
    1.99 +  if (mAttrCount != i) {
   1.100 +    memmove(&Attrs()[i + 1], &Attrs()[i], (mAttrCount - i) * sizeof(InternalAttr));
   1.101 +  }
   1.102 +
   1.103 +  new (&Attrs()[i].mName) nsAttrName(aAttrName);
   1.104 +  new (&Attrs()[i].mValue) nsAttrValue();
   1.105 +  Attrs()[i].mValue.SwapValueWith(aValue);
   1.106 +  ++mAttrCount;
   1.107 +}
   1.108 +
   1.109 +const nsAttrValue*
   1.110 +nsMappedAttributes::GetAttr(nsIAtom* aAttrName) const
   1.111 +{
   1.112 +  NS_PRECONDITION(aAttrName, "null name");
   1.113 +
   1.114 +  for (uint32_t i = 0; i < mAttrCount; ++i) {
   1.115 +    if (Attrs()[i].mName.Equals(aAttrName)) {
   1.116 +      return &Attrs()[i].mValue;
   1.117 +    }
   1.118 +  }
   1.119 +
   1.120 +  return nullptr;
   1.121 +}
   1.122 +
   1.123 +const nsAttrValue*
   1.124 +nsMappedAttributes::GetAttr(const nsAString& aAttrName) const
   1.125 +{
   1.126 +  for (uint32_t i = 0; i < mAttrCount; ++i) {
   1.127 +    if (Attrs()[i].mName.Atom()->Equals(aAttrName)) {
   1.128 +      return &Attrs()[i].mValue;
   1.129 +    }
   1.130 +  }
   1.131 +
   1.132 +  return nullptr;
   1.133 +}
   1.134 +
   1.135 +bool
   1.136 +nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const
   1.137 +{
   1.138 +  if (this == aOther) {
   1.139 +    return true;
   1.140 +  }
   1.141 +
   1.142 +  if (mRuleMapper != aOther->mRuleMapper || mAttrCount != aOther->mAttrCount) {
   1.143 +    return false;
   1.144 +  }
   1.145 +
   1.146 +  uint32_t i;
   1.147 +  for (i = 0; i < mAttrCount; ++i) {
   1.148 +    if (!Attrs()[i].mName.Equals(aOther->Attrs()[i].mName) ||
   1.149 +        !Attrs()[i].mValue.Equals(aOther->Attrs()[i].mValue)) {
   1.150 +      return false;
   1.151 +    }
   1.152 +  }
   1.153 +
   1.154 +  return true;
   1.155 +}
   1.156 +
   1.157 +uint32_t
   1.158 +nsMappedAttributes::HashValue() const
   1.159 +{
   1.160 +  uint32_t hash = HashGeneric(mRuleMapper);
   1.161 +
   1.162 +  uint32_t i;
   1.163 +  for (i = 0; i < mAttrCount; ++i) {
   1.164 +    hash = AddToHash(hash,
   1.165 +                     Attrs()[i].mName.HashValue(),
   1.166 +                     Attrs()[i].mValue.HashValue());
   1.167 +  }
   1.168 +
   1.169 +  return hash;
   1.170 +}
   1.171 +
   1.172 +void
   1.173 +nsMappedAttributes::SetStyleSheet(nsHTMLStyleSheet* aSheet)
   1.174 +{
   1.175 +  if (mSheet) {
   1.176 +    mSheet->DropMappedAttributes(this);
   1.177 +  }
   1.178 +  mSheet = aSheet;  // not ref counted
   1.179 +}
   1.180 +
   1.181 +/* virtual */ void
   1.182 +nsMappedAttributes::MapRuleInfoInto(nsRuleData* aRuleData)
   1.183 +{
   1.184 +  if (mRuleMapper) {
   1.185 +    (*mRuleMapper)(this, aRuleData);
   1.186 +  }
   1.187 +}
   1.188 +
   1.189 +#ifdef DEBUG
   1.190 +/* virtual */ void
   1.191 +nsMappedAttributes::List(FILE* out, int32_t aIndent) const
   1.192 +{
   1.193 +  nsAutoString buffer;
   1.194 +  uint32_t i;
   1.195 +
   1.196 +  for (i = 0; i < mAttrCount; ++i) {
   1.197 +    int32_t indent;
   1.198 +    for (indent = aIndent; indent > 0; --indent)
   1.199 +      fputs("  ", out);
   1.200 +
   1.201 +    Attrs()[i].mName.GetQualifiedName(buffer);
   1.202 +    fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
   1.203 +
   1.204 +    Attrs()[i].mValue.ToString(buffer);
   1.205 +    fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
   1.206 +    fputs("\n", out);
   1.207 +  }
   1.208 +}
   1.209 +#endif
   1.210 +
   1.211 +void
   1.212 +nsMappedAttributes::RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue)
   1.213 +{
   1.214 +  Attrs()[aPos].mValue.SwapValueWith(aValue);
   1.215 +  Attrs()[aPos].~InternalAttr();
   1.216 +  memmove(&Attrs()[aPos], &Attrs()[aPos + 1],
   1.217 +          (mAttrCount - aPos - 1) * sizeof(InternalAttr));
   1.218 +  mAttrCount--;
   1.219 +}
   1.220 +
   1.221 +const nsAttrName*
   1.222 +nsMappedAttributes::GetExistingAttrNameFromQName(const nsAString& aName) const
   1.223 +{
   1.224 +  uint32_t i;
   1.225 +  for (i = 0; i < mAttrCount; ++i) {
   1.226 +    if (Attrs()[i].mName.IsAtom()) {
   1.227 +      if (Attrs()[i].mName.Atom()->Equals(aName)) {
   1.228 +        return &Attrs()[i].mName;
   1.229 +      }
   1.230 +    }
   1.231 +    else {
   1.232 +      if (Attrs()[i].mName.NodeInfo()->QualifiedNameEquals(aName)) {
   1.233 +        return &Attrs()[i].mName;
   1.234 +      }
   1.235 +    }
   1.236 +  }
   1.237 +
   1.238 +  return nullptr;
   1.239 +}
   1.240 +
   1.241 +int32_t
   1.242 +nsMappedAttributes::IndexOfAttr(nsIAtom* aLocalName) const
   1.243 +{
   1.244 +  uint32_t i;
   1.245 +  for (i = 0; i < mAttrCount; ++i) {
   1.246 +    if (Attrs()[i].mName.Equals(aLocalName)) {
   1.247 +      return i;
   1.248 +    }
   1.249 +  }
   1.250 +
   1.251 +  return -1;
   1.252 +}
   1.253 +
   1.254 +size_t
   1.255 +nsMappedAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
   1.256 +{
   1.257 +  NS_ASSERTION(mAttrCount == mBufferSize,
   1.258 +               "mBufferSize and mAttrCount are expected to be the same.");
   1.259 +
   1.260 +  size_t n = aMallocSizeOf(this);
   1.261 +  for (uint16_t i = 0; i < mAttrCount; ++i) {
   1.262 +    n += Attrs()[i].mValue.SizeOfExcludingThis(aMallocSizeOf);
   1.263 +  }
   1.264 +  return n;
   1.265 +}
   1.266 +

mercurial