mirror of
https://github.com/openharmony/utils_native_lite.git
synced 2026-07-21 01:35:27 -04:00
@@ -0,0 +1 @@
|
||||
../../../foundation/distributeddatamgr/appdatamgr/frameworks/innerkitsimpl/kv_store
|
||||
@@ -1,18 +0,0 @@
|
||||
# Copyright (c) 2020 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.
|
||||
|
||||
import("//build/lite/config/component/lite_component.gni")
|
||||
|
||||
lite_component("kv_store") {
|
||||
features = [ "src:utils_kv_store" ]
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef KV_STORE_ENV_API_H
|
||||
#define KV_STORE_ENV_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int UtilsSetEnv(const char* path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // KV_STORE_ENV_API_H
|
||||
@@ -1,48 +0,0 @@
|
||||
# Copyright (c) 2020 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.
|
||||
|
||||
declare_args() {
|
||||
enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true
|
||||
}
|
||||
|
||||
if (ohos_kernel_type == "liteos_m") {
|
||||
static_library("utils_kv_store") {
|
||||
sources = [ "kvstore_common/kvstore_common.c" ]
|
||||
if (enable_ohos_utils_native_lite_kv_store_use_posix_kv_api) {
|
||||
sources += [ "kvstore_impl_posix/kv_store.c" ]
|
||||
} else {
|
||||
sources += [ "kvstore_impl_hal/kv_store.c" ]
|
||||
}
|
||||
include_dirs = [
|
||||
"//utils/native/lite/include",
|
||||
"kvstore_common",
|
||||
"//utils/native/lite/kv_store/innerkits",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
shared_library("utils_kv_store") {
|
||||
cflags = [ "-Wall" ]
|
||||
cflags_cc = cflags
|
||||
sources = [
|
||||
"kvstore_common/kvstore_common.c",
|
||||
"kvstore_impl_posix/kv_store.c",
|
||||
]
|
||||
include_dirs = [
|
||||
"//utils/native/lite/include",
|
||||
"kvstore_common",
|
||||
"//third_party/bounds_checking_function/include",
|
||||
"//utils/native/lite/kv_store/innerkits",
|
||||
]
|
||||
public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#include "kvstore_common.h"
|
||||
#include <ctype.h>
|
||||
#include <securec.h>
|
||||
#include <stdlib.h>
|
||||
#include "ohos_errno.h"
|
||||
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
static KvItem* g_itemHeader = NULL;
|
||||
static KvItem* g_itemTail = NULL;
|
||||
static int g_sum = 0;
|
||||
#endif
|
||||
|
||||
boolean IsValidChar(const char ch)
|
||||
{
|
||||
if (islower(ch) || isdigit(ch) || (ch == '_') || (ch == '.')) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
boolean IsValidValue(const char* value, unsigned int len)
|
||||
{
|
||||
if (value == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
size_t valueLen = strnlen(value, MAX_VALUE_LEN);
|
||||
if ((valueLen == 0) || (valueLen >= MAX_VALUE_LEN) || (valueLen >= len)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean IsValidKey(const char* key)
|
||||
{
|
||||
if (!IsValidValue(key, MAX_KEY_LEN)) {
|
||||
return FALSE;
|
||||
}
|
||||
size_t keyLen = strnlen(key, MAX_KEY_LEN);
|
||||
for (size_t i = 0; i < keyLen; i++) {
|
||||
if (!IsValidChar(key[i])) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
static void FreeItem(KvItem* item)
|
||||
{
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
if (item->key != NULL) {
|
||||
free(item->key);
|
||||
}
|
||||
if (item->value != NULL) {
|
||||
free(item->value);
|
||||
}
|
||||
free(item);
|
||||
}
|
||||
|
||||
void DeleteKVCache(const char* key)
|
||||
{
|
||||
if (key == NULL || g_itemHeader == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
KvItem* item = g_itemHeader;
|
||||
while (strcmp(key, item->key) != 0) {
|
||||
item = item->next;
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_sum--;
|
||||
if (g_sum == 0) {
|
||||
g_itemHeader = NULL;
|
||||
g_itemTail = NULL;
|
||||
} else if (item == g_itemHeader) {
|
||||
g_itemHeader = item->next;
|
||||
g_itemHeader->prev = NULL;
|
||||
} else if (item == g_itemTail) {
|
||||
g_itemTail = item->prev;
|
||||
g_itemTail->next = NULL;
|
||||
} else {
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
}
|
||||
FreeItem(item);
|
||||
}
|
||||
|
||||
void AddKVCache(const char* key, const char* value, boolean isNew)
|
||||
{
|
||||
if (key == NULL || value == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t keyLen = strnlen(key, MAX_KEY_LEN);
|
||||
size_t valueLen = strnlen(value, MAX_VALUE_LEN);
|
||||
if ((keyLen >= MAX_KEY_LEN) || (valueLen >= MAX_VALUE_LEN)) {
|
||||
return;
|
||||
}
|
||||
if (isNew) {
|
||||
DeleteKVCache(key);
|
||||
}
|
||||
KvItem* item = (KvItem *)malloc(sizeof(KvItem));
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
(void)memset_s(item, sizeof(KvItem), 0, sizeof(KvItem));
|
||||
item->key = (char *)malloc(keyLen + 1);
|
||||
item->value = (char *)malloc(valueLen + 1);
|
||||
if ((item->key == NULL) || (item->value == NULL)) {
|
||||
FreeItem(item);
|
||||
return;
|
||||
}
|
||||
if ((strcpy_s(item->key, keyLen + 1, key) != EOK) ||
|
||||
(strcpy_s(item->value, valueLen + 1, value) != EOK)) {
|
||||
FreeItem(item);
|
||||
return;
|
||||
}
|
||||
item->prev = NULL;
|
||||
item->next = NULL;
|
||||
if (g_itemHeader == NULL) {
|
||||
g_itemHeader = item;
|
||||
g_itemTail = item;
|
||||
g_sum++;
|
||||
return;
|
||||
}
|
||||
item->next = g_itemHeader;
|
||||
g_itemHeader->prev = item;
|
||||
g_itemHeader = item;
|
||||
g_sum++;
|
||||
while (g_sum > MAX_CACHE_SIZE) {
|
||||
KvItem* needDel = g_itemTail;
|
||||
g_itemTail = g_itemTail->prev;
|
||||
FreeItem(needDel);
|
||||
g_itemTail->next = NULL;
|
||||
g_sum--;
|
||||
}
|
||||
}
|
||||
|
||||
int GetValueByCache(const char* key, char* value, unsigned int maxLen)
|
||||
{
|
||||
if (key == NULL || value == NULL || g_itemHeader == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
|
||||
KvItem* item = g_itemHeader;
|
||||
while (strcmp(key, item->key) != 0) {
|
||||
item = item->next;
|
||||
if (item == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
}
|
||||
size_t valueLen = strnlen(item->value, MAX_VALUE_LEN);
|
||||
if (valueLen >= MAX_VALUE_LEN) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if ((valueLen >= maxLen) || (strcpy_s(value, maxLen, item->value) != EOK)) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
int ClearKVCacheInner(void)
|
||||
{
|
||||
if (g_itemHeader == NULL) {
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
KvItem* item = g_itemHeader;
|
||||
while (item != NULL) {
|
||||
KvItem* temp = item;
|
||||
item = item->next;
|
||||
FreeItem(temp);
|
||||
g_sum--;
|
||||
}
|
||||
g_itemHeader = NULL;
|
||||
g_itemTail = NULL;
|
||||
|
||||
return (g_sum != 0) ? EC_FAILURE : EC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef KV_STORE_COMMON_H
|
||||
#define KV_STORE_COMMON_H
|
||||
|
||||
#include "ohos_types.h"
|
||||
#include "utils_config.h"
|
||||
|
||||
#define MAX_KEY_LEN 32
|
||||
#define MAX_VALUE_LEN 128
|
||||
|
||||
boolean IsValidChar(const char ch);
|
||||
boolean IsValidValue(const char* value, unsigned int len);
|
||||
boolean IsValidKey(const char* key);
|
||||
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
typedef struct KvItem_ {
|
||||
char* key;
|
||||
char* value;
|
||||
struct KvItem_* next;
|
||||
struct KvItem_* prev;
|
||||
} KvItem;
|
||||
|
||||
void DeleteKVCache(const char* key);
|
||||
void AddKVCache(const char* key, const char* value, boolean isNew);
|
||||
int GetValueByCache(const char* key, char* value, unsigned int maxLen);
|
||||
int ClearKVCacheInner(void);
|
||||
#endif
|
||||
|
||||
#endif // KV_STORE_COMMON_H
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#include "kv_store.h"
|
||||
#include <ctype.h>
|
||||
#include <securec.h>
|
||||
#include <stdlib.h>
|
||||
#include "kvstore_common.h"
|
||||
#include "ohos_errno.h"
|
||||
#include "ohos_types.h"
|
||||
#include "utils_config.h"
|
||||
#include "utils_file.h"
|
||||
|
||||
#define MAX_GET_VALUE_LEN 0x7FFFFFFF
|
||||
#define KV_SUM_FILE "KV_FILE_SUM"
|
||||
#define KV_SUM_INDEX 4
|
||||
|
||||
static int GetValueByFile(const char* key, char* value, unsigned int len)
|
||||
{
|
||||
unsigned int valueLen = 0;
|
||||
if (UtilsFileStat(key, &valueLen) != EC_SUCCESS) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (valueLen >= len) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int fd = UtilsFileOpen(key, O_RDONLY_FS, 0);
|
||||
if (fd < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = UtilsFileRead(fd, value, valueLen);
|
||||
UtilsFileClose(fd);
|
||||
fd = -1;
|
||||
if (ret < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
value[valueLen] = '\0';
|
||||
return valueLen;
|
||||
}
|
||||
|
||||
static int SetValueToFile(const char* key, const char* value)
|
||||
{
|
||||
int fd = UtilsFileOpen(key, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0);
|
||||
if (fd < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = UtilsFileWrite(fd, value, strlen(value));
|
||||
UtilsFileClose(fd);
|
||||
fd = -1;
|
||||
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int GetCurrentItem(void)
|
||||
{
|
||||
int fd = UtilsFileOpen(KV_SUM_FILE, O_RDWR_FS, 0);
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
char value[KV_SUM_INDEX] = {0};
|
||||
int ret = UtilsFileRead(fd, value, KV_SUM_INDEX);
|
||||
UtilsFileClose(fd);
|
||||
fd = -1;
|
||||
return (ret < 0) ? 0 : atoi(value);
|
||||
}
|
||||
|
||||
static int SetCurrentItem(const int num)
|
||||
{
|
||||
char value[KV_SUM_INDEX] = {0};
|
||||
if (sprintf_s(value, KV_SUM_INDEX, "%d", num) < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int fd = UtilsFileOpen(KV_SUM_FILE, O_RDWR_FS | O_CREAT_FS, 0);
|
||||
if (fd < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = UtilsFileWrite(fd, value, KV_SUM_INDEX);
|
||||
UtilsFileClose(fd);
|
||||
fd = -1;
|
||||
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
|
||||
}
|
||||
|
||||
static boolean NewItem(const char* key)
|
||||
{
|
||||
int fd = UtilsFileOpen(key, O_RDONLY_FS, 0);
|
||||
if (fd < 0) {
|
||||
return TRUE;
|
||||
}
|
||||
UtilsFileClose(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int UtilsGetValue(const char* key, char* value, unsigned int len)
|
||||
{
|
||||
if (!IsValidKey(key) || (value == NULL) || (len > MAX_GET_VALUE_LEN)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
if (GetValueByCache(key, value, len) == EC_SUCCESS) {
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
int ret = GetValueByFile(key, value, len);
|
||||
if (ret < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
AddKVCache(key, value, FALSE);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UtilsSetValue(const char* key, const char* value)
|
||||
{
|
||||
if (!IsValidKey(key) || !IsValidValue(value, MAX_VALUE_LEN)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
int currentNum = GetCurrentItem();
|
||||
boolean newItem = NewItem(key);
|
||||
if ((currentNum >= MAX_KV_SUM) && newItem) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = SetValueToFile(key, value);
|
||||
if (ret == EC_SUCCESS) {
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
AddKVCache(key, value, TRUE);
|
||||
#endif
|
||||
if (newItem) {
|
||||
currentNum++;
|
||||
}
|
||||
}
|
||||
|
||||
return SetCurrentItem(currentNum);
|
||||
}
|
||||
|
||||
int UtilsDeleteValue(const char* key)
|
||||
{
|
||||
if (!IsValidKey(key)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
DeleteKVCache(key);
|
||||
#endif
|
||||
int ret = UtilsFileDelete(key);
|
||||
if (ret == EC_SUCCESS) {
|
||||
ret = SetCurrentItem(GetCurrentItem() - 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
int ClearKVCache(void)
|
||||
{
|
||||
return ClearKVCacheInner();
|
||||
}
|
||||
#endif
|
||||
|
||||
int UtilsSetEnv(const char* path)
|
||||
{
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
@@ -1,320 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#include "kv_store.h"
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <securec.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "kvstore_common.h"
|
||||
#include "kvstore_env.h"
|
||||
#include "ohos_errno.h"
|
||||
#include "ohos_types.h"
|
||||
#include "utils_config.h"
|
||||
|
||||
#define KVSTORE_PATH "kvstore"
|
||||
#define MAX_KEY_PATH 256
|
||||
#define MAX_GET_VALUE_LEN 0x7FFFFFFF
|
||||
static pthread_mutex_t g_kvGlobalMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int g_kvSum = 0;
|
||||
static boolean g_getKvSum = FALSE;
|
||||
static char g_dataPath[MAX_KEY_PATH + 1] = {0};
|
||||
|
||||
static int GetResolvedPath(const char* dataPath, const char* key, char* resolvedPath, unsigned int len)
|
||||
{
|
||||
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
|
||||
if (keyPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (realpath(keyPath, resolvedPath) != NULL) {
|
||||
free(keyPath);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
if (errno == ENOENT) {
|
||||
if (strncpy_s(resolvedPath, len, keyPath, strlen(keyPath)) == EOK) {
|
||||
free(keyPath);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
}
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
|
||||
static int GetValueByFile(const char* dataPath, const char* key, char* value, unsigned int len)
|
||||
{
|
||||
char* keyPath = (char *)malloc(PATH_MAX + 1);
|
||||
if (keyPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (GetResolvedPath(dataPath, key, keyPath, PATH_MAX + 1) != EC_SUCCESS) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
struct stat info = {0};
|
||||
if (stat(keyPath, &info) != F_OK) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (info.st_size >= len) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int fd = open(keyPath, O_RDONLY, S_IRUSR);
|
||||
free(keyPath);
|
||||
keyPath = NULL;
|
||||
if (fd < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = read(fd, value, info.st_size);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
if (ret < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
value[info.st_size] = '\0';
|
||||
return info.st_size;
|
||||
}
|
||||
|
||||
static int SetValueToFile(const char* dataPath, const char* key, const char* value)
|
||||
{
|
||||
char* keyPath = (char *)malloc(PATH_MAX + 1);
|
||||
if (keyPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (GetResolvedPath(dataPath, key, keyPath, PATH_MAX + 1) != EC_SUCCESS) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int fd = open(keyPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
free(keyPath);
|
||||
keyPath = NULL;
|
||||
if (fd < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = write(fd, value, strlen(value));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int DeleteValueFromFile(const char* dataPath, const char* key)
|
||||
{
|
||||
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
|
||||
if (keyPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
|
||||
free(keyPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
int ret = unlink(keyPath);
|
||||
free(keyPath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int InitKv(const char* dataPath)
|
||||
{
|
||||
if (dataPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
char* kvPath = (char *)malloc(MAX_KEY_PATH + 1);
|
||||
if (kvPath == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (sprintf_s(kvPath, MAX_KEY_PATH + 1, "%s/%s", dataPath, KVSTORE_PATH) < 0) {
|
||||
free(kvPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (access(kvPath, F_OK) == F_OK) {
|
||||
free(kvPath);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
if (mkdir(kvPath, S_IRUSR | S_IWUSR | S_IXUSR) != F_OK) {
|
||||
free(kvPath);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
free(kvPath);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
static int GetCurrentItem(const char* dataPath)
|
||||
{
|
||||
char kvPath[MAX_KEY_PATH + 1] = {0};
|
||||
if (sprintf_s(kvPath, MAX_KEY_PATH + 1, "%s/%s", dataPath, KVSTORE_PATH) < 0) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
DIR* fileDir = opendir(kvPath);
|
||||
if (fileDir == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
struct dirent* dir = readdir(fileDir);
|
||||
int sum = 0;
|
||||
while (dir != NULL) {
|
||||
char fullPath[MAX_KEY_PATH + 1] = {0};
|
||||
struct stat info = {0};
|
||||
if (sprintf_s(fullPath, MAX_KEY_PATH + 1, "%s/%s", kvPath, dir->d_name) < 0) {
|
||||
closedir(fileDir);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (stat(fullPath, &info) != 0) {
|
||||
closedir(fileDir);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (S_ISREG(info.st_mode)) {
|
||||
sum++;
|
||||
}
|
||||
dir = readdir(fileDir);
|
||||
}
|
||||
closedir(fileDir);
|
||||
return sum;
|
||||
}
|
||||
|
||||
static boolean NewItem(const char* dataPath, const char* key)
|
||||
{
|
||||
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
|
||||
if (keyPath == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
|
||||
free(keyPath);
|
||||
return FALSE;
|
||||
}
|
||||
if (access(keyPath, F_OK) == F_OK) {
|
||||
free(keyPath);
|
||||
return FALSE;
|
||||
}
|
||||
free(keyPath);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int UtilsGetValue(const char* key, char* value, unsigned int len)
|
||||
{
|
||||
if (!IsValidKey(key) || (value == NULL) || (len > MAX_GET_VALUE_LEN)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
pthread_mutex_lock(&g_kvGlobalMutex);
|
||||
const char* dataPath = g_dataPath;
|
||||
if (dataPath == NULL) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
if (GetValueByCache(key, value, len) == EC_SUCCESS) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
int ret = GetValueByFile(dataPath, key, value, len);
|
||||
if (ret < 0) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
AddKVCache(key, value, FALSE);
|
||||
#endif
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UtilsSetValue(const char* key, const char* value)
|
||||
{
|
||||
if (!IsValidKey(key) || !IsValidValue(value, MAX_VALUE_LEN)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
pthread_mutex_lock(&g_kvGlobalMutex);
|
||||
const char* dataPath = g_dataPath;
|
||||
int ret = InitKv(dataPath);
|
||||
if (ret != EC_SUCCESS) {
|
||||
g_getKvSum = FALSE;
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
if (!g_getKvSum) {
|
||||
g_kvSum = GetCurrentItem(dataPath);
|
||||
if (g_kvSum < 0) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
g_getKvSum = TRUE;
|
||||
}
|
||||
boolean newItem = NewItem(dataPath, key);
|
||||
if ((g_kvSum >= MAX_KV_SUM) && newItem) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
ret = SetValueToFile(dataPath, key, value);
|
||||
if (ret == EC_SUCCESS) {
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
AddKVCache(key, value, TRUE);
|
||||
#endif
|
||||
if (newItem) {
|
||||
g_kvSum++;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UtilsDeleteValue(const char* key)
|
||||
{
|
||||
if (!IsValidKey(key)) {
|
||||
return EC_INVALID;
|
||||
}
|
||||
pthread_mutex_lock(&g_kvGlobalMutex);
|
||||
const char* dataPath = g_dataPath;
|
||||
if (dataPath == NULL) {
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
DeleteKVCache(key);
|
||||
#endif
|
||||
int ret = DeleteValueFromFile(dataPath, key);
|
||||
if (ret == EC_SUCCESS) {
|
||||
g_kvSum--;
|
||||
}
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_KV_CACHE
|
||||
int ClearKVCache(void)
|
||||
{
|
||||
pthread_mutex_lock(&g_kvGlobalMutex);
|
||||
int ret = ClearKVCacheInner();
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int UtilsSetEnv(const char* path)
|
||||
{
|
||||
if (path == NULL) {
|
||||
return EC_FAILURE;
|
||||
}
|
||||
pthread_mutex_lock(&g_kvGlobalMutex);
|
||||
int ret = strcpy_s(g_dataPath, MAX_KEY_PATH + 1, path);
|
||||
pthread_mutex_unlock(&g_kvGlobalMutex);
|
||||
return (ret != EOK) ? EC_FAILURE : EC_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user