The world's most popular open source database
#include <my_global.h>#include "mysql_priv.h"#include "tzfile.h"#include <m_string.h>#include <my_dir.h>Include dependency graph for tztime.cc:

Go to the source code of this file.
| #define LEAPS_THRU_END_OF | ( | y | ) | ((y) / 4 - (y) / 100 + (y) / 400) |
| typedef struct st_time_zone_info TIME_ZONE_INFO |
| typedef struct ttinfo TRAN_TYPE_INFO |
| static uint find_time_range | ( | my_time_t | t, | |
| const my_time_t * | range_boundaries, | |||
| uint | higher_bound | |||
| ) | [static] |
Definition at line 626 of file tztime.cc.
References DBUG_ASSERT.
00628 { 00629 uint i, lower_bound= 0; 00630 00631 /* 00632 Function will work without this assertion but result would be meaningless. 00633 */ 00634 DBUG_ASSERT(higher_bound > 0 && t >= range_boundaries[0]); 00635 00636 /* 00637 Do binary search for minimal interval which contain t. We preserve: 00638 range_boundaries[lower_bound] <= t < range_boundaries[higher_bound] 00639 invariant and decrease this higher_bound - lower_bound gap twice 00640 times on each step. 00641 */ 00642 00643 while (higher_bound - lower_bound > 1) 00644 { 00645 i= (lower_bound + higher_bound) >> 1; 00646 if (range_boundaries[i] <= t) 00647 lower_bound= i; 00648 else 00649 higher_bound= i; 00650 } 00651 return lower_bound; 00652 }
| static const TRAN_TYPE_INFO* find_transition_type | ( | my_time_t | t, | |
| const TIME_ZONE_INFO * | sp | |||
| ) | [static] |
Definition at line 668 of file tztime.cc.
References st_time_zone_info::ats, st_time_zone_info::fallback_tti, find_time_range(), st_time_zone_info::timecnt, st_time_zone_info::ttis, st_time_zone_info::types, and unlikely.
00669 { 00670 if (unlikely(sp->timecnt == 0 || t < sp->ats[0])) 00671 { 00672 /* 00673 If we have not any transitions or t is before first transition let 00674 us use fallback time type. 00675 */ 00676 return sp->fallback_tti; 00677 } 00678 00679 /* 00680 Do binary search for minimal interval between transitions which 00681 contain t. With this localtime_r on real data may takes less 00682 time than with linear search (I've seen 30% speed up). 00683 */ 00684 return &(sp->ttis[sp->types[find_time_range(t, sp->ats, sp->timecnt)]]); 00685 }
Here is the call graph for this function:

| static void gmt_sec_to_TIME | ( | TIME * | tmp, | |
| my_time_t | sec_in_utc, | |||
| const TIME_ZONE_INFO * | sp | |||
| ) | [static] |
Definition at line 710 of file tztime.cc.
References find_transition_type(), st_time_zone_info::leapcnt, lsinfo::ls_corr, lsinfo::ls_trans, st_time_zone_info::lsis, sec_to_TIME(), st_mysql_time::second, and ttinfo::tt_gmtoff.
00711 { 00712 const TRAN_TYPE_INFO *ttisp; 00713 const LS_INFO *lp; 00714 long corr= 0; 00715 int hit= 0; 00716 int i; 00717 00718 /* 00719 Find proper transition (and its local time type) for our sec_in_utc value. 00720 Funny but again by separating this step in function we receive code 00721 which very close to glibc's code. No wonder since they obviously use 00722 the same base and all steps are sensible. 00723 */ 00724 ttisp= find_transition_type(sec_in_utc, sp); 00725 00726 /* 00727 Let us find leap correction for our sec_in_utc value and number of extra 00728 secs to add to this minute. 00729 This loop is rarely used because most users will use time zones without 00730 leap seconds, and even in case when we have such time zone there won't 00731 be many iterations (we have about 22 corrections at this moment (2004)). 00732 */ 00733 for ( i= sp->leapcnt; i-- > 0; ) 00734 { 00735 lp= &sp->lsis[i]; 00736 if (sec_in_utc >= lp->ls_trans) 00737 { 00738 if (sec_in_utc == lp->ls_trans) 00739 { 00740 hit= ((i == 0 && lp->ls_corr > 0) || 00741 lp->ls_corr > sp->lsis[i - 1].ls_corr); 00742 if (hit) 00743 { 00744 while (i > 0 && 00745 sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && 00746 sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) 00747 { 00748 hit++; 00749 i--; 00750 } 00751 } 00752 } 00753 corr= lp->ls_corr; 00754 break; 00755 } 00756 } 00757 00758 sec_to_TIME(tmp, sec_in_utc, ttisp->tt_gmtoff - corr); 00759 00760 tmp->second+= hit; 00761 }
Here is the call graph for this function:

| byte* my_offset_tzs_get_key | ( | Time_zone_offset * | entry, | |
| uint * | length, | |||
| my_bool not_used | __attribute__((unused)) | |||
| ) |
| Time_zone* my_tz_find | ( | const String * | name, | |
| TABLE_LIST * | tz_tables | |||
| ) |
Definition at line 2213 of file tztime.cc.
References current_thd, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, hash_search(), my_hash_insert(), name, offset, offset_tzs, pthread_mutex_lock, pthread_mutex_unlock, sql_print_error(), str_to_offset(), Tz_names_entry::tz, tz_load_from_open_tables(), tz_names, tz_storage, and VOID.
02214 { 02215 Tz_names_entry *tmp_tzname; 02216 Time_zone *result_tz= 0; 02217 long offset; 02218 DBUG_ENTER("my_tz_find"); 02219 DBUG_PRINT("enter", ("time zone name='%s'", 02220 name ? ((String *)name)->c_ptr_safe() : "NULL")); 02221 DBUG_ASSERT(!time_zone_tables_exist || tz_tables || 02222 current_thd->slave_thread); 02223 02224 if (!name) 02225 DBUG_RETURN(0); 02226 02227 VOID(pthread_mutex_lock(&tz_LOCK)); 02228 02229 if (!str_to_offset(name->ptr(), name->length(), &offset)) 02230 { 02231 02232 if (!(result_tz= (Time_zone_offset *)hash_search(&offset_tzs, 02233 (const byte *)&offset, 02234 sizeof(long)))) 02235 { 02236 DBUG_PRINT("info", ("Creating new Time_zone_offset object")); 02237 02238 if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) || 02239 my_hash_insert(&offset_tzs, (const byte *) result_tz)) 02240 { 02241 result_tz= 0; 02242 sql_print_error("Fatal error: Out of memory " 02243 "while setting new time zone"); 02244 } 02245 } 02246 } 02247 else 02248 { 02249 result_tz= 0; 02250 if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names, 02251 (const byte *)name->ptr(), 02252 name->length()))) 02253 result_tz= tmp_tzname->tz; 02254 else if (time_zone_tables_exist && tz_tables) 02255 result_tz= tz_load_from_open_tables(name, tz_tables); 02256 } 02257 02258 VOID(pthread_mutex_unlock(&tz_LOCK)); 02259 02260 DBUG_RETURN(result_tz); 02261 }
Here is the call graph for this function:

Definition at line 2289 of file tztime.cc.
References close_thread_tables(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, my_tz_find(), MY_TZ_TABLES_COUNT, name, simple_open_n_lock_tables(), and tz_init_table_list().
02290 { 02291 Time_zone *tz; 02292 DBUG_ENTER("my_tz_find_with_opening_tables"); 02293 DBUG_ASSERT(thd); 02294 DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only 02295 02296 if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist) 02297 { 02298 /* 02299 Probably we have not loaded this time zone yet so let us look it up in 02300 our time zone tables. Note that if we don't have tz tables on this 02301 slave, we don't even try. 02302 */ 02303 TABLE_LIST tables[MY_TZ_TABLES_COUNT]; 02304 TABLE_LIST *dummy; 02305 TABLE_LIST **dummyp= &dummy; 02306 tz_init_table_list(tables, &dummyp); 02307 if (simple_open_n_lock_tables(thd, tables)) 02308 DBUG_RETURN(0); 02309 tz= my_tz_find(name, tables); 02310 /* We need to close tables _now_ to not pollute coming query */ 02311 close_thread_tables(thd); 02312 } 02313 DBUG_RETURN(tz); 02314 }
Here is the call graph for this function:

| void my_tz_free | ( | ) |
Definition at line 1752 of file tztime.cc.
References free_root(), hash_free(), MYF, offset_tzs, pthread_mutex_destroy, tz_names, tz_storage, and VOID.
01753 { 01754 if (tz_inited) 01755 { 01756 tz_inited= 0; 01757 VOID(pthread_mutex_destroy(&tz_LOCK)); 01758 hash_free(&offset_tzs); 01759 hash_free(&tz_names); 01760 free_root(&tz_storage, MYF(0)); 01761 } 01762 }
Here is the call graph for this function:

| TABLE_LIST* my_tz_get_table_list | ( | THD * | thd, | |
| TABLE_LIST *** | global_next_ptr | |||
| ) |
Definition at line 1511 of file tztime.cc.
References DBUG_ENTER, DBUG_RETURN, fake_time_zone_tables_list, MY_TZ_TABLES_COUNT, and tz_init_table_list().
01512 { 01513 TABLE_LIST *tz_tabs; 01514 DBUG_ENTER("my_tz_get_table_list"); 01515 01516 if (!time_zone_tables_exist) 01517 DBUG_RETURN(0); 01518 01519 if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 01520 MY_TZ_TABLES_COUNT))) 01521 DBUG_RETURN(&fake_time_zone_tables_list); 01522 01523 tz_init_table_list(tz_tabs, global_next_ptr); 01524 01525 DBUG_RETURN(tz_tabs); 01526 }
Here is the call graph for this function:

Definition at line 1555 of file tztime.cc.
References alloc_root(), bzero, close_thread_tables(), db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table::field, st_table::file, global_system_variables, HA_ERR_END_OF_FILE, handler::ha_index_end(), handler::ha_index_init(), hash_free(), hash_init, handler::index_first(), handler::index_next(), init_alloc_root(), lsinfo::ls_corr, lsinfo::ls_trans, my_charset_latin1, my_hash_insert(), MY_MUTEX_INIT_FAST, my_offset_tzs_get_key(), my_pthread_setspecific_ptr, my_tz_find(), my_tz_free(), my_tz_names_get_key(), my_tz_SYSTEM, MY_TZ_TABLES_COUNT, Tz_names_entry::name, offset_tzs, pthread_mutex_init, st_table::record, String::set(), simple_open_n_lock_tables(), sql_print_error(), sql_print_warning(), STRING_WITH_LEN, system_variables::time_zone, TL_READ, Tz_names_entry::tz, tz_init_table_list(), tz_lsis, TZ_MAX_LEAPS, tz_names, tz_storage, st_table::use_all_columns(), Field::val_int(), and VOID.
01556 { 01557 THD *thd; 01558 TABLE_LIST *tables= 0; 01559 TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr; 01560 TABLE *table; 01561 Tz_names_entry *tmp_tzname; 01562 my_bool return_val= 1; 01563 char db[]= "mysql"; 01564 int res; 01565 DBUG_ENTER("my_tz_init"); 01566 01567 /* 01568 To be able to run this from boot, we allocate a temporary THD 01569 */ 01570 if (!(thd= new THD)) 01571 DBUG_RETURN(1); 01572 thd->thread_stack= (char*) &thd; 01573 thd->store_globals(); 01574 01575 /* Init all memory structures that require explicit destruction */ 01576 if (hash_init(&tz_names, &my_charset_latin1, 20, 01577 0, 0, (hash_get_key)my_tz_names_get_key, 0, 0)) 01578 { 01579 sql_print_error("Fatal error: OOM while initializing time zones"); 01580 goto end; 01581 } 01582 if (hash_init(&offset_tzs, &my_charset_latin1, 26, 0, 0, 01583 (hash_get_key)my_offset_tzs_get_key, 0, 0)) 01584 { 01585 sql_print_error("Fatal error: OOM while initializing time zones"); 01586 hash_free(&tz_names); 01587 goto end; 01588 } 01589 init_alloc_root(&tz_storage, 32 * 1024, 0); 01590 VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST)); 01591 tz_inited= 1; 01592 01593 /* Add 'SYSTEM' time zone to tz_names hash */ 01594 if (!(tmp_tzname= new (&tz_storage) Tz_names_entry())) 01595 { 01596 sql_print_error("Fatal error: OOM while initializing time zones"); 01597 goto end_with_cleanup; 01598 } 01599 tmp_tzname->name.set(STRING_WITH_LEN("SYSTEM"), &my_charset_latin1); 01600 tmp_tzname->tz= my_tz_SYSTEM; 01601 if (my_hash_insert(&tz_names, (const byte *)tmp_tzname)) 01602 { 01603 sql_print_error("Fatal error: OOM while initializing time zones"); 01604 goto end_with_cleanup; 01605 } 01606 01607 if (bootstrap) 01608 { 01609 /* If we are in bootstrap mode we should not load time zone tables */ 01610 return_val= time_zone_tables_exist= 0; 01611 goto end_with_setting_default_tz; 01612 } 01613 01614 /* 01615 After this point all memory structures are inited and we even can live 01616 without time zone description tables. Now try to load information about 01617 leap seconds shared by all time zones. 01618 */ 01619 01620 thd->set_db(db, sizeof(db)-1); 01621 bzero((char*) &tables_buff, sizeof(TABLE_LIST)); 01622 tables_buff[0].alias= tables_buff[0].table_name= 01623 (char*)"time_zone_leap_second"; 01624 tables_buff[0].lock_type= TL_READ; 01625 tables_buff[0].db= db; 01626 /* 01627 Fill TABLE_LIST for the rest of the time zone describing tables 01628 and link it to first one. 01629 */ 01630 last_global_next_ptr= &(tables_buff[0].next_global); 01631 tz_init_table_list(tables_buff + 1, &last_global_next_ptr); 01632 01633 if (simple_open_n_lock_tables(thd, tables_buff)) 01634 { 01635 sql_print_warning("Can't open and lock time zone table: %s " 01636 "trying to live without them", thd->net.last_error); 01637 /* We will try emulate that everything is ok */ 01638 return_val= time_zone_tables_exist= 0; 01639 goto end_with_setting_default_tz; 01640 } 01641 tables= tables_buff + 1; 01642 01643 /* 01644 Now we are going to load leap seconds descriptions that are shared 01645 between all time zones that use them. We are using index for getting 01646 records in proper order. Since we share the same MEM_ROOT between 01647 all time zones we just allocate enough memory for it first. 01648 */ 01649 if (!(tz_lsis= (LS_INFO*) alloc_root(&tz_storage, 01650 sizeof(LS_INFO) * TZ_MAX_LEAPS))) 01651 { 01652 sql_print_error("Fatal error: Out of memory while loading " 01653 "mysql.time_zone_leap_second table"); 01654 goto end_with_close; 01655 } 01656 01657 table= tables_buff[0].table; 01658 /* 01659 It is OK to ignore ha_index_init()/ha_index_end() return values since 01660 mysql.time_zone* tables are MyISAM and these operations always succeed 01661 for MyISAM. 01662 */ 01663 (void)table->file->ha_index_init(0, 1); 01664 table->use_all_columns(); 01665 01666 tz_leapcnt= 0; 01667 01668 res= table->file->index_first(table->record[0]); 01669 01670 while (!res) 01671 { 01672 if (tz_leapcnt + 1 > TZ_MAX_LEAPS) 01673 { 01674 sql_print_error("Fatal error: While loading mysql.time_zone_leap_second" 01675 " table: too much leaps"); 01676 table->file->ha_index_end(); 01677 goto end_with_close; 01678 } 01679 01680 tz_lsis[tz_leapcnt].ls_trans= (my_time_t)table->field[0]->val_int(); 01681 tz_lsis[tz_leapcnt].ls_corr= (long)table->field[1]->val_int(); 01682 01683 tz_leapcnt++; 01684 01685 DBUG_PRINT("info", 01686 ("time_zone_leap_second table: tz_leapcnt=%u tt_time=%lld offset=%ld", 01687 tz_leapcnt, (longlong)tz_lsis[tz_leapcnt-1].ls_trans, 01688 tz_lsis[tz_leapcnt-1].ls_corr)); 01689 01690 res= table->file->index_next(table->record[0]); 01691 } 01692 01693 (void)table->file->ha_index_end(); 01694 01695 if (res != HA_ERR_END_OF_FILE) 01696 { 01697 sql_print_error("Fatal error: Error while loading " 01698 "mysql.time_zone_leap_second table"); 01699 goto end_with_close; 01700 } 01701 01702 /* 01703 Loading of info about leap seconds succeeded 01704 */ 01705 01706 return_val= 0; 01707 01708 01709 end_with_setting_default_tz: 01710 /* If we have default time zone try to load it */ 01711 if (default_tzname) 01712 { 01713 String tmp_tzname(default_tzname, &my_charset_latin1); 01714 if (!(global_system_variables.time_zone= my_tz_find(&tmp_tzname, tables))) 01715 { 01716 sql_print_error("Fatal error: Illegal or unknown default time zone '%s'", 01717 default_tzname); 01718 return_val= 1; 01719 } 01720 } 01721 01722 end_with_close: 01723 thd->version--; /* Force close to free memory */ 01724 close_thread_tables(thd); 01725 01726 end_with_cleanup: 01727 01728 /* if there were error free time zone describing structs */ 01729 if (return_val) 01730 my_tz_free(); 01731 end: 01732 delete thd; 01733 if (org_thd) 01734 org_thd->store_globals(); /* purecov: inspected */ 01735 else 01736 { 01737 /* Remember that we don't have a THD */ 01738 my_pthread_setspecific_ptr(THR_THD, 0); 01739 my_pthread_setspecific_ptr(THR_MALLOC, 0); 01740 } 01741 DBUG_RETURN(return_val); 01742 }
Here is the call graph for this function:

| byte* my_tz_names_get_key | ( | Tz_names_entry * | entry, | |
| uint * | length, | |||
| my_bool not_used | __attribute__((unused)) | |||
| ) |
| static my_bool prepare_tz_info | ( | TIME_ZONE_INFO * | sp, | |
| MEM_ROOT * | storage | |||
| ) | [static] |
Definition at line 315 of file tztime.cc.
References st_time_zone_info::fallback_tti, LINT_INIT, MY_TIME_T_MIN, st_time_zone_info::revcnt, st_time_zone_info::timecnt, ttinfo::tt_isdst, st_time_zone_info::ttis, st_time_zone_info::typecnt, and TZ_MAX_REV_RANGES.
00316 { 00317 my_time_t cur_t= MY_TIME_T_MIN; 00318 my_time_t cur_l, end_t, end_l; 00319 my_time_t cur_max_seen_l= MY_TIME_T_MIN; 00320 long cur_offset, cur_corr, cur_off_and_corr; 00321 uint next_trans_idx, next_leap_idx; 00322 uint i; 00323 /* 00324 Temporary arrays where we will store tables. Needed because 00325 we don't know table sizes ahead. (Well we can estimate their 00326 upper bound but this will take extra space.) 00327 */ 00328 my_time_t revts[TZ_MAX_REV_RANGES]; 00329 REVT_INFO revtis[TZ_MAX_REV_RANGES]; 00330 00331 LINT_INIT(end_l); 00332 00333 /* 00334 Let us setup fallback time type which will be used if we have not any 00335 transitions or if we have moment of time before first transition. 00336 We will find first non-DST local time type and use it (or use first 00337 local time type if all of them are DST types). 00338 */ 00339 for (i= 0; i < sp->typecnt && sp->ttis[i].tt_isdst; i++) 00340 /* no-op */ ; 00341 if (i == sp->typecnt) 00342 i= 0; 00343 sp->fallback_tti= &(sp->ttis[i]); 00344 00345 00346 /* 00347 Let us build shifted my_time_t -> my_time_t map. 00348 */ 00349 sp->revcnt= 0; 00350 00351 /* Let us find initial offset */ 00352 if (sp->timecnt == 0 || cur_t < sp->ats[0]) 00353 { 00354 /* 00355 If we have not any transitions or t is before first transition we are using 00356 already found fallback time type which index is already in i. 00357 */ 00358 next_trans_idx= 0; 00359 } 00360 else 00361 { 00362 /* cur_t == sp->ats[0] so we found transition */ 00363 i= sp->types[0]; 00364 next_trans_idx= 1; 00365 } 00366 00367 cur_offset= sp->ttis[i].tt_gmtoff; 00368 00369 00370 /* let us find leap correction... unprobable, but... */ 00371 for (next_leap_idx= 0; next_leap_idx < sp->leapcnt && 00372 cur_t >= sp->lsis[next_leap_idx].ls_trans; 00373 ++next_leap_idx) 00374 continue; 00375 00376 if (next_leap_idx > 0) 00377 cur_corr= sp->lsis[next_leap_idx - 1].ls_corr; 00378 else 00379 cur_corr= 0; 00380 00381 /* Iterate trough t space */ 00382 while (sp->revcnt < TZ_MAX_REV_RANGES - 1) 00383 { 00384 cur_off_and_corr= cur_offset - cur_corr; 00385 00386 /* 00387 We assuming that cur_t could be only overflowed downwards, 00388 we also assume that end_t won't be overflowed in this case. 00389 */ 00390 if (cur_off_and_corr < 0 && 00391 cur_t < MY_TIME_T_MIN - cur_off_and_corr) 00392 cur_t= MY_TIME_T_MIN - cur_off_and_corr; 00393 00394 cur_l= cur_t + cur_off_and_corr; 00395 00396 /* 00397 Let us choose end_t as point before next time type change or leap 00398 second correction. 00399 */ 00400 end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1: 00401 MY_TIME_T_MAX, 00402 (next_leap_idx < sp->leapcnt) ? 00403 sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX); 00404 /* 00405 again assuming that end_t can be overlowed only in positive side 00406 we also assume that end_t won't be overflowed in this case. 00407 */ 00408 if (cur_off_and_corr > 0 && 00409 end_t > MY_TIME_T_MAX - cur_off_and_corr) 00410 end_t= MY_TIME_T_MAX - cur_off_and_corr; 00411 00412 end_l= end_t + cur_off_and_corr; 00413 00414 00415 if (end_l > cur_max_seen_l) 00416 { 00417 /* We want special handling in the case of first range */ 00418 if (cur_max_seen_l == MY_TIME_T_MIN) 00419 { 00420 revts[sp->revcnt]= cur_l; 00421 revtis[sp->revcnt].rt_offset= cur_off_and_corr; 00422 revtis[sp->revcnt].rt_type= 0; 00423 sp->revcnt++; 00424 cur_max_seen_l= end_l; 00425 } 00426 else 00427 { 00428 if (cur_l > cur_max_seen_l + 1) 00429 { 00430 /* We have a spring time-gap and we are not at the first range */ 00431 revts[sp->revcnt]= cur_max_seen_l + 1; 00432 revtis[sp->revcnt].rt_offset= revtis[sp->revcnt-1].rt_offset; 00433 revtis[sp->revcnt].rt_type= 1; 00434 sp->revcnt++; 00435 if (sp->revcnt == TZ_MAX_TIMES + TZ_MAX_LEAPS + 1) 00436 break; /* That was too much */ 00437 cur_max_seen_l= cur_l - 1; 00438 } 00439 00440 /* Assume here end_l > cur_max_seen_l (because end_l>=cur_l) */ 00441 00442 revts[sp->revcnt]= cur_max_seen_l + 1; 00443 revtis[sp->revcnt].rt_offset= cur_off_and_corr; 00444 revtis[sp->revcnt].rt_type= 0; 00445 sp->revcnt++; 00446 cur_max_seen_l= end_l; 00447 } 00448 } 00449 00450 if (end_t == MY_TIME_T_MAX || 00451 (cur_off_and_corr > 0) && 00452 (end_t >= MY_TIME_T_MAX - cur_off_and_corr)) 00453 /* end of t space */ 00454 break; 00455 00456 cur_t= end_t + 1; 00457 00458 /* 00459 Let us find new offset and correction. Because of our choice of end_t 00460 cur_t can only be point where new time type starts or/and leap 00461 correction is performed. 00462 */ 00463 if (sp->timecnt != 0 && cur_t >= sp->ats[0]) /* else reuse old offset */ 00464 if (next_trans_idx < sp->timecnt && 00465 cur_t == sp->ats[next_trans_idx]) 00466 { 00467 /* We are at offset point */ 00468 cur_offset= sp->ttis[sp->types[next_trans_idx]].tt_gmtoff; 00469 ++next_trans_idx; 00470 } 00471 00472 if (next_leap_idx < sp->leapcnt && 00473 cur_t == sp->lsis[next_leap_idx].ls_trans) 00474 { 00475 /* we are at leap point */ 00476 cur_corr= sp->lsis[next_leap_idx].ls_corr; 00477 ++next_leap_idx; 00478 } 00479 } 00480 00481 /* check if we have had enough space */ 00482 if (sp->revcnt == TZ_MAX_REV_RANGES - 1) 00483 return 1; 00484 00485 /* set maximum end_l as finisher */ 00486 revts[sp->revcnt]= end_l; 00487 00488 /* Allocate arrays of proper size in sp and copy result there */ 00489 if (!(sp->revts= (my_time_t *)alloc_root(storage, 00490 sizeof(my_time_t) * (sp->revcnt + 1))) || 00491 !(sp->revtis= (REVT_INFO *)alloc_root(storage, 00492 sizeof(REVT_INFO) * sp->revcnt))) 00493 return 1; 00494 00495 memcpy(sp->revts, revts, sizeof(my_time_t) * (sp->revcnt + 1)); 00496 memcpy(sp->revtis, revtis, sizeof(REVT_INFO) * sp->revcnt); 00497 00498 return 0; 00499 }

