BalancingRobot/Software/HighLevelApp/MutableStorageKVP/MutableStorageKVP.c (143 lines of code) (raw):
/* Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License. */
#include "MutableStorageKVP.h"
#include <applibs/storage.h>
#include <string.h>
#include "cJSON.h"
#include <errno.h>
ssize_t getStorageString(char **jsonString);
bool writeJsonToStorage(cJSON *cJson);
/// <summary>
/// Writes Key/Value pair (keyName, String) into Mutable storage (JSON).
/// Returns 'true' on success, 'false' on failure.
/// </summary>
bool WriteProfileString(char *keyName, char *value)
{
#ifdef SHOW_DEBUG_MSGS
Log_Debug(">>> %s\n", __func__);
#endif
char *jsonString = 0x00;
ssize_t length = getStorageString(&jsonString);
if (length == -1)
{
Log_Debug("Error: writing to mutable storage: errno %d\n", errno);
return false;
}
cJSON *cJson = NULL;
if (length == 0) // nothing in storage.
{
cJson = cJSON_CreateObject();
cJSON_AddStringToObject(cJson, keyName, value);
}
else
{
// convert to JSON, read the element.
cJson = cJSON_Parse(jsonString);
cJSON *pItem = cJSON_GetObjectItemCaseSensitive(cJson, keyName);
if (pItem == NULL) // don't have the item in the JSON
{
cJSON_AddStringToObject(cJson, keyName, value);
}
else
{
cJSON *pNewItem = cJSON_CreateString(value);
cJSON_ReplaceItemInObjectCaseSensitive(cJson, keyName, pNewItem);
}
}
writeJsonToStorage(cJson);
cJSON_Delete(cJson);
free(jsonString);
return true;
}
bool DeleteProfileString(char *keyName)
{
#ifdef SHOW_DEBUG_MSGS
Log_Debug(">>> %s\n", __func__);
#endif
char *jsonString = 0x00;
ssize_t length = getStorageString(&jsonString);
// nothing in storage, bail
if (length == -1)
return false;
// convert to JSON, read the element.
cJSON *cJson = cJSON_Parse(jsonString);
bool ret = false;
cJSON *pItem = cJSON_GetObjectItemCaseSensitive(cJson, keyName);
if (pItem != NULL) // item is in the JSON
{
cJSON_DeleteItemFromObject(cJson, keyName);
writeJsonToStorage(cJson);
ret = true;
}
cJSON_Delete(cJson);
free(jsonString);
return ret;
}
/// <summary>
/// Gets Value from storage based on KeyName.
/// returns -1 for error or no matching Key
/// </summary>
ssize_t GetProfileString(char *keyName, char *returnedString, size_t Size)
{
#ifdef SHOW_DEBUG_MSGS
Log_Debug(">>> %s\n", __func__);
#endif
char *jsonString = 0x00;
ssize_t length = getStorageString(&jsonString);
// Log_Debug("GetProfileString JSON: %s\n", jsonString);
if (length <= 0)
{
Log_Debug("Error: reading mutable storage: errno %d\n", errno);
return -1;
}
ssize_t retVal = -1;
memset(returnedString, 0x00, Size);
// convert to JSON, read the element.
cJSON *cJson = cJSON_Parse(jsonString);
cJSON *pItem = cJSON_GetObjectItemCaseSensitive(cJson, keyName);
if (pItem != NULL)
{
size_t sLength = strlen(pItem->valuestring);
if (sLength <= Size)
{
strncpy(returnedString, pItem->valuestring, sLength);
retVal = (ssize_t)sLength;
}
}
cJSON_Delete(cJson);
free(jsonString);
return retVal;
}
/// <summary>
/// Reads JSON string from storage
/// returns -1 for error or length of string on success
/// caller is responsible for releasing allocated memory
/// </summary>
ssize_t getStorageString(char **jsonString)
{
#ifdef SHOW_DEBUG_MSGS
Log_Debug(">>> %s\n", __func__);
#endif
int fd = Storage_OpenMutableFile();
ssize_t ret = -1;
if (fd != -1)
{
off_t length = lseek(fd, 0, SEEK_END);
*jsonString = (char*)malloc((size_t)length + 1);
#ifdef SHOW_DEBUG_MSGS
Log_Debug("malloc %s, 0x%lx\n", __func__, jsonString);
#endif
memset(*jsonString, 0x00, (size_t)length + 1);
lseek(fd, 0, SEEK_SET);
ret = read(fd, *jsonString, (size_t)length);
close(fd);
}
return ret;
}
/// <summary>
/// Writes JSON string to storage (extracts char * from cJSON object)
/// Returns 'true' for success, 'false' for failure.
/// </summary>
bool writeJsonToStorage(cJSON *cJson)
{
#ifdef SHOW_DEBUG_MSGS
Log_Debug(">>> %s\n", __func__);
#endif
bool bRet = false;
Storage_DeleteMutableFile(); // delete original file before writing new file
int fd = Storage_OpenMutableFile();
if (fd != -1)
{
char *data = cJSON_Print(cJson);
size_t dataLen = strlen(data);
lseek(fd, 0, SEEK_SET);
ssize_t numWritten=write(fd, data, dataLen);
close(fd);
free(data);
if (numWritten == (ssize_t)dataLen)
bRet = true;
}
#ifdef SHOW_DEBUG_MSGS
if (bRet == false)
{
Log_Debug("Error: error writing json to mutable storage\n");
}
#endif
return bRet;
}