Mercurial > urweb
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 |