00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00038 #include <adt/measured_strings.h>
00039 #include <malloc.h>
00040 #include <mem.h>
00041 #include <unistd.h>
00042 #include <errno.h>
00043 #include <async.h>
00044
00060 measured_string_t *
00061 measured_string_create_bulk(const uint8_t *string, size_t length)
00062 {
00063 measured_string_t *new;
00064
00065 if (length == 0) {
00066 while (string[length])
00067 length++;
00068 }
00069 new = (measured_string_t *) malloc(sizeof(measured_string_t) +
00070 (sizeof(uint8_t) * (length + 1)));
00071 if (!new)
00072 return NULL;
00073
00074 new->length = length;
00075 new->value = ((uint8_t *) new) + sizeof(measured_string_t);
00076
00077 memcpy(new->value, string, new->length);
00078 new->value[new->length] = '\0';
00079
00080 return new;
00081 }
00082
00090 measured_string_t *measured_string_copy(measured_string_t *source)
00091 {
00092 measured_string_t *new;
00093
00094 if (!source)
00095 return NULL;
00096
00097 new = (measured_string_t *) malloc(sizeof(measured_string_t));
00098 if (new) {
00099 new->value = (uint8_t *) malloc(source->length + 1);
00100 if (new->value) {
00101 new->length = source->length;
00102 memcpy(new->value, source->value, new->length);
00103 new->value[new->length] = '\0';
00104 return new;
00105 }
00106 free(new);
00107 }
00108
00109 return NULL;
00110 }
00111
00132 int
00133 measured_strings_receive(measured_string_t **strings, uint8_t **data,
00134 size_t count)
00135 {
00136 size_t *lengths;
00137 size_t index;
00138 size_t length;
00139 uint8_t *next;
00140 ipc_callid_t callid;
00141 int rc;
00142
00143 if ((!strings) || (!data) || (count <= 0))
00144 return EINVAL;
00145
00146 lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
00147 if (!lengths)
00148 return ENOMEM;
00149
00150 if ((!async_data_write_receive(&callid, &length)) ||
00151 (length != sizeof(size_t) * (count + 1))) {
00152 free(lengths);
00153 return EINVAL;
00154 }
00155 rc = async_data_write_finalize(callid, lengths, length);
00156 if (rc != EOK) {
00157 free(lengths);
00158 return rc;
00159 }
00160
00161 *data = malloc(lengths[count]);
00162 if (!*data) {
00163 free(lengths);
00164 return ENOMEM;
00165 }
00166 (*data)[lengths[count] - 1] = '\0';
00167
00168 *strings = (measured_string_t *) malloc(sizeof(measured_string_t) *
00169 count);
00170 if (!*strings) {
00171 free(lengths);
00172 free(*data);
00173 return ENOMEM;
00174 }
00175
00176 next = *data;
00177 for (index = 0; index < count; index++) {
00178 (*strings)[index].length = lengths[index];
00179 if (lengths[index] > 0) {
00180 if (!async_data_write_receive(&callid, &length) ||
00181 (length != lengths[index])) {
00182 free(*data);
00183 free(*strings);
00184 free(lengths);
00185 return EINVAL;
00186 }
00187 rc = async_data_write_finalize(callid, next,
00188 lengths[index]);
00189 if (rc != EOK) {
00190 free(*data);
00191 free(*strings);
00192 free(lengths);
00193 return rc;
00194 }
00195 (*strings)[index].value = next;
00196 next += lengths[index];
00197 *next++ = '\0';
00198 } else {
00199 (*strings)[index].value = NULL;
00200 }
00201 }
00202
00203 free(lengths);
00204 return EOK;
00205 }
00206
00214 static size_t *prepare_lengths(const measured_string_t *strings, size_t count)
00215 {
00216 size_t *lengths;
00217 size_t index;
00218 size_t length;
00219
00220 lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
00221 if (!lengths)
00222 return NULL;
00223
00224 length = 0;
00225 for (index = 0; index < count; index++) {
00226 lengths[index] = strings[index].length;
00227 length += lengths[index] + 1;
00228 }
00229 lengths[count] = length;
00230 return lengths;
00231 }
00232
00250 int measured_strings_reply(const measured_string_t *strings, size_t count)
00251 {
00252 size_t *lengths;
00253 size_t index;
00254 size_t length;
00255 ipc_callid_t callid;
00256 int rc;
00257
00258 if ((!strings) || (count <= 0))
00259 return EINVAL;
00260
00261 lengths = prepare_lengths(strings, count);
00262 if (!lengths)
00263 return ENOMEM;
00264
00265 if (!async_data_read_receive(&callid, &length) ||
00266 (length != sizeof(size_t) * (count + 1))) {
00267 free(lengths);
00268 return EINVAL;
00269 }
00270 rc = async_data_read_finalize(callid, lengths, length);
00271 if (rc != EOK) {
00272 free(lengths);
00273 return rc;
00274 }
00275 free(lengths);
00276
00277 for (index = 0; index < count; index++) {
00278 if (strings[index].length > 0) {
00279 if (!async_data_read_receive(&callid, &length) ||
00280 (length != strings[index].length)) {
00281 return EINVAL;
00282 }
00283 rc = async_data_read_finalize(callid,
00284 strings[index].value, strings[index].length);
00285 if (rc != EOK)
00286 return rc;
00287 }
00288 }
00289
00290 return EOK;
00291 }
00292
00312 int
00313 measured_strings_return(int phone, measured_string_t **strings, uint8_t **data,
00314 size_t count)
00315 {
00316 size_t *lengths;
00317 size_t index;
00318 uint8_t *next;
00319 int rc;
00320
00321 if ((phone < 0) || (!strings) || (!data) || (count <= 0))
00322 return EINVAL;
00323
00324 lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
00325 if (!lengths)
00326 return ENOMEM;
00327
00328 rc = async_data_read_start(phone, lengths,
00329 sizeof(size_t) * (count + 1));
00330 if (rc != EOK) {
00331 free(lengths);
00332 return rc;
00333 }
00334
00335 *data = malloc(lengths[count]);
00336 if (!*data) {
00337 free(lengths);
00338 return ENOMEM;
00339 }
00340
00341 *strings = (measured_string_t *) malloc(sizeof(measured_string_t) *
00342 count);
00343 if (!*strings) {
00344 free(lengths);
00345 free(*data);
00346 return ENOMEM;
00347 }
00348
00349 next = *data;
00350 for (index = 0; index < count; index++) {
00351 (*strings)[index].length = lengths[index];
00352 if (lengths[index] > 0) {
00353 rc = async_data_read_start(phone, next, lengths[index]);
00354 if (rc != EOK) {
00355 free(lengths);
00356 free(data);
00357 free(strings);
00358 return rc;
00359 }
00360 (*strings)[index].value = next;
00361 next += lengths[index];
00362 *next++ = '\0';
00363 } else {
00364 (*strings)[index].value = NULL;
00365 }
00366 }
00367
00368 free(lengths);
00369 return EOK;
00370 }
00371
00386 int
00387 measured_strings_send(int phone, const measured_string_t *strings,
00388 size_t count)
00389 {
00390 size_t *lengths;
00391 size_t index;
00392 int rc;
00393
00394 if ((phone < 0) || (!strings) || (count <= 0))
00395 return EINVAL;
00396
00397 lengths = prepare_lengths(strings, count);
00398 if (!lengths)
00399 return ENOMEM;
00400
00401 rc = async_data_write_start(phone, lengths,
00402 sizeof(size_t) * (count + 1));
00403 if (rc != EOK) {
00404 free(lengths);
00405 return rc;
00406 }
00407
00408 free(lengths);
00409
00410 for (index = 0; index < count; index++) {
00411 if (strings[index].length > 0) {
00412 rc = async_data_write_start(phone, strings[index].value,
00413 strings[index].length);
00414 if (rc != EOK)
00415 return rc;
00416 }
00417 }
00418
00419 return EOK;
00420 }
00421