source: mainline/uspace/srv/net/structures/measured_strings.c@ b5cbff4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b5cbff4 was 21580dd, checked in by Lukas Mejdrech <lukas@…>, 16 years ago

Merged with network branch svn://svn.helenos.org/HelenOS/branches/network revision 4759; ipc_share_* and ipc_data_* changed to async_*; client connection in module.c returns on IPC_M_PHONE_HUNGUP; * Qemu scripts renamed to net-qe.*; (the dp8390 does not respond)

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net
30 * @{
31 */
32
33/** @file
34 * Character string with measured length implementation.
35 * @see measured_strings.h
36 */
37
38#include <errno.h>
39#include <malloc.h>
40#include <mem.h>
41#include <unistd.h>
42
43#include <ipc/ipc.h>
44
45#include "../err.h"
46#include "../modules.h"
47
48#include "measured_strings.h"
49
50/** Computes the lengths of the measured strings in the given array.
51 * @param[in] strings The measured strings array to be processed.
52 * @param[in] count The measured strings array size.
53 * @returns The computed sizes array.
54 * @returns NULL if there is not enough memory left.
55 */
56size_t * prepare_lengths( const measured_string_ref strings, size_t count );
57
58measured_string_ref measured_string_create_bulk( const char * string, size_t length ){
59 measured_string_ref new;
60
61 if( length == 0 ){
62 while( string[ length ] ) ++ length;
63 }
64 new = ( measured_string_ref ) malloc( sizeof( measured_string_t ) + ( sizeof( char ) * ( length + 1 )));
65 if( ! new ) return NULL;
66 new->length = length;
67 new->value = (( char * ) new ) + sizeof( measured_string_t );
68 // append terminating zero explicitly - to be safe
69 memcpy( new->value, string, new->length );
70 new->value[ new->length ] = '\0';
71 return new;
72}
73
74measured_string_ref measured_string_copy( measured_string_ref source ){
75 measured_string_ref new;
76
77 if( ! source ) return NULL;
78 new = ( measured_string_ref ) malloc( sizeof( measured_string_t ));
79 if( new ){
80 new->value = ( char * ) malloc( source->length + 1 );
81 if( new->value ){
82 new->length = source->length;
83 memcpy( new->value, source->value, new->length );
84 new->value[ new->length ] = '\0';
85 return new;
86 }else{
87 free( new );
88 }
89 }
90 return NULL;
91}
92
93int measured_strings_receive( measured_string_ref * strings, char ** data, size_t count ){
94 ERROR_DECLARE;
95
96 size_t * lengths;
97 size_t index;
98 size_t length;
99 char * next;
100 ipc_callid_t callid;
101
102 if(( ! strings ) || ( ! data ) || ( count <= 0 )){
103 return EINVAL;
104 }
105 lengths = ( size_t * ) malloc( sizeof( size_t ) * ( count + 1 ));
106 if( ! lengths ) return ENOMEM;
107 if(( ! async_data_write_receive( & callid, & length ))
108 || ( length != sizeof( size_t ) * ( count + 1 ))){
109 free( lengths );
110 return EINVAL;
111 }
112 if( ERROR_OCCURRED( async_data_write_finalize( callid, lengths, sizeof( size_t ) * ( count + 1 )))){
113 free( lengths );
114 return ERROR_CODE;
115 }
116 * data = malloc( lengths[ count ] );
117 if( !( * data )) return ENOMEM;
118 ( * data )[ lengths[ count ] - 1 ] = '\0';
119 * strings = ( measured_string_ref ) malloc( sizeof( measured_string_t ) * count );
120 if( !( * strings )){
121 free( lengths );
122 free( * data );
123 return ENOMEM;
124 }
125 next = * data;
126 for( index = 0; index < count; ++ index ){
127 ( * strings)[ index ].length = lengths[ index ];
128 if( lengths[ index ] > 0 ){
129 if(( ! async_data_write_receive( & callid, & length ))
130 || ( length != lengths[ index ] )){
131 free( * data );
132 free( * strings );
133 free( lengths );
134 return EINVAL;
135 }
136 ERROR_PROPAGATE( async_data_write_finalize( callid, next, lengths[ index ] ));
137 ( * strings)[ index ].value = next;
138 next += lengths[ index ];
139 * next = '\0';
140 ++ next;
141 }else{
142 ( * strings )[ index ].value = NULL;
143 }
144 }
145 free( lengths );
146 return EOK;
147}
148
149int measured_strings_reply( const measured_string_ref strings, size_t count ){
150 ERROR_DECLARE;
151
152 size_t * lengths;
153 size_t index;
154 size_t length;
155 ipc_callid_t callid;
156
157 if(( ! strings ) || ( count <= 0 )){
158 return EINVAL;
159 }
160 lengths = prepare_lengths( strings, count );
161 if( ! lengths ) return ENOMEM;
162 if(( ! async_data_read_receive( & callid, & length ))
163 || ( length != sizeof( size_t ) * ( count + 1 ))){
164 free( lengths );
165 return EINVAL;
166 }
167 if( ERROR_OCCURRED( async_data_read_finalize( callid, lengths, sizeof( size_t ) * ( count + 1 )))){
168 free( lengths );
169 return ERROR_CODE;
170 }
171 free( lengths );
172 for( index = 0; index < count; ++ index ){
173 if( strings[ index ].length > 0 ){
174 if(( ! async_data_read_receive( & callid, & length ))
175 || ( length != strings[ index ].length )){
176 return EINVAL;
177 }
178 ERROR_PROPAGATE( async_data_read_finalize( callid, strings[ index ].value, strings[ index ].length ));
179 }
180 }
181 return EOK;
182}
183
184int measured_strings_return( int phone, measured_string_ref * strings, char ** data, size_t count ){
185 ERROR_DECLARE;
186
187 size_t * lengths;
188 size_t index;
189 char * next;
190
191 if(( phone <= 0 ) || ( ! strings ) || ( ! data ) || ( count <= 0 )){
192 return EINVAL;
193 }
194 lengths = ( size_t * ) malloc( sizeof( size_t ) * ( count + 1 ));
195 if( ! lengths ) return ENOMEM;
196 if( ERROR_OCCURRED( async_data_read_start( phone, lengths, sizeof( size_t ) * ( count + 1 )))){
197 free( lengths );
198 return ERROR_CODE;
199 }
200 * data = malloc( lengths[ count ] );
201 if( !( * data )) return ENOMEM;
202 * strings = ( measured_string_ref ) malloc( sizeof( measured_string_t ) * count );
203 if( !( * strings )){
204 free( lengths );
205 free( * data );
206 return ENOMEM;
207 }
208 next = * data;
209 for( index = 0; index < count; ++ index ){
210 ( * strings )[ index ].length = lengths[ index ];
211 if( lengths[ index ] > 0 ){
212 ERROR_PROPAGATE( async_data_read_start( phone, next, lengths[ index ] ));
213 ( * strings )[ index ].value = next;
214 next += lengths[ index ];
215 * next = '\0';
216 ++ next;
217 }else{
218 ( * strings )[ index ].value = NULL;
219 }
220 }
221 free( lengths );
222 return EOK;
223}
224
225int measured_strings_send( int phone, const measured_string_ref strings, size_t count ){
226 ERROR_DECLARE;
227
228 size_t * lengths;
229 size_t index;
230
231 if(( phone <= 0 ) || ( ! strings ) || ( count <= 0 )){
232 return EINVAL;
233 }
234 lengths = prepare_lengths( strings, count );
235 if( ! lengths ) return ENOMEM;
236 if( ERROR_OCCURRED( async_data_write_start( phone, lengths, sizeof( size_t ) * ( count + 1 )))){
237 free( lengths );
238 return ERROR_CODE;
239 }
240 free( lengths );
241 for( index = 0; index < count; ++ index ){
242 if( strings[ index ].length > 0 ){
243 ERROR_PROPAGATE( async_data_write_start( phone, strings[ index ].value, strings[ index ].length ));
244 }
245 }
246 return EOK;
247}
248
249size_t * prepare_lengths( const measured_string_ref strings, size_t count ){
250 size_t * lengths;
251 size_t index;
252 size_t length;
253
254 lengths = ( size_t * ) malloc( sizeof( size_t ) * ( count + 1 ));
255 if( ! lengths ) return NULL;
256 length = 0;
257 for( index = 0; index < count; ++ index ){
258 lengths[ index ] = strings[ index ].length;
259 length += lengths[ index ] + 1;
260 }
261 lengths[ count ] = length;
262 return lengths;
263}
264
265/** @}
266 */
267
Note: See TracBrowser for help on using the repository browser.