Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document additional commonly-used cJSON functions and types. #145

Merged
merged 2 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ INPUT = @NOTE_C_BASE@/n_hooks.c \
@NOTE_C_BASE@/n_request.c \
@NOTE_C_BASE@/n_cjson.h \
@NOTE_C_BASE@/n_cjson.c \
@NOTE_C_BASE@/n_cjson_helpers.c \
@NOTE_C_BASE@/note.h

# This tag can be used to specify the character encoding of the source files
Expand Down
37 changes: 31 additions & 6 deletions docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ JSON Manipulation
Functions
---------

.. doxygenfunction:: JCreateObject

.. doxygenfunction:: JDelete
.. doxygenfunction:: JAddBinaryToObject

.. doxygenfunction:: JAddBoolToObject

Expand All @@ -144,19 +142,46 @@ Functions

.. doxygenfunction:: JAddArrayToObject

.. doxygenfunction:: JParse
.. doxygenfunction:: JCreateObject

.. doxygenfunction:: JPrintUnformatted
.. doxygenfunction:: JDelete

.. doxygenfunction:: JFree

.. doxygenfunction:: JGetArray

.. doxygenfunction:: JGetBinaryFromObject

.. doxygenfunction:: JGetBool

.. doxygenfunction:: JGetInt

.. doxygenfunction:: JGetNumber

.. doxygenfunction:: JGetObject

.. doxygenfunction:: JGetString

.. doxygenfunction:: JIsPresent

.. doxygenfunction:: JMalloc

.. doxygenfunction:: JFree
.. doxygenfunction:: JParse

.. doxygenfunction:: JPrintUnformatted


Types
-----

.. doxygenstruct:: J

.. doxygentypedef:: JNUMBER

.. doxygentypedef:: JINTEGER

.. doxygentypedef:: JUINTEGER

Macros
------

Expand Down
172 changes: 102 additions & 70 deletions n_cjson_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
#include <time.h>
#include "n_lib.h"

//**************************************************************************/
/*!
@brief Determine if a field is present in a JSON response object.
@param rsp The JSON response object.
@param field The field to find.
@returns boolean. `true` if the field is present.
*/
/**************************************************************************/
@brief Determine if a field is present in a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you're changing things, should we go ahead and rename this parameter j or json?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would also be nice to have a note describing that false is returned if the JSON object is NULL?

This would allow folks to program against it, instead of guess.

@param field The field to find.

@returns True if the field is present and false otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns True if the field is present and false otherwise.
@returns True if the field is present, or false otherwise.

*/
bool JIsPresent(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand All @@ -32,14 +32,19 @@ bool JIsPresent(J *rsp, const char *field)
return (JGetObjectItem(rsp, field) != NULL);
}

//**************************************************************************/
/*!
@brief Return a string from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The string response, or an empty string, if not present.
*/
/**************************************************************************/
@brief Get the value of a string field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The string field to query.

@returns A pointer to the string if the field exists and is a string and the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns A pointer to the string if the field exists and is a string and the
@returns A pointer to the string if the field exists and is a string, or an

empty string ("") otherwise.

@note The returned string is a pointer to the string contained in the JSON
object. It is not a copy of the string, so once the JSON object is freed,
the pointer is no longer valid.
*/
char *JGetString(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand All @@ -58,14 +63,19 @@ char *JGetString(J *rsp, const char *field)
return item->valuestring;
}

//**************************************************************************/
/*!
@brief Return an array from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The array found, or NULL, if not present.
*/
/**************************************************************************/
@brief Get the value of an array field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The array field to query.

@returns A pointer to the array, which is itself a JSON object (`J *`), if the
field exists and is an array and NULL otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this one, "and and...", made me realize a function only returns one OR the other. It also reads a little easier in my opinion, so I added it to others above.

Suggested change
field exists and is an array and NULL otherwise.
field exists and is an array, or NULL otherwise.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna go with "otherwise NULL." I like removing "and", but I feel like "or" and "otherwise" together is wordy and sort of feels redundant.


@note The returned JSON object is a pointer to the array contained in the
parent JSON object. It is not a copy, so once the parent JSON object is
freed, the pointer is no longer valid.
*/
J *JGetArray(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand All @@ -81,14 +91,19 @@ J *JGetArray(J *rsp, const char *field)
return item;
}

//**************************************************************************/
/*!
@brief Return an object from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The object found, or NULL, if not present.
*/
/**************************************************************************/
@brief Get the value of an object field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The object field to query.

@returns A pointer to the object, which is itself a JSON object (`J *`), if the
field exists and is an object and NULL otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
field exists and is an object and NULL otherwise.
field exists and is an object, or NULL otherwise.


@note The returned JSON object is a pointer to the object contained in the
parent JSON object. It is not a copy, so once the parent JSON object is
freed, the pointer is no longer valid.
*/
J *JGetObject(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand Down Expand Up @@ -149,14 +164,19 @@ JNUMBER JNumberValue(J *item)
return item->valuenumber;
}

//**************************************************************************/
/*!
@brief Return a number from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The number found, or 0.0, if not present.
*/
/**************************************************************************/
@brief Get the floating point value of a number field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The number field to query.

@returns The value of the number field if the field exists and is a number and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns The value of the number field if the field exists and is a number and
@returns The value of the number field if the field exists and is a number, or

0.0 otherwise.

@note The returned value is the floating point representation of the number. If
the field is an integer rather than a floating point number, use
`JGetInt`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@note The returned value is the floating point representation of the number. If
the field is an integer rather than a floating point number, use
`JGetInt`.
@note The returned value is the floating point representation of the number.
@see JGetBool
@see JGetInt

https://www.doxygen.nl/manual/commands.html#cmdsee

*/
JNUMBER JGetNumber(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand Down Expand Up @@ -187,14 +207,19 @@ JINTEGER JIntValue(J *item)
return item->valueint;
}

//**************************************************************************/
/*!
@brief Return an integer from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The int found, or 0, if not present.
*/
/**************************************************************************/
@brief Get the integer value of a number field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The number field to query.

@returns The value of the number field if the field exists and is a number and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns The value of the number field if the field exists and is a number and
@returns The value of the number field if the field exists and is a number, or

0 otherwise.

@note The returned value is the integer representation of the number. If the
field is a floating point number rather than an integer, use
`JGetNumber`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@note The returned value is the integer representation of the number. If the
field is a floating point number rather than an integer, use
`JGetNumber`.
@note The returned value is the integer representation of the number.
@see JGetBool
@see JGetNumber

*/
JINTEGER JGetInt(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand All @@ -210,14 +235,15 @@ JINTEGER JGetInt(J *rsp, const char *field)
return JIntValue(item);
}

//**************************************************************************/
/*!
@brief Return a boolean from the specified JSON object.
@param rsp The JSON response object.
@param field The field to return.
@returns The boolean value, or false if not present.
*/
/**************************************************************************/
@brief Get the value of a boolean field from a JSON object.

@param rsp The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param field The boolean field to query.

@returns The value of the boolean field if it exists and is a boolean and false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns The value of the boolean field if it exists and is a boolean and false
@returns The value of the boolean field if it exists and is a boolean, or false otherwise.

otherwise.
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*/
@see JGetInt
@see JGetNumber
*/

bool JGetBool(J *rsp, const char *field)
{
if (rsp == NULL) {
Expand Down Expand Up @@ -325,16 +351,18 @@ bool JContainsString(J *rsp, const char *field, const char *substr)
return (strstr(item->valuestring, substr) != NULL);
}

//**************************************************************************/

/*!
@brief Add a binary to a Note as a Base64-encoded string.
@param req The JSON object to which the field should be added
@param fieldName The field to set.
@param binaryData The binary data to set.
@param binaryDataLen The length of the binary string.
@returns bool. Whether the binary field was set.
*/
/**************************************************************************/
@brief Add binary data as a Base64-encoded string field to a JSON object.

@param req The JSON object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

j or json

@param fieldName The name to use for the field.
@param binaryData A buffer of binary data to encode.
@param binaryDataLen The length of the binary data in bytes.

@returns True if the string was successfully encoded and added to the object
and false otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns True if the string was successfully encoded and added to the object
and false otherwise.
@returns True if the string was successfully encoded and added to the object,
or false otherwise.

*/
bool JAddBinaryToObject(J *req, const char *fieldName, const void *binaryData, uint32_t binaryDataLen)
{
if (req == NULL) {
Expand All @@ -355,19 +383,23 @@ bool JAddBinaryToObject(J *req, const char *fieldName, const void *binaryData, u
return true;
}

//**************************************************************************/

/*!
@brief Get binary from an object that is expected to be a Base64-encoded string.
@param rsp The JSON object containing the field.
@param fieldName The field to get data from.
@param retBinaryData The binary data object allocated. (Use standard "free" method to free it.)
Note that, as a convenience to the caller in case the "binary data" is actually a string,
one byte extra is allocated in the return buffer which is filled with '\0'. This byte
is not included in the retBinaryDataLen length.
@param retBinaryDataLen The length of the binary data.
@returns bool. Whether the binary data was allocated and returned.
*/
/**************************************************************************/
@brief Decode a Base64-encoded string field in a JSON object and return the
decoded bytes.

@param rsp The JSON object.
@param fieldName The name of the field.
@param retBinaryData A pointer to a buffer to hold the decoded bytes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@param retBinaryData A pointer to a buffer to hold the decoded bytes.
@param retBinaryData A pointer to a pointer, used to hold the pointer to the decoded bytes.

@param retBinaryDataLen A pointer to a number to hold the length of the decoded
bytes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@param retBinaryDataLen A pointer to a number to hold the length of the decoded
bytes.
```suggestion
@param retBinaryDataLen A pointer to an unsigned integer, used to hold the
length of the decoded bytes.


@returns True if the string was successfully decoded and returned and false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns True if the string was successfully decoded and returned and false
@returns True if the string was successfully decoded and returned, or false

otherwise.

@note The returned binary buffer must be freed by the user with `JFree` when it
haydenroche5 marked this conversation as resolved.
Show resolved Hide resolved
is no longer needed.
*/
bool JGetBinaryFromObject(J *rsp, const char *fieldName, uint8_t **retBinaryData, uint32_t *retBinaryDataLen)
{
if (rsp == NULL) {
Expand Down
9 changes: 9 additions & 0 deletions note.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,25 @@
#define ERRSTR(x,y) (x)
#endif

/*!
@brief The floating point type used for JSON handling in note-c.
*/
#ifdef NOTE_C_TEST_SINGLE_PRECISION
typedef float JNUMBER;
#else
typedef double JNUMBER;
#endif

/*!
@brief The signed integer type used for JSON handling in note-c.
*/
typedef int64_t JINTEGER;
#define JINTEGER_MIN INT64_MIN
#define JINTEGER_MAX INT64_MAX

/*!
@brief The unsigned integer type used for JSON handling in note-c.
*/
typedef uint64_t JUINTEGER;

// UNIX Epoch time (also known as POSIX time) is the number of seconds that have elapsed since
Expand Down
Loading