pack.c (2001B)
1 /* 2 * ISC License 3 * 4 * (c) 2019 Roberto E. Vargas Caballero <k0ga@shike2.com> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <ctype.h> 20 #include <stdarg.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 24 static int 25 lpack(unsigned char *dst, char *fmt, va_list va) 26 { 27 unsigned char *bp, *cp; 28 unsigned s; 29 unsigned long l; 30 unsigned long long q; 31 int n; 32 33 bp = dst; 34 while (*fmt) { 35 switch (*fmt++) { 36 case '\'': 37 n = atoi(fmt); 38 while (isdigit(*fmt)) 39 fmt++; 40 cp = va_arg(va, unsigned char *); 41 while (n--) 42 *bp++ = *cp++; 43 break; 44 case 'c': 45 *bp++ = va_arg(va, unsigned); 46 break; 47 case 's': 48 s = va_arg(va, unsigned); 49 *bp++ = s; 50 *bp++ = s >> 8; 51 break; 52 case 'l': 53 l = va_arg(va, unsigned long); 54 *bp++ = l; 55 *bp++ = l >> 8; 56 *bp++ = l >> 16; 57 *bp++ = l >> 24; 58 break; 59 case 'q': 60 q = va_arg(va, unsigned long long); 61 *bp++ = q; 62 *bp++ = q >> 8; 63 *bp++ = q >> 16; 64 *bp++ = q >> 24; 65 *bp++ = q >> 32; 66 *bp++ = q >> 40; 67 *bp++ = q >> 48; 68 *bp++ = q >> 56; 69 break; 70 default: 71 va_end(va); 72 return -1; 73 } 74 } 75 76 return bp - dst; 77 } 78 79 int 80 pack(unsigned char *dst, char *fmt, ...) 81 { 82 int r; 83 int (*fn)(unsigned char *dst, char *fmt, va_list va); 84 va_list va; 85 86 va_start(va, fmt); 87 fn = lpack; 88 r = (*fn)(dst, fmt, va); 89 va_end(va); 90 91 return r; 92 }