Merge remote-tracking branch 'refs/remotes/cabo/master' into windows

Conflicts:
	include/cn-cbor/cn-cbor.h
	src/cn-cbor.c
	src/cn-get.c
diff --git a/.gitignore b/.gitignore
index 2eef09e..4e0b78a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,20 @@
 new.out
 *.o
 build
+
+# Emacs temp files
+*~
+
+# Visual Studio build directories
+Debug
+Release
+*.vcxproj
+*.vcxproj.filters
+
+# Output of cmake
+CMakeCache.txt
+CMakeFiles
+Makefile
+*.cmake
+install_manifest.txt
+
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 bf71af8..a0f9e4e 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
@@ -16,7 +28,11 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#ifdef _MSC_VER
+typedef long ssize_t;
+#else
 #include <unistd.h>
+#endif
 
 /**
  * All of the different kinds of CBOR values.
@@ -86,17 +102,33 @@
     /** 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 */
@@ -144,6 +176,7 @@
  *
  * @todo: turn into a function to make the type safety more clear?
  */
+MYLIB_EXPORT
 extern const char *cn_cbor_error_str[];
 
 /**
@@ -218,7 +251,8 @@
  * @param[out] errp         Error, if NULL is returned
  * @return                  The parsed CBOR structure, or NULL on error
  */
-cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
 
 /**
  * Get a value from a CBOR map that has the given string as a key.
@@ -227,7 +261,8 @@
  * @param[in]  key          The string to look up in the map
  * @return                  The matching value, or NULL if the key is not found
  */
-cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
 
 /**
  * Get a value from a CBOR map that has the given integer as a key.
@@ -236,7 +271,8 @@
  * @param[in]  key          The int to look up in the map
  * @return                  The matching value, or NULL if the key is not found
  */
-cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
 
 /**
  * Get the item with the given index from a CBOR array.
@@ -245,7 +281,8 @@
  * @param[in]  idx          The array index
  * @return                  The matching value, or NULL if the index is invalid
  */
-cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
 
 /**
  * Free the given CBOR structure.
@@ -255,7 +292,8 @@
  * @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)
  */
-void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT);
+MYLIB_EXPORT
+void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT);
 
 /**
  * Write a CBOR value and all of the child values.
@@ -279,6 +317,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);
 
 /**
@@ -291,6 +330,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);
@@ -308,6 +348,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);
@@ -320,6 +361,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);
@@ -334,6 +376,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);
@@ -349,6 +392,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,
@@ -368,6 +412,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,
@@ -380,6 +425,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);
 
 /**
@@ -390,6 +436,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 ceb0608..ecaefa0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,7 +13,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 )
 
@@ -42,9 +50,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/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 a7677ae..61416f1 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
+#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;
@@ -158,7 +165,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:
@@ -190,7 +197,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);
@@ -238,7 +245,8 @@
   return 0;
 }
 
-cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) {
+MYLIB_EXPORT
+const 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;
   cn_cbor* ret;
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 8593b39..b52a996 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -8,12 +8,19 @@
 } /* Duh. */
 #endif
 
+#ifdef _MSC_VER
+#include <WinSock2.h>
+#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"
 
@@ -46,6 +53,7 @@
 ws->offset += sz;
 
 #define write_byte(b) \
+ensure_writable(1); \
 ws->buf[ws->offset++] = (b); \
 
 #define write_byte_ensured(b) \
@@ -89,7 +97,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..0e36495 100644
--- a/src/cn-get.c
+++ b/src/cn-get.c
@@ -2,9 +2,12 @@
 #include <string.h>
 #include <assert.h>
 
+#include "dll-export.h"
+
 #include "cn-cbor/cn-cbor.h"
 
-cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) {
   cn_cbor* cp;
   assert(cb);
   for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) {
@@ -25,7 +28,8 @@
   return NULL;
 }
 
-cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
   cn_cbor *cp;
   int keylen;
   assert(cb);
@@ -48,7 +52,8 @@
   return NULL;
 }
 
-cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
   cn_cbor *cp;
   unsigned int i = 0;
   assert(cb);
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..409d197 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);
@@ -48,10 +56,16 @@
 #ifdef __APPLE__
 #define __Test_Section __attribute__ ((unused,section ("__DATA, .ctest")))
 #else
+#ifdef _MSC_VER
+#define __Test_Section
+#define MS__Test_Section __declspec(allocate(".ctest"))
+#else
 #define __Test_Section __attribute__ ((unused,section (".ctest")))
 #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 +152,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 +324,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 +416,7 @@
     }
 
     color_output = isatty(1);
+
     uint64_t t1 = getCurrentTime();
 
     struct ctest* ctest_begin = &__TNAME(suite, test);