Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #pragma once
5 : :
6 : : #if !defined (VALENT_INSIDE) && !defined (VALENT_COMPILATION)
7 : : # error "Only <valent.h> can be included directly."
8 : : #endif
9 : :
10 : : #include <json-glib/json-glib.h>
11 : :
12 : : #include "../core/valent-object.h"
13 : :
14 : : G_BEGIN_DECLS
15 : :
16 : :
17 : : /**
18 : : * ValentPacketError:
19 : : * @VALENT_PACKET_ERROR_UNKNOWN: an unknown error
20 : : * @VALENT_PACKET_ERROR_INVALID_DATA: the packet is %NULL or not JSON
21 : : * @VALENT_PACKET_ERROR_MALFORMED: the packet structure is malformed
22 : : * @VALENT_PACKET_ERROR_INVALID_FIELD: an expected field holds an invalid type
23 : : * @VALENT_PACKET_ERROR_MISSING_FIELD: an expected field is missing
24 : : *
25 : : * Error enumeration for KDE Connect packet validation.
26 : : *
27 : : * This enumeration can be extended at later date
28 : : *
29 : : * Since: 1.0
30 : : */
31 : : typedef enum {
32 : : VALENT_PACKET_ERROR_UNKNOWN,
33 : : VALENT_PACKET_ERROR_INVALID_DATA,
34 : : VALENT_PACKET_ERROR_MALFORMED,
35 : : VALENT_PACKET_ERROR_INVALID_FIELD,
36 : : VALENT_PACKET_ERROR_MISSING_FIELD,
37 : : } ValentPacketError;
38 : :
39 : : VALENT_AVAILABLE_IN_1_0
40 : : GQuark valent_packet_error_quark (void);
41 : : #define VALENT_PACKET_ERROR (valent_packet_error_quark ())
42 : :
43 : :
44 : : /**
45 : : * valent_packet_is_valid:
46 : : * @packet: (nullable): a `JsonNode`
47 : : *
48 : : * Check if @packet is a well-formed KDE Connect packet. This can be used in
49 : : * g_return_if_fail() checks.
50 : : *
51 : : * Returns: %TRUE if @packet is valid, or %FALSE if not
52 : : */
53 : : static inline gboolean
54 : 2000 : valent_packet_is_valid (JsonNode *packet)
55 : : {
56 : 2000 : JsonObject *root;
57 : 2000 : JsonNode *node;
58 : :
59 [ + - - + ]: 2000 : if G_UNLIKELY (packet == NULL || !JSON_NODE_HOLDS_OBJECT (packet))
60 : 0 : return FALSE;
61 : :
62 : 2000 : root = json_node_get_object (packet);
63 : :
64 : : /* TODO: kdeconnect-kde stringifies this in identity packets
65 : : * https://invent.kde.org/network/kdeconnect-kde/-/merge_requests/380 */
66 [ + - - + : 2000 : if G_UNLIKELY ((node = json_object_get_member (root, "id")) == NULL ||
- - ]
67 : : (json_node_get_value_type (node) != G_TYPE_INT64 &&
68 : : json_node_get_value_type (node) != G_TYPE_STRING))
69 : 0 : return FALSE;
70 : :
71 [ + - + - ]: 2000 : if G_UNLIKELY ((node = json_object_get_member (root, "type")) == NULL ||
72 : : json_node_get_value_type (node) != G_TYPE_STRING)
73 : 0 : return FALSE;
74 : :
75 [ + - + - ]: 2000 : if G_UNLIKELY ((node = json_object_get_member (root, "body")) == NULL ||
76 : : json_node_get_node_type (node) != JSON_NODE_OBJECT)
77 : 0 : return FALSE;
78 : :
79 : : /* These two are optional, but have defined value types */
80 [ + + - + ]: 2000 : if G_UNLIKELY ((node = json_object_get_member (root, "payloadSize")) != NULL &&
81 : : json_node_get_value_type (node) != G_TYPE_INT64)
82 : : return FALSE;
83 : :
84 [ + + - + ]: 2000 : if G_UNLIKELY ((node = json_object_get_member (root, "payloadTransferInfo")) != NULL &&
85 : : json_node_get_node_type (node) != JSON_NODE_OBJECT)
86 : : return FALSE;
87 : :
88 : : return TRUE;
89 : : }
90 : : #define VALENT_IS_PACKET(packet) (valent_packet_is_valid (packet))
91 : :
92 : :
93 : : /* Packet Helpers */
94 : : VALENT_AVAILABLE_IN_1_0
95 : : JsonNode * valent_packet_new (const char *type);
96 : : VALENT_AVAILABLE_IN_1_0
97 : : void valent_packet_init (JsonBuilder **builder,
98 : : const char *type);
99 : : VALENT_AVAILABLE_IN_1_0
100 : : JsonNode * valent_packet_end (JsonBuilder **builder);
101 : : VALENT_AVAILABLE_IN_1_0
102 : : int64_t valent_packet_get_id (JsonNode *packet);
103 : : VALENT_AVAILABLE_IN_1_0
104 : : const char * valent_packet_get_type (JsonNode *packet);
105 : : VALENT_AVAILABLE_IN_1_0
106 : : JsonObject * valent_packet_get_body (JsonNode *packet);
107 : : VALENT_AVAILABLE_IN_1_0
108 : : gboolean valent_packet_has_payload (JsonNode *packet);
109 : : VALENT_AVAILABLE_IN_1_0
110 : : JsonObject * valent_packet_get_payload_full (JsonNode *packet,
111 : : goffset *size,
112 : : GError **error);
113 : : VALENT_AVAILABLE_IN_1_0
114 : : void valent_packet_set_payload_full (JsonNode *packet,
115 : : JsonObject *info,
116 : : goffset size);
117 : : VALENT_AVAILABLE_IN_1_0
118 : : JsonObject * valent_packet_get_payload_info (JsonNode *packet);
119 : : VALENT_AVAILABLE_IN_1_0
120 : : void valent_packet_set_payload_info (JsonNode *packet,
121 : : JsonObject *info);
122 : : VALENT_AVAILABLE_IN_1_0
123 : : goffset valent_packet_get_payload_size (JsonNode *packet);
124 : : VALENT_AVAILABLE_IN_1_0
125 : : void valent_packet_set_payload_size (JsonNode *packet,
126 : : goffset size);
127 : :
128 : : /* Field Helpers */
129 : : VALENT_AVAILABLE_IN_1_0
130 : : gboolean valent_packet_check_field (JsonNode *packet,
131 : : const char *field);
132 : : VALENT_AVAILABLE_IN_1_0
133 : : gboolean valent_packet_get_boolean (JsonNode *packet,
134 : : const char *field,
135 : : gboolean *value);
136 : : VALENT_AVAILABLE_IN_1_0
137 : : gboolean valent_packet_get_double (JsonNode *packet,
138 : : const char *field,
139 : : double *value);
140 : : VALENT_AVAILABLE_IN_1_0
141 : : gboolean valent_packet_get_int (JsonNode *packet,
142 : : const char *field,
143 : : int64_t *value);
144 : : VALENT_AVAILABLE_IN_1_0
145 : : gboolean valent_packet_get_string (JsonNode *packet,
146 : : const char *field,
147 : : const char **value);
148 : : VALENT_AVAILABLE_IN_1_0
149 : : gboolean valent_packet_get_array (JsonNode *packet,
150 : : const char *field,
151 : : JsonArray **value);
152 : : VALENT_AVAILABLE_IN_1_0
153 : : gboolean valent_packet_get_object (JsonNode *packet,
154 : : const char *field,
155 : : JsonObject **value);
156 : : VALENT_AVAILABLE_IN_1_0
157 : : GStrv valent_packet_dup_strv (JsonNode *packet,
158 : : const char *field);
159 : :
160 : : /* I/O Helpers */
161 : : VALENT_AVAILABLE_IN_1_0
162 : : gboolean valent_packet_validate (JsonNode *packet,
163 : : GError **error);
164 : : VALENT_AVAILABLE_IN_1_0
165 : : JsonNode * valent_packet_from_stream (GInputStream *stream,
166 : : gssize max_len,
167 : : GCancellable *cancellable,
168 : : GError **error);
169 : : VALENT_AVAILABLE_IN_1_0
170 : : gboolean valent_packet_to_stream (GOutputStream *stream,
171 : : JsonNode *packet,
172 : : GCancellable *cancellable,
173 : : GError **error);
174 : : VALENT_AVAILABLE_IN_1_0
175 : : char * valent_packet_serialize (JsonNode *packet);
176 : : VALENT_AVAILABLE_IN_1_0
177 : : JsonNode * valent_packet_deserialize (const char *json,
178 : : GError **error);
179 : :
180 : : G_END_DECLS
|