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 
27 namespace 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          */
ConvertXml(napi_env env)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          */
~ConvertXml()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, bool deprecated);
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, bool deprecated);
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,
131                         int flag = 0, 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         bool deprecated_ {false};
159     };
160 } // namespace OHOS::Xml
161 #endif // CONVERTXML_JS_CONVERTXML_H
162