Xively C library

Dependents:   Application-xively-jumpstart-demo Application-xively-jumpstart-demo Modified_Xively_Jumpstart HW7-1_Xively_Thermostat

This is Xively C library, the code lives on GitHub.

See our example program and the tutorial, documentation can bee found here.

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?

UserRevisionLine numberNew 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 }