1 /*
2 * Copyright (c) 2024 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 #define LOG_TAG "Text"
17
18 #include "napi_text.h"
19
20 #include "napi_error_utils.h"
21 #include "napi_parser.h"
22
23 namespace OHOS::CollaborationEdit {
24 static __thread napi_ref g_text_cons_ref = nullptr;
25
Text()26 Text::Text() : AbstractType()
27 {}
28
~Text()29 Text::~Text()
30 {}
31
Init(napi_env env,napi_value exports)32 void Text::Init(napi_env env, napi_value exports)
33 {
34 napi_value cons = Text::Constructor(env);
35 NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &g_text_cons_ref));
36 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, exports, "Text", cons));
37 LOG_DEBUG("Text::Init end.");
38 }
39
Constructor(napi_env env)40 napi_value Text::Constructor(napi_env env)
41 {
42 napi_property_descriptor descriptors[] = {
43 DECLARE_NAPI_FUNCTION("getId", GetUniqueId),
44 DECLARE_NAPI_FUNCTION("insert", Insert),
45 DECLARE_NAPI_FUNCTION("delete", Delete),
46 DECLARE_NAPI_FUNCTION("format", Format),
47 DECLARE_NAPI_FUNCTION("getPlainText", GetPlainText),
48 DECLARE_NAPI_FUNCTION("getJsonResult", GetJsonResult),
49 };
50 napi_value cons = nullptr;
51 NAPI_CALL(env, napi_define_class(env, "Text", NAPI_AUTO_LENGTH, New, nullptr,
52 sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons));
53 return cons;
54 }
55
New(napi_env env,napi_callback_info info)56 napi_value Text::New(napi_env env, napi_callback_info info)
57 {
58 napi_value newTarget = nullptr;
59 NAPI_CALL(env, napi_get_new_target(env, info, &newTarget));
60
61 napi_value self = nullptr;
62 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
63
64 // create instance by 'new Node(name)'
65 if (newTarget != nullptr) {
66 Text *text = new (std::nothrow) Text();
67 ASSERT_THROW_BASE(env, text != nullptr, Status::INTERNAL_ERROR, "text new: new text go wrong", self);
68 auto finalize = [](napi_env env, void *data, void *hint) {
69 Text *text = reinterpret_cast<Text *>(data);
70 delete text;
71 };
72 napi_status status = napi_wrap(env, self, text, finalize, nullptr, nullptr);
73 if (status != napi_ok) {
74 LOG_ERROR("napi_wrap failed. code:%{public}d", status);
75 delete text;
76 return nullptr;
77 }
78 return self;
79 }
80
81 // create instance by 'Node(name)'
82 napi_value cons = nullptr;
83 NAPI_CALL(env, napi_get_reference_value(env, g_text_cons_ref, &cons));
84 napi_value output = nullptr;
85 NAPI_CALL(env, napi_new_instance(env, cons, 0, nullptr, &output));
86 return output;
87 }
88
GetUniqueId(napi_env env,napi_callback_info info)89 napi_value Text::GetUniqueId(napi_env env, napi_callback_info info)
90 {
91 napi_value self = nullptr;
92 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
93 Text *text = nullptr;
94 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
95 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
96 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
97 if (!text->GetID().has_value()) {
98 ThrowNapiError(env, Status::INVALID_ARGUMENT, "empty id");
99 return nullptr;
100 }
101 ID id = text->GetID().value();
102 napi_value result;
103 NAPI_CALL(env, napi_create_object(env, &result));
104 napi_value jsDeviceId;
105 NapiUtils::SetValue(env, id.deviceId, jsDeviceId);
106 NAPI_CALL(env, napi_set_named_property(env, result, "deviceId", jsDeviceId));
107 napi_value jsClock;
108 NapiUtils::SetValue(env, static_cast<int64_t>(id.clock), jsClock);
109 NAPI_CALL(env, napi_set_named_property(env, result, "clock", jsClock));
110 return result;
111 }
112
Insert(napi_env env,napi_callback_info info)113 napi_value Text::Insert(napi_env env, napi_callback_info info)
114 {
115 size_t argc = 3;
116 napi_value argv[3] = {nullptr};
117 napi_value self = nullptr;
118 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
119 Text *text = nullptr;
120 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
121 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
122 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
123 int64_t index;
124 napi_status status = NapiUtils::GetValue(env, argv[0], index);
125 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read index go wrong");
126 ASSERT_THROW(env, index >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid index");
127 std::string content;
128 status = NapiUtils::GetValue(env, argv[1], content);
129 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read content go wrong");
130 napi_valuetype valueType;
131 // argv[2] represents the third parameter
132 NAPI_CALL(env, napi_typeof(env, argv[2], &valueType));
133 std::string formatStr;
134 if (valueType != napi_undefined) {
135 int ret = Parser::ParseJsFormatToStr(env, argv[2], formatStr);
136 ASSERT_THROW(env, ret == OK, Status::INVALID_ARGUMENT, "convert format go wrong");
137 }
138 int32_t retCode = text->GetAdapter()->TextInsert(index, content, formatStr);
139 if (retCode != SUCCESS) {
140 ThrowNapiError(env, retCode, "TextInsert go wrong.");
141 }
142 return nullptr;
143 }
144
Delete(napi_env env,napi_callback_info info)145 napi_value Text::Delete(napi_env env, napi_callback_info info)
146 {
147 size_t argc = 2;
148 napi_value argv[2] = {nullptr};
149 napi_value self = nullptr;
150 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
151 Text *text = nullptr;
152 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
153 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
154 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
155 int64_t index;
156 napi_status status = NapiUtils::GetValue(env, argv[0], index);
157 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read index go wrong");
158 ASSERT_THROW(env, index >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid index");
159 int64_t length = 0;
160 status = NapiUtils::GetValue(env, argv[1], length);
161 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read length go wrong");
162 ASSERT_THROW(env, length > 0, Status::INVALID_ARGUMENT, "Param Error: Invalid length");
163 int32_t retCode = text->GetAdapter()->TextDelete(index, length);
164 if (retCode != SUCCESS) {
165 ThrowNapiError(env, retCode, "TextDelete go wrong.");
166 }
167 return nullptr;
168 }
169
Format(napi_env env,napi_callback_info info)170 napi_value Text::Format(napi_env env, napi_callback_info info)
171 {
172 size_t argc = 3;
173 napi_value argv[3] = {nullptr};
174 napi_value self = nullptr;
175 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
176 Text *text = nullptr;
177 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
178 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
179 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
180 int64_t index;
181 napi_status status = NapiUtils::GetValue(env, argv[0], index);
182 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read index go wrong");
183 ASSERT_THROW(env, index >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid index");
184 int64_t length = 0;
185 status = NapiUtils::GetValue(env, argv[1], length);
186 ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: read length go wrong");
187 ASSERT_THROW(env, length > 0, Status::INVALID_ARGUMENT, "Param Error: Invalid length");
188 napi_valuetype valueType;
189 // argv[2] represents the third parameter
190 NAPI_CALL(env, napi_typeof(env, argv[2], &valueType));
191 std::string formatStr;
192 if (valueType != napi_undefined) {
193 // argv[2] represents the third parameter
194 (void)Parser::ParseJsFormatToStr(env, argv[2], formatStr);
195 }
196 int32_t retCode = text->GetAdapter()->TextFormat(index, length, formatStr);
197 if (retCode != SUCCESS) {
198 ThrowNapiError(env, retCode, "TextFormat go wrong.");
199 }
200 return nullptr;
201 }
202
GetPlainText(napi_env env,napi_callback_info info)203 napi_value Text::GetPlainText(napi_env env, napi_callback_info info)
204 {
205 napi_value self = nullptr;
206 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
207 Text *text = nullptr;
208 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
209 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
210 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
211 auto [retCode, result] = text->GetAdapter()->ReadStringText();
212 if (retCode != SUCCESS) {
213 ThrowNapiError(env, retCode, "ReadStringText go wrong.");
214 return nullptr;
215 }
216 napi_value output = nullptr;
217 NapiUtils::SetValue(env, result, output);
218 return output;
219 }
220
GetJsonResult(napi_env env,napi_callback_info info)221 napi_value Text::GetJsonResult(napi_env env, napi_callback_info info)
222 {
223 napi_value self = nullptr;
224 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
225 Text *text = nullptr;
226 NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&text)));
227 ASSERT(text != nullptr, "unwrap self go wrong.", nullptr);
228 ASSERT_THROW(env, text->GetID().has_value(), Status::UNSUPPORTED_OPERATION, "empty id");
229 auto [retCode, result] = text->GetAdapter()->ReadDeltaText("", "");
230 if (retCode != SUCCESS) {
231 ThrowNapiError(env, retCode, "ReadDeltaText go wrong.");
232 return nullptr;
233 }
234 napi_value output = nullptr;
235 NapiUtils::SetValue(env, result, output);
236 return output;
237 }
238 } // namespace OHOS::CollaborationEdit
239