1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 3cb93a386Sopenharmony_ci * Description: Implementation for Css style parser. 4cb93a386Sopenharmony_ci * Create: 2023/4/25 5cb93a386Sopenharmony_ci */ 6cb93a386Sopenharmony_ci 7cb93a386Sopenharmony_ci#include "src/xml/SkDOM.h" 8cb93a386Sopenharmony_ci#include "src/xml/SkDOMParser.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_cichar* SkDOMParser::dupstr(SkArenaAlloc* chunk, const char src[], size_t srcLen) { 11cb93a386Sopenharmony_ci SkASSERT(chunk && src); 12cb93a386Sopenharmony_ci char* dst = chunk->makeArrayDefault<char>(srcLen + 1); 13cb93a386Sopenharmony_ci memcpy(dst, src, srcLen); 14cb93a386Sopenharmony_ci dst[srcLen] = '\0'; 15cb93a386Sopenharmony_ci return dst; 16cb93a386Sopenharmony_ci} 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciSkDOM::Node* SkDOMParser::getRoot() const { 19cb93a386Sopenharmony_ci return fRoot; 20cb93a386Sopenharmony_ci} 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_civoid SkDOMParser::flushAttributes() { 23cb93a386Sopenharmony_ci SkASSERT(fLevel > 0); 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci int attrCount = fAttrs.count(); 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci SkDOMAttr* attrs = fAlloc->makeArrayDefault<SkDOMAttr>(attrCount); 28cb93a386Sopenharmony_ci SkDOM::Node* node = fAlloc->make<SkDOM::Node>(); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci node->fName = fElemName; 31cb93a386Sopenharmony_ci node->fFirstChild = nullptr; 32cb93a386Sopenharmony_ci node->fAttrCount = SkToU16(attrCount); 33cb93a386Sopenharmony_ci node->fAttrs = attrs; 34cb93a386Sopenharmony_ci node->fType = fElemType; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci if (fRoot == nullptr) { 37cb93a386Sopenharmony_ci node->fNextSibling = nullptr; 38cb93a386Sopenharmony_ci fRoot = node; 39cb93a386Sopenharmony_ci } else { // this adds siblings in reverse order. gets corrected in onEndElement() 40cb93a386Sopenharmony_ci SkDOM::Node* parent = fParentStack.top(); 41cb93a386Sopenharmony_ci SkASSERT(fRoot && parent); 42cb93a386Sopenharmony_ci node->fNextSibling = parent->fFirstChild; 43cb93a386Sopenharmony_ci parent->fFirstChild = node; 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci *fParentStack.push() = node; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci sk_careful_memcpy(node->attrs(), fAttrs.begin(), attrCount * sizeof(SkDOM::Attr)); 48cb93a386Sopenharmony_ci fAttrs.reset(); 49cb93a386Sopenharmony_ci} 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_cibool SkDOMParser::onStartElement(const char elem[]) { 52cb93a386Sopenharmony_ci this->startCommon(elem, strlen(elem), SkDOM::kElement_Type); 53cb93a386Sopenharmony_ci return false; 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_cibool SkDOMParser::onAddAttribute(const char name[], const char value[]) { 57cb93a386Sopenharmony_ci SkDOM::Attr* attr = fAttrs.append(); 58cb93a386Sopenharmony_ci attr->fName = dupstr(fAlloc, name, strlen(name)); 59cb93a386Sopenharmony_ci attr->fValue = dupstr(fAlloc, value, strlen(value)); 60cb93a386Sopenharmony_ci return false; 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_cibool SkDOMParser::onEndElement(const char elem[]) { 64cb93a386Sopenharmony_ci --fLevel; 65cb93a386Sopenharmony_ci if (fNeedToFlush) 66cb93a386Sopenharmony_ci flushAttributes(); 67cb93a386Sopenharmony_ci fNeedToFlush = false; 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci SkDOM::Node* parent; 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci fParentStack.pop(&parent); 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci SkDOM::Node* child = parent->fFirstChild; 74cb93a386Sopenharmony_ci SkDOM::Node* prev = nullptr; 75cb93a386Sopenharmony_ci while (child) { 76cb93a386Sopenharmony_ci SkDOM::Node* next = child->fNextSibling; 77cb93a386Sopenharmony_ci child->fNextSibling = prev; 78cb93a386Sopenharmony_ci prev = child; 79cb93a386Sopenharmony_ci child = next; 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci parent->fFirstChild = prev; 82cb93a386Sopenharmony_ci return false; 83cb93a386Sopenharmony_ci} 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_cibool SkDOMParser::onText(const char text[], int len) { 86cb93a386Sopenharmony_ci startCommon(text, len, SkDOM::kText_Type); 87cb93a386Sopenharmony_ci SkDOMParser::onEndElement(fElemName); 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci return false; 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_civoid SkDOMParser::startCommon(const char elem[], size_t elemSize, SkDOM::Type type) { 93cb93a386Sopenharmony_ci if (fLevel > 0 && fNeedToFlush) { 94cb93a386Sopenharmony_ci flushAttributes(); 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci fNeedToFlush = true; 97cb93a386Sopenharmony_ci fElemName = dupstr(fAlloc, elem, elemSize); 98cb93a386Sopenharmony_ci fElemType = type; 99cb93a386Sopenharmony_ci ++fLevel; 100cb93a386Sopenharmony_ci} 101