1/* Marshalling and unmarshalling.
2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include <cc1plugin-config.h>
21#include <new>
22#include <string.h>
23#include "marshall.hh"
24#include "connection.hh"
25#include "rpc.hh"
26
27cc1_plugin::status
28cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
29{
30 unsigned long long r;
31
32 if (!unmarshall (conn, scalar: &r))
33 return FAIL;
34 return check == r ? OK : FAIL;
35}
36
37cc1_plugin::status
38cc1_plugin::marshall_intlike (connection *conn, unsigned long long val)
39{
40 if (!conn->send (c: 'i'))
41 return FAIL;
42 return conn->send (buf: &val, len: sizeof (val));
43}
44
45cc1_plugin::status
46cc1_plugin::unmarshall_intlike (connection *conn, unsigned long long *result)
47{
48 if (!conn->require (c: 'i'))
49 return FAIL;
50 return conn->get (buf: result, len: sizeof (*result));
51}
52
53cc1_plugin::status
54cc1_plugin::marshall (connection *conn, const char *str)
55{
56 if (!conn->send (c: 's'))
57 return FAIL;
58
59 unsigned long long len = str == NULL ? -1ULL : strlen (s: str);
60 if (!conn->send (buf: &len, len: sizeof (len)))
61 return FAIL;
62
63 if (str == NULL)
64 return OK;
65
66 return conn->send (buf: str, len);
67}
68
69cc1_plugin::status
70cc1_plugin::unmarshall (connection *conn, char **result)
71{
72 unsigned long long len;
73
74 if (!conn->require (c: 's'))
75 return FAIL;
76 if (!conn->get (buf: &len, len: sizeof (len)))
77 return FAIL;
78
79 if (len == -1ULL)
80 {
81 *result = NULL;
82 return OK;
83 }
84
85 char *str = new (std::nothrow) char[len + 1];
86 if (str == NULL)
87 return FAIL;
88
89 if (!conn->get (buf: str, len))
90 {
91 delete[] str;
92 return FAIL;
93 }
94
95 str[len] = '\0';
96 *result = str;
97
98 return OK;
99}
100
101cc1_plugin::status
102cc1_plugin::marshall_array_start (connection *conn, char id,
103 size_t n_elements)
104{
105 if (!conn->send (c: id))
106 return FAIL;
107
108 unsigned long long r = n_elements;
109 if (!conn->send (buf: &r, len: sizeof (r)))
110 return FAIL;
111
112 return OK;
113}
114
115cc1_plugin::status
116cc1_plugin::marshall_array_elmts (connection *conn, size_t n_bytes,
117 void *elements)
118{
119 return conn->send (buf: elements, len: n_bytes);
120}
121
122cc1_plugin::status
123cc1_plugin::unmarshall_array_start (connection *conn, char id,
124 size_t *n_elements)
125{
126 unsigned long long len;
127
128 if (!conn->require (c: id))
129 return FAIL;
130 if (!conn->get (buf: &len, len: sizeof (len)))
131 return FAIL;
132
133 *n_elements = len;
134
135 return OK;
136}
137
138cc1_plugin::status
139cc1_plugin::unmarshall_array_elmts (connection *conn, size_t n_bytes,
140 void *elements)
141{
142 return conn->get (buf: elements, len: n_bytes);
143}
144
145cc1_plugin::status
146cc1_plugin::marshall (connection *conn, const gcc_type_array *a)
147{
148 size_t len;
149
150 if (a)
151 len = a->n_elements;
152 else
153 len = (size_t)-1;
154
155 if (!marshall_array_start (conn, id: 'a', n_elements: len))
156 return FAIL;
157
158 if (!a)
159 return OK;
160
161 return marshall_array_elmts (conn, n_bytes: len * sizeof (a->elements[0]),
162 elements: a->elements);
163}
164
165cc1_plugin::status
166cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
167{
168 size_t len;
169
170 if (!unmarshall_array_start (conn, id: 'a', n_elements: &len))
171 return FAIL;
172
173 if (len == (size_t)-1)
174 {
175 *result = NULL;
176 return OK;
177 }
178
179 cc1_plugin::unique_ptr<gcc_type_array> gta (new gcc_type_array {});
180
181 gta->n_elements = len;
182 gta->elements = new gcc_type[len];
183
184 if (!unmarshall_array_elmts (conn,
185 n_bytes: len * sizeof (gta->elements[0]),
186 elements: gta->elements))
187 return FAIL;
188
189 *result = gta.release ();
190
191 return OK;
192}
193

source code of libcc1/marshall.cc