Document CanonicalJson

This commit is contained in:
Jordan Bancino 2022-11-30 18:23:25 +00:00
parent 439e14a410
commit 5771e615d7
4 changed files with 76 additions and 50 deletions

View file

@ -27,7 +27,7 @@ Due: January 1, 2023
[~] Internal API docs [~] Internal API docs
[x] Array [x] Array
[x] Base64 [x] Base64
[ ] CanonicalJson [x] CanonicalJson
[ ] Config [ ] Config
[ ] API (Config.3) [ ] API (Config.3)
[ ] File format (Config.5) [ ] File format (Config.5)

69
man/man3/CanonicalJson.3 Normal file
View file

@ -0,0 +1,69 @@
.Dd $Mdocdate: November 30 2022 $
.Dt CANONICALJSON 3
.Os Telodendria Project
.Sh NAME
.Nm CanonicalJson
.Nd An extension of JSON that produces the Matrix spec's "canonical" JSON.
.Sh SYNOPSIS
.In CanonicalJson.h
.Ft int
.Fn CanonicalJsonEncode "HashMap *" "FILE *"
.Ft char *
.Fn CanonicalJsonEncodeToString "HashMap *"
.Sh DESCRIPTION
.Pp
.Nm
is an extension of
.Xr Json 3
that is specifically designed to produce the Matrix specification's
"canonical" JSON.
.Pp
Canonical JSON is defined as JSON that:
.Bl -bullet -offset indent
.It
Does not have any unecessary whitespace.
.It
Has all object keys lexicographically sorted.
.It
Does not contain any floating point numerical values.
.El
.Pp
The regular JSON encoder has no such rules, because normally they are
not needed. However, Canonical JSON is needed to consistently sign JSON
objects.
.Pp
.Fn CanonicalJsonEncode
encodes a JSON object following the rules of Canonical Json. See the
documentation for
.Fn JsonEncode ,
documented in
.Xr Json 3
for more details on how JSON encoding operates. This function exists
as an alternative to
.Fn JsonEncode ,
but should not be preferred to it in most circumstances. It is a lot
more costly, as it must lexicographically sort all keys and strip out
float values. If at all possible, use
.Fn JsonEncode
because it is much cheaper both in terms of memory and CPU time.
.Pp
.Fn CanonicalJsonEncodeToString
encodes a JSON object to a string.
.Xr Json 3
doesn't have any way to send JSON to a string, because there's
absolutely no reason to handle JSON strings in most cases. However,
the sole reason Canonical JSON exists is so that JSON objects can
be signed in a consistent way. Thus, you need a string to pass to
the signing function.
.Sh RETURN VALUES
.Pp
.Fn CanonicalJsonEncode
returns whether or not the JSON encoding operation was sucessful.
This function will fail only if NULL was given for any parameter.
Otherwise, if an invalid pointer is given, undefined behavior results.
.Pp
.Fn CanonicalJsonEncodeToString
returns a C string containing the canonical JSON representation of
the given object, or NULL if the encoding failed.
.Sh SEE ALSO
.Xr Json 3

View file

@ -235,6 +235,12 @@ Smart memory management API.
A feature-complete API for reading and writing JSON. A feature-complete API for reading and writing JSON.
</td> </td>
</tr> </tr>
<tr>
<td><a href="man/man3/CanonicalJson.3.html">CanonicalJson(3)</a></td>
<td>
An extension to the Json API that implements Matrix's canonical JSON.
</td>
</tr>
</table> </table>
<h2 id="resources">Resources</h2> <h2 id="resources">Resources</h2>
<ul> <ul>

View file

@ -22,64 +22,15 @@
* SOFTWARE. * SOFTWARE.
*/ */
/*
* CanonicalJson.h: An expansion of the JSON encoding functionality
* that is specifically designed to produce the Matrix spec's
* "canonical" JSON.
*
* Canonical JSON is defined as JSON that:
*
* - Does not have any unecessary whitespace.
* - Has all object keys lexicographically sorted.
* - Does not contain any float values.
*
* The regular JSON encoder has no such rules, because normally they
* are not needed. However, Canonical JSON is needed to be able to
* sign JSON objects in a consistent way.
*/
#ifndef TELODENDRIA_CANONICALJSON_H #ifndef TELODENDRIA_CANONICALJSON_H
#define TELODENDRIA_CANONICALJSON_H #define TELODENDRIA_CANONICALJSON_H
#include <stdio.h> #include <stdio.h>
#include <HashMap.h> #include <HashMap.h>
/*
* Encode a JSON object following the rules of canonical JSON. See
* JsonEncode() for more details on how JSON encoding operates.
*
* This function exists as an alternative to JsonEncode(), but should
* not be preferred to JsonEncode() in normal circumstances. It is
* a lot more costly, as it must lexicographically sort all keys and
* strip out float values. If at all possible, use JsonEncode(),
* because it is much cheaper in terms of memory and CPU time.
*
* Params:
*
* (HashMap *) The JSON object to encode. Note that all values must
* be JsonValues.
* (FILE *) The output stream to write the JSON object to.
*
* Return: Whether or not the JSON encoding was successful. This
* function may fail if NULL was given for any parameter.
*/
extern int extern int
CanonicalJsonEncode(HashMap *, FILE *); CanonicalJsonEncode(HashMap *, FILE *);
/*
* Encode the JSON object to a string. The regular JSON encoding
* library doesn't have a way to send JSON to strings, because there's
* absolutely no reason to handle JSON strings. However, the sole
* reason canonical JSON exists is so that JSON objects can be signed.
* Thus, you need a string to pass to the signing function.
*
* Params:
*
* (HashMap *) The JSON object to encode. Note that all values must
* be JsonValues.
*
* Return: A string containing the canonical JSON representation of
* the given object, or NULL if the encoding failed.
*/
extern char * extern char *
CanonicalJsonEncodeToString(HashMap *); CanonicalJsonEncodeToString(HashMap *);