add scan_httpdate

master
leitner 22 years ago
parent 40bba8865b
commit 9e85dc61a0

@ -12,7 +12,7 @@
add stralloc versions of textcode API (Kai Ruemmler)
add html to textcode ('<' to '&lt;' etc)
add fmt_human and fmt_humank (format numbers ala ls -H/-h)
add fmt_httpdate
add fmt_httpdate and scan_httpdate
0.14:
avoid bus errors in byte_copy

@ -1,6 +1,8 @@
#ifndef SCAN_H
#define SCAN_H
#include <sys/types.h>
#ifdef __dietlibc__
#include <sys/cdefs.h>
#endif
@ -58,4 +60,12 @@ extern unsigned int scan_charsetnskip(const char *in,const char *charset,unsigne
* charset (ASCIIZ string) for all 0<=i<=n */
extern unsigned int scan_noncharsetnskip(const char *in,const char *charset,unsigned int limit) __pure__;
/* try to parse ASCII GMT date; does not understand time zones. */
/* example dates:
* "Sun, 06 Nov 1994 08:49:37 GMT"
* "Sunday, 06-Nov-94 08:49:37 GMT"
* "Sun Nov 6 08:49:37 1994"
*/
extern unsigned int scan_httpdate(const char *in,time_t *t) __pure__;
#endif

@ -0,0 +1,15 @@
.TH scan_httpdate 3
.SH NAME
scan_httpdate \- parse a HTTP date
.SH SYNTAX
.B #include <scan.h>
int \fBscan_httpdate\fP(const char *\fIsrc\fR,time_t *\fIdest\fR);
.SH DESCRIPTION
scan_httpdate parses a date as defined in the HTTP standard into a
time_t. It returns the number of bytes read from \fIsrc\fR (0 for parse
error).
The only supported time zone is GMT.
.SH "SEE ALSO"
fmt_httpdate(3)

@ -0,0 +1,59 @@
#include "scan.h"
#include "byte.h"
#include "case.h"
#include <time.h>
static int parsetime(const char*c,struct tm* x) {
unsigned long tmp;
c+=scan_ulong(c,&tmp); x->tm_hour=tmp;
if (*c!=':') return -1; ++c;
c+=scan_ulong(c,&tmp); x->tm_min=tmp;
if (*c!=':') return -1; ++c;
c+=scan_ulong(c,&tmp); x->tm_sec=tmp;
if (*c!=' ') return -1;
return 0;
}
unsigned int scan_httpdate(const char *in,time_t *t) {
struct tm x;
int i;
unsigned long tmp;
const char* c;
static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
if (!(c=in)) return 0;
if (c[3]==',') c+=5; else
if (c[6]==',') c+=8; else {
c+=4;
for (i=0; i<12; ++i) {
if (case_equalb(c,3,months+i*3)) {
x.tm_mon=i; break;
}
}
c+=4; if (*c==' ') ++c;
c+=scan_ulong(c,&tmp); x.tm_mday=tmp;
++c;
if (parsetime(c,&x)) return 0;
c+=9;
c+=scan_ulong(c,&tmp); x.tm_year=tmp-1900;
goto done;
}
c+=scan_ulong(c,&tmp); x.tm_mday=tmp;
++c;
for (i=0; i<12; ++i)
if (case_equalb(c,3,months+i*3)) {
x.tm_mon=i; break;
}
c+=4;
c+=scan_ulong(c,&tmp);
if (tmp>1000) x.tm_year=tmp-1900; else
if (tmp<70) x.tm_year=tmp+100; else
x.tm_year=tmp;
++c;
if (parsetime(c,&x)) return 0;
c+=9;
if (byte_equal(c,3,"GMT")) c+=3;
done:
x.tm_wday=x.tm_yday=x.tm_isdst=0;
*t=mktime(&x);
return c-in;
}

@ -1,8 +1,16 @@
#include <time.h>
#include <scan.h>
#include <buffer.h>
main() {
char buf[100];
buffer_put(buffer_1,buf,fmt_httpdate(buf,time(0)));
time_t s,t;
buffer_put(buffer_1,buf,fmt_httpdate(buf,time(&s)));
buffer_putnlflush(buffer_1);
buffer_puts(buffer_1,buf+scan_httpdate(buf,&t));
buffer_putnlflush(buffer_1);
buffer_putulong(buffer_1,s);
buffer_puts(buffer_1," vs. ");
buffer_putulong(buffer_1,t);
buffer_putnlflush(buffer_1);
}

Loading…
Cancel
Save