comparison src/c/urweb.c @ 1365:b02cb9da5686

Changed uw_Basis_time to store microseconds
author Adam Chlipala <adam@chlipala.net>
date Fri, 24 Dec 2010 18:08:29 -0500
parents 0dec38af601c
children 8301ee4ab58c
comparison
equal deleted inserted replaced
1364:0dec38af601c 1365:b02cb9da5686
1772 1772
1773 return uw_unit_v; 1773 return uw_unit_v;
1774 } 1774 }
1775 1775
1776 uw_Basis_string uw_Basis_urlifyTime(uw_context ctx, uw_Basis_time t) { 1776 uw_Basis_string uw_Basis_urlifyTime(uw_context ctx, uw_Basis_time t) {
1777 return uw_Basis_urlifyInt(ctx, t); 1777 return uw_Basis_urlifyInt(ctx, t.seconds * 1000000 + t.microseconds);
1778 } 1778 }
1779 1779
1780 uw_unit uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) { 1780 uw_unit uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) {
1781 if (s[0] == '\0') { 1781 if (s[0] == '\0') {
1782 uw_check(ctx, 1); 1782 uw_check(ctx, 1);
1843 *s = new_s; 1843 *s = new_s;
1844 return r; 1844 return r;
1845 } 1845 }
1846 1846
1847 uw_Basis_time uw_Basis_unurlifyTime(uw_context ctx, char **s) { 1847 uw_Basis_time uw_Basis_unurlifyTime(uw_context ctx, char **s) {
1848 return uw_Basis_unurlifyInt(ctx, s); 1848 uw_Basis_int n = uw_Basis_unurlifyInt(ctx, s);
1849 uw_Basis_time r = {n / 1000000, n % 1000000};
1850 return r;
1849 } 1851 }
1850 1852
1851 static uw_Basis_string uw_unurlifyString_to(int fromClient, uw_context ctx, char *r, char *s) { 1853 static uw_Basis_string uw_unurlifyString_to(int fromClient, uw_context ctx, char *r, char *s) {
1852 char *s1, *s2 = s; 1854 char *s1, *s2 = s;
1853 int n; 1855 int n;
2005 ctx->page.front += len; 2007 ctx->page.front += len;
2006 2008
2007 return uw_unit_v; 2009 return uw_unit_v;
2008 } 2010 }
2009 2011
2010 char *uw_Basis_jsifyTime(uw_context ctx, uw_Basis_time n) { 2012 char *uw_Basis_jsifyTime(uw_context ctx, uw_Basis_time t) {
2011 int len; 2013 int len;
2012 char *r; 2014 char *r;
2013 2015
2014 uw_check_heap(ctx, INTS_MAX); 2016 uw_check_heap(ctx, INTS_MAX);
2015 r = ctx->heap.front; 2017 r = ctx->heap.front;
2016 sprintf(r, "%lld%n", (uw_Basis_int)n, &len); 2018 sprintf(r, "%lld%n", (uw_Basis_int)(t.seconds * 1000000 + t.microseconds), &len);
2017 ctx->heap.front += len+1; 2019 ctx->heap.front += len+1;
2018 return r; 2020 return r;
2019 } 2021 }
2020 2022
2021 uw_unit uw_Basis_jsifyInt_w(uw_context ctx, uw_Basis_time n) { 2023 uw_unit uw_Basis_jsifyInt_w(uw_context ctx, uw_Basis_int n) {
2022 int len; 2024 int len;
2023 2025
2024 uw_check(ctx, INTS_MAX); 2026 uw_check(ctx, INTS_MAX);
2025 sprintf(ctx->page.front, "%lld%n", (uw_Basis_int)n, &len); 2027 sprintf(ctx->page.front, "%lld%n", (uw_Basis_int)n, &len);
2026 ctx->page.front += len; 2028 ctx->page.front += len;
2103 uw_Basis_string uw_Basis_htmlifyTime(uw_context ctx, uw_Basis_time t) { 2105 uw_Basis_string uw_Basis_htmlifyTime(uw_context ctx, uw_Basis_time t) {
2104 size_t len; 2106 size_t len;
2105 char *r; 2107 char *r;
2106 struct tm stm; 2108 struct tm stm;
2107 2109
2108 if (localtime_r(&t, &stm)) { 2110 if (localtime_r(&t.seconds, &stm)) {
2109 uw_check_heap(ctx, TIMES_MAX); 2111 uw_check_heap(ctx, TIMES_MAX);
2110 r = ctx->heap.front; 2112 r = ctx->heap.front;
2111 len = strftime(r, TIMES_MAX, TIME_FMT, &stm); 2113 len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
2112 ctx->heap.front += len+1; 2114 ctx->heap.front += len+1;
2113 return r; 2115 return r;
2118 uw_unit uw_Basis_htmlifyTime_w(uw_context ctx, uw_Basis_time t) { 2120 uw_unit uw_Basis_htmlifyTime_w(uw_context ctx, uw_Basis_time t) {
2119 size_t len; 2121 size_t len;
2120 char *r; 2122 char *r;
2121 struct tm stm; 2123 struct tm stm;
2122 2124
2123 if (localtime_r(&t, &stm)) { 2125 if (localtime_r(&t.seconds, &stm)) {
2124 uw_check(ctx, TIMES_MAX); 2126 uw_check(ctx, TIMES_MAX);
2125 r = ctx->page.front; 2127 r = ctx->page.front;
2126 len = strftime(r, TIMES_MAX, TIME_FMT, &stm); 2128 len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
2127 ctx->page.front += len; 2129 ctx->page.front += len;
2128 } else { 2130 } else {
2509 char *uw_Basis_sqlifyTime(uw_context ctx, uw_Basis_time t) { 2511 char *uw_Basis_sqlifyTime(uw_context ctx, uw_Basis_time t) {
2510 size_t len; 2512 size_t len;
2511 char *r, *s; 2513 char *r, *s;
2512 struct tm stm; 2514 struct tm stm;
2513 2515
2514 if (localtime_r(&t, &stm)) { 2516 if (localtime_r(&t.seconds, &stm)) {
2515 s = uw_malloc(ctx, TIMES_MAX); 2517 s = uw_malloc(ctx, TIMES_MAX);
2516 len = strftime(s, TIMES_MAX, TIME_FMT_PG, &stm); 2518 len = strftime(s, TIMES_MAX, TIME_FMT_PG, &stm);
2517 r = uw_malloc(ctx, len + 14); 2519 r = uw_malloc(ctx, len + 14);
2518 sprintf(r, "'%s'::timestamp", s); 2520 sprintf(r, "'%s'::timestamp", s);
2519 return r; 2521 return r;
2524 char *uw_Basis_attrifyTime(uw_context ctx, uw_Basis_time t) { 2526 char *uw_Basis_attrifyTime(uw_context ctx, uw_Basis_time t) {
2525 size_t len; 2527 size_t len;
2526 char *r; 2528 char *r;
2527 struct tm stm; 2529 struct tm stm;
2528 2530
2529 if (localtime_r(&t, &stm)) { 2531 if (localtime_r(&t.seconds, &stm)) {
2530 uw_check_heap(ctx, TIMES_MAX); 2532 uw_check_heap(ctx, TIMES_MAX);
2531 r = ctx->heap.front; 2533 r = ctx->heap.front;
2532 len = strftime(r, TIMES_MAX, TIME_FMT, &stm); 2534 len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
2533 ctx->heap.front += len+1; 2535 ctx->heap.front += len+1;
2534 return r; 2536 return r;
2539 char *uw_Basis_ensqlTime(uw_context ctx, uw_Basis_time t) { 2541 char *uw_Basis_ensqlTime(uw_context ctx, uw_Basis_time t) {
2540 size_t len; 2542 size_t len;
2541 char *r; 2543 char *r;
2542 struct tm stm; 2544 struct tm stm;
2543 2545
2544 if (localtime_r(&t, &stm)) { 2546 if (localtime_r(&t.seconds, &stm)) {
2545 uw_check_heap(ctx, TIMES_MAX); 2547 uw_check_heap(ctx, TIMES_MAX);
2546 r = ctx->heap.front; 2548 r = ctx->heap.front;
2547 len = strftime(r, TIMES_MAX, TIME_FMT_PG, &stm); 2549 len = strftime(r, TIMES_MAX-7, TIME_FMT_PG, &stm);
2548 ctx->heap.front += len+1; 2550 ctx->heap.front += len;
2551 sprintf(ctx->heap.front, ".%06u", t.microseconds);
2552 ctx->heap.front += 8;
2549 return r; 2553 return r;
2550 } else 2554 } else
2551 return "<Invalid time>"; 2555 return "<Invalid time>";
2552 } 2556 }
2553 2557
2607 uw_Basis_string uw_Basis_timeToString(uw_context ctx, uw_Basis_time t) { 2611 uw_Basis_string uw_Basis_timeToString(uw_context ctx, uw_Basis_time t) {
2608 size_t len; 2612 size_t len;
2609 char *r; 2613 char *r;
2610 struct tm stm; 2614 struct tm stm;
2611 2615
2612 if (localtime_r(&t, &stm)) { 2616 if (localtime_r(&t.seconds, &stm)) {
2613 uw_check_heap(ctx, TIMES_MAX); 2617 uw_check_heap(ctx, TIMES_MAX);
2614 r = ctx->heap.front; 2618 r = ctx->heap.front;
2615 len = strftime(r, TIMES_MAX, TIME_FMT, &stm); 2619 len = strftime(r, TIMES_MAX, TIME_FMT, &stm);
2616 ctx->heap.front += len+1; 2620 ctx->heap.front += len+1;
2617 return r; 2621 return r;
2622 uw_Basis_string uw_Basis_timef(uw_context ctx, const char *fmt, uw_Basis_time t) { 2626 uw_Basis_string uw_Basis_timef(uw_context ctx, const char *fmt, uw_Basis_time t) {
2623 size_t len; 2627 size_t len;
2624 char *r; 2628 char *r;
2625 struct tm stm; 2629 struct tm stm;
2626 2630
2627 if (localtime_r(&t, &stm)) { 2631 if (localtime_r(&t.seconds, &stm)) {
2628 uw_check_heap(ctx, TIMES_MAX); 2632 uw_check_heap(ctx, TIMES_MAX);
2629 r = ctx->heap.front; 2633 r = ctx->heap.front;
2630 len = strftime(r, TIMES_MAX, fmt, &stm); 2634 len = strftime(r, TIMES_MAX, fmt, &stm);
2631 ctx->heap.front += len+1; 2635 ctx->heap.front += len+1;
2632 return r; 2636 return r;
2691 if (dot) { 2695 if (dot) {
2692 *dot = 0; 2696 *dot = 0;
2693 if (strptime(s, TIME_FMT_PG, &stm) == end) { 2697 if (strptime(s, TIME_FMT_PG, &stm) == end) {
2694 *dot = '.'; 2698 *dot = '.';
2695 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time)); 2699 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
2696 *r = mktime(&stm); 2700 r->seconds = mktime(&stm);
2701 r->microseconds = 0;
2697 return r; 2702 return r;
2698 } 2703 }
2699 else { 2704 else {
2700 *dot = '.'; 2705 *dot = '.';
2701 return NULL; 2706 return NULL;
2702 } 2707 }
2703 } 2708 }
2704 else { 2709 else {
2705 if (strptime(s, TIME_FMT_PG, &stm) == end) { 2710 if (strptime(s, TIME_FMT_PG, &stm) == end) {
2706 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time)); 2711 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
2707 *r = mktime(&stm); 2712 r->seconds = mktime(&stm);
2713 r->microseconds = 0;
2708 return r; 2714 return r;
2709 } 2715 }
2710 else if (strptime(s, TIME_FMT, &stm) == end) { 2716 else if (strptime(s, TIME_FMT, &stm) == end) {
2711 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time)); 2717 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
2712 *r = mktime(&stm); 2718 r->seconds = mktime(&stm);
2719 r->microseconds = 0;
2713 return r; 2720 return r;
2714 } 2721 }
2715 else 2722 else
2716 return NULL; 2723 return NULL;
2717 } 2724 }
2721 char *end = strchr(s, 0); 2728 char *end = strchr(s, 0);
2722 struct tm stm; 2729 struct tm stm;
2723 2730
2724 if (strptime(s, fmt, &stm) == end) { 2731 if (strptime(s, fmt, &stm) == end) {
2725 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time)); 2732 uw_Basis_time *r = uw_malloc(ctx, sizeof(uw_Basis_time));
2726 *r = mktime(&stm); 2733 r->seconds = mktime(&stm);
2734 r->microseconds = 0;
2727 return r; 2735 return r;
2728 } 2736 }
2729 else 2737 else
2730 return NULL; 2738 return NULL;
2731 } 2739 }
2797 2805
2798 if (dot) { 2806 if (dot) {
2799 *dot = 0; 2807 *dot = 0;
2800 if (strptime(s, TIME_FMT_PG, &stm)) { 2808 if (strptime(s, TIME_FMT_PG, &stm)) {
2801 *dot = '.'; 2809 *dot = '.';
2802 return mktime(&stm); 2810 uw_Basis_time r = { mktime(&stm), atoi(dot+1) };
2811 return r;
2803 } 2812 }
2804 else { 2813 else {
2805 *dot = '.'; 2814 *dot = '.';
2806 uw_error(ctx, FATAL, "Can't parse time: %s", s); 2815 uw_error(ctx, FATAL, "Can't parse time: %s", s);
2807 } 2816 }
2808 } 2817 }
2809 else { 2818 else {
2810 if (strptime(s, TIME_FMT_PG, &stm) == end) { 2819 if (strptime(s, TIME_FMT_PG, &stm) == end) {
2811 return mktime(&stm); 2820 uw_Basis_time r = { mktime(&stm) };
2821 return r;
2812 } else if (strptime(s, TIME_FMT, &stm) == end) { 2822 } else if (strptime(s, TIME_FMT, &stm) == end) {
2813 return mktime(&stm); 2823 uw_Basis_time r = { mktime(&stm) };
2824 return r;
2814 } else 2825 } else
2815 uw_error(ctx, FATAL, "Can't parse time: %s", s); 2826 uw_error(ctx, FATAL, "Can't parse time: %s", s);
2816 } 2827 }
2817 } 2828 }
2818 2829
2822 2833
2823 if (dot) { 2834 if (dot) {
2824 *dot = 0; 2835 *dot = 0;
2825 if (strptime(s, TIME_FMT_PG, &stm)) { 2836 if (strptime(s, TIME_FMT_PG, &stm)) {
2826 *dot = '.'; 2837 *dot = '.';
2827 return mktime(&stm); 2838 {
2839 uw_Basis_time r = { mktime(&stm) };
2840 return r;
2841 }
2828 } 2842 }
2829 else { 2843 else {
2830 *dot = '.'; 2844 *dot = '.';
2831 uw_error(ctx, FATAL, "Can't parse time: %s", s); 2845 uw_error(ctx, FATAL, "Can't parse time: %s", s);
2832 } 2846 }
2833 } 2847 }
2834 else { 2848 else {
2835 if (strptime(s, TIME_FMT_PG, &stm) == end) 2849 if (strptime(s, TIME_FMT_PG, &stm) == end) {
2836 return mktime(&stm); 2850 uw_Basis_time r = { mktime(&stm) };
2837 else if (strptime(s, TIME_FMT, &stm) == end) 2851 return r;
2838 return mktime(&stm); 2852 } else if (strptime(s, TIME_FMT, &stm) == end) {
2839 else 2853 uw_Basis_time r = { mktime(&stm) };
2854 return r;
2855 } else
2840 uw_error(ctx, FATAL, "Can't parse time: %s", s); 2856 uw_error(ctx, FATAL, "Can't parse time: %s", s);
2841 } 2857 }
2842 } 2858 }
2843 2859
2844 uw_Basis_time uw_Basis_stringToTimef_error(uw_context ctx, const char *fmt, uw_Basis_string s) { 2860 uw_Basis_time uw_Basis_stringToTimef_error(uw_context ctx, const char *fmt, uw_Basis_string s) {
2845 char *end = strchr(s, 0); 2861 char *end = strchr(s, 0);
2846 struct tm stm = {}; 2862 struct tm stm = {};
2847 2863
2848 if (strptime(s, fmt, &stm) == end) 2864 if (strptime(s, fmt, &stm) == end) {
2849 return mktime(&stm); 2865 uw_Basis_time r = { mktime(&stm) };
2850 else 2866 return r;
2867 } else
2851 uw_error(ctx, FATAL, "Can't parse time: %s", s); 2868 uw_error(ctx, FATAL, "Can't parse time: %s", s);
2852 } 2869 }
2853 2870
2854 uw_Basis_blob uw_Basis_stringToBlob_error(uw_context ctx, uw_Basis_string s, size_t len) { 2871 uw_Basis_blob uw_Basis_stringToBlob_error(uw_context ctx, uw_Basis_string s, size_t len) {
2855 char *r = ctx->heap.front; 2872 char *r = ctx->heap.front;
2940 uw_write_header(ctx, prefix); 2957 uw_write_header(ctx, prefix);
2941 if (expires) { 2958 if (expires) {
2942 char formatted[30]; 2959 char formatted[30];
2943 struct tm tm; 2960 struct tm tm;
2944 2961
2945 gmtime_r(expires, &tm); 2962 gmtime_r(&expires->seconds, &tm);
2946 2963
2947 strftime(formatted, sizeof formatted, "%a, %d-%b-%Y %T GMT", &tm); 2964 strftime(formatted, sizeof formatted, "%a, %d-%b-%Y %T GMT", &tm);
2948 2965
2949 uw_write_header(ctx, "; expires="); 2966 uw_write_header(ctx, "; expires=");
2950 uw_write_header(ctx, formatted); 2967 uw_write_header(ctx, formatted);
3428 *s2 = 0; 3445 *s2 = 0;
3429 3446
3430 return r; 3447 return r;
3431 } 3448 }
3432 3449
3433 const uw_Basis_time uw_Basis_minTime = 0; 3450 const uw_Basis_time uw_Basis_minTime = {};
3434 3451
3435 uw_Basis_time uw_Basis_now(uw_context ctx) { 3452 uw_Basis_time uw_Basis_now(uw_context ctx) {
3436 return time(NULL); 3453 uw_Basis_time r = { time(NULL) };
3454 return r;
3437 } 3455 }
3438 3456
3439 uw_Basis_time uw_Basis_minusSeconds(uw_context ctx, uw_Basis_time tm, uw_Basis_int n) { 3457 uw_Basis_time uw_Basis_minusSeconds(uw_context ctx, uw_Basis_time tm, uw_Basis_int n) {
3440 return tm - n; 3458 tm.seconds -= n;
3459 return tm;
3441 } 3460 }
3442 3461
3443 void *uw_get_global(uw_context ctx, char *name) { 3462 void *uw_get_global(uw_context ctx, char *name) {
3444 int i; 3463 int i;
3445 3464
3615 uw_set_global(ctx, "crypt", data, free); 3634 uw_set_global(ctx, "crypt", data, free);
3616 } 3635 }
3617 3636
3618 return uw_strdup(ctx, crypt_r(key, salt, data)); 3637 return uw_strdup(ctx, crypt_r(key, salt, data));
3619 } 3638 }
3639
3640 uw_Basis_bool uw_Basis_eq_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
3641 return !!(t1.seconds == t2.seconds && t1.microseconds == t2.microseconds);
3642 }
3643
3644 uw_Basis_bool uw_Basis_lt_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
3645 return !!(t1.seconds < t2.seconds || t1.microseconds < t2.microseconds);
3646 }
3647
3648 uw_Basis_bool uw_Basis_le_time(uw_context ctx, uw_Basis_time t1, uw_Basis_time t2) {
3649 return !!(uw_Basis_eq_time(ctx, t1, t2) || uw_Basis_lt_time(ctx, t1, t2));
3650 }
3651