summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt15
-rw-r--r--src/ecbor.c2
-rw-r--r--src/ecbor_describe.c227
-rw-r--r--test/files/array0002
4 files changed, 242 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 957588a..db2b684 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,9 @@ cmake_minimum_required (VERSION 3.1)
project (ecbor LANGUAGES C)
+# Options
+option (BUILD_DESCRIBE_TOOL "build ecbor-describe" ON)
+
# Compiler setup
set (CMAKE_C_STANDARD 99)
@@ -29,8 +32,8 @@ set (LIB_SOURCES
"${SRC_DIR}/ecbor_decoder.c"
)
-set (TOOL_SOURCES
- # TODO
+set (DESCRIBE_TOOL_SOURCES
+ "${SRC_DIR}/ecbor_describe.c"
)
# Targets
@@ -40,4 +43,10 @@ add_library (${PROJECT_NAME}_static STATIC ${LIB_SOURCES})
set_target_properties (${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties (${PROJECT_NAME}_static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
-target_compile_options (${PROJECT_NAME}_static PRIVATE -nostdlib) \ No newline at end of file
+target_compile_options (${PROJECT_NAME}_static PRIVATE -nostdlib)
+
+# Tool Targets
+if (BUILD_DESCRIBE_TOOL)
+ add_executable (${PROJECT_NAME}-describe ${DESCRIBE_TOOL_SOURCES})
+ target_link_libraries (${PROJECT_NAME}-describe ${PROJECT_NAME}_shared)
+endif (BUILD_DESCRIBE_TOOL) \ No newline at end of file
diff --git a/src/ecbor.c b/src/ecbor.c
index 882f729..9612605 100644
--- a/src/ecbor.c
+++ b/src/ecbor.c
@@ -112,7 +112,7 @@ ecbor_get_array_item (ecbor_item_t *array, uint64_t index,
return rc;
}
- for (i = 0; i < index; i ++) {
+ for (i = 0; i < index+1; i ++) {
rc = ecbor_decode (&context, item);
if (rc != ECBOR_OK) {
if (rc == ECBOR_END_OF_BUFFER) {
diff --git a/src/ecbor_describe.c b/src/ecbor_describe.c
new file mode 100644
index 0000000..301505e
--- /dev/null
+++ b/src/ecbor_describe.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2018 Vasile Vilvoiu <vasi.vilvoiu@gmail.com>
+ *
+ * libecbor is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <malloc.h>
+#include <ecbor.h>
+
+/*
+ * Command line arguments
+ */
+static struct option long_options[] = {
+ { "help", no_argument, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+void print_help (void);
+void print_ecbor_error (ecbor_error_t err);
+ecbor_error_t print_ecbor_item (ecbor_item_t *item, int level);
+
+/*
+ * Print help
+ */
+void
+print_help (void)
+{
+ printf ("Usage: ecbor-describe [options] <filename>\n");
+ printf (" options:\n");
+ printf (" -h, --help Display this help message\n");
+}
+
+void
+print_ecbor_error (ecbor_error_t err)
+{
+ printf ("ECBOR error %d\n", err);
+}
+
+ecbor_error_t
+print_ecbor_item (ecbor_item_t *item, int level)
+{
+ ecbor_major_type_t mt;
+ ecbor_error_t rc;
+ int i;
+
+ for(i = 0; i < level * 2; i ++) putchar(' ');
+
+ mt = ecbor_get_type (item);
+ switch (mt) {
+ case ECBOR_MT_NINT:
+ {
+ int64_t val;
+
+ rc = ecbor_get_value (item, (void *) &val);
+ if (rc != ECBOR_OK) {
+ print_ecbor_error (rc);
+ return rc;
+ }
+
+ printf ("[NINT] value %d\n", (int)val);
+ }
+ break;
+
+ case ECBOR_MT_UINT:
+ {
+ uint64_t val;
+
+ rc = ecbor_get_value (item, (void *) &val);
+ if (rc != ECBOR_OK) {
+ print_ecbor_error (rc);
+ return rc;
+ }
+
+ printf ("[UINT] value %u\n", (unsigned int) val);
+ }
+ break;
+
+ case ECBOR_MT_ARRAY:
+ {
+ uint64_t len, i;
+
+ rc = ecbor_get_length (item, &len);
+ if (rc != ECBOR_OK) {
+ print_ecbor_error (rc);
+ return rc;
+ }
+
+ printf ("[ARRAY] len %u\n", (unsigned int) len);
+ for (i = 0; i < len; i ++) {
+ ecbor_item_t child;
+
+ rc = ecbor_get_array_item (item, i, &child);
+ if (rc != ECBOR_OK) {
+ print_ecbor_error (rc);
+ return rc;
+ }
+
+ print_ecbor_item (&child, level+1);
+ }
+ }
+ break;
+
+ default:
+ printf ("[UNKNOWN]\n");
+ break;
+ }
+
+ return ECBOR_OK;
+}
+
+/*
+ * Program entry
+ */
+int
+main(int argc, char **argv)
+{
+ char *filename = NULL;
+ unsigned char *cbor = NULL;
+ long int cbor_length = 0;
+
+ /* parse arguments */
+ while (1) {
+ int option_index, c;
+
+ c = getopt_long (argc, argv, "h", long_options, &option_index);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ default:
+ print_help ();
+ return 0;
+ }
+ }
+
+ if (optind != (argc-1)) {
+ printf ("Expecting exactly one file name!\n");
+ print_help ();
+ return -1;
+ } else {
+ filename = strdup (argv[optind]);
+ }
+
+ /* load CBOR data from file */
+ {
+ FILE *fp;
+
+ printf ("Reading CBOR from file '%s'\n", filename);
+ fp = fopen (filename, "rb");
+ if (!fp) {
+ printf ("Error opening file!\n");
+ return -1;
+ }
+
+ if (fseek (fp, 0L, SEEK_END)) {
+ printf ("Error seeking end of file!\n");
+ fclose (fp);
+ return -1;
+ }
+ cbor_length = ftell(fp);
+ if (cbor_length < 0) {
+ printf ("Error determining input size!\n");
+ fclose (fp);
+ return -1;
+ }
+ if (fseek (fp, 0L, SEEK_SET)) {
+ printf ("Error seeking beginning of file!\n");
+ fclose (fp);
+ return -1;
+ }
+
+ cbor = (unsigned char *) malloc (cbor_length);
+ if (!cbor) {
+ printf ("Error allocating %d bytes!\n", (int) cbor_length);
+ fclose (fp);
+ return -1;
+ }
+
+ if (fread (cbor, 1, cbor_length, fp) != (size_t) cbor_length) {
+ printf ("Error reading %d bytes!\n", (int) cbor_length);
+ fclose (fp);
+ return -1;
+ }
+
+ fclose (fp);
+ free (filename);
+ }
+
+ /* parse CBOR data */
+ {
+ ecbor_decode_context_t context;
+ ecbor_item_t item;
+ ecbor_error_t rc;
+
+ rc = ecbor_initialize_decode (&context, cbor, cbor_length);
+ if (rc != ECBOR_OK) {
+ print_ecbor_error (rc);
+ return -1;
+ }
+
+ printf ("CBOR objects:\n");
+
+ while (1) {
+ rc = ecbor_decode (&context, &item);
+ if (rc != ECBOR_OK) {
+ if (rc == ECBOR_END_OF_BUFFER) {
+ break;
+ }
+ print_ecbor_error (rc);
+ return -1;
+ }
+
+ print_ecbor_item (&item, 0);
+ }
+ }
+
+ free (cbor);
+
+ /* all ok */
+ return 0;
+} \ No newline at end of file
diff --git a/test/files/array000 b/test/files/array000
new file mode 100644
index 0000000..81c9910
--- /dev/null
+++ b/test/files/array000
@@ -0,0 +1,2 @@
+Ÿ
+ ÿ \ No newline at end of file