Merge remote-tracking branch 'upstream/master'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 195c780..e076dc8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,6 +24,7 @@
 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 )
 
 set ( dist_dir    ${CMAKE_BINARY_DIR}/dist )
 set ( prefix      ${CMAKE_INSTALL_PREFIX} )
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index bf71af8..187a55c 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -1,3 +1,4 @@
+
 /**
  * \file
  * \brief
@@ -52,6 +53,8 @@
   CN_CBOR_SIMPLE,
   /** Doubles, floats, and half-floats */
   CN_CBOR_DOUBLE,
+  /** Floats, and half-floats */
+  CN_CBOR_FLOAT,
   /** An error has occurred */
   CN_CBOR_INVALID
 } cn_cbor_type;
@@ -91,6 +94,8 @@
     unsigned long uint;
     /** CN_CBOR_DOUBLE */
     double dbl;
+    /** CN_CBOR_FLOAT */
+    float f;
     /** for use during parsing */
     unsigned long count;
   } v;                          /* TBD: optimize immediate */
@@ -324,6 +329,32 @@
                             CBOR_CONTEXT,
                             cn_cbor_errback *errp);
 
+#ifndef CBOR_NO_FLOAT
+/**
+ * Create a CBOR float.
+ *
+ * @param[in]   value    the value of the float
+ * @param[in]   CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined)
+ * @param[out]  errp         Error, if NULL is returned
+ * @return                   The created object, or NULL on error
+ */
+cn_cbor* cn_cbor_float_create(float value
+                              CBOR_CONTEXT,
+                              cn_cbor_errback *errp);
+
+/**
+ * Create a CBOR double.
+ *
+ * @param[in]   value    the value of the double
+ * @param[in]   CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined)
+ * @param[out]  errp         Error, if NULL is returned
+ * @return                   The created object, or NULL on error
+ */
+cn_cbor* cn_cbor_double_create(double value
+                               CBOR_CONTEXT,
+                               cn_cbor_errback *errp);
+#endif /* CBOR_NO_FLOAT */
+
 /**
  * Put a CBOR object into a map with a CBOR object key.  Duplicate checks are NOT
  * currently performed.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ceb0608..babe95c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,6 +10,9 @@
       cn-get.c
 )
 
+if (align_reads)
+  add_definitions(-DCBOR_ALIGN_READS)
+endif()
 if (use_context)
   add_definitions(-DUSE_CBOR_CONTEXT)
 endif()
diff --git a/src/cn-cbor.c b/src/cn-cbor.c
index a7677ae..9093537 100644
--- a/src/cn-cbor.c
+++ b/src/cn-cbor.c
@@ -49,10 +49,25 @@
 }
 #endif /* CBOR_NO_FLOAT */
 
-/* Fix these if you can't do non-aligned reads */
 #define ntoh8p(p) (*(unsigned char*)(p))
+
+#ifndef CBOR_ALIGN_READS
 #define ntoh16p(p) (ntohs(*(unsigned short*)(p)))
 #define ntoh32p(p) (ntohl(*(unsigned long*)(p)))
+#else
+static uint16_t ntoh16p(unsigned char *p) {
+    uint16_t tmp;
+    memcpy(&tmp, p, sizeof(tmp));
+    return ntohs(tmp);
+}
+
+static uint32_t ntoh32p(unsigned char *p) {
+    uint32_t tmp;
+    memcpy(&tmp, p, sizeof(tmp));
+    return ntohl(tmp);
+}
+#endif /* CBOR_ALIGN_READS */
+
 static uint64_t ntoh64p(unsigned char *p) {
   uint64_t ret = ntoh32p(p);
   ret <<= 32;
diff --git a/src/cn-create.c b/src/cn-create.c
index bc448e9..4ddce3b 100644
--- a/src/cn-create.c
+++ b/src/cn-create.c
@@ -73,6 +73,34 @@
   return ret;
 }
 
+#ifndef CBOR_NO_FLOAT
+cn_cbor* cn_cbor_float_create(float value
+                              CBOR_CONTEXT,
+                              cn_cbor_errback *errp)
+{
+  cn_cbor* ret;
+  INIT_CB(ret);
+
+  ret->type = CN_CBOR_FLOAT;
+  ret->v.f = value;
+
+  return ret;
+}
+
+cn_cbor* cn_cbor_double_create(double value
+                               CBOR_CONTEXT,
+                               cn_cbor_errback *errp)
+{
+  cn_cbor* ret;
+  INIT_CB(ret);
+
+  ret->type = CN_CBOR_DOUBLE;
+  ret->v.dbl = value;
+
+  return ret;
+}
+#endif /* CBOR_NO_FLOAT */
+
 static bool _append_kv(cn_cbor *cb_map, cn_cbor *key, cn_cbor *val)
 {
   //Connect key and value and insert them into the map.
diff --git a/src/cn-encoder.c b/src/cn-encoder.c
index 3365535..ffaf3e8 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -276,6 +276,11 @@
     CHECK(_write_double(ws, cb->v.dbl));
 #endif /* CBOR_NO_FLOAT */
     break;
+  case CN_CBOR_FLOAT:
+#ifndef CBOR_NO_FLOAT
+    CHECK(_write_double(ws, cb->v.f));
+#endif /* CBOR_NO_FLOAT */
+    break;
 
   case CN_CBOR_INVALID:
     ws->offset = -1;
diff --git a/src/cn-get.c b/src/cn-get.c
index cc276a5..79d3d72 100644
--- a/src/cn-get.c
+++ b/src/cn-get.c
@@ -13,6 +13,7 @@
       if (cp->v.uint == (unsigned long)key) {
         return cp->next;
       }
+      break;
     case CN_CBOR_INT:
       if (cp->v.sint == (long)key) {
         return cp->next;
diff --git a/test/cbor_test.c b/test/cbor_test.c
index 3326497..eafea5d 100644
--- a/test/cbor_test.c
+++ b/test/cbor_test.c
@@ -327,6 +327,9 @@
     cn_cbor *cb_map = cn_cbor_map_create(CONTEXT_NULL_COMMA &err);
     cn_cbor *cb_int;
     cn_cbor *cb_data;
+#ifndef CBOR_NO_FLOAT
+    cn_cbor *cb_dbl;
+#endif
 
     ASSERT_NOT_NULL(cb_map);
     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
@@ -339,6 +342,12 @@
     ASSERT_NOT_NULL(cb_data);
     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
 
+#ifndef CBOR_NO_FLOAT
+    cb_dbl = cn_cbor_double_create(3.14159 CONTEXT_NULL, &err);
+    ASSERT_NOT_NULL(cb_dbl);
+    ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+#endif
+
     cn_cbor_mapput_int(cb_map, 5, cb_int CONTEXT_NULL, &err);
     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
     ASSERT_TRUE(cb_map->length == 2);
@@ -360,6 +369,12 @@
     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
     ASSERT_TRUE(cb_map->length == 8);
 
+#ifndef CBOR_NO_FLOAT
+    cn_cbor_mapput_int(cb_map, 42, cb_dbl CONTEXT_NULL, &err);
+    ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
+    ASSERT_TRUE(cb_map->length == 10);
+#endif
+
     val = cn_cbor_mapget_int(cb_map, 5);
     ASSERT_NOT_NULL(val);
     ASSERT_TRUE(val->v.sint == 256);
@@ -368,6 +383,12 @@
     ASSERT_NOT_NULL(val);
     ASSERT_STR(val->v.str, "abc");
 
+#ifndef CBOR_NO_FLOAT
+    val = cn_cbor_mapget_int(cb_map, 42);
+    ASSERT_NOT_NULL(val);
+    ASSERT_TRUE(val->v.dbl > 3.14 && val->v.dbl < 3.15);
+#endif
+
     cn_cbor_free(cb_map CONTEXT_NULL);
 }
 
diff --git a/test/test.c b/test/test.c
index d24992f..b7d85af 100644
--- a/test/test.c
+++ b/test/test.c
@@ -109,7 +109,7 @@
   printf("%s at %d\n", err_name[back.err], back.pos);
 }
 
-int main() {
+int main(void) {
   char buf[100000];
   unsigned char *end;
   char *bufend;