-
Notifications
You must be signed in to change notification settings - Fork 19
/
compact.c
66 lines (65 loc) · 1.51 KB
/
compact.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* compact.c - function to convert hex/octal/decimal/raw string to raw
* ChangeLog since initial release in sendip 2.1.
*/
#include <stdio.h>
#include <string.h>
int compact_string(char *data_out) {
char *data_in = data_out;
int i=0;
if(*data_in=='0') {
data_in++;
if(*data_in=='x' || *data_in=='X') {
/* Hex */
char c='\0';
data_in++;
while(*data_in) {
if(*data_in>='0' && *data_in<='9') {
c+=*data_in-'0';
} else if(*data_in>='A' && *data_in<='F') {
c+=*data_in-'A'+10;
} else if(*data_in>='a' && *data_in<='f') {
c+=*data_in-'a'+10;
} else {
fprintf(stderr,"Character %c invalid in hex data stream\n",
*data_in);
return 0;
}
if( i&1) {
*(data_out++)=c; // odd nibble - output it
c='\0';
} else {
c<<=4; // even nibble - shift to top of byte
}
data_in++; i++;
}
*data_out=c; // make sure last nibble is added
i++; i>>=1; // i was a nibble count...
return i;
} else {
/* Octal */
char c='\0';
while(*data_in) {
if(*data_in>='0' && *data_in<='7') {
c+=*data_in-'0';
} else {
fprintf(stderr,"Character %c invalid in octal data stream\n",
*data_in);
return 0;
}
if( (i&3) == 3 ) {
*(data_out++)=c; // output every 4th char
c='\0';
} else { // otherwise just shift it up
c<<=2;
}
data_in++; i++;
}
*data_out=c; // add partial last byte
i+=3; i>>=2;
return i;
}
} else {
/* String */
return strlen(data_in);
}
}