Metadata is saved only when the item in question is part of a map,
otherwise we don't have anywhere to save the metadata.
The metadata consists of an extra JSON object, whose key is the same key
with "$cbor" appended. The possible entries in that map are:
- tag: the innermost tag before the actual type
- t: the original CBOR type (CborType)
- v: supplemental value to reconstruct the original value
for simple types, it's the simple type (0-255)
for integers, it's the sign followed by the hex dump
for floating point, it's "nan", "inf" or "-inf"
In addition, if CborConvertStringifyMapKeys is active and the key itself
wasn't a string, an extra object entry with the same string key followed
by "$keycbordump" is added, indicating that the key was stringified.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This avoids having a third set of CborValue-to-text conversion
functions. What's more, the CBOR dump format is unique and reversible
(except for inf & nan, which lose their precision indication).
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Normally, only three tags are handled and only for byte strings. But if
you set the CborConvertTagsToObjects flag, then all tags are transformed
into JSON objects (and the byte string-specific tags don't get
honoured).
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This fixes issue #4. The code is placed in a new file and function so
that only people who need it will pay the cost of this function. The
impact to existing code is minimal.
Before:
text data bss dec hex filename
945 0 0 945 3b1 cborencoder.o
2743 0 0 2743 ab7 cborparser.o
After:
1026 0 0 1026 424 cborencoder.o
2756 0 0 2756 ac4 cborparser.o
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This causes the 64-bit store to be aligned. On x86 and x86-64 this
should improve performance; on some other architectures, this should
prevent a byte-by-byte copy due to the misalignment.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
When we wrote:
encoder->end = encoder->ptr = NULL;
}
++encoder->ptr;
We're incrementing a null pointer. This could be considered undefined
behaviour and the compiler would be free to remove the increment.
This commit solves that by using an integer called bytes_needed to store
the number of bytes needed.
The trick is, however, that this commit is actually a no-op: the new
member occupies the same storage as ptr and in all of the new
conditionals, both branches evaluate to the same code, so the
conditional can be removed.
The code is complex like this to ensure we don't run afoul of another
undefined behaviour: reading from a member of an union that was not the
last written to.
CID: 306167
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This makes the create_array and map functions simpler. The noinline
forces the compiler not to inline create_container. There's a net gain
this way.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This avoids writing to a buffer and scanning it. As an advantage, we
always print full precision when it matches an integer.
Incidentally, let's make sure we use the C11 macro that has the correct
number of decimal digits a double-precision floating-point can hold.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
floats and double are too big for value->extra and the
CborIteratorFlag_IntegerValueTooLarge flag is always set (see
cborparser.c:174). So there's no point in checking for the flag and we
can instead go straight to the internal function.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Don't include .gitignore and .gitattributes itself, but do include the
SHA-1 of the commit in the .tag file.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Release steps:
1) run distcheck
2) update the version number && commit it
3) create a new tag
4) create the release files
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
We then avoid recompiling every time. Exceptions:
- tst_parser requires a recursion limit set
- tst_cpp #includes so that the sources are compiled as C++
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
The top-level Makefile will build the library, the cbordump tool and possibly
install them. Along with the buildsystem, tinycbor also gets a pkgconfig file
and a version number.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This calculates the length of a text string to be encoded using
strlen(). Useful when encoding constant strings.
Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This patch causes TinyCbor Encoder to remain in a valid-state in the situation
where it has overrun its buffer. It does this by setting the pointer
and end variable of the encoder to NULL, making encoder->ptr - NULL (or
encoder->ptr - encoder->end) equal the amount of additional data
necessary to properly encode the package.
Signed-off-by: Erich Keane <erich.keane@intel.com>
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Provided they have GCC 4.3 or a GCC-like compiler. For GCC, we were
already not using htonl and ntohl and for GCC >= 4.8, we weren't using
htons and ntohs either. So make it official and stop using for GCC 4.3
through 4.7, removing the #include too.
Systems without GCC will still attempt to include <arpa/inet.h>, as we
hope that ntohl/htonl are more optimised than a hand-rolled 32-bit byte-
swap.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
C99 also requires them in <stdint.h>, but some systems (Arduino 1.6.3)
are lacking the definitions.
Unlike for SIZE_MAX, we know the number of bits of the exact-width
integer types (C99 7.18.1.1), so we just define/use the values we need.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Instead of by pointer, which was inconsistent with all the other
cbor_encode_xxx functions.
Now only cbor_encode_half_float is an exception, but since the C
language doesn't have a standardised half-float type, we can't have it
in the API. Even for targets where GCC has an __fp16 type, we couldn't,
as the manual says (Top > C Extensions > Half-Precision):
In addition, you cannot declare a function with a return value or
parameters of type `__fp16'.
But I might remove the function and force you to use
cbor_encode_floating_point.
Fixes: #3
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This introduces the checking of the actual type and also gets us type-
safety of the binary data.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Unlike calculate_string_length(), dup_string() failed to pre-initialise
*buflen to SIZE_MAX. I believe I had chosen not to call the calculate
function to make the code smaller, so the compiler won't have to move
the parameters around just to move them back to the same register in
order to call copy_string().
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
The CBOR_INLINE_API define previously was just 'inline'
for newer C compilers, however this was causing a failure
to link to these functions in the event that optimizations
were turned off. This fix removes the condition on newer
compilers, and makes it ALWAYS static inline unless
the compiler is in C++ mode.
Signed-off-by: Erich Keane <erich.keane@intel.com>
The C standard says that if you #include <assert.h> again, it will
redefine assert() (because you my have defined or undefined NDEBUG).
Since that is the case, we need to "fix" assert as the last #include.
The "fix" has two advantages:
1) it "uses" the condition, so you don't get a warning for variables
only used in asserts, like
cborparser.c:236:15: warning: unused variable ‘err’ [-Wunused-variable]
2) it tells the compiler that the condition is always true in release
mode, so it may optimise the code for that case. In other words, bad
things might happen otherwise. There's currently no measured benefit in
code size for GCC 4.9 with -Os, but it does additionally suppress bogus warnings
from GCC:
cborparser.c:244:17: warning: ‘length’ may be used uninitialized in this function [-Wmaybe-uninitialized]
The compiler is saying that 'length' could be uninitialised if
extract_number returned CborErrorIllegalNumber. But since we asserted
that it isn't the case, all code paths that would use the uninitialised
value are eliminated. In debug mode, those code paths are eliminated by
assert() calling the noreturn function __assert_fail.
If the compiler had inlined extract_number, it would also have
eliminated the comparison additional_information > Value64Bit (line 92)
by dead code elimination.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
It's actually in __clang_major__, but instead let's check that the
builtin intrinsics that we were looking for are actually present. This
should also fix any issues with Apple's backports of Clang into XCode.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Clang insists in inlining extract_number even with -Os, which increases
the code size considerably. Without the markers, now both Clang and GCC
inline extract_length but not extract_number.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Unsigned additions are guaranteed to operate on modulo 2, so if there's
an overflow, the sum will be smaller than both v1 and v2. We don't need
to check both, though, one is enough.
Tested with GCC 4.9 to actually produce a jump-on-overflow instruction
on x86-64:
108: add %r15,%r11
10b: jb 1cb <iterate_string_chunks+0x1cb>
With GCC 5:
108: add %r9,%r11
10b: jb 123 <iterate_string_chunks+0x123>
With Clang:
a9: add %rdx,%r14
ac: jb 1d1 <iterate_string_chunks+0x1d1>
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Match the intrinsic we were trying to use. This makes the check now work
on GCC 5 and Clang. Previously, it would always fail.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
GCC didn't introduce __builtin_bswap16 until version 4.8. I don't know
which version of ICC introduced it, but _bswap16 seems to have been
supported for longer (a 2012 commit to include/linux/compiler-intel.h
used it).
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Now char is only used in the text string API, which is supposed to be
UTF-8.
Negative values for UTF-8 is stupid by itself, but the C++ committee
felt no need to add char8_t, so let's live with it.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Force the code to use the __builtin_swapXX functions if we know them to
be available. GCC added them in version 4.3 and Clang in version 3.2.
But since Apple released XCode with a 3.2 version prior to the release,
we can't check for Clang version numbers, we have to use __has_builtin.
In order to force the using of the builtins, we can't use ntohl and
ntohs, so we define our own set of macros.
This fixes the issue that glibc's ntohs is implemented with a ROR
instruction instead of BSWAP or MOVBE. It also fixes the cross-build
using Clang because glibc apparently assumes that you either have GCC or
you have x86.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
One caused a test failure, the other caused memory corruption (valgrind
complained about jump conditions on uninitialised data).
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Move the #include for the moc file closer to the top so that qmake sees
it. Something in the source code is throwing qmake off and it can't
parse the dependencies.
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>