// ------------------------------------------------------------------------------------------------- static json_t* CreateJsonNodeFromIterator ( le_cfg_IteratorRef_t iterRef ///< The iterator to read from. ) // ------------------------------------------------------------------------------------------------- { char nodeName[LE_CFG_NAME_LEN_BYTES] = ""; le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); le_cfg_GetNodeName(iterRef, "", nodeName, sizeof(nodeName)); json_t* nodePtr = CreateJsonNode(nodeName, NodeTypeStr(type)); switch (type) { case LE_CFG_TYPE_EMPTY: json_object_set_new(nodePtr, JSON_FIELD_TYPE, json_string(NodeTypeStr(LE_CFG_TYPE_STEM))); json_object_set_new(nodePtr, JSON_FIELD_CHILDREN, json_array()); break; case LE_CFG_TYPE_BOOL: json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_boolean(le_cfg_GetBool(iterRef, "", false))); break; case LE_CFG_TYPE_STRING: { char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, ""); json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_string(strBuffer)); } break; case LE_CFG_TYPE_INT: json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_integer(le_cfg_GetInt(iterRef, "", false))); break; case LE_CFG_TYPE_FLOAT: json_object_set_new(nodePtr, JSON_FIELD_VALUE, json_real(le_cfg_GetFloat(iterRef, "", false))); break; case LE_CFG_TYPE_STEM: default: // Unknown type, nothing to do json_decref(nodePtr); nodePtr = NULL; break; } return nodePtr; }
// ------------------------------------------------------------------------------------------------- static void DumpTreeJSON ( le_cfg_IteratorRef_t iterRef, ///< Read the tree data from this iterator. json_t* jsonObject ///< JSON object to hold the tree data. ) // ------------------------------------------------------------------------------------------------- { // Note that because this is a recursive function, the buffer here is static in order to save on // stack space. The implication here is that we then have to be careful how it is later // accessed. Also, this makes the function not thread safe. But this trade off was made as // this was not intended to be a multi-threaded program. static char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; // Build up the child array. json_t* childArrayPtr = json_array(); do { // Simply grab the name and the type of the current node. le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer)); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { // It's a stem object, so mark this item as being a stem and recurse into the stem's // sub-items. case LE_CFG_TYPE_STEM: { json_t* nodePtr = CreateJsonNode(strBuffer, NodeTypeStr(type)); le_cfg_GoToFirstChild(iterRef); DumpTreeJSON(iterRef, nodePtr); le_cfg_GoToParent(iterRef); json_array_append(childArrayPtr, nodePtr); } break; default: { json_t* nodePtr = CreateJsonNodeFromIterator(iterRef); if (nodePtr != NULL) { json_array_append(childArrayPtr, nodePtr); } } break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); // Set children into the JSON document. json_object_set_new(jsonObject, JSON_FIELD_CHILDREN, childArrayPtr); }
static void DumpTree(le_cfg_IteratorRef_t iterRef, size_t indent) { if (le_arg_NumArgs() == 1) { return; } static char strBuffer[STR_SIZE] = { 0 }; do { size_t i; for (i = 0; i < indent; i++) { printf(" "); } le_cfg_GetNodeName(iterRef, "", strBuffer, STR_SIZE); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { case LE_CFG_TYPE_STEM: printf("%s/\n", strBuffer); le_cfg_GoToFirstChild(iterRef); DumpTree(iterRef, indent + 2); le_cfg_GoToParent(iterRef); break; case LE_CFG_TYPE_EMPTY: printf("%s~~\n", strBuffer); break; default: printf("%s<%s> == ", strBuffer, NodeTypeStr(iterRef)); le_cfg_GetString(iterRef, "", strBuffer, STR_SIZE, ""); printf("%s\n", strBuffer); break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); }
// ------------------------------------------------------------------------------------------------- static int HandleSet ( void ) // ------------------------------------------------------------------------------------------------- { // Looks like we're trying to write a value to a node. Get the node's current type and then // write the requested value to that node. le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(NodePath); le_cfg_nodeType_t originalType = le_cfg_GetNodeType(iterRef, ""); le_cfg_nodeType_t newType = DataType; if ( (newType != originalType) && (originalType != LE_CFG_TYPE_DOESNT_EXIST)) { printf("Converting node '%s' type from %s to %s.\n", NodePath, NodeTypeStr(originalType), NodeTypeStr(newType)); } int result = EXIT_SUCCESS; switch (newType) { case LE_CFG_TYPE_STRING: le_cfg_SetString(iterRef, "", NodeValue); break; case LE_CFG_TYPE_BOOL: if (strcmp(NodeValue, "false") == 0) { le_cfg_SetBool(iterRef, "", false); } else if (strcmp(NodeValue, "true") == 0) { le_cfg_SetBool(iterRef, "", true); } else { fprintf(stderr, "Bad boolean value '%s'.\n", NodeValue); } break; case LE_CFG_TYPE_INT: { char *endIntp; errno = 0; int32_t value = strtol(NodeValue, &endIntp, 10); if (errno != 0) { fprintf(stderr, "Integer '%s' out of range\n", NodeValue); result = EXIT_FAILURE; } else if (*endIntp != '\0') { fprintf(stderr, "Invalid character in integer '%s'\n", NodeValue); result = EXIT_FAILURE; } else { le_cfg_SetInt(iterRef, "", value); } break; } case LE_CFG_TYPE_FLOAT: { char *endFloatp; errno = 0; double floatVal = strtod(NodeValue, &endFloatp); if (errno != 0) { fprintf(stderr, "Float value '%s' out of range\n", NodeValue); result = EXIT_FAILURE; } else if (*endFloatp != '\0') { fprintf(stderr, "Invalid character in float value '%s'\n", NodeValue); result = EXIT_FAILURE; } else { le_cfg_SetFloat(iterRef, "", floatVal); } break; } case LE_CFG_TYPE_DOESNT_EXIST: result = EXIT_FAILURE; break; default: fprintf(stderr, "Unexpected node type specified, %s.\n", NodeTypeStr(newType)); result = EXIT_FAILURE; break; } // Finally, commit the value update, if the set was successful. if (result != EXIT_FAILURE) { le_cfg_CommitTxn(iterRef); } else { le_cfg_CancelTxn(iterRef); } return result; }
// ------------------------------------------------------------------------------------------------- static int HandleGetJSON ( const char* nodePathPtr, ///< Path to the node in the configTree. const char* filePathPtr ///< Path to the file in the file system. If NULL STDOUT is used ///< instead of a file. ) // ------------------------------------------------------------------------------------------------- { json_t* nodePtr = NULL; // Get the node path from our command line arguments. if (strcmp("*", nodePathPtr) == 0) { // Dump all trees // Create JSON root item json_t* rootPtr = CreateJsonNode("root", "root"); json_t* treeListPtr = json_array(); // Loop through the trees in the system. le_cfgAdmin_IteratorRef_t iteratorRef = le_cfgAdmin_CreateTreeIterator(); while (le_cfgAdmin_NextTree(iteratorRef) == LE_OK) { // Allocate space for the tree name, plus space for a trailing :/ used when we create a // transaction for that tree. char treeName[MAX_TREE_NAME_BYTES + 2] = ""; if (le_cfgAdmin_GetTreeName(iteratorRef, treeName, MAX_TREE_NAME_BYTES) != LE_OK) { continue; } // JSON node for the tree. json_t* treeNodePtr = CreateJsonNode(treeName, "tree"); strcat(treeName, ":/"); // Start a read transaction at the specified node path. Then dump the value, (if any.) le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(treeName); le_cfg_GoToFirstChild(iterRef); // Dump tree to JSON DumpTreeJSON(iterRef, treeNodePtr); le_cfg_CancelTxn(iterRef); json_array_append(treeListPtr, treeNodePtr); } le_cfgAdmin_ReleaseTreeIterator(iteratorRef); // Finalize root object... json_object_set_new(rootPtr, "trees", treeListPtr); nodePtr = rootPtr; } else { // Start a read transaction at the specified node path. Then dump the value, (if any.) le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(nodePathPtr); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { case LE_CFG_TYPE_STEM: { char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; char nodeType[LE_CFG_STR_LEN_BYTES] = ""; le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer)); // If no name, we are dumping a complete tree. if (strlen(strBuffer) == 0) { strcpy(nodeType, "tree"); } else { strcpy(nodeType, NodeTypeStr(type)); } nodePtr = CreateJsonNode(strBuffer, nodeType); le_cfg_GoToFirstChild(iterRef); DumpTreeJSON(iterRef, nodePtr); le_cfg_GoToParent(iterRef); } break; default: nodePtr = CreateJsonNodeFromIterator(iterRef); break; } le_cfg_CancelTxn(iterRef); } if (nodePtr == NULL) { // Empty node nodePtr = json_object(); } // Dump Json content // stdout mode? int result = EXIT_SUCCESS; if (filePathPtr == NULL) { printf("%s\n", json_dumps(nodePtr, JSON_COMPACT)); } else if (json_dump_file(nodePtr, filePathPtr, JSON_COMPACT) != 0) { result = EXIT_FAILURE; } json_decref(nodePtr); return result; }
// ------------------------------------------------------------------------------------------------- static void DumpTree ( le_cfg_IteratorRef_t iterRef, ///< Write out the tree pointed to by this iterator. size_t indent ///< The amount of indentation to use for this item. ) // ------------------------------------------------------------------------------------------------- { // Note that because this is a recursive function, the buffer here is static in order to save on // stack space. The implication here is that we then have to be careful how it is later // accessed. Also, this makes the function not thread safe. But this trade off was made as // this was not intended to be a multi-threaded program. static char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; do { // Quick and dirty way to indent the tree item. size_t i; for (i = 0; i < indent; i++) { printf(" "); } // Simply grab the name and the type of the current node. le_cfg_GetNodeName(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { // It's a stem object, so mark this item as being a stem and recurse into the stem's // sub-items. case LE_CFG_TYPE_STEM: printf("%s/\n", strBuffer); le_cfg_GoToFirstChild(iterRef); DumpTree(iterRef, indent + 2); le_cfg_GoToParent(iterRef); // If we got back up to where we started then don't iterate the "root" node's // siblings. if (indent == 0) { return; } break; // The node is empty, so simply mark it as such. case LE_CFG_TYPE_EMPTY: printf("%s<empty>\n", strBuffer); break; case LE_CFG_TYPE_BOOL: { char* value = NULL; if (le_cfg_GetBool(iterRef, "", false)) { value = "true"; } else { value = "false"; } printf("%s<bool> == %s\n", strBuffer, value); } break; // The node has a different type. So write out the name and the type. Then print the // value. default: printf("%s<%s> == ", strBuffer, NodeTypeStr(le_cfg_GetNodeType(iterRef, ""))); le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, ""); printf("%s\n", strBuffer); break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); }