Xively Official / mbed-libxively-5d6fdd4

Dependents:   xively-jumpstart-demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xi_helpers.c Source File

xi_helpers.c

Go to the documentation of this file.
00001 // Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved.
00002 // This is part of Xively C library, it is under the BSD 3-Clause license.
00003 
00004 // This file also containes code from MINIX C library, which is under MINIX license
00005 // Copyright (c) 1987, 1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands
00006 
00007 /**
00008  * \file    xi_helpers.c
00009  * \author  Olgierd Humenczuk
00010  * \brief   General helpers used by the library [see xi_helpers.h]
00011  */
00012 
00013 #include <string.h>
00014 #include <assert.h>
00015 
00016 #include "xi_helpers.h"
00017 #include "xi_allocator.h"
00018 
00019 char* xi_str_dup ( const char* s )
00020 {
00021     // PRECONDITIONS
00022     assert( s != 0 );
00023 
00024     size_t len = strlen( s );
00025     char * ret = xi_alloc( len + 1 );
00026     if( ret == 0 ) { return 0; }
00027     memcpy( ret, s, len + 1 );
00028     return ret;
00029 }
00030 
00031 int xi_str_copy_untiln( char* dst, size_t dst_size, const char* src, char delim )
00032 {
00033     // PRECONDITIONS
00034     assert( dst != 0 );
00035     assert( dst_size > 1 );
00036     assert( src != 0 );
00037 
00038     size_t counter = 0;
00039     size_t real_size = dst_size - 1;
00040 
00041     while( *src != delim && counter < real_size && *src != '\0' )
00042     {
00043         *dst++ = *src++;
00044         counter++;
00045     }
00046 
00047     *dst = '\0';
00048     return counter;
00049 }
00050 
00051 // used by the xi_mktime
00052 #define YEAR0               1900  /* the first year */
00053 #define EPOCH_YR            1970  /* EPOCH = Jan 1 1970 00:00:00 */
00054 #define SECS_DAY            (24L * 60L * 60L)
00055 #define LEAPYEAR(year)      (!((year) % 4) && (((year) % 100) || !((year) % 400)))
00056 #define YEARSIZE(year)      (LEAPYEAR(year) ? 366 : 365)
00057 #define FIRSTSUNDAY(timp)    (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
00058 #define FIRSTDAYOF(timp)    (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
00059 #define TIME_MAX            ULONG_MAX
00060 #define ABB_LEN             3
00061 
00062 // used by the xi_mktime
00063 static const int _ytab[2][12] = {
00064     { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
00065       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
00066 
00067 time_t xi_mktime(register struct tm *timep)
00068 {
00069     register long day, year;
00070     register int tm_year;
00071     int yday, month;
00072     register signed long seconds;
00073     int overflow;
00074 
00075     timep->tm_min += timep->tm_sec / 60;
00076     timep->tm_sec %= 60;
00077     if (timep->tm_sec < 0) {
00078          timep->tm_sec += 60;
00079          timep->tm_min--;
00080     }
00081     timep->tm_hour += timep->tm_min / 60;
00082     timep->tm_min = timep->tm_min % 60;
00083     if (timep->tm_min < 0) {
00084          timep->tm_min += 60;
00085          timep->tm_hour--;
00086     }
00087     day = timep->tm_hour / 24;
00088     timep->tm_hour= timep->tm_hour % 24;
00089     if (timep->tm_hour < 0) {
00090          timep->tm_hour += 24;
00091          day--;
00092     }
00093     timep->tm_year += timep->tm_mon / 12;
00094     timep->tm_mon %= 12;
00095     if (timep->tm_mon < 0) {
00096          timep->tm_mon += 12;
00097          timep->tm_year--;
00098     }
00099     day += (timep->tm_mday - 1);
00100     while (day < 0) {
00101          if(--timep->tm_mon < 0) {
00102                  timep->tm_year--;
00103                  timep->tm_mon = 11;
00104          }
00105          day += _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon];
00106     }
00107     while (day >= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon]) {
00108          day -= _ytab[LEAPYEAR(YEAR0 + timep->tm_year)][timep->tm_mon];
00109          if (++(timep->tm_mon) == 12) {
00110                  timep->tm_mon = 0;
00111                  timep->tm_year++;
00112          }
00113     }
00114     timep->tm_mday = day + 1;
00115     year = EPOCH_YR;
00116     if (timep->tm_year < year - YEAR0) return (time_t)-1;
00117     seconds = 0;
00118     day = 0;
00119     overflow = 0;
00120 
00121     /*
00122      * Assume that when day becomes negative, there will certainly be overflow on seconds.
00123      * The check for overflow needs not to be done for leapyears divisible by 400.
00124      * The code only works when year (1970) is not a leapyear.
00125      */
00126     #if EPOCH_YR != 1970
00127     #error EPOCH_YR != 1970
00128     #endif
00129 
00130     tm_year = timep->tm_year + YEAR0;
00131 
00132     if (LONG_MAX / 365 < tm_year - year) overflow++;
00133     day = (tm_year - year) * 365;
00134     if (LONG_MAX - day < (tm_year - year) / 4 + 1) overflow++;
00135     day += (tm_year - year) / 4
00136          + ((tm_year % 4) && tm_year % 4 < year % 4);
00137     day -= (tm_year - year) / 100
00138          + ((tm_year % 100) && tm_year % 100 < year % 100);
00139     day += (tm_year - year) / 400
00140          + ((tm_year % 400) && tm_year % 400 < year % 400);
00141 
00142     yday = month = 0;
00143     while (month < timep->tm_mon) {
00144          yday += _ytab[LEAPYEAR(tm_year)][month];
00145          month++;
00146     }
00147     yday += (timep->tm_mday - 1);
00148     if (day + yday < 0) overflow++;
00149     day += yday;
00150 
00151     timep->tm_yday = yday;
00152     timep->tm_wday = (day + 4) % 7;
00153 
00154     seconds = ( ( timep->tm_hour * 60L ) + timep->tm_min ) * 60L + timep->tm_sec;
00155 
00156     if ( ( TIME_MAX - seconds ) / SECS_DAY < ( unsigned long ) day ) overflow++;
00157     seconds += day * SECS_DAY;
00158 
00159     if ( overflow ) return ( time_t ) - 1;
00160 
00161     if ( ( time_t ) seconds != seconds) return ( time_t ) - 1;
00162     return ( time_t ) seconds;
00163 }
00164 
00165 struct tm* xi_gmtime( time_t* t )
00166 {
00167     return gmtime( t );
00168 }
00169 
00170 char* xi_replace_with(
00171       char p, char r
00172     , char* buffer
00173     , size_t max_chars )
00174 {
00175     char* c = buffer;
00176 
00177     while( *c != '\0' && max_chars-- )
00178     {
00179         if( *c == p ) { *c = r; }
00180         c++;
00181     }
00182 
00183     return c;
00184 }