[multiple changes]
[gcc.git] / libcc1 / marshall.cc
1 /* Marshalling and unmarshalling.
2 Copyright (C) 2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along 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
26 cc1_plugin::status
27 cc1_plugin::unmarshall_check (connection *conn, unsigned long long check)
28 {
29 unsigned long long r;
30
31 if (!unmarshall (conn, &r))
32 return FAIL;
33 return check == r ? OK : FAIL;
34 }
35
36 cc1_plugin::status
37 cc1_plugin::marshall_intlike (connection *conn, unsigned long long val)
38 {
39 if (!conn->send ('i'))
40 return FAIL;
41 return conn->send (&val, sizeof (val));
42 }
43
44 cc1_plugin::status
45 cc1_plugin::unmarshall_intlike (connection *conn, unsigned long long *result)
46 {
47 if (!conn->require ('i'))
48 return FAIL;
49 return conn->get (result, sizeof (*result));
50 }
51
52 cc1_plugin::status
53 cc1_plugin::unmarshall (connection *conn, enum gcc_c_symbol_kind *result)
54 {
55 protocol_int p;
56 if (!unmarshall_intlike (conn, &p))
57 return FAIL;
58 *result = (enum gcc_c_symbol_kind) p;
59 return OK;
60 }
61
62 cc1_plugin::status
63 cc1_plugin::unmarshall (connection *conn, enum gcc_c_oracle_request *result)
64 {
65 protocol_int p;
66 if (!unmarshall_intlike (conn, &p))
67 return FAIL;
68 *result = (enum gcc_c_oracle_request) p;
69 return OK;
70 }
71
72 cc1_plugin::status
73 cc1_plugin::unmarshall (connection *conn, enum gcc_qualifiers *result)
74 {
75 protocol_int p;
76 if (!unmarshall_intlike (conn, &p))
77 return FAIL;
78 *result = (enum gcc_qualifiers) p;
79 return OK;
80 }
81
82 cc1_plugin::status
83 cc1_plugin::marshall (connection *conn, const char *str)
84 {
85 if (!conn->send ('s'))
86 return FAIL;
87
88 unsigned long long len = str == NULL ? -1ULL : strlen (str);
89 if (!conn->send (&len, sizeof (len)))
90 return FAIL;
91
92 if (str == NULL)
93 return OK;
94
95 return conn->send (str, len);
96 }
97
98 cc1_plugin::status
99 cc1_plugin::unmarshall (connection *conn, char **result)
100 {
101 unsigned long long len;
102
103 if (!conn->require ('s'))
104 return FAIL;
105 if (!conn->get (&len, sizeof (len)))
106 return FAIL;
107
108 if (len == -1ULL)
109 {
110 *result = NULL;
111 return OK;
112 }
113
114 char *str = new (std::nothrow) char[len + 1];
115 if (str == NULL)
116 return FAIL;
117
118 if (!conn->get (str, len))
119 {
120 delete[] str;
121 return FAIL;
122 }
123
124 str[len] = '\0';
125 *result = str;
126
127 return OK;
128 }
129
130 cc1_plugin::status
131 cc1_plugin::marshall (connection *conn, const gcc_type_array *a)
132 {
133 if (!conn->send ('a'))
134 return FAIL;
135
136 unsigned long long r = a->n_elements;
137 if (!conn->send (&r, sizeof (r)))
138 return FAIL;
139
140 return conn->send (a->elements, r * sizeof (a->elements[0]));
141 }
142
143 cc1_plugin::status
144 cc1_plugin::unmarshall (connection *conn, gcc_type_array **result)
145 {
146 unsigned long long len;
147
148 if (!conn->require ('a'))
149 return FAIL;
150 if (!conn->get (&len, sizeof (len)))
151 return FAIL;
152
153 *result = new gcc_type_array;
154
155 (*result)->n_elements = len;
156 (*result)->elements = new gcc_type[len];
157
158 if (!conn->get ((*result)->elements, len * sizeof ((*result)->elements[0])))
159 {
160 delete[] (*result)->elements;
161 delete *result;
162 return FAIL;
163 }
164
165 return OK;
166 }