/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "QueryHelper" #include "query_helper.h" #include <regex> #include <sstream> #include "data_query.h" #include "device_manager_adapter.h" #include "kvstore_utils.h" #include "log_print.h" #include "types.h" namespace OHOS::DistributedKv { constexpr int QUERY_SKIP_SIZE = 1; constexpr int QUERY_WORD_SIZE = 2; constexpr int MAX_QUERY_LENGTH = 5 * 1024; // Max query string length 5k constexpr int MAX_QUERY_COMPLEXITY = 500; // Max query complexity 500 bool QueryHelper::hasPrefixKey_ = false; std::string QueryHelper::deviceId_; DistributedDB::Query QueryHelper::StringToDbQuery(const std::string &query, bool &isSuccess) { ZLOGI("query string length:%{public}zu", query.length()); DBQuery dbQuery = DBQuery::Select(); if (query.empty()) { ZLOGD("Query string is empty."); isSuccess = true; return dbQuery; } if (query.size() > MAX_QUERY_LENGTH) { ZLOGE("Query string is too long."); isSuccess = false; return dbQuery; } deviceId_.clear(); hasPrefixKey_ = (query.find(DataQuery::KEY_PREFIX) != std::string::npos); size_t pos = query.find_first_not_of(DataQuery::SPACE); std::string inputTrim = (pos == std::string::npos) ? "" : query.substr(pos); std::regex regex(" "); // regex split string by space std::vector<std::string> words(std::sregex_token_iterator(inputTrim.begin(), inputTrim.end(), regex, -1), std::sregex_token_iterator()); if (words.empty()) { ZLOGE("not enough params."); return dbQuery; } int pointer = 0; // Read pointer starts at 0 int end = words.size() - 1; // Read pointer ends at size - 1 // Counts how many keywords has been handled for (int count = 0; pointer <= end && count <= MAX_QUERY_COMPLEXITY; ++count) { std::string keyword = words.at(pointer); if (keyword == DataQuery::EQUAL_TO) { isSuccess = HandleEqualTo(words, pointer, end, dbQuery); } else if (keyword == DataQuery::NOT_EQUAL_TO) { isSuccess = HandleNotEqualTo(words, pointer, end, dbQuery); } else if (keyword == DataQuery::GREATER_THAN) { isSuccess = HandleGreaterThan(words, pointer, end, dbQuery); } else if (keyword == DataQuery::LESS_THAN) { isSuccess = HandleLessThan(words, pointer, end, dbQuery); } else if (keyword == DataQuery::GREATER_THAN_OR_EQUAL_TO) { isSuccess = HandleGreaterThanOrEqualTo(words, pointer, end, dbQuery); } else if (keyword == DataQuery::LESS_THAN_OR_EQUAL_TO) { isSuccess = HandleLessThanOrEqualTo(words, pointer, end, dbQuery); } else { isSuccess = Handle(words, pointer, end, dbQuery); } if (!isSuccess) { ZLOGE("Invalid params."); return DBQuery::Select(); } } return dbQuery; } bool QueryHelper::Handle(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { std::string keyword = words.at(pointer); if (keyword == DataQuery::IS_NULL) { return HandleIsNull(words, pointer, end, dbQuery); } else if (keyword == DataQuery::IN) { return HandleIn(words, pointer, end, dbQuery); } else if (keyword == DataQuery::NOT_IN) { return HandleNotIn(words, pointer, end, dbQuery); } else if (keyword == DataQuery::LIKE) { return HandleLike(words, pointer, end, dbQuery); } else if (keyword == DataQuery::NOT_LIKE) { return HandleNotLike(words, pointer, end, dbQuery); } else if (keyword == DataQuery::AND) { return HandleAnd(words, pointer, end, dbQuery); } else if (keyword == DataQuery::OR) { return HandleOr(words, pointer, end, dbQuery); } else if (keyword == DataQuery::ORDER_BY_ASC) { return HandleOrderByAsc(words, pointer, end, dbQuery); } else if (keyword == DataQuery::ORDER_BY_DESC) { return HandleOrderByDesc(words, pointer, end, dbQuery); } else if (keyword == DataQuery::ORDER_BY_WRITE_TIME) { return HandleOrderByWriteTime(words, pointer, end, dbQuery); } else if (keyword == DataQuery::LIMIT) { return HandleLimit(words, pointer, end, dbQuery); } else { return HandleExtra(words, pointer, end, dbQuery); } } bool QueryHelper::HandleExtra(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { std::string keyword = words.at(pointer); if (keyword == DataQuery::BEGIN_GROUP) { return HandleBeginGroup(words, pointer, end, dbQuery); } else if (keyword == DataQuery::END_GROUP) { return HandleEndGroup(words, pointer, end, dbQuery); } else if (keyword == DataQuery::KEY_PREFIX) { return HandleKeyPrefix(words, pointer, end, dbQuery); } else if (keyword == DataQuery::IS_NOT_NULL) { return HandleIsNotNull(words, pointer, end, dbQuery); } else if (keyword == DataQuery::DEVICE_ID) { return HandleDeviceId(words, pointer, end, dbQuery); } else if (keyword == DataQuery::SUGGEST_INDEX) { return HandleSetSuggestIndex(words, pointer, end, dbQuery); } else if (keyword == DataQuery::IN_KEYS) { return HandleInKeys(words, pointer, end, dbQuery); } ZLOGE("Invalid keyword."); return false; } bool QueryHelper::HandleEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("EqualTo not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.EqualTo(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.EqualTo(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.EqualTo(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_BOOLEAN) { dbQuery.EqualTo(StringToString(fieldName), StringToBoolean(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.EqualTo(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("EqualTo wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleNotEqualTo(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("NotEqualTo not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.NotEqualTo(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.NotEqualTo(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.NotEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_BOOLEAN) { dbQuery.NotEqualTo(StringToString(fieldName), StringToBoolean(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.NotEqualTo(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("NotEqualTo wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleGreaterThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("GreaterThan not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.GreaterThan(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.GreaterThan(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.GreaterThan(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.GreaterThan(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("GreaterThan wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleLessThan(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("LessThan not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.LessThan(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.LessThan(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.LessThan(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.LessThan(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("LessThan wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleGreaterThanOrEqualTo( const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("GreaterThanOrEqualTo not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.GreaterThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("GreaterThanOrEqualTo wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleLessThanOrEqualTo( const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 3 > end) { // This keyword has 3 following params ZLOGE("LessThanOrEqualTo not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName const std::string &fieldValue = words.at(pointer + 3); // fieldValue if (fieldType == DataQuery::TYPE_INTEGER) { dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToInt(fieldValue)); } else if (fieldType == DataQuery::TYPE_LONG) { dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToLong(fieldValue)); } else if (fieldType == DataQuery::TYPE_DOUBLE) { dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToDouble(fieldValue)); } else if (fieldType == DataQuery::TYPE_STRING) { dbQuery.LessThanOrEqualTo(StringToString(fieldName), StringToString(fieldValue)); } else { ZLOGE("LessThanOrEqualTo wrong type."); return false; } pointer += 4; // 4 Pointer goes to next keyword return true; } bool QueryHelper::HandleIsNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("IsNull not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName dbQuery.IsNull(StringToString(fieldName)); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleIsNotNull(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("IsNotNull not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName dbQuery.IsNotNull(StringToString(fieldName)); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { // | <-------------------------4---------------------------->| // words [ DataQuery::IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ] // index [ -------0-----, ----1----, ----2----, ---------3---------, ... , ---------n--------] // ^ ^ // | | // pointer end // first fieldValue, or END if list is empty if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) { ZLOGE("In not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName int elementPointer = pointer + 4; // first fieldValue, or END if list is empty if (fieldType == DataQuery::TYPE_INTEGER) { const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end); dbQuery.In(StringToString(fieldName), intValueList); } else if (fieldType == DataQuery::TYPE_LONG) { const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end); dbQuery.In(StringToString(fieldName), longValueList); } else if (fieldType == DataQuery::TYPE_DOUBLE) { const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end); dbQuery.In(StringToString(fieldName), doubleValueList); } else if (fieldType == DataQuery::TYPE_STRING) { const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end); dbQuery.In(StringToString(fieldName), stringValueList); } else { ZLOGE("In wrong type."); return false; } pointer = elementPointer + 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleNotIn(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { // |<--------------------------4-------------------------------->| // words [ DataQuery::NOT_IN, fieldType, fieldName, DataQuery::START_IN, ...valueList, DataQuery::END_IN ] // index [ --------0--------, ----1----, ----2----, ---------3---------, ... , ---------n--------] // ^ ^ // | | // pointer end // first fieldValue, or END if list is empty if (pointer + 4 > end || words.at(pointer + 3) != DataQuery::START_IN) { ZLOGE("NotIn not enough params."); return false; } const std::string &fieldType = words.at(pointer + 1); // fieldType const std::string &fieldName = words.at(pointer + 2); // fieldName int elementPointer = pointer + 4; // first fieldValue, or END if list is empty if (fieldType == DataQuery::TYPE_INTEGER) { const std::vector<int> intValueList = GetIntegerList(words, elementPointer, end); dbQuery.NotIn(StringToString(fieldName), intValueList); } else if (fieldType == DataQuery::TYPE_LONG) { const std::vector<int64_t> longValueList = GetLongList(words, elementPointer, end); dbQuery.NotIn(StringToString(fieldName), longValueList); } else if (fieldType == DataQuery::TYPE_DOUBLE) { const std::vector<double> doubleValueList = GetDoubleList(words, elementPointer, end); dbQuery.NotIn(StringToString(fieldName), doubleValueList); } else if (fieldType == DataQuery::TYPE_STRING) { const std::vector<std::string> stringValueList = GetStringList(words, elementPointer, end); dbQuery.NotIn(StringToString(fieldName), stringValueList); } else { ZLOGE("NotIn wrong type."); return false; } pointer = elementPointer + 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 2 > end) { // This keyword has 2 following params ZLOGE("Like not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName const std::string &fieldValue = words.at(pointer + 2); // fieldValue dbQuery.Like(StringToString(fieldName), StringToString(fieldValue)); pointer += 3; // 3 Pointer goes to next keyword return true; } bool QueryHelper::HandleNotLike(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 2 > end) { // This keyword has 2 following params ZLOGE("NotLike not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName const std::string &fieldValue = words.at(pointer + 2); // fieldValue dbQuery.NotLike(StringToString(fieldName), StringToString(fieldValue)); pointer += 3; // 3 Pointer goes to next keyword return true; } bool QueryHelper::HandleAnd(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { dbQuery.And(); pointer += 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleOr(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { dbQuery.Or(); pointer += 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleOrderByAsc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("OrderByAsc not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName dbQuery.OrderBy(StringToString(fieldName), true); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleOrderByDesc(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("OrderByDesc not enough params."); return false; } const std::string &fieldName = words.at(pointer + 1); // fieldName dbQuery.OrderBy(StringToString(fieldName), false); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleOrderByWriteTime(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("HandleOrderByWriteTime not enough params."); return false; } const std::string isAsc = words.at(pointer + 1); // isASC dbQuery.OrderByWriteTime(isAsc == DataQuery::IS_ASC); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleLimit(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 2 > end) { // This keyword has 2 following params ZLOGE("Limit not enough params."); return false; } const int number = StringToInt(words.at(pointer + 1)); // number const int offset = StringToInt(words.at(pointer + 2)); // offset dbQuery.Limit(number, offset); pointer += 3; // 3 Pointer goes to next keyword return true; } bool QueryHelper::HandleBeginGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { dbQuery.BeginGroup(); pointer += 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleEndGroup(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { dbQuery.EndGroup(); pointer += 1; // Pointer goes to next keyword return true; } bool QueryHelper::HandleKeyPrefix(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("KeyPrefix not enough params."); return false; } const std::string &prefix = deviceId_ + StringToString(words.at(pointer + 1)); // prefix const std::vector<uint8_t> prefixVector(prefix.begin(), prefix.end()); dbQuery.PrefixKey(prefixVector); pointer += 2; // 2 Pointer goes to next keyword return true; } bool QueryHelper::HandleInKeys(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { // pointer points at keyword "IN_KEYS", (pointer + 1) points at keyword "START_IN" int startInOffSet = pointer + 1; int queryLen = end - pointer; if (queryLen < 2 || words.at(startInOffSet) != DataQuery::START_IN) { // This keyword has at least 2 params ZLOGE("In not enough params."); return false; } int inkeyOffSet = startInOffSet + 1; // inkeyOffSet points at the first inkey value const std::vector<std::string> inKeys = GetStringList(words, inkeyOffSet, end); std::set<std::vector<uint8_t>> inDbKeys; for (const std::string &inKey : inKeys) { ZLOGI("inKey=%{public}s", inKey.c_str()); std::vector<uint8_t> dbKey; dbKey.assign(inKey.begin(), inKey.end()); inDbKeys.insert(dbKey); } int size = inDbKeys.size(); ZLOGI("size of inKeys=%{public}d", size); dbQuery.InKeys(inDbKeys); int endOffSet = inkeyOffSet; pointer = endOffSet + 1; // endOffSet points at keyword "END", Pointer goes to next keyword return true; } bool QueryHelper::HandleSetSuggestIndex(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + QUERY_SKIP_SIZE > end) { ZLOGE("HandleSetSuggestIndex not enough params."); return false; } std::string index = StringToString(words.at(pointer + QUERY_SKIP_SIZE)); dbQuery.SuggestIndex(index); pointer += QUERY_WORD_SIZE; return true; } bool QueryHelper::HandleDeviceId(const std::vector<std::string> &words, int &pointer, int end, DBQuery &dbQuery) { if (pointer + 1 > end) { // This keyword has 1 following params ZLOGE("DeviceId not enough params."); return false; } deviceId_ = StringToString(words.at(pointer + 1)); // deviceId ZLOGI("query devId string length:%zu", deviceId_.length()); deviceId_ = DistributedData::DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(deviceId_); // convert to UUId ZLOGI("query converted devId string length:%zu", deviceId_.length()); if (!hasPrefixKey_) { ZLOGD("DeviceId as the only prefixKey."); const std::vector<uint8_t> prefixVector(deviceId_.begin(), deviceId_.end()); dbQuery.PrefixKey(prefixVector); } else { ZLOGD("Join deviceId with user specified prefixkey later."); } pointer += 2; // 2 Pointer goes to next keyword return true; } int QueryHelper::StringToInt(const std::string &word) { int result; std::istringstream(word) >> result; return result; } int64_t QueryHelper::StringToLong(const std::string &word) { int64_t result; std::istringstream(word) >> result; return result; } double QueryHelper::StringToDouble(const std::string &word) { double result; std::istringstream(word) >> result; return result; } bool QueryHelper::StringToBoolean(const std::string &word) { if (word == DataQuery::VALUE_TRUE) { return true; } else if (word == DataQuery::VALUE_FALSE) { return false; } else { ZLOGE("StringToBoolean wrong value."); return false; } } std::string QueryHelper::StringToString(const std::string &word) { std::string result = word; if (result.compare(DataQuery::EMPTY_STRING) == 0) { result = ""; return result; } size_t index = 0; // search from the beginning of the string while (true) { index = result.find(DataQuery::SPACE_ESCAPE, index); if (index == std::string::npos) { break; } result.replace(index, 2, DataQuery::SPACE); // 2 chars to be replaced index += 1; // replaced with 1 char, keep searching the remaining string } index = 0; // search from the beginning of the string while (true) { index = result.find(DataQuery::SPECIAL_ESCAPE, index); if (index == std::string::npos) { break; } result.replace(index, 3, DataQuery::SPECIAL); // 3 chars to be replaced index += 1; // replaced with 1 char, keep searching the remaining string } return result; } std::vector<int> QueryHelper::GetIntegerList(const std::vector<std::string> &words, int &elementPointer, int end) { std::vector<int> valueList; bool isEndFound = false; while (elementPointer <= end) { if (words.at(elementPointer) == DataQuery::END_IN) { isEndFound = true; break; } valueList.push_back(StringToInt(words.at(elementPointer))); elementPointer++; } if (isEndFound) { return valueList; } else { ZLOGE("GetIntegerList failed."); return std::vector<int>(); } } std::vector<int64_t> QueryHelper::GetLongList(const std::vector<std::string> &words, int &elementPointer, int end) { std::vector<int64_t> valueList; bool isEndFound = false; while (elementPointer <= end) { if (words.at(elementPointer) == DataQuery::END_IN) { isEndFound = true; break; } valueList.push_back(StringToLong(words.at(elementPointer))); elementPointer++; } if (isEndFound) { return valueList; } else { ZLOGE("GetLongList failed."); return std::vector<int64_t>(); } } std::vector<double> QueryHelper::GetDoubleList(const std::vector<std::string> &words, int &elementPointer, int end) { std::vector<double> valueList; bool isEndFound = false; while (elementPointer <= end) { if (words.at(elementPointer) == DataQuery::END_IN) { isEndFound = true; break; } valueList.push_back(StringToDouble(words.at(elementPointer))); elementPointer++; } if (isEndFound) { return valueList; } else { ZLOGE("GetDoubleList failed."); return std::vector<double>(); } } std::vector<std::string> QueryHelper::GetStringList(const std::vector<std::string> &words, int &elementPointer, int end) { std::vector<std::string> valueList; bool isEndFound = false; while (elementPointer <= end) { if (words.at(elementPointer) == DataQuery::END_IN) { isEndFound = true; break; } valueList.push_back(StringToString(words.at(elementPointer))); elementPointer++; } if (isEndFound) { return valueList; } else { ZLOGE("GetStringList failed."); return std::vector<std::string>(); } } } // namespace OHOS::DistributedKv