// Copyright 2017 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fxcrt/css/cfx_cssselector.h" #include #include "core/fxcrt/fx_extension.h" #include "third_party/base/check.h" namespace { size_t GetCSSNameLen(WideStringView str) { for (size_t i = 0; i < str.GetLength(); ++i) { wchar_t wch = str[i]; if (!isascii(wch) || (!isalnum(wch) && wch != '_' && wch != '-')) return i; } return str.GetLength(); } } // namespace CFX_CSSSelector::CFX_CSSSelector(WideStringView str, std::unique_ptr next) : name_hash_(FX_HashCode_GetLoweredW(str)), next_(std::move(next)) {} CFX_CSSSelector::~CFX_CSSSelector() = default; // static. std::unique_ptr CFX_CSSSelector::FromString( WideStringView str) { DCHECK(!str.IsEmpty()); for (wchar_t wch : str) { switch (wch) { case '>': case '[': case '+': return nullptr; } } std::unique_ptr head; for (size_t i = 0; i < str.GetLength();) { wchar_t wch = str[i]; if (wch == ' ') { ++i; continue; } const bool is_star = wch == '*'; const bool is_valid_char = is_star || (isascii(wch) && isalpha(wch)); if (!is_valid_char) return nullptr; if (head) head->set_is_descendant(); size_t len = is_star ? 1 : GetCSSNameLen(str.Last(str.GetLength() - i)); auto new_head = std::make_unique(str.Substr(i, len), std::move(head)); head = std::move(new_head); i += len; } return head; }