Merge branch 'master' into complete
diff --git "a/\043CMakeLists.txt\043" "b/\043CMakeLists.txt\043"
new file mode 100644
index 0000000..fb5a071
--- /dev/null
+++ "b/\043CMakeLists.txt\043"
@@ -0,0 +1,146 @@
+#
+#
+# top level build file for cn-cbor
+
+## prepare CMAKE
+cmake_minimum_required ( VERSION 3.0.0 )
+
+set ( VERSION_MAJOR 0 CACHE STRING "Project major version number")
+set ( VERSION_MINOR "1" CACHE STRING "Project minor version number" )
+set ( VERSION_PATCH "0" CACHE STRING "Project patch version number" )
+set ( CN_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )
+mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH CN_VERSION)
+
+project ( "cn-cbor" VERSION "${CN_VERSION}")
+
+find_package(Doxygen)
+
+## setup options
+option ( use_context "Use context pointer for CBOR functions" OFF )
+option ( verbose "Produce verbose makefile output" OFF )
+option ( optimize "Optimize for size" OFF )
+option ( fatal_warnings "Treat build warnings as errors" ON )
+option ( coveralls "Generate coveralls data" ON )
+option ( coveralls_send "Send data to coveralls site" OFF )
+option ( build_docs "Create docs using Doxygen" ${DOXYGEN_FOUND} )
+option ( build_shared_libs "Build Shared Libraries" ON)
+option ( no_floats "Build without floating point support" OFF )
+
+set ( dist_dir ${CMAKE_BINARY_DIR}/dist )
+set ( prefix ${CMAKE_INSTALL_PREFIX} )
+set ( exec_prefix ${CMAKE_INSTALL_PREFIX}/bin )
+set ( libdir ${CMAKE_INSTALL_PREFIX}/lib )
+set ( includedir ${CMAKE_INSTALL_PREFIX}/include )
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cn-cbor.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/cn-cbor.pc @ONLY)
+install (FILES ${CMAKE_CURRENT_BINARY_DIR}/cn-cbor.pc DESTINATION lib/pkgconfig )
+
+set ( package_prefix "${CMAKE_PACKAGE_NAME}-${CMAKE_SYSTEM_NAME}" )
+
+set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/bin )
+set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${dist_dir}/lib )
+set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${dist_dir}/lib )
+
+if (NOT CMAKE_BUILD_TYPE)
+ if ( optimize )
+ set ( CMAKE_BUILD_TYPE MinSizeRel )
+ set ( coveralls OFF )
+ set ( coveralls_send OFF )
+ else ()
+ set ( CMAKE_BUILD_TYPE Debug )
+ endif ()
+endif()
+
+if ( MSVC )
+ set (coveralls OFF)
+endif ()
+
+set (LIB_TYPE STATIC)
+if (build_shared_libs)
+ set (LIB_TYPE SHARED)
+endif (build_shared_libs)
+
+message ( "Build type: ${CMAKE_BUILD_TYPE}" )
+
+if ( CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
+ CMAKE_C_COMPILER_ID MATCHES "Clang" )
+ message ( STATUS "adding GCC/Clang options ")
+ add_definitions ( -std=gnu99 -Wall -Wextra -pedantic )
+ if ( fatal_warnings )
+ add_definitions ( -Werror )
+ endif ()
+ if ( optimize )
+ add_definitions ( -Os )
+ endif ()
+elseif ( MSVC )
+ add_definitions ( /W3 )
+ if ( fatal_warnings )
+ add_definitions ( /WX )
+ endif ()
+else ()
+ message ( FATAL_ERROR "unhandled compiler id: ${CMAKE_C_COMPILER_ID}" )
+endif ()
+
+if ( no_floats )
+ add_definitions(-DCBOR_NO_FLOAT)
+endif()
+
+if ( verbose )
+ set ( CMAKE_VERBOSE_MAKEFILE ON )
+endif ()
+
+## include the parts
+add_subdirectory ( include )
+add_subdirectory ( src )
+add_subdirectory ( test )
+
+install (FILES LICENSE README.md DESTINATION .)
+
+## setup packaging
+set ( CPACK_GENERATOR "TGZ" )
+set ( CPACK_PACKAGE_VERSION "${PROJECT_VERSION}" )
+set ( CPACK_SOURCE_GENERATOR "TGZ" )
+set ( CPACK_SOURCE_IGNORE_FILES "/\\\\.git/" )
+file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/.gitignore igs)
+foreach (ig IN ITEMS ${igs})
+ # remove comments
+ string ( REGEX REPLACE "^\\s*#.*" "" ig "${ig}")
+ # remove any other whitespace
+ string ( STRIP "${ig}" ig)
+ # anything left?
+ if (ig)
+ # dots are literal
+ string ( REPLACE "." "\\\\." ig "${ig}" )
+ # stars are on thars
+ string ( REPLACE "*" ".*" ig "${ig}" )
+ list ( APPEND CPACK_SOURCE_IGNORE_FILES "/${ig}/" )
+ endif()
+endforeach()
+
+set ( CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md )
+set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" )
+
+include ( CPack )
+include ( CTest )
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
+include ( LCov )
+
+if (build_docs)
+ if(NOT DOXYGEN_FOUND)
+ message(FATAL_ERROR "Doxygen is needed to build the documentation.")
+ endif()
+
+ set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
+ set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
+
+ configure_file(${doxyfile_in} ${doxyfile} @ONLY)
+
+ add_custom_target(doc
+ COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating API documentation with Doxygen"
+ VERBATIM)
+
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc)
+endif()
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..9c01ae9
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,16 @@
+image:
+ - Visual Studio 2019
+
+platform:
+ - x64
+
+configuration:
+ - release
+ - debug
+
+before_build:
+ - cmake -G "Visual Studio 16 2019" -Dfatal_warnings=OFF
+
+build:
+ project: $(APPVEYOR_BUILD_FOLDER)\$(APPVEYOR_PROJECT_NAME).sln
+
diff --git a/.gitignore b/.gitignore
index 09170e2..5fdd120 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,20 +3,25 @@
*.o
build
-# Files from Visual Studio Builds
-Debug
-Release
-
-# Files from emacs
+# Emacs temp files
*~
.#*
*#
-# files from cmake
+# Visual Stdio build directories
+Debug
+Release
+*.sln
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
-CMakeFiles
-CMakeCache.txt
-*.cmake
+*.VC.db
+*.VC.opendb
+/.vscode/
+# Output of CMake
+CMakeCache.txt
+CMakeFiles
+Makefile
+*.cmake
+install_manifest.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e076dc8..96911b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,137 +1,254 @@
-#
-#
-# top level build file for cn-cbor
+cmake_minimum_required(VERSION 3.0.0)
-## prepare CMAKE
-cmake_minimum_required ( VERSION 3.0.0 )
-
-set ( VERSION_MAJOR 0 CACHE STRING "Project major version number")
-set ( VERSION_MINOR "1" CACHE STRING "Project minor version number" )
-set ( VERSION_PATCH "0" CACHE STRING "Project patch version number" )
-set ( CN_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )
+set(VERSION_MAJOR
+ 0
+ CACHE STRING "Project major version number")
+set(VERSION_MINOR
+ "1"
+ CACHE STRING "Project minor version number")
+set(VERSION_PATCH
+ "0"
+ CACHE STRING "Project patch version number")
+set(CN_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH CN_VERSION)
-project ( "cn-cbor" VERSION "${CN_VERSION}")
+project("cn-cbor" VERSION "${CN_VERSION}")
-find_package(Doxygen)
+# ##############################################################################
+# OPTIONS
+# ##############################################################################
-## setup options
-option ( use_context "Use context pointer for CBOR functions" OFF )
-option ( verbose "Produce verbose makefile output" OFF )
-option ( optimize "Optimize for size" OFF )
-option ( fatal_warnings "Treat build warnings as errors" ON )
-option ( coveralls "Generate coveralls data" ON )
-option ( coveralls_send "Send data to coveralls site" OFF )
-option ( build_docs "Create docs using Doxygen" ${DOXYGEN_FOUND} )
-option ( no_floats "Build without floating point support" OFF )
-option ( align_reads "Use memcpy in ntoh*p()" OFF )
+option(use_context "Use context pointer for CBOR functions" OFF)
+option(verbose "Produce verbose makefile output" OFF)
+option(optimize "Optimize for size" OFF)
+option(fatal_warnings "Treat build warnings as errors" ON)
+option(coveralls "Generate coveralls data" ON)
+option(coveralls_send "Send data to coveralls site" OFF)
+option(build_docs "Create docs using Doxygen" OFF)
+option(build_tests "Create tests" ON)
+option(no_floats "Build without floating point support" OFF)
+option(align_reads "Use memcpy in ntoh*p()" OFF)
-set ( dist_dir ${CMAKE_BINARY_DIR}/dist )
-set ( prefix ${CMAKE_INSTALL_PREFIX} )
-set ( exec_prefix ${CMAKE_INSTALL_PREFIX}/bin )
-set ( libdir ${CMAKE_INSTALL_PREFIX}/lib )
-set ( includedir ${CMAKE_INSTALL_PREFIX}/include )
+include(GNUInstallDirs)
+
+set(dist_dir ${CMAKE_BINARY_DIR}/dist)
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin)
+set(libdir ${CMAKE_INSTALL_PREFIX}/lib)
+set(includedir ${CMAKE_INSTALL_PREFIX}/include)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cn-cbor.pc.in
${CMAKE_CURRENT_BINARY_DIR}/cn-cbor.pc @ONLY)
-install (FILES ${CMAKE_CURRENT_BINARY_DIR}/cn-cbor.pc DESTINATION lib/pkgconfig )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cn-cbor.pc DESTINATION lib/pkgconfig)
-set ( package_prefix "${CMAKE_PACKAGE_NAME}-${CMAKE_SYSTEM_NAME}" )
+set(package_prefix "${CMAKE_PACKAGE_NAME}-${CMAKE_SYSTEM_NAME}")
-set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/bin )
-set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${dist_dir}/lib )
-set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${dist_dir}/lib )
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/bin)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${dist_dir}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${dist_dir}/lib)
-if (NOT CMAKE_BUILD_TYPE)
- if ( optimize )
- set ( CMAKE_BUILD_TYPE MinSizeRel )
- set ( coveralls OFF )
- set ( coveralls_send OFF )
- else ()
- set ( CMAKE_BUILD_TYPE Debug )
- endif ()
+if(NOT CMAKE_BUILD_TYPE)
+ if(optimize)
+ set(CMAKE_BUILD_TYPE MinSizeRel)
+ set(coveralls OFF)
+ set(coveralls_send OFF)
+ else()
+ set(CMAKE_BUILD_TYPE Debug)
+ endif()
endif()
-message ( "Build type: ${CMAKE_BUILD_TYPE}" )
-
-if ( CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
- CMAKE_C_COMPILER_ID MATCHES "Clang" )
- message ( STATUS "adding GCC/Clang options ")
- add_definitions ( -std=gnu99 -Wall -Wextra -pedantic )
- if ( fatal_warnings )
- add_definitions ( -Werror )
- endif ()
- if ( optimize )
- add_definitions ( -Os )
- endif ()
-elseif ( MSVC )
- add_definitions ( /W3 )
- if ( fatal_warnings )
- add_definitions ( /WX )
- endif ()
-else ()
- message ( FATAL_ERROR "unhandled compiler id: ${CMAKE_C_COMPILER_ID}" )
-endif ()
-
-if ( no_floats )
- add_definitions(-DCBOR_NO_FLOAT)
+if(MSVC)
+ set(coveralls OFF)
endif()
-if ( verbose )
- set ( CMAKE_VERBOSE_MAKEFILE ON )
-endif ()
+message("Build type: ${CMAKE_BUILD_TYPE}")
-## include the parts
-add_subdirectory ( include )
-add_subdirectory ( src )
-add_subdirectory ( test )
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ message(STATUS "adding GCC/Clang options ")
+ add_definitions(-std=gnu99 -Wall -Wextra -pedantic)
+ if(fatal_warnings)
+ add_definitions(-Werror)
+ endif()
+ if(optimize)
+ add_definitions(-Os)
+ endif()
+elseif(MSVC)
+ add_definitions(/W3)
+ if(fatal_warnings)
+ add_definitions(/WX)
+ endif()
+else()
+ message(FATAL_ERROR "unhandled compiler id: ${CMAKE_C_COMPILER_ID}")
+endif()
-install (FILES LICENSE README.md DESTINATION .)
+if(no_floats)
+ add_definitions(-DCBOR_NO_FLOAT)
+endif()
-## setup packaging
-set ( CPACK_GENERATOR "TGZ" )
-set ( CPACK_PACKAGE_VERSION "${PROJECT_VERSION}" )
-set ( CPACK_SOURCE_GENERATOR "TGZ" )
-set ( CPACK_SOURCE_IGNORE_FILES "/\\\\.git/" )
-file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/.gitignore igs)
-foreach (ig IN ITEMS ${igs})
- # remove comments
- string ( REGEX REPLACE "^\\s*#.*" "" ig "${ig}")
- # remove any other whitespace
- string ( STRIP "${ig}" ig)
- # anything left?
- if (ig)
- # dots are literal
- string ( REPLACE "." "\\\\." ig "${ig}" )
- # stars are on thars
- string ( REPLACE "*" ".*" ig "${ig}" )
- list ( APPEND CPACK_SOURCE_IGNORE_FILES "/${ig}/" )
- endif()
-endforeach()
+if(verbose)
+ set(CMAKE_VERBOSE_MAKEFILE ON)
+endif()
-set ( CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md )
-set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" )
+# ##############################################################################
+# LIBRARY
+# ##############################################################################
-include ( CPack )
-include ( CTest )
+set(cbor_srcs src/cn-cbor.c src/cn-create.c src/cn-encoder.c src/cn-error.c
+ src/cn-get.c src/cn-print.c)
+
+if(align_reads)
+ add_definitions(-DCBOR_ALIGN_READS)
+endif()
+if(use_context)
+ add_definitions(-DUSE_CBOR_CONTEXT)
+endif()
+# default is static, can be shared if -DBUILD_SHARED_LIBS=ON passed to cmake
+add_library(${PROJECT_NAME})
+target_sources(${PROJECT_NAME} PRIVATE include/cn-cbor/cn-cbor.h ${cbor_srcs})
+target_include_directories(
+ ${PROJECT_NAME}
+ PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+ PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src)
+if(MSVC)
+ message("test: ${BUILD_SHARED_LIBS}")
+ message("verbose: ${verbose}")
+ target_link_libraries(${PROJECT_NAME} ws2_32)
+endif()
+add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
-include ( LCov )
+if(coveralls)
+ include(Coveralls)
+ coveralls_turn_on_coverage()
-if (build_docs)
- if(NOT DOXYGEN_FOUND)
- message(FATAL_ERROR "Doxygen is needed to build the documentation.")
- endif()
+ set(COVERAGE_SRCS "")
+ foreach(S ${cbor_srcs})
+ get_filename_component(S_ABS ${S} ABSOLUTE)
+ list(APPEND COVERAGE_SRCS ${S_ABS})
+ endforeach()
+ # Create the coveralls target.
+ coveralls_setup("${COVERAGE_SRCS}" ${coveralls_send} # If we should upload.
+ )
+
+ # add_dependencies(coveralls, all)
+endif()
+
+if(NOT MSVC)
+ add_custom_target(
+ size
+ COMMAND echo "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
+ COMMAND size "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
+ COMMAND size -m "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
+ DEPENDS cn-cbor
+ COMMENT "Output the size of the parse routine")
+endif(NOT MSVC)
+
+# ##############################################################################
+# DOCS
+# ##############################################################################
+
+if(build_docs)
+ find_package(Doxygen)
+
+ if(NOT DOXYGEN_FOUND)
+ message(WARNING "Doxygen is needed to build the documentation.")
+ else()
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)
- add_custom_target(doc
- COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMENT "Generating API documentation with Doxygen"
- VERBATIM)
+ add_custom_target(
+ doc
+ COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating API documentation with Doxygen"
+ VERBATIM)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc)
+ endif()
endif()
+
+# ##############################################################################
+# TESTS
+# ##############################################################################
+
+if(build_tests)
+ include(CTest)
+ add_subdirectory(test)
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
+ include(LCov)
+endif()
+
+# ##############################################################################
+# PACKAGING
+# ##############################################################################
+
+set(CPACK_GENERATOR "TGZ")
+set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
+set(CPACK_SOURCE_GENERATOR "TGZ")
+set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/")
+file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/.gitignore igs)
+foreach(ig IN ITEMS ${igs})
+ # remove comments
+ string(REGEX REPLACE "^\\s*#.*" "" ig "${ig}")
+ # remove any other whitespace
+ string(STRIP "${ig}" ig)
+ # anything left?
+ if(ig)
+ # dots are literal
+ string(REPLACE "." "\\\\." ig "${ig}")
+ # stars are on thars
+ string(REPLACE "*" ".*" ig "${ig}")
+ list(APPEND CPACK_SOURCE_IGNORE_FILES "/${ig}/")
+ endif()
+endforeach()
+
+set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+
+include(CPack)
+
+# ##############################################################################
+# INSTALL
+# ##############################################################################
+
+include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+
+install(FILES LICENSE README.md DESTINATION .)
+set(CN_CBOR_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
+
+install(
+ TARGETS ${PROJECT_NAME}
+ EXPORT ${PROJECT_NAME}Targets
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
+
+install(
+ EXPORT ${PROJECT_NAME}Targets
+ DESTINATION ${CN_CBOR_CONFIG_INSTALL_DIR}
+ NAMESPACE ${PROJECT_NAME}::
+ COMPONENT dev)
+
+configure_package_config_file(cmake/Config.cmake.in ${PROJECT_NAME}Config.cmake
+ INSTALL_DESTINATION ${CN_CBOR_CONFIG_INSTALL_DIR})
+write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake
+ COMPATIBILITY SameMajorVersion)
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
+ DESTINATION ${CN_CBOR_CONFIG_INSTALL_DIR}
+ COMPONENT dev)
+
+install(
+ DIRECTORY include/
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ COMPONENT dev
+ FILES_MATCHING
+ PATTERN "*.h")
+install(
+ TARGETS cn-cbor
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ RUNTIME DESTINATION bin)
diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in
new file mode 100644
index 0000000..9c15f36
--- /dev/null
+++ b/cmake/Config.cmake.in
@@ -0,0 +1,4 @@
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+check_required_components("@PROJECT_NAME@")
diff --git a/conanfile.py b/conanfile.py
new file mode 100644
index 0000000..977ee57
--- /dev/null
+++ b/conanfile.py
@@ -0,0 +1,63 @@
+import os
+from conans import ConanFile, CMake, tools
+
+
+class CnCborConan(ConanFile):
+ name = "cn-cbor"
+ version = "20200227"
+ license = "BSD"
+ url = "https://github.com/cose-wg/cn-cbor"
+ description = """A constrained node implementation of CBOR in C"""
+ topics = ("cn-cbor")
+ settings = "os", "compiler", "build_type", "arch"
+ options = {
+ "shared": [True, False],
+ }
+ default_options = {
+ "shared": False,
+ }
+ generators = "cmake"
+
+ _cmake = None
+
+ @property
+ def _source_subfolder(self):
+ return "source_subfolder"
+
+ @property
+ def _build_subfolder(self):
+ return "build_subfolder"
+
+ def source(self):
+ self.run(
+ "git clone -b complete git@github.com:jimsch/cn-cbor.git")
+ os.rename("cn-cbor", self._source_subfolder)
+
+ def configure(self):
+ del self.settings.compiler.libcxx
+ del self.settings.compiler.cppstd
+
+ def _configure_cmake(self):
+ if not self._cmake:
+ self._cmake = CMake(self)
+ self._cmake.definitions["build_tests"] = False
+ self._cmake.definitions["build_docs"] = False
+ self._cmake.definitions["coveralls"] = False
+ self._cmake.configure(
+ source_folder=self._source_subfolder, build_folder=self._build_subfolder)
+
+ return self._cmake
+
+ def build(self):
+ cmake = self._configure_cmake()
+ cmake.build()
+
+ def package(self):
+ cmake = self._configure_cmake()
+ cmake.install()
+
+ def package_info(self):
+ self.cpp_info.libs = tools.collect_libs(self)
+ self.cpp_info.name = "cn-cbor"
+ if self.settings.os == "Linux":
+ self.cpp_info.system_libs = ["m"]
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
deleted file mode 100644
index 898676a..0000000
--- a/include/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-install ( DIRECTORY ../include DESTINATION .
- PATTERN CMakeLists.txt EXCLUDE )
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index 187a55c..0416bd2 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -8,6 +8,18 @@
#ifndef CN_CBOR_H
#define CN_CBOR_H
+#ifndef MYLIB_EXPORT
+#if defined (_WIN32)
+#if defined(CN_CBOR_IS_DLL)
+#define MYLIB_EXPORT __declspec(dllimport)
+#else
+#define MYLIB_EXPORT
+#endif /* CN_CBOR_IS_DLL */
+#else /* defined (_WIN32) */
+#define MYLIB_EXPORT
+#endif
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -17,7 +29,12 @@
#include <stdbool.h>
#include <stdint.h>
+#ifdef _MSC_VER
+#include <WinSock2.h>
+typedef signed long ssize_t;
+#else
#include <unistd.h>
+#endif
/**
* All of the different kinds of CBOR values.
@@ -89,19 +106,35 @@
/** CN_CBOR_TEXT */
const char* str;
/** CN_CBOR_INT */
+#ifdef _MSC_VER
+ int64_t sint;
+#else
long sint;
+#endif
/** CN_CBOR_UINT */
+#ifdef _MSC_VER
+ uint64_t uint;
+#else
unsigned long uint;
+#endif
/** CN_CBOR_DOUBLE */
double dbl;
/** CN_CBOR_FLOAT */
float f;
/** for use during parsing */
- unsigned long count;
+#ifdef _MSC_VER
+ uint64_t count;
+#else
+ unsigned long count;
+#endif
} v; /* TBD: optimize immediate */
/** Number of children.
* @note: for maps, this is 2x the number of entries */
+#ifdef _MSC_VER
+ size_t length;
+#else
int length;
+#endif
/** The first child value */
struct cn_cbor* first_child;
/** The last child value */
@@ -149,6 +182,7 @@
*
* @todo: turn into a function to make the type safety more clear?
*/
+MYLIB_EXPORT
extern const char *cn_cbor_error_str[];
/**
@@ -223,6 +257,7 @@
* @param[out] errp Error, if NULL is returned
* @return The parsed CBOR structure, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
/**
@@ -232,6 +267,7 @@
* @param[in] key The string to look up in the map
* @return The matching value, or NULL if the key is not found
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
/**
@@ -241,6 +277,7 @@
* @param[in] key The int to look up in the map
* @return The matching value, or NULL if the key is not found
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
/**
@@ -250,6 +287,7 @@
* @param[in] idx The array index
* @return The matching value, or NULL if the index is invalid
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
/**
@@ -260,15 +298,19 @@
* @param[in] cb The CBOR value to free. May be NULL, or a root object.
* @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined)
*/
+MYLIB_EXPORT
void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT);
/**
* Write a CBOR value and all of the child values.
*
- * @param[in] buf The buffer into which to write
+ * @param[in] buf The buffer into which to write. May be NULL to
+ * determine the necessary size.
* @param[in] buf_offset The offset (in bytes) from the beginning of the buffer
* to start writing at
- * @param[in] buf_size The total length (in bytes) of the buffer
+ * @param[in] buf_size The total length (in bytes) of the buffer. If buf is
+ * NULL, this is an upper limit and may be 0 to specify
+ * no limit.
* @param[in] cb [description]
* @return -1 on fail, or number of bytes written
*/
@@ -284,6 +326,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created map, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
/**
@@ -296,6 +339,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -313,6 +357,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_string_create(const char* data
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -325,6 +370,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -365,6 +411,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map,
cn_cbor *cb_key, cn_cbor *cb_value,
cn_cbor_errback *errp);
@@ -380,6 +427,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map,
int64_t key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -399,6 +447,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map,
const char* key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -411,6 +460,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
/**
@@ -421,10 +471,26 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array,
cn_cbor* cb_value,
cn_cbor_errback *errp);
+/**
+ * Dump the object to a file pointer
+ * If buffer is NULL, then return required size to generate output
+ *
+ * @param[in] buffer Location to place output
+ * @param[in] bufferSize Size of return buffer
+ * @param[in] fp File pointer to print on
+ * @param[in] cb tree to be dumped
+ * @param[in] indent string to use for each level of indention
+ * @param[in] crlf string to use for end of line marker
+ * @return size of output generated, -1 if buffer is too small
+ */
+
+extern ssize_t cn_cbor_printer_write(char * buffer, size_t bufferSize, const cn_cbor * cb, const char * indent, const char * crlf);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
deleted file mode 100644
index babe95c..0000000
--- a/src/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-#
-# compiling/installing sources for cn-cbor
-
-set ( cbor_srcs
- cn-cbor.c
- cn-create.c
- cn-encoder.c
- cn-error.c
- cn-get.c
-)
-
-if (align_reads)
- add_definitions(-DCBOR_ALIGN_READS)
-endif()
-if (use_context)
- add_definitions(-DUSE_CBOR_CONTEXT)
-endif()
-add_library ( cn-cbor SHARED ${cbor_srcs} )
-target_include_directories ( cn-cbor PUBLIC ../include )
-target_include_directories ( cn-cbor PRIVATE ../src )
-
-install ( TARGETS cn-cbor
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib
- RUNTIME DESTINATION bin)
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
-if (coveralls)
- include(Coveralls)
- coveralls_turn_on_coverage()
-
- set(COVERAGE_SRCS "")
- foreach (S ${cbor_srcs})
- get_filename_component(S_ABS ${S} ABSOLUTE)
- list (APPEND COVERAGE_SRCS ${S_ABS})
- endforeach()
-
- # Create the coveralls target.
- coveralls_setup(
- "${COVERAGE_SRCS}"
- ${coveralls_send} # If we should upload.
- )
-
- #add_dependencies(coveralls, all)
-endif()
-
-add_custom_target(size
- COMMAND echo "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
- COMMAND size "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
- COMMAND size -m "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
- DEPENDS cn-cbor
-COMMENT "Output the size of the parse routine")
diff --git a/src/cbor.h b/src/cbor.h
index 1859f09..6329477 100644
--- a/src/cbor.h
+++ b/src/cbor.h
@@ -1,6 +1,10 @@
#ifndef CBOR_PROTOCOL_H__
#define CBOR_PROTOCOL_H__
+#ifdef _MSC_VER
+#define inline _inline
+#endif
+
/* The 8 major types */
#define MT_UNSIGNED 0
#define MT_NEGATIVE 1
diff --git a/src/cn-cbor.c b/src/cn-cbor.c
index 9093537..7da5f88 100644
--- a/src/cn-cbor.c
+++ b/src/cn-cbor.c
@@ -13,15 +13,22 @@
#include <string.h>
#include <assert.h>
#include <math.h>
+#ifdef _MSC_VER
+#include <WinSock2.h> // needed for ntohl on Windows
+#else
#include <arpa/inet.h> // needed for ntohl (e.g.) on Linux
+#include "dll-export.h"
+#endif // _MSC_VER
+
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
#define CN_CBOR_FAIL(code) do { pb->err = code; goto fail; } while(0)
+MYLIB_EXPORT
void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT) {
- cn_cbor* p = cb;
+ cn_cbor* p = (cn_cbor*) cb;
assert(!p || !p->parent);
while (p) {
cn_cbor* p1;
@@ -173,7 +180,7 @@
break;
case MT_BYTES: case MT_TEXT:
cb->v.str = (char *) pos;
- cb->length = val;
+ cb->length = (size_t) val;
TAKE(pos, ebuf, val, ;);
break;
case MT_MAP:
@@ -205,7 +212,7 @@
case AI_4:
#ifndef CBOR_NO_FLOAT
cb->type = CN_CBOR_DOUBLE;
- u32.u = val;
+ u32.u = (uint32_t) val;
cb->v.dbl = u32.f;
#else /* CBOR_NO_FLOAT */
CN_CBOR_FAIL(CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
@@ -253,6 +260,7 @@
return 0;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) {
cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL};
struct parse_buf pb;
diff --git a/src/cn-create.c b/src/cn-create.c
index 4ddce3b..c9ab816 100644
--- a/src/cn-create.c
+++ b/src/cn-create.c
@@ -8,6 +8,7 @@
#include <string.h>
#include <stdlib.h>
+#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
@@ -16,6 +17,7 @@
(v) = CN_CALLOC_CONTEXT(); \
if (!(v)) { if (errp) {errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;} return NULL; }
+MYLIB_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
cn_cbor* ret;
@@ -27,6 +29,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -41,6 +44,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_string_create(const char* data
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -55,6 +59,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -119,6 +124,7 @@
return true;
}
+MYLIB_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map,
cn_cbor *cb_key, cn_cbor *cb_value,
cn_cbor_errback *errp)
@@ -133,6 +139,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map,
int64_t key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -152,6 +159,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map,
const char* key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -171,6 +179,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
cn_cbor* ret;
@@ -182,6 +191,7 @@
return ret;
}
+MYLIB_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array,
cn_cbor* cb_value,
cn_cbor_errback *errp)
diff --git a/src/cn-encoder.c b/src/cn-encoder.c
index ffaf3e8..18de686 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -8,12 +8,20 @@
} /* Duh. */
#endif
+#ifdef _MSC_VER
+#include <WinSock2.h>
+#define inline _inline
+#else
#include <arpa/inet.h>
+#endif
#include <string.h>
+#ifndef _MSC_VER
#include <strings.h>
+#endif
#include <stdbool.h>
#include <assert.h>
+#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
@@ -35,22 +43,30 @@
ssize_t size;
} cn_write_state;
-#define ensure_writable(sz) if ((ws->offset<0) || (ws->offset + (sz) > ws->size)) { \
+#define ensure_writable(sz) if ((ws->buf != NULL) && ((ws->offset<0) || (ws->offset + (sz) > ws->size))) { \
ws->offset = -1; \
return; \
}
#define write_byte_and_data(b, data, sz) \
-ws->buf[ws->offset++] = (b); \
-memcpy(ws->buf+ws->offset, (data), (sz)); \
+if(ws->buf) { \
+ ws->buf[ws->offset++] = (b); \
+ memcpy(ws->buf+ws->offset, (data), (sz)); \
+} else { \
+ ws->offset++; \
+} \
ws->offset += sz;
#define write_byte(b) \
-ws->buf[ws->offset++] = (b); \
+if(ws->buf) { \
+ ws->buf[ws->offset++] = (b); \
+} else { \
+ ws->offset++; \
+}
#define write_byte_ensured(b) \
ensure_writable(1); \
-write_byte(b); \
+write_byte(b);
static uint8_t _xlate[] = {
IB_FALSE, /* CN_CBOR_FALSE */
@@ -89,7 +105,7 @@
if (val < 24) {
ensure_writable(1);
- write_byte(ib | val);
+ write_byte(ib | (uint8_t) val);
} else if (val < 256) {
ensure_writable(2);
write_byte(ib | 24);
@@ -178,7 +194,7 @@
// TODO: make public?
typedef void (*cn_visit_func)(const cn_cbor *cb, int depth, void *context);
-static void _visit(const cn_cbor *cb,
+void _visit(const cn_cbor *cb,
cn_visit_func visitor,
cn_visit_func breaker,
void *context)
@@ -194,17 +210,25 @@
depth++;
} else{
// Empty indefinite
+#ifdef CN_INCLUDE_DUMPER
+ breaker(p, depth, context);
+#else
if (is_indefinite(p)) {
- breaker(p->parent, depth, context);
+ breaker(p, depth, context);
}
+#endif
if (p->next) {
p = p->next;
} else {
while (p->parent) {
depth--;
+#ifdef CN_INCLUDE_DUMPER
+ breaker(p->parent, depth, context);
+#else
if (is_indefinite(p->parent)) {
breaker(p->parent, depth, context);
}
+#endif
if (p->parent->next) {
p = p->parent->next;
goto visit;
@@ -249,7 +273,9 @@
case CN_CBOR_BYTES:
CHECK(_write_positive(ws, cb->type, cb->length));
ensure_writable(cb->length);
- memcpy(ws->buf+ws->offset, cb->v.str, cb->length);
+ if (ws->buf) {
+ memcpy(ws->buf+ws->offset, cb->v.str, cb->length);
+ }
ws->offset += cb->length;
break;
@@ -293,7 +319,13 @@
cn_write_state *ws = context;
UNUSED_PARAM(cb);
UNUSED_PARAM(depth);
- write_byte_ensured(IB_BREAK);
+#ifdef CN_INCLUDE_DUMPER
+ if (is_indefinite(cb)) {
+#endif
+ write_byte_ensured(IB_BREAK);
+#ifdef CN_INCLUDE_DUMPER
+ }
+#endif
}
ssize_t cn_cbor_encoder_write(uint8_t *buf,
@@ -302,6 +334,7 @@
const cn_cbor *cb)
{
cn_write_state ws = { buf, buf_offset, buf_size };
+ if (!ws.buf && ws.size <= 0) { ws.size = (ssize_t)(((size_t)-1) / 2); }
_visit(cb, _encoder_visitor, _encoder_breaker, &ws);
if (ws.offset < 0) { return -1; }
return ws.offset - buf_offset;
diff --git a/src/cn-error.c b/src/cn-error.c
index 4953cc9..ad48746 100644
--- a/src/cn-error.c
+++ b/src/cn-error.c
@@ -1,3 +1,6 @@
+#include "dll-export.h"
+
+MYLIB_EXPORT
const char *cn_cbor_error_str[] = {
"CN_CBOR_NO_ERROR",
"CN_CBOR_ERR_OUT_OF_DATA",
diff --git a/src/cn-get.c b/src/cn-get.c
index 79d3d72..4b2ee13 100644
--- a/src/cn-get.c
+++ b/src/cn-get.c
@@ -2,8 +2,11 @@
#include <string.h>
#include <assert.h>
+#include "dll-export.h"
+
#include "cn-cbor/cn-cbor.h"
+MYLIB_EXPORT
cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) {
cn_cbor* cp;
assert(cb);
@@ -26,6 +29,7 @@
return NULL;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
cn_cbor *cp;
int keylen;
@@ -49,6 +53,7 @@
return NULL;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
cn_cbor *cp;
unsigned int i = 0;
diff --git a/src/cn-print.c b/src/cn-print.c
new file mode 100644
index 0000000..2eb76f4
--- /dev/null
+++ b/src/cn-print.c
@@ -0,0 +1,253 @@
+#ifndef CN_PRINT_C
+#define CN_PRINT_C
+#define CN_INCLUDE_DUMPER
+#ifdef CN_INCLUDE_DUMPER
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#include <stdio.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef EMACS_INDENTATION_HELPER
+} /* Duh. */
+#endif
+
+#include <stdio.h>
+#ifdef MSV_CRT
+#include <winsock2.h>
+#else
+#define _snprintf snprintf
+#endif
+#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include "cn-cbor/cn-cbor.h"
+#include "cbor.h"
+
+typedef struct _write_state
+{
+ char * rgbOutput;
+ ssize_t ib;
+ size_t cbLeft;
+ uint8_t * rgFlags;
+ const char * szIndentWith;
+ const char * szEndOfLine;
+} cn_write_state;
+
+typedef void(*cn_visit_func)(const cn_cbor *cb, int depth, void *context);
+extern void _visit(const cn_cbor *cb,
+ cn_visit_func visitor,
+ cn_visit_func breaker,
+ void *context);
+
+const char RgchHex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+bool _isWritable(cn_write_state * ws, size_t cb)
+{
+ if (ws->rgbOutput == NULL) return true;
+ if ((ws->ib < 0) || (ws->ib + cb > ws->cbLeft)) {
+ ws->ib = -1;
+ return false;
+ }
+ return true;
+}
+
+void write_data(cn_write_state * ws, const char * sz, size_t cb)
+{
+ if (_isWritable(ws, cb)) {
+ if (ws->rgbOutput != NULL) memcpy(ws->rgbOutput + ws->ib, sz, cb);
+ ws->ib += cb;
+ }
+}
+
+void _doIndent(cn_write_state * ws, int depth)
+{
+ int i;
+ char * sz = ws->rgbOutput + ws->ib;
+ size_t cbIndentWith = strlen(ws->szIndentWith);
+ int cbIndent = depth * cbIndentWith;
+
+
+ if (ws->rgbOutput == NULL) {
+ ws->ib += cbIndent;
+ return;
+ }
+
+ if (_isWritable(ws, cbIndent)) {
+ for (i = 0; i < depth; i++) {
+ memcpy(sz, ws->szIndentWith, cbIndentWith);
+ sz += cbIndentWith;
+ }
+ }
+
+ ws->ib += cbIndent;
+
+ return;
+}
+
+void _print_encoder(const cn_cbor * cb, int depth, void * context)
+{
+ int i;
+ char rgchT[256];
+ int cch;
+ cn_write_state * ws = (cn_write_state *)context;
+ uint8_t flags = ws->rgFlags[depth];
+
+ if (flags & 1) {
+ write_data(ws, ", ", 2);
+ ws->rgFlags[depth] &= 0xfe;
+
+ if (ws->szIndentWith) {
+ write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
+ _doIndent(ws, depth);
+ }
+ }
+
+ if (flags & 2) {
+ write_data(ws, ": ", 2);
+ ws->rgFlags[depth] &= 0xfd;
+ }
+
+ switch (cb->type) {
+ case CN_CBOR_BYTES_CHUNKED:
+ case CN_CBOR_TEXT_CHUNKED:
+ break;
+
+ case CN_CBOR_ARRAY:
+ write_data(ws, "[", 1);
+ ws->rgFlags[depth] |= 4;
+
+ if (ws->szIndentWith) {
+ write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
+ _doIndent(ws, depth + 1);
+ }
+ break;
+
+ case CN_CBOR_MAP:
+ write_data(ws, "{", 1);
+ ws->rgFlags[depth] |= 8;
+
+ if (ws->szIndentWith) {
+ write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
+ _doIndent(ws, depth + 1);
+ }
+ break;
+
+ case CN_CBOR_TAG:
+ case CN_CBOR_UINT:
+ case CN_CBOR_SIMPLE:
+ cch = _snprintf(rgchT, sizeof(rgchT), "%u", (unsigned int) cb->v.uint);
+ write_data(ws, rgchT, cch);
+ break;
+
+ case CN_CBOR_FALSE:
+ write_data(ws, "false", 5);
+ break;
+
+ case CN_CBOR_TRUE:
+ write_data(ws, "true", 4);
+ break;
+
+ case CN_CBOR_NULL:
+ write_data(ws, "null", 4);
+ break;
+
+ case CN_CBOR_UNDEF:
+ write_data(ws, "undef", 5);
+ break;
+
+ case CN_CBOR_INT:
+ cch = _snprintf(rgchT, sizeof(rgchT), "%d", (unsigned int) cb->v.sint);
+ write_data(ws, rgchT, cch);
+ break;
+
+ case CN_CBOR_DOUBLE:
+ cch = _snprintf(rgchT, sizeof(rgchT), "%f", cb->v.dbl);
+ write_data(ws, rgchT, cch);
+ break;
+
+ case CN_CBOR_INVALID:
+ write_data(ws, "invalid", 7);
+ break;
+
+ case CN_CBOR_TEXT:
+ write_data(ws, "\"", 1);
+ write_data(ws, cb->v.str, cb->length);
+ write_data(ws, "\"", 1);
+ break;
+
+ case CN_CBOR_BYTES:
+ write_data(ws, "h'", 2);
+ for (i = 0; i < cb->length; i++) {
+ write_data(ws, &RgchHex[(cb->v.str[i] / 16) & 0xf], 1);
+ write_data(ws, &RgchHex[cb->v.str[i] & 0xf], 1);
+ }
+ write_data(ws, "\'", 1);
+ break;
+ }
+
+ if (depth > 0) {
+ if (ws->rgFlags[depth - 1] & 4) ws->rgFlags[depth] |= 1;
+ else if (ws->rgFlags[depth - 1] & 8) {
+ if (flags & 2) ws->rgFlags[depth] |= 1;
+ else ws->rgFlags[depth] |= 2;
+ }
+ }
+}
+
+void _print_breaker(const cn_cbor * cb, int depth, void * context)
+{
+ cn_write_state * ws = (cn_write_state *)context;
+
+ switch (cb->type) {
+ case CN_CBOR_ARRAY:
+ if (ws->szIndentWith) {
+ write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
+ _doIndent(ws, depth);
+ }
+
+ write_data(ws, "]", 1);
+ ws->rgFlags[depth + 1] = 0;
+ break;
+
+ case CN_CBOR_MAP:
+ if (ws->szIndentWith) {
+ write_data(ws, ws->szEndOfLine, strlen(ws->szEndOfLine));
+ _doIndent(ws, depth);
+ }
+
+ write_data(ws, "}", 1);
+ ws->rgFlags[depth + 1] = 0;
+ break;
+
+ default:
+ break;
+ }
+}
+
+ssize_t cn_cbor_printer_write(char * rgbBuffer, size_t cbBuffer, const cn_cbor * cb, const char * szIndentWith, const char * szEndOfLine)
+{
+ uint8_t flags[128] = { 0 };
+ char rgchZero[1] = { 0 };
+
+ cn_write_state ws = { rgbBuffer, 0, cbBuffer, flags, szIndentWith, szEndOfLine };
+ _visit(cb, _print_encoder, _print_breaker, &ws);
+ write_data(&ws, rgchZero, 1);
+
+ return ws.ib;
+}
+
+#ifdef EMACS_INDENTATION_HELPER
+{ /* Duh. */
+#endif
+#ifdef _cplusplus
+} /* extern "C" */
+#endif
+
+#endif // CN_INCLUDE_DUMPER
+#endif // CN_PRINT_C
+
diff --git a/src/dll-export.h b/src/dll-export.h
new file mode 100644
index 0000000..3d0c928
--- /dev/null
+++ b/src/dll-export.h
@@ -0,0 +1,23 @@
+// Contents of DLLDefines.h
+#ifndef _cn_cbor_DLLDEFINES_H_
+#define _cn_cbor_DLLDEFINES_H_
+
+/* Cmake will define cn_cbor_EXPORTS on Windows when it
+configures to build a shared library. If you are going to use
+another build system on windows or create the visual studio
+projects by hand you need to define cn_cbor_EXPORTS when
+building a DLL on windows.
+*/
+// We are using the Visual Studio Compiler and building Shared libraries
+
+#if defined (_WIN32)
+#if defined(CN_CBOR_IS_DLL)
+ #define MYLIB_EXPORT __declspec(dllexport)
+#else
+ #define MYLIB_EXPORT
+#endif /* cn_cbor_EXPORTS */
+#else /* defined (_WIN32) */
+ #define MYLIB_EXPORT
+#endif
+
+#endif /* _cn_cbor_DLLDEFINES_H_ */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3181a8d..18eaa47 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,33 +1,32 @@
#
-#
# Compiling/running tests
-if (use_context)
+if(use_context)
add_definitions(-DUSE_CBOR_CONTEXT)
endif()
-set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/test )
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/test)
-function (create_test name)
- add_executable ( ${name}_test ${name}_test.c )
- target_link_libraries ( ${name}_test PRIVATE cn-cbor )
- target_include_directories ( ${name}_test PRIVATE ../include )
- add_test ( NAME ${name} COMMAND ${name}_test )
+function(create_test name)
+ add_executable(${name}_test ${name}_test.c)
+ target_link_libraries(${name}_test PRIVATE cn-cbor)
+ target_include_directories(${name}_test PRIVATE ../include)
+ add_test(NAME ${name} COMMAND ${name}_test)
endfunction()
-create_test ( cbor )
-include ( CTest )
+create_test(cbor)
+include(CTest)
-if (APPLE)
+if(APPLE)
# difftest uses Apple-specific memory tests
- add_executable (cn-test test.c )
- target_include_directories ( cn-test PRIVATE ../include )
- target_link_libraries ( cn-test PRIVATE cn-cbor )
+ add_executable(cn-test test.c)
+ target_link_libraries(cn-test PRIVATE cn-cbor)
configure_file(cases.cbor cases.cbor COPYONLY)
configure_file(expected.out expected.out COPYONLY)
- add_custom_target(difftest
+ add_custom_target(
+ difftest
COMMAND env MallocStackLogging=true ./cn-test >new.out
COMMAND diff new.out expected.out
DEPENDS cn-test
diff --git a/test/cbor_test.c b/test/cbor_test.c
index eafea5d..3888723 100644
--- a/test/cbor_test.c
+++ b/test/cbor_test.c
@@ -1,12 +1,22 @@
/*
* Copyright (c) 2015 SPUDlib authors. See LICENSE file.
*/
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#endif
+
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
+#ifdef _MSC_VER
+#include "winsock2.h"
+#endif
#include "cn-cbor/cn-cbor.h"
@@ -43,7 +53,13 @@
b->sz = len / 2;
b->ptr = malloc(b->sz);
for (i=0; i<b->sz; i++) {
+#ifdef _MSC_VER
+ unsigned int iX;
+ sscanf(inp+(2*i), "%02hx", &iX);
+ b->ptr[i] = (byte)iX;
+#else
sscanf(inp+(2*i), "%02hhx", &b->ptr[i]);
+#endif
}
return true;
}
@@ -116,6 +132,7 @@
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
+ ssize_t enc_sz2;
for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
ASSERT_TRUE(parse_hex(tests[i], &b));
@@ -125,7 +142,9 @@
ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
ASSERT_NOT_NULL(cb);
+ enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
+ ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);
free(b.ptr);
cn_cbor_free(cb CONTEXT_NULL);
@@ -164,6 +183,7 @@
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
+ ssize_t enc_sz2;
for (i=0; i<sizeof(basic_tests)/sizeof(char*); i+=2) {
ASSERT_TRUE(parse_hex(basic_tests[i], &b));
@@ -174,7 +194,9 @@
ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
ASSERT_NOT_NULL(cb);
+ enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
+ ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz);
free(b.ptr);
free(b2.ptr);
@@ -195,7 +217,9 @@
ASSERT_NULL(cb);
#endif /* CBOR_NO_FLOAT */
+ /* enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb); */
/* enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */
+ /* ASSERT_EQUAL(enc_sz, enc_sz2); */
/* ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); */
free(b.ptr);
free(b2.ptr);
@@ -258,13 +282,16 @@
size_t i;
unsigned char encoded[1024];
ssize_t enc_sz;
+ ssize_t enc_sz2;
for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
ASSERT_TRUE(parse_hex(tests[i], &b));
cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
ASSERT_NOT_NULL(cb);
+ enc_sz2 = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), cb);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
+ ASSERT_EQUAL(enc_sz, enc_sz2);
ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);
free(b.ptr);
@@ -446,6 +473,8 @@
ASSERT_NOT_NULL(cdata);
ASSERT_TRUE(cn_cbor_mapput_int(map, 0, cdata, CONTEXT_NULL_COMMA NULL));
+ enc_sz = cn_cbor_encoder_write(NULL, 0, sizeof(encoded), map);
+ ASSERT_EQUAL(7, enc_sz);
enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), map);
ASSERT_EQUAL(7, enc_sz);
}
diff --git a/test/ctest.h b/test/ctest.h
index 75fda66..c971c55 100644
--- a/test/ctest.h
+++ b/test/ctest.h
@@ -16,6 +16,14 @@
#ifndef CTEST_H
#define CTEST_H
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#pragma section(".ctest")
+
+#include <io.h>
+#define isatty _isatty
+#endif
+
#ifndef UNUSED_PARAM
/**
* \def UNUSED_PARAM(p);
@@ -47,11 +55,19 @@
#define __CTEST_MAGIC (0xdeadbeef)
#ifdef __APPLE__
#define __Test_Section __attribute__ ((unused,section ("__DATA, .ctest")))
+#define MS__Test_Section
+#else
+#ifdef _MSC_VER
+#define __Test_Section
+#define MS__Test_Section __declspec(allocate(".ctest"))
#else
#define __Test_Section __attribute__ ((unused,section (".ctest")))
+#define MS__Test_Section
+#endif
#endif
#define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
+ MS__Test_Section \
struct ctest __TNAME(sname, tname) __Test_Section = { \
.ssname=#sname, \
.ttname=#tname, \
@@ -138,9 +154,13 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#ifndef _MSC_VER
#include <sys/time.h>
+#endif
#include <inttypes.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#endif
#include <stdint.h>
#include <stdlib.h>
@@ -306,6 +326,27 @@
return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
}
+#ifdef _MSC_VER
+int gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((uint64_t)file_time.dwLowDateTime);
+ time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long)((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
+ return 0;
+}
+#endif
+
static uint64_t getCurrentTime() {
struct timeval now;
gettimeofday(&now, NULL);
@@ -377,6 +418,7 @@
}
color_output = isatty(1);
+
uint64_t t1 = getCurrentTime();
struct ctest* ctest_begin = &__TNAME(suite, test);