1 /* 2 3 silcbuffmt.h 4 5 Author: Pekka Riikonen <priikone@silcnet.org> 6 7 Copyright (C) 1997 - 2007 Pekka Riikonen 8 9 The contents of this file are subject to one of the Licenses specified 10 in the COPYING file; You may not use this file except in compliance 11 with the License. 12 13 The software distributed under the License is distributed on an "AS IS" 14 basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY 15 KIND, either expressed or implied. See the COPYING file for more 16 information. 17 18 */ 19 20 /****h* silcutil/SILC Buffer Format Interface 21 * 22 * DESCRIPTION 23 * 24 * SILC Buffer Format API provides functions for formatting different data 25 * types into a buffer and retrieving different data types from a buffer 26 * into specified data types. It is especially useful to format packets, 27 * protocol payloads and such. 28 * 29 * As the SilcBuffer API is not thread-safe these routines may not be used 30 * in multithreaded environment with a same SilcBuffer context without 31 * concurrency control. 32 * 33 ***/ 34 35 #ifndef SILCBUFFMT_H 36 #define SILCBUFFMT_H 37 38 /****f* silcutil/SilcBufferFormatAPI/SilcBufferFormatFunc 39 * 40 * SYNOPSIS 41 * 42 * typedef int (*SilcBufferFormatFunc)(SilcBuffer buffer, 43 * void *value, 44 * void *context); 45 * 46 * DESCRIPTION 47 * 48 * Formatting function callback given with SILC_STR_FUNC type. The 49 * `buffer' is the buffer being formatted at the location where the 50 * SILC_STR_FUNC was placed in formatting. The function should call 51 * silc_buffer_enlarge before it adds the data to the buffer to make 52 * sure that it has enough space. The buffer->head points to the 53 * start of the buffer and silc_buffer_headlen() gives the length 54 * of the currently formatted data area. It is also possible to use 55 * silc_buffer_format with `buffer' which will enlarge the buffer if 56 * needed. 57 * 58 * The `value' is the value given to SILC_STR_FUNC that is to be formatted 59 * into the buffer. It may be NULL if the function is not formatting 60 * new data into the buffer. The `context' is caller specific context. 61 * Returns -1 on error and length of the formatted value otherwise, and 62 * 0 if nothing was formatted. 63 * 64 ***/ 65 typedef int (*SilcBufferFormatFunc)(SilcBuffer buffer, void *value, 66 void *context); 67 68 /****f* silcutil/SilcBufferFormatAPI/SilcBufferSFormatFunc 69 * 70 * SYNOPSIS 71 * 72 * typedef int (*SilcBufferSFormatFunc)(SilcStack stack, 73 * SilcBuffer buffer, 74 * void *value, 75 * void *context); 76 * 77 * DESCRIPTION 78 * 79 * Formatting function callback given with SILC_STR_FUNC type. The 80 * `buffer' is the buffer being formatted at the location where the 81 * SILC_STR_FUNC was placed in formatting. The function should call 82 * silc_buffer_senlarge before it adds the data to the buffer to make 83 * sure that it has enough space. The buffer->head points to the 84 * start of the buffer and silc_buffer_headlen() gives the length 85 * of the currently formatted data area. It is also possible to use 86 * silc_buffer_sformat with `buffer' which will enlarge the buffer if 87 * needed. 88 * 89 * The `value' is the value given to SILC_STR_FUNC that is to be formatted 90 * into the buffer. It may be NULL if the function is not formatting 91 * new data into the buffer. The `context' is caller specific context. 92 * Returns -1 on error and length of the formatted value otherwise, and 93 * 0 if nothing was formatted. 94 * 95 * This is same as SilcBufferFormatFunc except the SilcStack will be 96 * delivered. This callback must be used when SilcStack is used with 97 * formatting. 98 * 99 ***/ 100 typedef int (*SilcBufferSFormatFunc)(SilcStack stack, SilcBuffer buffer, 101 void *value, void *context); 102 103 /****f* silcutil/SilcBufferFormatAPI/SilcBufferUnformatFunc 104 * 105 * SYNOPSIS 106 * 107 * typedef int (*SilcBufferUnformatFunc)(SilcBuffer buffer, 108 * void **value, 109 * void *context); 110 * 111 * DESCRIPTION 112 * 113 * Unformatting function callback given with SILC_STR_FUNC type. The 114 * `buffer' is the buffer being unformatted and is at the location where 115 * the SILC_STR_FUNC was placed in unformatting. The function should 116 * check there is enough data in the `buffer' before trying to decode 117 * from it. 118 * 119 * If this function unformats anything from the buffer its value is to 120 * be returned to the `value' pointer. The implementation should itself 121 * decide whether the unformatted value is allocated or not. If this 122 * function does not unformat anything, nothing is returned to `value' 123 * 124 * The `context' is caller specific context. Returns -1 on error, and 125 * length of the unformatted value otherwise, and 0 if nothing was 126 * unformatted. 127 * 128 ***/ 129 typedef int (*SilcBufferUnformatFunc)(SilcBuffer buffer, void **value, 130 void *context); 131 132 /****f* silcutil/SilcBufferFormatAPI/SilcBufferSUnformatFunc 133 * 134 * SYNOPSIS 135 * 136 * typedef int (*SilcBufferSUnformatFunc)(SilcStack stack, 137 * SilcBuffer buffer, 138 * void **value, 139 * void *context); 140 * 141 * DESCRIPTION 142 * 143 * Unformatting function callback given with SILC_STR_FUNC type. The 144 * `buffer' is the buffer being unformatted and is at the location where 145 * the SILC_STR_FUNC was placed in unformatting. The function should 146 * check there is enough data in the `buffer' before trying to decode 147 * from it. 148 * 149 * If this function unformats anything from the buffer its value is to 150 * be returned to the `value' pointer. The implementation should itself 151 * decide whether the unformatted value is allocated or not. If this 152 * function does not unformat anything, nothing is returned to `value' 153 * 154 * The `context' is caller specific context. Returns -1 on error, and 155 * length of the unformatted value otherwise, and 0 if nothing was 156 * unformatted. 157 * 158 * This is same as SilcBufferUnformatFunc except the SilcStack will be 159 * delivered. This callback must be used when SilcStack is used with 160 * unformatting. 161 * 162 ***/ 163 typedef int (*SilcBufferSUnformatFunc)(SilcStack stack, SilcBuffer buffer, 164 void **value, void *context); 165 166 /* Prototypes */ 167 168 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format 169 * 170 * SYNOPSIS 171 * 172 * int silc_buffer_format(SilcBuffer dst, ...); 173 * 174 * DESCRIPTION 175 * 176 * Formats a buffer from a variable argument list. Returns -1 on error 177 * and the length of the formatted buffer otherwise. The buffer is 178 * enlarged automatically during formatting, if it doesn't already have 179 * enough space. 180 * 181 * EXAMPLE 182 * 183 * Three basic ways of using silc_buffer_format: 184 * 185 * // Statically allocated zero size buffer 186 * SilcBufferStruct buffer; 187 * 188 * memset(&buffer, 0, sizeof(buffer)); 189 * ret = silc_buffer_format(&buffer, 190 * SILC_STR_UI_INT(intval), 191 * SILC_STR_CHAR(charval), 192 * SILC_STR_UI_INT(intval), 193 * SILC_STR_SHORT(str_len), 194 * SILC_STR_DATA(str, str_len), 195 * SILC_STR_END); 196 * if (ret < 0) 197 * error; 198 * 199 * // Free the allocated data 200 * silc_buffer_purge(&buffer); 201 * 202 * // Dynamically allocated zero size buffer 203 * SilcBuffer buf; 204 * buf = silc_buffer_alloc(0); 205 * ret = silc_buffer_format(buf, 206 * SILC_STR_UI_INT(intval), 207 * SILC_STR_CHAR(charval), 208 * SILC_STR_END); 209 * if (ret < 0) 210 * error; 211 * 212 * // Free the allocated buffer 213 * silc_buffer_free(buf); 214 * 215 * // Dynamically allocated buffer with enough space 216 * SilcBuffer buf; 217 * buf = silc_buffer_alloc(2 + str_len); 218 * ret = silc_buffer_format(buf, 219 * SILC_STR_UI_SHORT(str_len), 220 * SILC_STR_DATA(str, str_len), 221 * SILC_STR_END); 222 * if (ret < 0) 223 * error; 224 * 225 ***/ 226 int silc_buffer_format(SilcBuffer dst, ...); 227 228 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sformat 229 * 230 * SYNOPSIS 231 * 232 * int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...); 233 * 234 * DESCRIPTION 235 * 236 * Same as silc_buffer_format but uses `stack' to allocate the memory. 237 * if `stack' is NULL reverts back to silc_buffer_format call. 238 * 239 ***/ 240 int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...); 241 242 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp 243 * 244 * SYNOPSIS 245 * 246 * int silc_buffer_format_vp(SilcBuffer dst, va_list vp); 247 * 248 * DESCRIPTION 249 * 250 * Formats a buffer from a variable argument list indicated by the `ap'. 251 * Returns -1 on error and the length of the formatted buffer otherwise. 252 * 253 ***/ 254 int silc_buffer_format_vp(SilcBuffer dst, va_list ap); 255 256 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sformat_vp 257 * 258 * SYNOPSIS 259 * 260 * int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list vp); 261 * 262 * DESCRIPTION 263 * 264 * Same as silc_buffer_format_vp but uses `stack' to allocate the memory. 265 * if `stack' is NULL reverts back to silc_buffer_format_vp call. 266 * 267 ***/ 268 int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap); 269 270 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat 271 * 272 * SYNOPSIS 273 * 274 * int silc_buffer_unformat(SilcBuffer src, ...); 275 * 276 * DESCRIPTION 277 * 278 * Unformats a buffer from a variable argument list. Returns -1 on error 279 * and the length of the unformatted buffer otherwise. 280 * 281 * EXAMPLE 282 * 283 * ret = silc_buffer_unformat(buffer, 284 * SILC_STR_UI_INT(&intval), 285 * SILC_STR_CHAR(&charval), 286 * SILC_STR_OFFSET(4), 287 * SILC_STR_UI16_NSTRING_ALLOC(&str, &str_len), 288 * SILC_STR_END); 289 * if (ret < 0) 290 * error; 291 * 292 ***/ 293 int silc_buffer_unformat(SilcBuffer src, ...); 294 295 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sunformat 296 * 297 * SYNOPSIS 298 * 299 * int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...); 300 * 301 * DESCRIPTION 302 * 303 * Same as silc_buffer_unformat but uses `stack' to allocate the memory. 304 * if `stack' is NULL reverts back to silc_buffer_format call. 305 * 306 ***/ 307 int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...); 308 309 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat_vp 310 * 311 * SYNOPSIS 312 * 313 * int silc_buffer_unformat_vp(SilcBuffer src, va_list vp); 314 * 315 * DESCRIPTION 316 * 317 * Unformats a buffer from a variable argument list indicated by the `ap'. 318 * Returns -1 on error and the length of the unformatted buffer otherwise. 319 * 320 ***/ 321 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap); 322 323 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sunformat_vp 324 * 325 * SYNOPSIS 326 * 327 * int silc_buffer_sunformat_vp(SilcBuffer src, va_list vp); 328 * 329 * DESCRIPTION 330 * 331 * Same as silc_buffer_unformat_vp but uses `stack' to allocate the 332 * memory. if `stack' is NULL reverts back to silc_buffer_format_vp call. 333 * 334 ***/ 335 int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap); 336 337 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_strformat 338 * 339 * SYNOPSIS 340 * 341 * int silc_buffer_strformat(SilcBuffer dst, ...); 342 * 343 * DESCRIPTION 344 * 345 * Formats a buffer from variable argument list of strings. Each 346 * string must be NULL-terminated and the variable argument list must 347 * be end with SILC_STRFMT_END argument. This allows that a string in 348 * the list can be NULL, in which case it is skipped. This automatically 349 * allocates the space for the buffer data but `dst' must be already 350 * allocated by the caller. 351 * 352 * EXAMPLE 353 * 354 * ret = silc_buffer_strformat(buffer, "foo", "bar", SILC_STRFMT_END); 355 * if (ret < 0) 356 * error; 357 * 358 ***/ 359 int silc_buffer_strformat(SilcBuffer dst, ...); 360 361 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sstrformat 362 * 363 * SYNOPSIS 364 * 365 * int silc_buffer_strformat(SilcStack stack, SilcBuffer dst, ...); 366 * 367 * DESCRIPTION 368 * 369 * Formats a buffer from variable argument list of strings. Each 370 * string must be NULL-terminated and the variable argument list must 371 * be end with SILC_STRFMT_END argument. This allows that a string in 372 * the list can be NULL, in which case it is skipped. This automatically 373 * allocates the space for the buffer data but `dst' must be already 374 * allocated by the caller. This function is equivalent to 375 * silc_buffer_strformat but allocates memory from `stack'. 376 * 377 ***/ 378 int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...); 379 380 /****d* silcutil/SilcBufferFormatAPI/SilcBufferParamType 381 * 382 * NAME 383 * 384 * typedef enum { ... } SilcBufferParamType; 385 * 386 * DESCRIPTION 387 * 388 * Buffer parameter types. These are not needed when formatting or 389 * unformatting buffers. Use the macros such as SILC_STR_UI_CHAR and 390 * others instead. These types may be used when describing what a 391 * buffer looks like, and how it may be formatted and unformatted. 392 * 393 * SOURCE 394 */ 395 typedef enum { 396 SILC_PARAM_SI8_CHAR, /* Signed 8-bit char */ 397 SILC_PARAM_UI8_CHAR, /* Unsigned 8-bit char */ 398 SILC_PARAM_SI16_SHORT, /* Signed 16-bit int */ 399 SILC_PARAM_UI16_SHORT, /* Unsigned 16-bit int */ 400 SILC_PARAM_SI32_INT, /* Signed 32-bit int */ 401 SILC_PARAM_UI32_INT, /* Unsigned 32-bit int */ 402 SILC_PARAM_SI64_INT, /* Signed 64-bit int */ 403 SILC_PARAM_UI64_INT, /* Unsigned 64-bit int */ 404 SILC_PARAM_UI8_STRING, /* String (max len 8-bits)*/ 405 SILC_PARAM_UI16_STRING, /* String (max len 16-bits) */ 406 SILC_PARAM_UI32_STRING, /* String (max len 32-bits) */ 407 SILC_PARAM_BUFFER, /* SilcBuffer */ 408 409 /* Internal types */ 410 SILC_PARAM_DATA, /* Binary data */ 411 SILC_PARAM_UI8_NSTRING, /* String (max len 8-bits) */ 412 SILC_PARAM_UI16_NSTRING, /* String (max len 16-bits) */ 413 SILC_PARAM_UI32_NSTRING, /* String (max len 32-bits) */ 414 SILC_PARAM_UI8_STRING_ALLOC, /* Alloc + memcpy */ 415 SILC_PARAM_UI16_STRING_ALLOC, /* Alloc + memcpy */ 416 SILC_PARAM_UI32_STRING_ALLOC, /* Alloc + memcpy */ 417 SILC_PARAM_UI8_NSTRING_ALLOC, /* Alloc + memcpy */ 418 SILC_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */ 419 SILC_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */ 420 SILC_PARAM_DATA_ALLOC, /* Alloc + memcpy */ 421 SILC_PARAM_BUFFER_ALLOC, /* Alloc + memcpy */ 422 423 SILC_PARAM_OFFSET, 424 SILC_PARAM_ADVANCE, 425 SILC_PARAM_FUNC, 426 427 SILC_PARAM_UI_XNSTRING, 428 SILC_PARAM_UI_XNSTRING_ALLOC, 429 430 SILC_PARAM_END 431 } SilcBufferParamType; 432 /***/ 433 434 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_CHAR 435 * 436 * NAME 437 * 438 * #define SILC_STR_UI_CHAR() ... 439 * #define SILC_STR_SI_CHAR() ... 440 * 441 * DESCRIPTION 442 * 443 * One signed/unsigned character. 444 * 445 * Formatting: SILC_STR_SI_CHAR(char) 446 * SILC_STR_UI_CHAR(unsigned char) 447 * Unformatting: SILC_STR_SI_CHAR(char *) 448 * SILC_STR_UI_CHAR(unsigned char *) 449 * 450 ***/ 451 #define SILC_STR_SI_CHAR(x) SILC_PARAM_SI8_CHAR, (x) 452 #define SILC_STR_UI_CHAR(x) SILC_PARAM_UI8_CHAR, (x) 453 454 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_SHORT 455 * 456 * NAME 457 * 458 * #define SILC_STR_UI_SHORT() ... 459 * #define SILC_STR_SI_SHORT() ... 460 * 461 * DESCRIPTION 462 * 463 * SilcInt16/SilcUInt16. 464 * 465 * Formatting: SILC_STR_SI_SHORT(SilcInt16) 466 * SILC_STR_UI_SHORT(SilcUInt16) 467 * Unformatting: SILC_STR_SI_SHORT(SilcInt16 *) 468 * SILC_STR_UI_SHORT(SilcUInt16 *) 469 * 470 ***/ 471 #define SILC_STR_SI_SHORT(x) SILC_PARAM_SI16_SHORT, (x) 472 #define SILC_STR_UI_SHORT(x) SILC_PARAM_UI16_SHORT, (x) 473 474 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT 475 * 476 * NAME 477 * 478 * #define SILC_STR_UI_INT() ... 479 * #define SILC_STR_SI_INT() ... 480 * 481 * DESCRIPTION 482 * 483 * SilcInt32/SilcUInt32. 484 * 485 * Formatting: SILC_STR_SI_INT(SilcInt32) 486 * SILC_STR_UI_INT(SilcUInt32) 487 * Unformatting: SILC_STR_SI_INT(SilcInt32 *) 488 * SILC_STR_UI_INT(SilcUInt32 *) 489 * 490 ***/ 491 #define SILC_STR_SI_INT(x) SILC_PARAM_SI32_INT, (x) 492 #define SILC_STR_UI_INT(x) SILC_PARAM_UI32_INT, (x) 493 494 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT64 495 * 496 * NAME 497 * 498 * #define SILC_STR_UI_INT64() ... 499 * #define SILC_STR_SI_INT64() ... 500 * 501 * DESCRIPTION 502 * 503 * SilcInt64/SilcUInt64. 504 * 505 * Formatting: SILC_STR_SI_INT64(SilcInt64) 506 * SILC_STR_UI_INT64(SilcUInt64) 507 * Unformatting: SILC_STR_SI_INT64(SilcInt64 *) 508 * SILC_STR_UI_INT64(SilcUInt64 *) 509 * 510 ***/ 511 #define SILC_STR_SI_INT64(x) SILC_PARAM_SI64_INT, (x) 512 #define SILC_STR_UI_INT64(x) SILC_PARAM_UI64_INT, (x) 513 514 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_STRING 515 * 516 * NAME 517 * 518 * #define SILC_STR_UI8_STRING() ... 519 * #define SILC_STR_UI8_STRING_ALLOC() ... 520 * #define SILC_STR_UI16_STRING() ... 521 * #define SILC_STR_UI16_STRING_ALLOC() ... 522 * #define SILC_STR_UI32_STRING() ... 523 * #define SILC_STR_UI32_STRING_ALLOC() ... 524 * 525 * DESCRIPTION 526 * 527 * Unsigned NULL terminated string. Note that the string must be 528 * NULL terminated because strlen() will be used to get the length of 529 * the string. 530 * 531 * Formatting: SILC_STR_UI32_STRING(unsigned char *) 532 * Unformatting: SILC_STR_UI32_STRING(unsigned char **) 533 * 534 * Unformatting procedure will check for length of the string from the 535 * buffer before trying to get the string out. Thus, one *must* format the 536 * length as UI_INT or UI_SHORT into the buffer *before* formatting the 537 * actual string to the buffer, and, in unformatting one must ignore the 538 * length of the string because unformatting procedure will take it 539 * automatically. 540 * 541 * Example: 542 * 543 * Formatting: ..., SILC_STR_UI_INT(strlen(string)), 544 * SILC_STR_UI32_STRING(string), ... 545 * Unformatting: ..., SILC_STR_UI32_STRING(&string), ... 546 * 547 * I.e., you can ignore the formatted length field in unformatting. 548 * 549 * UI8, UI16 and UI32 means that the length is considered to be 550 * either char (8 bits), short (16 bits) or int (32 bits) in 551 * unformatting. 552 * 553 * _ALLOC routines automatically allocates memory for the variable sent 554 * as argument in unformatting. 555 * 556 ***/ 557 #define SILC_STR_UI8_STRING(x) SILC_PARAM_UI8_STRING, (x) 558 #define SILC_STR_UI8_STRING_ALLOC(x) SILC_PARAM_UI8_STRING_ALLOC, (x) 559 #define SILC_STR_UI16_STRING(x) SILC_PARAM_UI16_STRING, (x) 560 #define SILC_STR_UI16_STRING_ALLOC(x) SILC_PARAM_UI16_STRING_ALLOC, (x) 561 #define SILC_STR_UI32_STRING(x) SILC_PARAM_UI32_STRING, (x) 562 #define SILC_STR_UI32_STRING_ALLOC(x) SILC_PARAM_UI32_STRING_ALLOC, (x) 563 564 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_NSTRING 565 * 566 * NAME 567 * 568 * #define SILC_STR_UI8_NSTRING() ... 569 * #define SILC_STR_UI8_NSTRING_ALLOC() ... 570 * #define SILC_STR_UI16_NSTRING() ... 571 * #define SILC_STR_UI16_NSTRING_ALLOC() ... 572 * #define SILC_STR_UI32_NSTRING() ... 573 * #define SILC_STR_UI32_NSTRING_ALLOC() ... 574 * 575 * DESCRIPTION 576 * 577 * Unsigned string. Second argument is the length of the string. 578 * 579 * Formatting: SILC_STR_UI32_NSTRING(unsigned char *, SilcUInt32) 580 * Unformatting: SILC_STR_UI32_NSTRING(unsigned char **, SilcUInt32 *) 581 * 582 * Unformatting procedure will check for length of the string from the 583 * buffer before trying to get the string out. Thus, one *must* format the 584 * length as UI_INT or UI_SHORT into the buffer *before* formatting the 585 * actual string to the buffer, and, in unformatting one must ignore the 586 * length of the string because unformatting procedure will take it 587 * automatically. 588 * 589 * Example: 590 * 591 * Formatting: ..., SILC_STR_UI_INT(strlen(string)), 592 * SILC_STR_UI32_NSTRING(string, strlen(string)), ... 593 * Unformatting: ..., SILC_STR_UI32_NSTRING(&string, &len), ... 594 * 595 * I.e., you can ignore the formatted length field in unformatting. The 596 * length taken from the buffer is returned to the pointer sent as 597 * argument (&len in above example). 598 * 599 * UI8, UI16 and UI32 means that the length is considered to be 600 * either char (8 bits), short (16 bits) or int (32 bits) in 601 * unformatting. 602 * 603 * _ALLOC routines automatically allocates memory for the variable sent 604 * as argument in unformatting. 605 * 606 ***/ 607 #define SILC_STR_UI8_NSTRING(x, l) SILC_PARAM_UI8_NSTRING, (x), (l) 608 #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \ 609 SILC_PARAM_UI8_NSTRING_ALLOC, (x), (l) 610 #define SILC_STR_UI16_NSTRING(x, l) SILC_PARAM_UI16_NSTRING, (x), (l) 611 #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \ 612 SILC_PARAM_UI16_NSTRING_ALLOC, (x), (l) 613 #define SILC_STR_UI32_NSTRING(x, l) SILC_PARAM_UI32_NSTRING, (x), (l) 614 #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \ 615 SILC_PARAM_UI32_NSTRING_ALLOC, (x), (l) 616 617 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_DATA 618 * 619 * NAME 620 * 621 * #define SILC_STR_DATA() ... 622 * #define SILC_STR_DATA_ALLOC() ... 623 * 624 * DESCRIPTION 625 * 626 * Binary data formatting. Second argument is the length of the data. 627 * 628 * Formatting: SILC_STR_DATA(unsigned char *, SilcUInt32) 629 * Unformatting: SILC_STR_DATA(unsigned char **, SilcUInt32) 630 * 631 * This type can be used to take arbitrary size data block from the buffer 632 * by sending the requested amount of bytes as argument. 633 * 634 * _ALLOC routines automatically allocates memory for the variable sent 635 * as argument in unformatting. 636 * 637 ***/ 638 #define SILC_STR_DATA(x, l) SILC_PARAM_DATA, (x), (l) 639 #define SILC_STR_DATA_ALLOC(x, l) SILC_PARAM_DATA_ALLOC, (x), (l) 640 641 /* Deprecated */ 642 #define SILC_STR_UI_XNSTRING(x, l) SILC_PARAM_UI_XNSTRING, (x), (l) 643 #define SILC_STR_UI_XNSTRING_ALLOC(x, l) SILC_PARAM_UI_XNSTRING_ALLOC, (x), (l) 644 645 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_BUFFER 646 * 647 * NAME 648 * 649 * #define SILC_STR_BUFFER() ... 650 * #define SILC_STR_BUFFER_ALLOC() ... 651 * 652 * DESCRIPTION 653 * 654 * SilcBuffer formatting. 655 * 656 * Formatting: SILC_STR_BUFFER(SilcBuffer) 657 * Unformatting: SILC_STR_BUFFER(SilcBuffer) 658 * 659 * This type can be used to format and unformat SilcBuffer. Note that, the 660 * length of the buffer will be automatically encoded into the buffer as 661 * a 32-bit integer. In unformatting the SilcBuffer context must be 662 * pre-allocated. 663 * 664 * _ALLOC routines automatically allocates memory inside SilcBuffer in 665 * unformatting. 666 * 667 ***/ 668 #define SILC_STR_BUFFER(x) SILC_PARAM_BUFFER, (x) 669 #define SILC_STR_BUFFER_ALLOC(x) SILC_PARAM_BUFFER_ALLOC, (x) 670 671 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_FUNC 672 * 673 * NAME 674 * 675 * #define SILC_STR_FUNC() ... 676 * 677 * DESCRIPTION 678 * 679 * SilcBuffer formatting. 680 * 681 * Formatting: SILC_STR_FUNC(function, void *value, void *context) 682 * Unformatting: SILC_STR_FUNC(function, void **value, void *context) 683 * 684 * This type can be used to call the `function' of the type 685 * SilcBufferFormatFunc or SilcBufferUnformatFunc to encode or decode 686 * the `value'. In encoding the `value' will be passed to the `function' 687 * and can be encoded into the buffer. The buffer will be passed as 688 * well to the `function' at the location where SILC_STR_FUNC is placed 689 * in formatting. The `context' delivers caller specific context to 690 * the `function' 691 * 692 * In unformatting the `function' will decode the encoded type and 693 * return it to `value' pointer. The decoding function should decide 694 * itself whether to allocate or not the decoded value. 695 * 696 * The `function' does not have to encode anything and passing `value' 697 * as NULL is allowed. The `function' could for example modify the 698 * existing buffer. 699 * 700 * EXAMPLE 701 * 702 * // Encode payload, encrypt and compute MAC. 703 * silc_buffer_format(buf, 704 * SILC_STR_FUNC(foo_encode_id, id, ctx), 705 * SILC_STR_UI_SHORT(len), 706 * SILC_STR_DATA(data, len), 707 * SILC_STR_FUNC(foo_buf_encrypt, NULL, key), 708 * SILC_STR_FUNC(foo_buf_hmac, NULL, hmac), 709 * SILC_STR_DATA(iv, iv_len); 710 * SILC_STR_END); 711 * 712 * // Check MAC, decrypt and decode payload 713 * silc_buffer_unformat(buf, 714 * SILC_STR_FUNC(foo_buf_hmac, NULL, hmac), 715 * SILC_STR_FUNC(foo_buf_decrypt, NULL, key), 716 * SILC_STR_FUNC(foo_decode_id, &id, ctx), 717 * SILC_STR_UI_SHORT(&len), 718 * SILC_STR_END); 719 * 720 ***/ 721 #define SILC_STR_FUNC(func, val, context) SILC_PARAM_FUNC, \ 722 func, (val), (context) 723 724 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET 725 * 726 * NAME 727 * 728 * #define SILC_STR_OFFSET() ... 729 * 730 * DESCRIPTION 731 * 732 * Offset in buffer. This can be used in formatting and unformatting to 733 * move the data pointer of the buffer either forwards (positive offset) 734 * or backwards (negative offset). It can be used to for example skip 735 * some types during unformatting. 736 * 737 * Example: 738 * 739 * ..., SILC_STR_OFFSET(5), ... 740 * ..., SILC_STR_OFFSET(-3), ... 741 * 742 * Moves the data pointer at the point of the offset either forward 743 * or backward and then moves to the next type. Multiple SILC_STR_OFFSETs 744 * can be used in formatting and unformatting at the same time. 745 * 746 ***/ 747 #define SILC_STR_OFFSET(x) SILC_PARAM_OFFSET, (x) 748 749 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_ADVANCE 750 * 751 * NAME 752 * 753 * #define SILC_STR_ADVANCE ... 754 * 755 * DESCRIPTION 756 * 757 * Advance the buffer to the end of the data after the formatting is 758 * done. In normal operation when the formatted data is written the 759 * buffer is located at the start of the data. With SILC_STR_ADVANCE 760 * the buffer will be located at the end of the data. This makes it 761 * easy to add new data immediately after the previously added data. 762 * The SILC_STR_ADVANCE may also be used in unformatting. 763 * 764 * EXAMPLE 765 * 766 * do { 767 * len = read(fd, buf, sizeof(buf)); 768 * if (len > 0) 769 * // Add read data to the buffer 770 * silc_buffer_format(buffer, 771 * SILC_STR_ADVANCE, 772 * SILC_STR_DATA(buf, len), 773 * SILC_STR_END); 774 * } while (len > 0); 775 * 776 * // Move to beginning of buffer 777 * silc_buffer_start(buffer); 778 * 779 ***/ 780 #define SILC_STR_ADVANCE SILC_PARAM_ADVANCE 781 782 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_END 783 * 784 * NAME 785 * 786 * #define SILC_STR_END ... 787 * 788 * DESCRIPTION 789 * 790 * Marks end of the argument list. This must be at the end of the 791 * argument list or error will occur. 792 * 793 ***/ 794 #define SILC_STR_END SILC_PARAM_END 795 796 /****d* silcutil/SilcBufferFormatAPI/SILC_STRFMT_END 797 * 798 * NAME 799 * 800 * #define SILC_STRFMT_END ... 801 * 802 * DESCRIPTION 803 * 804 * Marks end of the argument list in silc_buffer_strformat function. 805 * This must be at the end of the argument list or error will occur. 806 * 807 ***/ 808 #define SILC_STRFMT_END (void *)SILC_STR_END 809 810 #endif /* !SILCBUFFMT_H */ 811