Bug 911451: Refactor nsStringBuffer-to-nsString code into a helper-method, and invoke it instead of nsCheapString in one other place. r=dbaron
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 10 Sep 2013 10:03:28 -0700
changeset 159353 a405e2e0bef8d0edb12d22c15289aaaab3ad0579
parent 159352 5f52bbf813be121c857176759d8a5299ba664829
child 159354 db3e565b758635cc85b82069839b36afe444d05b
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs911451
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 911451: Refactor nsStringBuffer-to-nsString code into a helper-method, and invoke it instead of nsCheapString in one other place. r=dbaron
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/smil/nsSMILMappedAttribute.cpp
content/svg/content/src/nsSVGElement.cpp
layout/reftests/svg/smil/mapped-attr-long-url-2.svg
layout/reftests/svg/smil/reftest.list
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -84,16 +84,17 @@ class nsIWidget;
 class nsIWordBreaker;
 class nsIXPConnect;
 class nsIXPConnectJSObjectHolder;
 class nsKeyEvent;
 class nsNodeInfoManager;
 class nsPIDOMWindow;
 class nsPresContext;
 class nsScriptObjectTracer;
+class nsStringBuffer;
 class nsStringHashKey;
 class nsTextFragment;
 class nsViewportInfo;
 class nsWrapperCache;
 
 struct JSPropertyDescriptor;
 struct JSRuntime;
 struct nsIntMargin;
@@ -1681,16 +1682,24 @@ public:
   static void RemoveNewlines(nsString &aString);
 
   /**
    * Convert Windows and Mac platform linebreaks to \n.
    * @param aString the string to convert the newlines inside [in/out]
    */
   static void PlatformToDOMLineBreaks(nsString &aString);
 
+  /**
+   * Populates aResultString with the contents of the string-buffer aBuf, up
+   * to aBuf's null-terminator.  aBuf must not be null. Ownership of the string
+   * is not transferred.
+   */
+  static void PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
+                                             nsAString& aResultString);
+
   static bool IsHandlingKeyBoardEvent()
   {
     return sIsHandlingKeyBoardEvent;
   }
 
   static void SetIsHandlingKeyBoardEvent(bool aHandling)
   {
     sIsHandlingKeyBoardEvent = aHandling;
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5917,16 +5917,37 @@ nsContentUtils::PlatformToDOMLineBreaks(
                              NS_LITERAL_STRING("\n").get());
 
     // Mac linebreaks: Map any remaining CR to LF:
     aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
                              NS_LITERAL_STRING("\n").get());
   }
 }
 
+void
+nsContentUtils::PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
+                                               nsAString& aResultString)
+{
+  MOZ_ASSERT(aBuf, "Expecting a non-null string buffer");
+
+  uint32_t stringLen = NS_strlen(static_cast<PRUnichar*>(aBuf->Data()));
+
+  // SANITY CHECK: In case the nsStringBuffer isn't correctly
+  // null-terminated, let's clamp its length using the allocated size, to be
+  // sure the resulting string doesn't sample past the end of the the buffer.
+  // (Note that StorageSize() is in units of bytes, so we have to convert that
+  // to units of PRUnichars, and subtract 1 for the null-terminator.)
+  uint32_t allocStringLen = (aBuf->StorageSize() / sizeof(PRUnichar)) - 1;
+  MOZ_ASSERT(stringLen <= allocStringLen,
+             "string buffer lacks null terminator!");
+  stringLen = std::min(stringLen, allocStringLen);
+
+  aBuf->ToString(stringLen, aResultString);
+}
+
 nsIPresShell*
 nsContentUtils::FindPresShellForDocument(const nsIDocument* aDoc)
 {
   const nsIDocument* doc = aDoc;
   nsIDocument* displayDoc = doc->GetDisplayDocument();
   if (displayDoc) {
     doc = displayDoc;
   }
--- a/content/smil/nsSMILMappedAttribute.cpp
+++ b/content/smil/nsSMILMappedAttribute.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* representation of a SMIL-animatable mapped attribute on an element */
 #include "nsSMILMappedAttribute.h"
-#include "nsAttrValue.h"
+#include "nsContentUtils.h"
 #include "nsError.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
 #include "nsSMILValue.h"
 #include "nsSMILCSSValueType.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsCSSProps.h"
 #include "mozilla/dom/Element.h"
 
@@ -89,18 +89,23 @@ nsSMILMappedAttribute::SetAnimValue(cons
   if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
     NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
   nsStringBuffer* oldValStrBuf = static_cast<nsStringBuffer*>
     (mElement->GetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName));
-  if (oldValStrBuf && valStr.Equals(nsCheapString(oldValStrBuf))) {
-    return NS_OK;
+  if (oldValStrBuf) {
+    nsString oldValStr;
+    nsContentUtils::PopulateStringFromStringBuffer(oldValStrBuf, oldValStr);
+    if (valStr.Equals(oldValStr)) {
+      // New animated value is the same as the old; nothing to do.
+      return NS_OK;
+    }
   }
 
   // Set the string as this mapped attribute's animated value.
   nsStringBuffer* valStrBuf =
     nsCSSValue::BufferFromString(nsString(valStr)).get();
   nsresult rv = mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
                                       attrName, valStrBuf,
                                       ReleaseStringBufferPropertyValue);
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -5,16 +5,17 @@
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Util.h"
 
 #include "nsSVGElement.h"
 
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
+#include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsMutationEvent.h"
 #include "nsError.h"
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #include "mozilla/css/StyleRule.h"
@@ -1307,32 +1308,18 @@ ParseMappedAttrAnimValueCallback(void*  
              "from properties table already (we're rebuilding it now)");
 
   MappedAttrParser* mappedAttrParser = static_cast<MappedAttrParser*>(aData);
   MOZ_ASSERT(mappedAttrParser, "parser should be non-null");
 
   nsStringBuffer* animValBuf = static_cast<nsStringBuffer*>(aPropertyValue);
   MOZ_ASSERT(animValBuf, "animated value should be non-null");
 
-  PRUnichar* animValBufData = static_cast<PRUnichar*>(animValBuf->Data());
-  uint32_t logicalStringLen = NS_strlen(animValBufData);
-  // SANITY CHECK: In case the string buffer wasn't correctly
-  // null-terminated, let's check the allocated size, too, and make sure we
-  // don't read further than that. (Note that StorageSize() is in units of
-  // bytes, so we have to convert that to units of PRUnichars, and subtract
-  // 1 for the null-terminator.)
-  uint32_t allocStringLen =
-    (animValBuf->StorageSize() / sizeof(PRUnichar)) - 1;
-
-  MOZ_ASSERT(logicalStringLen <= allocStringLen,
-             "The string in our string buffer wasn't null-terminated!!");
-
   nsString animValStr;
-  animValBuf->ToString(std::min(logicalStringLen, allocStringLen),
-                       animValStr);
+  nsContentUtils::PopulateStringFromStringBuffer(animValBuf, animValStr);
 
   mappedAttrParser->ParseMappedAttrValue(aPropertyName, animValStr);
 }
 
 // Callback for freeing animated content style rule, in property table.
 static void
 ReleaseStyleRule(void*    aObject,       /* unused */
                  nsIAtom* aPropertyName,
copy from layout/reftests/svg/smil/mapped-attr-long-url-1.svg
copy to layout/reftests/svg/smil/mapped-attr-long-url-2.svg
--- a/layout/reftests/svg/smil/mapped-attr-long-url-1.svg
+++ b/layout/reftests/svg/smil/mapped-attr-long-url-2.svg
@@ -1,13 +1,32 @@
 <!--
      Any copyright is dedicated to the Public Domain.
      http://creativecommons.org/publicdomain/zero/1.0/
 -->
 
 <svg xmlns="http://www.w3.org/2000/svg"
-     xmlns:xlink="http://www.w3.org/1999/xlink">
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     class="reftest-wait">
+  <script>
+    window.addEventListener("MozReftestInvalidate", run, false);
+
+    function run() {
+      var svg = document.documentElement;
+      svg.pauseAnimations();
+
+      // Seek to first half of animation
+      svg.setCurrentTime(101);
+
+      // Seek to second half of animation
+      svg.setCurrentTime(103);
+
+      // Take snapshot
+      svg.removeAttribute("class");
+    }
+  </script>
   <rect height="100%" width="100%" fill="lime" />
   <rect height="100" width="100" fill="red">
-    <set attributeName="fill" attributeType="XML" dur="indefinite"
+    <animate attributeName="fill" attributeType="XML" begin="100s" dur="4s"
+         from="url(#another_reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallyLongURL) purple"
          to="url(#reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallyLongURL) transparent"/>
   </rect>
 </svg>
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -241,16 +241,17 @@ fuzzy-if(cocoaWidget&&layersGPUAccelerat
 == freeze-applied-late-3.svg anim-standard-ref.svg
 == freeze-applied-late-4.svg anim-standard-ref.svg
 == frozen-to-anim-1.svg lime.svg
 
 == inactivate-with-active-unchanged-1.svg anim-standard-ref.svg
 == inactivate-with-active-unchanged-2.svg anim-standard-ref.svg
 
 == mapped-attr-long-url-1.svg lime.svg
+== mapped-attr-long-url-2.svg lime.svg
 
 # interaction between xml mapped attributes and their css equivalents
 == mapped-attr-vs-css-prop-1.svg lime.svg
 
 == smil-transitions-interaction-1a.svg lime.svg
 == smil-transitions-interaction-1b.svg lime.svg
 == smil-transitions-interaction-2a.svg lime.svg
 skip-if(B2G) == smil-transitions-interaction-2b.svg lime.svg