dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | LICENSE

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 }