Browse Source

add scan_netstring

master
Felix von Leitner 8 years ago
parent
commit
91b2116a38
  1. 10
      scan/scan_8long.c
  2. 18
      scan/scan_long.c
  3. 25
      scan/scan_netstring.c
  4. 16
      scan/scan_ulong.c
  5. 10
      scan/scan_xlong.c
  6. 8
      test/scan_long.c
  7. 11
      test/scan_netstring.c

10
scan/scan_8long.c

@ -1,13 +1,5 @@
#include "scan.h"
size_t scan_8long(const char *src,unsigned long *dest) {
register const char *tmp=src;
register unsigned long l=0;
register unsigned char c;
while ((c=*tmp-'0')<8) {
l=l*8+c;
++tmp;
}
*dest=l;
return tmp-src;
return scan_8longn(src,-1,dest);
}

18
scan/scan_long.c

@ -1,21 +1,5 @@
#include "scan.h"
size_t scan_long(const char *src,long *dest) {
register const char *tmp;
register long int l;
register unsigned char c;
int neg;
int ok;
tmp=src; l=0; ok=neg=0;
switch (*tmp) {
case '-': neg=1;
case '+': ++tmp;
}
while ((c=*tmp-'0')<10) {
l=l*10+c;
++tmp;
ok=1;
}
if (ok) *dest=(neg?-l:l);
return tmp-src;
return scan_longn(src,-1,dest);
}

25
scan/scan_netstring.c

@ -0,0 +1,25 @@
#include "scan.h"
/* parse a netstring, input buffer is in (len bytes).
* if parsing is successful:
* *dest points to string and *slen is size of string
* return number of bytes parsed
* else
* return 0
* Note: *dest will point inside the input buffer!
*/
size_t scan_netstring(const char* in,size_t len,char** dest,size_t* slen) {
// [len]":"[string]","
// 3:foo,3:bar,4:fini,
unsigned long l;
size_t n=scan_ulongn(in,len,&l);
if (!n || /* did not start with a number */
n+2+l<l || /* overflow */
n+2+l>len || /* longer than we have input data */
in[n]!=':' || /* syntax error */
in[n+l+1]!=',')
return 0;
*dest=(char*)in+n+1;
*slen=n;
return n+2+l;
}

16
scan/scan_ulong.c

@ -1,19 +1,5 @@
#include "scan.h"
size_t scan_ulong(const char* src,unsigned long int* dest) {
register const char *tmp=src;
register unsigned long int l=0;
register unsigned char c;
while ((c=*tmp-'0')<10) {
unsigned long int n;
/* division is very slow on most architectures */
n=l<<3; if ((n>>3)!=l) break;
if (n+(l<<1) < n) break;
n+=l<<1;
if (n+c < n) break;
l=n+c;
++tmp;
}
if (tmp-src) *dest=l;
return tmp-src;
return scan_ulongn(src,(size_t)-1,dest);
}

10
scan/scan_xlong.c

@ -1,13 +1,5 @@
#include "scan.h"
size_t scan_xlong(const char *src,unsigned long *dest) {
register const char *tmp=src;
register unsigned long l=0;
register unsigned char c;
while ((c=scan_fromhex(*tmp))<16) {
l=(l<<4)+c;
++tmp;
}
*dest=l;
return tmp-src;
return scan_xlongn(src,(size_t)-1,dest);
}

8
test/scan_long.c

@ -6,6 +6,14 @@
int main() {
char buf[1024];
unsigned long long int i;
unsigned long l;
if (sizeof(unsigned long)==4) {
assert(scan_ulong("4294967295",&l) == 10 && l==4294967295ul);
assert(scan_ulong("4294967296",&l) == 9 && l==429496729);
} else {
assert(scan_ulong("18446744073709551615",&l) == 20 && l==18446744073709551615ull);
assert(scan_ulong("18446744073709551616",&l) == 19 && l==1844674407370955161ull);
}
if (sizeof(unsigned long) != 4)
return 0;
for (i=1; i<0xfffffffffull; i+=i+1) {

11
test/scan_netstring.c

@ -0,0 +1,11 @@
#include "scan.h"
#include <assert.h>
int main() {
char* s;
size_t l;
const char* orig;
orig="3:foo,"; assert(scan_netstring(orig,6,&s,&l)==6); assert(s==orig+2);
orig="4294967295:foo,"; assert(scan_netstring(orig,15,&s,&l)==0);
orig="18446744073709551615:foo,"; assert(scan_netstring(orig,25,&s,&l)==0);
}
Loading…
Cancel
Save