]> git.tdb.fi Git - libs/core.git/blob - source/time/unix/timezone.cpp
Move non-oneliner functions out of RefPtr class declaration
[libs/core.git] / source / time / unix / timezone.cpp
1 #include <unistd.h>
2 #include <fcntl.h>
3 #include "timestamp.h"
4 #include "timezone.h"
5 #include "utils.h"
6
7 using namespace std;
8
9 namespace {
10
11 long get_long(char *&ptr)
12 {
13         long result = 0;
14         for(unsigned i=0; i<4; ++i)
15                 result = (result<<8)+static_cast<unsigned char >(*ptr++);
16         return result;
17 }
18
19 }
20
21
22 namespace Msp {
23 namespace Time {
24
25 TimeZone TimeZone::platform_get_local_timezone()
26 {
27         int fd = open("/etc/localtime", O_RDONLY);
28         if(fd!=-1)
29         {
30                 char hdr[44];
31                 int len = read(fd, hdr, sizeof(hdr));
32                 long gmtoff = -1;
33                 string name;
34                 if(len==44 && hdr[0]=='T' && hdr[1]=='Z' && hdr[2]=='i' && hdr[3]=='f')
35                 {
36                         char *ptr = hdr+20;
37                         long isgmtcnt = get_long(ptr);
38                         long isstdcnt = get_long(ptr);
39                         long leapcnt = get_long(ptr);
40                         long timecnt = get_long(ptr);
41                         long typecnt = get_long(ptr);
42                         long charcnt = get_long(ptr);
43                         int size = timecnt*5+typecnt*6+isgmtcnt+isstdcnt+leapcnt*8+charcnt;
44                         char *buf = new char[size];
45                         len = read(fd, buf, size);
46                         if(len==size)
47                         {
48                                 ptr = buf;
49                                 int index = -1;
50                                 time_t cur_time = Msp::Time::now().to_unixtime();
51                                 for(int i=0; i<timecnt; ++i)
52                                         if(get_long(ptr)<=cur_time)
53                                                 index = i;
54
55                                 if(index>0)
56                                         index = ptr[index];
57                                 ptr += timecnt;
58
59                                 int abbrind = 0;
60                                 for(int i=0; i<typecnt; ++i)
61                                 {
62                                         if((index>=0 && i==index) || (index<0 && !ptr[4] && gmtoff==-1))
63                                         {
64                                                 gmtoff = get_long(ptr);
65                                                 ++ptr;
66                                                 abbrind = *ptr++;
67                                         }
68                                         else
69                                                 ptr += 6;
70                                 }
71
72                                 name = ptr+abbrind;
73                         }
74                         delete[] buf;
75                 }
76                 close(fd);
77
78                 if(gmtoff!=-1)
79                         return TimeZone(gmtoff/60, name);
80         }
81         return TimeZone();
82 }
83
84 } // namespace Time
85 } // namespace Msp