test
Fork of mbed-libxively-6eca970 by
src/libxively/xi_helpers.c@0:82702e998d3f, 2013-06-26 (annotated)
- Committer:
- xively
- Date:
- Wed Jun 26 10:40:43 2013 +0000
- Revision:
- 0:82702e998d3f
libxively v0.1.1-rc0 (34c8b32)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xively | 0:82702e998d3f | 1 | // Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved. |
xively | 0:82702e998d3f | 2 | // This is part of Xively C library, it is under the BSD 3-Clause license. |
xively | 0:82702e998d3f | 3 | |
xively | 0:82702e998d3f | 4 | // This file also containes code from MINIX C library, which is under MINIX license |
xively | 0:82702e998d3f | 5 | // Copyright (c) 1987, 1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands |
xively | 0:82702e998d3f | 6 | |
xively | 0:82702e998d3f | 7 | /** |
xively | 0:82702e998d3f | 8 | * \file xi_helpers.c |
xively | 0:82702e998d3f | 9 | * \author Olgierd Humenczuk |
xively | 0:82702e998d3f | 10 | * \brief General helpers used by the library [see xi_helpers.h] |
xively | 0:82702e998d3f | 11 | */ |
xively | 0:82702e998d3f | 12 | |
xively | 0:82702e998d3f | 13 | #include <string.h> |
xively | 0:82702e998d3f | 14 | #include <assert.h> |
xively | 0:82702e998d3f | 15 | |
xively | 0:82702e998d3f | 16 | #include "xi_helpers.h" |
xively | 0:82702e998d3f | 17 | #include "xi_allocator.h" |
xively | 0:82702e998d3f | 18 | |
xively | 0:82702e998d3f | 19 | char* xi_str_dup( const char* s ) |
xively | 0:82702e998d3f | 20 | { |
xively | 0:82702e998d3f | 21 | // PRECONDITIONS |
xively | 0:82702e998d3f | 22 | assert( s != 0 ); |
xively | 0:82702e998d3f | 23 | |
xively | 0:82702e998d3f | 24 | size_t len = strlen( s ); |
xively | 0:82702e998d3f | 25 | char * ret = xi_alloc( len + 1 ); |
xively | 0:82702e998d3f | 26 | if( ret == 0 ) { return 0; } |
xively | 0:82702e998d3f | 27 | memcpy( ret, s, len + 1 ); |
xively | 0:82702e998d3f | 28 | return ret; |
xively | 0:82702e998d3f | 29 | } |
xively | 0:82702e998d3f | 30 | |
xively | 0:82702e998d3f | 31 | int xi_str_copy_untiln( char* dst, size_t dst_size, const char* src, char delim ) |
xively | 0:82702e998d3f | 32 | { |
xively | 0:82702e998d3f | 33 | // PRECONDITIONS |
xively | 0:82702e998d3f | 34 | assert( dst != 0 ); |
xively | 0:82702e998d3f | 35 | assert( dst_size > 1 ); |
xively | 0:82702e998d3f | 36 | assert( src != 0 ); |
xively | 0:82702e998d3f | 37 | |
xively | 0:82702e998d3f | 38 | size_t counter = 0; |
xively | 0:82702e998d3f | 39 | size_t real_size = dst_size - 1; |
xively | 0:82702e998d3f | 40 | |
xively | 0:82702e998d3f | 41 | while( *src != delim && counter < real_size && *src != '\0' ) |
xively | 0:82702e998d3f | 42 | { |
xively | 0:82702e998d3f | 43 | *dst++ = *src++; |
xively | 0:82702e998d3f | 44 | counter++; |
xively | 0:82702e998d3f | 45 | } |
xively | 0:82702e998d3f | 46 | |
xively | 0:82702e998d3f | 47 | *dst = '\0'; |
xively | 0:82702e998d3f | 48 | return counter; |
xively | 0:82702e998d3f | 49 | } |
xively | 0:82702e998d3f | 50 | |
xively | 0:82702e998d3f | 51 | // used by the xi_mktime |
xively | 0:82702e998d3f | 52 | #define YEAR0 1900 /* the first year */ |
xively | 0:82702e998d3f | 53 | #define EPOCH_YR 1970 /* EPOCH = Jan 1 1970 00:00:00 */ |
xively | 0:82702e998d3f | 54 | #define SECS_DAY (24L * 60L * 60L) |
xively | 0:82702e998d3f | 55 | #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) |
xively | 0:82702e998d3f | 56 | #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) |
xively | 0:82702e998d3f | 57 | #define FIRSTSUNDAY(timp) (((timp)->tm_yday - (timp)->tm_wday + 420) % 7) |
xively | 0:82702e998d3f | 58 | #define FIRSTDAYOF(timp) (((timp)->tm_wday - (timp)->tm_yday + 420) % 7) |
xively | 0:82702e998d3f | 59 | #define TIME_MAX ULONG_MAX |
xively | 0:82702e998d3f | 60 | #define ABB_LEN 3 |
xively | 0:82702e998d3f | 61 | |
xively | 0:82702e998d3f | 62 | // used by the xi_mktime |
xively | 0:82702e998d3f | 63 | static const int _ytab[2][12] = { |
xively | 0:82702e998d3f | 64 | { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, |
xively | 0:82702e998d3f | 65 | { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; |
xively | 0:82702e998d3f | 66 | |
xively | 0:82702e998d3f | 67 | time_t xi_mktime(register struct tm *timep) |
xively | 0:82702e998d3f | 68 | { |
xively | 0:82702e998d3f | 69 | register long day, year; |
xively | 0:82702e998d3f | 70 | register int tm_year; |
xively | 0:82702e998d3f | 71 | int yday, month; |
xively | 0:82702e998d3f | 72 | register signed long seconds; |
xively | 0:82702e998d3f | 73 | int overflow; |
xively | 0:82702e998d3f | 74 | |
xively | 0:82702e998d3f | 75 | timep->tm_min += timep->tm_sec / 60; |
xively | 0:82702e998d3f | 76 | timep->tm_sec %= 60; |
xively | 0:82702e998d3f | 77 | if (timep->tm_sec < 0) { |
xively | 0:82702e998d3f | 78 | timep->tm_sec += 60; |
xively | 0:82702e998d3f | 79 | timep->tm_min--; |
xively | 0:82702e998d3f | 80 | } |
xively | 0:82702e998d3f | 81 | timep->tm_hour += timep->tm_min / 60; |
xively | 0:82702e998d3f | 82 | timep->tm_min = timep->tm_min % 60; |
xively | 0:82702e998d3f | 83 | if (timep->tm_min < 0) { |
xively | 0:82702e998d3f | 84 | timep->tm_min += 60; |
xively | 0:82702e998d3f | 85 | timep->tm_hour--; |
xively | 0:82702e998d3f | 86 | } |
xively | 0:82702e998d3f | 87 | day = timep->tm_hour / 24; |
xively | 0:82702e998d3f | 88 | timep->tm_hour= timep->tm_hour % 24; |
xively | 0:82702e998d3f | 89 | if (timep->tm_hour < 0) { |
xively | 0:82702e998d3f | 90 | timep->tm_hour += 24; |
xively | 0:82702e998d3f | 91 | day--; |
xively | 0:82702e998d3f | 92 | } |
xively | 0:82702e998d3f | 93 | timep->tm_year += timep->tm_mon / 12; |
xively | 0:82702e998d3f | 94 | timep->tm_mon %= 12; |
xively | 0:82702e998d3f | 95 | if (timep->tm_mon < 0) { |
xively | 0:82702e998d3f | 96 | timep->tm_mon += 12; |
xively | 0:82702e998d3f | 97 | timep->tm_year--; |
xively | 0:82702e998d3f | 98 | } |
xively | 0:82702e998d3f | 99 | day += (timep->tm_mday - 1); |
xively | 0:82702e998d3f | 100 | while (day < 0) { |
xively | 0:82702e998d3f | 101 | if(--timep->tm_mon < 0) { |
xively | 0:82702e998d3f | 102 | timep->tm_year--; |
xively | 0:82702e998d3f | 103 | timep->tm_mon = 11; |
xively | 0:82702e998d3f | 104 | } |
xively | 0:82702e998d3f | 105 | day += _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon]; |
xively | 0:82702e998d3f | 106 | } |
xively | 0:82702e998d3f | 107 | while (day >= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon]) { |
xively | 0:82702e998d3f | 108 | day -= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon]; |
xively | 0:82702e998d3f | 109 | if (++(timep->tm_mon) == 12) { |
xively | 0:82702e998d3f | 110 | timep->tm_mon = 0; |
xively | 0:82702e998d3f | 111 | timep->tm_year++; |
xively | 0:82702e998d3f | 112 | } |
xively | 0:82702e998d3f | 113 | } |
xively | 0:82702e998d3f | 114 | timep->tm_mday = day + 1; |
xively | 0:82702e998d3f | 115 | year = EPOCH_YR; |
xively | 0:82702e998d3f | 116 | if (timep->tm_year < year - YEAR0) return (time_t)-1; |
xively | 0:82702e998d3f | 117 | seconds = 0; |
xively | 0:82702e998d3f | 118 | day = 0; |
xively | 0:82702e998d3f | 119 | overflow = 0; |
xively | 0:82702e998d3f | 120 | |
xively | 0:82702e998d3f | 121 | /* |
xively | 0:82702e998d3f | 122 | * Assume that when day becomes negative, there will certainly be overflow on seconds. |
xively | 0:82702e998d3f | 123 | * The check for overflow needs not to be done for leapyears divisible by 400. |
xively | 0:82702e998d3f | 124 | * The code only works when year (1970) is not a leapyear. |
xively | 0:82702e998d3f | 125 | */ |
xively | 0:82702e998d3f | 126 | #if EPOCH_YR != 1970 |
xively | 0:82702e998d3f | 127 | #error EPOCH_YR != 1970 |
xively | 0:82702e998d3f | 128 | #endif |
xively | 0:82702e998d3f | 129 | |
xively | 0:82702e998d3f | 130 | tm_year = timep->tm_year + YEAR0; |
xively | 0:82702e998d3f | 131 | |
xively | 0:82702e998d3f | 132 | if (LONG_MAX / 365 < tm_year - year) overflow++; |
xively | 0:82702e998d3f | 133 | day = (tm_year - year) * 365; |
xively | 0:82702e998d3f | 134 | if (LONG_MAX - day < (tm_year - year) / 4 + 1) overflow++; |
xively | 0:82702e998d3f | 135 | day += (tm_year - year) / 4 |
xively | 0:82702e998d3f | 136 | + ((tm_year % 4) && tm_year % 4 < year % 4); |
xively | 0:82702e998d3f | 137 | day -= (tm_year - year) / 100 |
xively | 0:82702e998d3f | 138 | + ((tm_year % 100) && tm_year % 100 < year % 100); |
xively | 0:82702e998d3f | 139 | day += (tm_year - year) / 400 |
xively | 0:82702e998d3f | 140 | + ((tm_year % 400) && tm_year % 400 < year % 400); |
xively | 0:82702e998d3f | 141 | |
xively | 0:82702e998d3f | 142 | yday = month = 0; |
xively | 0:82702e998d3f | 143 | while (month < timep->tm_mon) { |
xively | 0:82702e998d3f | 144 | yday += _ytab[LEAPYEAR(tm_year)][month]; |
xively | 0:82702e998d3f | 145 | month++; |
xively | 0:82702e998d3f | 146 | } |
xively | 0:82702e998d3f | 147 | yday += (timep->tm_mday - 1); |
xively | 0:82702e998d3f | 148 | if (day + yday < 0) overflow++; |
xively | 0:82702e998d3f | 149 | day += yday; |
xively | 0:82702e998d3f | 150 | |
xively | 0:82702e998d3f | 151 | timep->tm_yday = yday; |
xively | 0:82702e998d3f | 152 | timep->tm_wday = (day + 4) % 7; |
xively | 0:82702e998d3f | 153 | |
xively | 0:82702e998d3f | 154 | seconds = ( ( timep->tm_hour * 60L ) + timep->tm_min ) * 60L + timep->tm_sec; |
xively | 0:82702e998d3f | 155 | |
xively | 0:82702e998d3f | 156 | if ( ( TIME_MAX - seconds ) / SECS_DAY < ( unsigned long ) day ) overflow++; |
xively | 0:82702e998d3f | 157 | seconds += day * SECS_DAY; |
xively | 0:82702e998d3f | 158 | |
xively | 0:82702e998d3f | 159 | if ( overflow ) return ( time_t ) - 1; |
xively | 0:82702e998d3f | 160 | |
xively | 0:82702e998d3f | 161 | if ( ( time_t ) seconds != seconds) return ( time_t ) - 1; |
xively | 0:82702e998d3f | 162 | return ( time_t ) seconds; |
xively | 0:82702e998d3f | 163 | } |
xively | 0:82702e998d3f | 164 | |
xively | 0:82702e998d3f | 165 | struct tm* xi_gmtime( time_t* t ) |
xively | 0:82702e998d3f | 166 | { |
xively | 0:82702e998d3f | 167 | return gmtime( t ); |
xively | 0:82702e998d3f | 168 | } |
xively | 0:82702e998d3f | 169 | |
xively | 0:82702e998d3f | 170 | char* xi_replace_with( |
xively | 0:82702e998d3f | 171 | char p, char r |
xively | 0:82702e998d3f | 172 | , char* buffer |
xively | 0:82702e998d3f | 173 | , size_t max_chars ) |
xively | 0:82702e998d3f | 174 | { |
xively | 0:82702e998d3f | 175 | char* c = buffer; |
xively | 0:82702e998d3f | 176 | |
xively | 0:82702e998d3f | 177 | while( *c != '\0' && max_chars-- ) |
xively | 0:82702e998d3f | 178 | { |
xively | 0:82702e998d3f | 179 | if( *c == p ) { *c = r; } |
xively | 0:82702e998d3f | 180 | c++; |
xively | 0:82702e998d3f | 181 | } |
xively | 0:82702e998d3f | 182 | |
xively | 0:82702e998d3f | 183 | return c; |
xively | 0:82702e998d3f | 184 | } |