Merge branch 'vendor/GCC50' - gcc 5.0 snapshot 1 FEB 2015
[dragonfly.git] / contrib / gcc-5.0 / 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 }