Merge remote-tracking branch 'refs/remotes/origin/windows' into complete

# Conflicts:
#	.gitignore
#	include/cn-cbor/cn-cbor.h
#	src/cn-cbor.c
#	src/cn-encoder.c
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/.travis.yml b/.travis.yml
index f1c9628..dc33aff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@
 - gcc
 sudo: false
 before_install:
-- wget http://www.cmake.org/files/v3.3/cmake-3.3.1-Linux-x86_64.tar.gz  -O /tmp/cmake.tar.gz
+- wget http://cmake.org/files/v3.3/cmake-3.3.1-Linux-x86_64.tar.gz  -O /tmp/cmake.tar.gz --no-check-certificate --debug
 - tar xzf /tmp/cmake.tar.gz
 - export PATH=$PWD/cmake-3.3.1-Linux-x86_64/bin/:$PATH
 script:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 195c780..fb5a071 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@
 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 )
@@ -50,6 +51,15 @@
   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
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index 15f150c..109eb9e 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -7,6 +7,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
@@ -86,22 +98,38 @@
   /** Data associated with the value; different branches of the union are
       used depending on the `type` field. */
   union {
-	/** CN_CBOR_BYTES */
-	const uint8_t * bytes;
+    /** CN_CBOR_BYTES */
+    const uint8_t* bytes;
     /** 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;
     /** 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 +177,7 @@
  *
  * @todo: turn into a function to make the type safety more clear?
  */
+MYLIB_EXPORT
 extern const char *cn_cbor_error_str[];
 
 /**
@@ -223,6 +252,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 +262,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 +272,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 +282,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,6 +293,7 @@
  * @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);
 
 /**
@@ -284,6 +318,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 +331,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 +349,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 +362,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);
@@ -339,6 +377,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);
@@ -354,6 +393,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,
@@ -373,6 +413,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,
@@ -385,6 +426,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);
 
 /**
@@ -395,6 +437,7 @@
  * @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);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 8193cc6..2cef043 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,7 +14,15 @@
 if (use_context)
   add_definitions(-DUSE_CBOR_CONTEXT)
 endif()
-add_library ( cn-cbor SHARED ${cbor_srcs} )
+add_library ( cn-cbor ${LIB_TYPE} ${cbor_srcs} )
+message ( "MSVC: ${MSVC}")
+if ( MSVC )
+   message ( "test: ${build_shared_libs}")
+   message ( "verbose: ${verbose}")
+
+   target_link_libraries(cn-cbor ws2_32)
+endif()
+
 target_include_directories ( cn-cbor PUBLIC ../include )
 target_include_directories ( cn-cbor PRIVATE ../src )
 
@@ -43,9 +51,11 @@
     #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)
diff --git a/src/cn-cbor.c b/src/cn-cbor.c
index 4947e63..44cae3c 100644
--- a/src/cn-cbor.c
+++ b/src/cn-cbor.c
@@ -14,18 +14,20 @@
 #include <assert.h>
 #include <math.h>
 #ifdef _MSC_VER
-#include <WinSock2.h>
+#include <WinSock2.h>  // needed for ntohl on Windows
 #else
 #include <arpa/inet.h> // needed for ntohl (e.g.) on Linux
-#endif
+
+#include "dll-export.h"
 
 #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;
@@ -162,7 +164,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:
@@ -194,7 +196,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);
@@ -242,6 +244,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 bc448e9..a6f6b5b 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)
@@ -91,6 +96,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)
@@ -105,6 +111,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,
@@ -124,6 +131,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,
@@ -143,6 +151,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;
@@ -154,6 +163,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 f5e4207..939c0e3 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -21,6 +21,7 @@
 #include <stdbool.h>
 #include <assert.h>
 
+#include "dll-export.h"
 #include "cn-cbor/cn-cbor.h"
 #include "cbor.h"
 
@@ -97,7 +98,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);
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 cc276a5..b704cf3 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);
@@ -25,6 +28,7 @@
   return NULL;
 }
 
+MYLIB_EXPORT
 cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
   cn_cbor *cp;
   int keylen;
@@ -48,6 +52,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/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/cbor_test.c b/test/cbor_test.c
index 3326497..3266631 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;
 }
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);