tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGPointList.cpp (3019B)


      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 "SVGPointList.h"
      8 
      9 #include "SVGContentUtils.h"
     10 #include "nsCharSeparatedTokenizer.h"
     11 #include "nsContentUtils.h"
     12 #include "nsTextFormatter.h"
     13 
     14 namespace mozilla {
     15 
     16 nsresult SVGPointList::CopyFrom(const SVGPointList& rhs) {
     17  if (!mItems.Assign(rhs.mItems, fallible)) {
     18    return NS_ERROR_OUT_OF_MEMORY;
     19  }
     20  return NS_OK;
     21 }
     22 
     23 void SVGPointList::GetValueAsString(nsAString& aValue) const {
     24  aValue.Truncate();
     25  char16_t buf[50];
     26  uint32_t last = mItems.Length() - 1;
     27  for (uint32_t i = 0; i < mItems.Length(); ++i) {
     28    // Would like to use aValue.AppendPrintf("%f,%f", item.mX, item.mY),
     29    // but it's not possible to always avoid trailing zeros.
     30    nsTextFormatter::snprintf(buf, std::size(buf), u"%g,%g",
     31                              double(mItems[i].mX), double(mItems[i].mY));
     32    // We ignore OOM, since it's not useful for us to return an error.
     33    aValue.Append(buf);
     34    if (i != last) {
     35      aValue.Append(' ');
     36    }
     37  }
     38 }
     39 
     40 nsresult SVGPointList::SetValueFromString(const nsAString& aValue) {
     41  // The spec says that the list is parsed and accepted up to the first error
     42  // encountered, so we must call CopyFrom even if an error occurs. We still
     43  // want to throw any error code from setAttribute if there's a problem
     44  // though, so we must take care to return any error code.
     45 
     46  nsresult rv = NS_OK;
     47 
     48  SVGPointList temp;
     49 
     50  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
     51                                   nsTokenizerFlags::SeparatorOptional>
     52      tokenizer(aValue, ',');
     53 
     54  while (tokenizer.hasMoreTokens()) {
     55    const nsAString& token = tokenizer.nextToken();
     56 
     57    nsAString::const_iterator iter, end;
     58    token.BeginReading(iter);
     59    token.EndReading(end);
     60 
     61    float x;
     62    if (!SVGContentUtils::ParseNumber(iter, end, x)) {
     63      rv = NS_ERROR_DOM_SYNTAX_ERR;
     64      break;
     65    }
     66 
     67    float y;
     68    if (iter == end) {
     69      if (!tokenizer.hasMoreTokens() ||
     70          !SVGContentUtils::ParseNumber(tokenizer.nextToken(), y)) {
     71        rv = NS_ERROR_DOM_SYNTAX_ERR;
     72        break;
     73      }
     74    } else {
     75      // It's possible for the token to be 10-30 which has
     76      // no separator but needs to be parsed as 10, -30
     77      const nsAString& leftOver = Substring(iter, end);
     78      if (leftOver[0] != '-' || !SVGContentUtils::ParseNumber(leftOver, y)) {
     79        rv = NS_ERROR_DOM_SYNTAX_ERR;
     80        break;
     81      }
     82    }
     83    temp.AppendItem(SVGPoint(x, y));
     84  }
     85  if (tokenizer.separatorAfterCurrentToken()) {
     86    rv = NS_ERROR_DOM_SYNTAX_ERR;  // trailing comma
     87  }
     88  nsresult rv2 = CopyFrom(temp);
     89  if (NS_FAILED(rv2)) {
     90    return rv2;  // prioritize OOM error code over syntax errors
     91  }
     92  return rv;
     93 }
     94 
     95 }  // namespace mozilla