1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef CONVERTXML_JS_CONVERTXML_H
17#define CONVERTXML_JS_CONVERTXML_H
18
19#include <string>
20#include <vector>
21#include "libxml/parser.h"
22#include "libxml/tree.h"
23#include "napi/native_api.h"
24#include "napi/native_node_api.h"
25#include "native_engine/native_engine.h"
26
27namespace OHOS::Xml {
28    enum class SpaceType {
29        T_INT32,
30        T_STRING,
31        T_INIT = -1
32    };
33
34    struct Options {
35        std::string declaration = "_declaration";
36        std::string instruction = "_instruction";
37        std::string attributes = "_attributes";
38        std::string text = "_text";
39        std::string cdata = "_cdata";
40        std::string doctype = "_doctype";
41        std::string comment = "_comment";
42        std::string parent = "_parent";
43        std::string type = "_type";
44        std::string name = "_name";
45        std::string elements = "_elements";
46        bool compact = false;
47        bool trim = false;
48        bool nativetype = false;
49        bool nativetypeattributes = false;
50        bool addparent = false;
51        bool alwaysArray = false;
52        bool alwaysChildren = false;
53        bool instructionHasAttributes = false;
54        bool ignoreDeclaration = false;
55        bool ignoreInstruction = false;
56        bool ignoreAttributes = false;
57        bool ignoreComment = false;
58        bool ignoreCdata = false;
59        bool ignoreDoctype = false;
60        bool ignoreText = false;
61        bool spaces = false;
62    };
63
64    struct XmlInfo {
65        bool bXml = false;
66        bool bVersion = false;
67        std::string strVersion = "";
68        bool bEncoding = false;
69        std::string strEncoding = "";
70    };
71
72    class ConvertXml {
73    struct APIVersion {
74        const int32_t API13 = 13;
75    };
76    public:
77        /**
78         * To convert XML text to JavaScript object.
79         */
80        explicit ConvertXml(napi_env env) :env_(env)
81        {
82            NativeEngine* engine = reinterpret_cast<NativeEngine*>(env);
83            if (engine != nullptr) {
84                apiVersion_ = engine->GetApiVersion() % API_VERSION_MOD;
85            }
86            spaceType_ = SpaceType::T_INIT;
87            strSpace_ = "";
88            iSpace_ = 0;
89            apiFlag_ = apiVersion_ >= APIVerIsolation_.API13;
90        };
91
92        /**
93         * The destructor of the ConvertXml.
94         */
95        virtual ~ConvertXml() {}
96
97        /**
98         * To convert XML text to JavaScript object.
99         *
100         * @param env NAPI environment parameters.
101         * @param strXml A string of XML text.
102         */
103        napi_value Convert(napi_env env, std::string strXml);
104
105        /**
106         * Converts the string of js to string of C++.
107         *
108         * @param env NAPI environment parameters.
109         * @param napi_StrValue JS layer incoming stringing.
110         * @param result The C++ layer accepts stringing.
111         */
112        napi_status DealNapiStrValue(napi_env env, const napi_value napi_StrValue, std::string &result) const;
113
114        /**
115         * Handles user input of optional information
116         *
117         * @param env NAPI environment parameters.
118         * @param napiObj Get the option parameter from js to the napi layer
119         */
120        void DealOptions(napi_env env, const napi_value napiObj);
121
122        friend class CxmlTest;
123
124    private:
125        void SetAttributes(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject) const;
126        void SetXmlElementType(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject, bool &bFlag) const;
127        void SetNodeInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
128                         const std::string parentName = "") const;
129        void SetEndInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject, bool &bFlag) const;
130        void GetXMLInfo(napi_env env, xmlNodePtr curNode, const napi_value &object, int flag = 0,
131                        const std::string parentName = "");
132        std::string GetNodeType(const xmlElementType enumType) const;
133        void SetKeyValue(napi_env env, const napi_value &object, const std::string strKey,
134                         const std::string strValue) const;
135        std::string Trim(std::string strXmltrim) const;
136        void GetPrevNodeList(napi_env env, xmlNodePtr curNode);
137        void DealSpaces(napi_env env, const napi_value napiObj);
138        void DealIgnore(napi_env env, const napi_value napiObj);
139        void SetPrevInfo(napi_env env, const napi_value &recvElement, int flag, int32_t &index1) const;
140        void SetDefaultKey(size_t i, const std::string strRecv);
141        void SetSpacesInfo(napi_env env, const napi_value &object) const;
142        void DealSingleLine(napi_env env, std::string &strXml, const napi_value &object);
143        void DealComplex(napi_env env, std::string &strXml, const napi_value &object) const;
144        void Replace(std::string &str, const std::string src, const std::string dst) const;
145        void DealCDataInfo(bool bCData, xmlNodePtr &curNode) const;
146
147        SpaceType spaceType_ {SpaceType::T_INIT};
148        int32_t iSpace_ {};
149        std::string strSpace_ {};
150        Options options_;
151        std::vector<napi_value> prevObj_ {};
152        XmlInfo xmlInfo_;
153        int32_t apiVersion_ {0};
154        int32_t API_VERSION_MOD {100};
155        APIVersion APIVerIsolation_;
156        bool apiFlag_ {false};
157        napi_env env_ {nullptr};
158    };
159} // namespace OHOS::Xml
160#endif // CONVERTXML_JS_CONVERTXML_H
161