OSDN Git Service

Fix error in call to GetTimeZoneInformation().
[tortoisegit/TortoiseGitJp.git] / src / Git / GitRev.cpp
1 #include "StdAfx.h"\r
2 #include "GitRev.h"\r
3 #include "Git.h"\r
4 \r
5 // provide an ASSERT macro for when compiled without MFC\r
6 #if !defined ASSERT\r
7         #ifdef _DEBUG\r
8                 #define ASSERT(x) {if(!(x)) _asm{int 0x03}}\r
9         #else\r
10                 #define ASSERT(x)       \r
11         #endif\r
12 #endif\r
13 \r
14 \r
15 GitRev::GitRev(void)\r
16 {\r
17         m_Action=0;\r
18         m_IsFull = 0;\r
19         m_IsUpdateing = 0;\r
20 }\r
21 \r
22 GitRev::~GitRev(void)\r
23 {\r
24 }\r
25 \r
26 #if 0\r
27 GitRev::GitRev(GitRev & rev)\r
28 {\r
29 }\r
30 GitRev& GitRev::operator=(GitRev &rev)\r
31 {\r
32         return *this;\r
33 }\r
34 #endif\r
35 void GitRev::Clear()\r
36 {\r
37         this->m_Action=0;\r
38         this->m_Files.Clear();\r
39         this->m_Action=0;\r
40         this->m_ParentHash.clear();\r
41         m_CommitterName.Empty();\r
42         m_CommitterEmail.Empty();\r
43         m_Body.Empty();\r
44         m_Subject.Empty();\r
45         m_CommitHash.Empty();\r
46         m_Mark=0;\r
47 \r
48 }\r
49 int GitRev::CopyFrom(GitRev &rev,bool OmitParentAndMark)\r
50 {\r
51         m_AuthorName    =rev.m_AuthorName       ;\r
52         m_AuthorEmail   =rev.m_AuthorEmail      ;\r
53         m_AuthorDate    =rev.m_AuthorDate       ;\r
54         m_CommitterName =rev.m_CommitterName    ;\r
55         m_CommitterEmail=rev.m_CommitterEmail;\r
56         m_CommitterDate =rev.m_CommitterDate    ;\r
57         m_Subject               =rev.m_Subject          ;\r
58         m_Body                  =rev.m_Body                     ;\r
59         m_CommitHash    =rev.m_CommitHash       ;\r
60         m_Files                 =rev.m_Files                    ;       \r
61         m_Action                =rev.m_Action           ;\r
62 \r
63         if(!OmitParentAndMark)\r
64         {\r
65                 m_ParentHash    =rev.m_ParentHash       ;\r
66                 m_Mark                  =rev.m_Mark;\r
67         }\r
68         return 0;\r
69 }\r
70 int GitRev::ParserFromLog(BYTE_VECTOR &log,int start)\r
71 {\r
72         int pos=start;\r
73         CString one;\r
74         CString key;\r
75         CString text;\r
76         BYTE_VECTOR filelist;\r
77         BYTE mode=0;\r
78         CTGitPath  path;\r
79         this->m_Files.Clear();\r
80     m_Action=0;\r
81         int begintime=0;\r
82         int filebegin=-1;\r
83 \r
84         while( pos < log.size() && pos>=0)\r
85         {\r
86                 \r
87                 //one=log.Tokenize(_T("\n"),pos);\r
88                 if(log[pos]==_T('#') && log[pos+1] == _T('<') && log[pos+3] == _T('>'))\r
89                 {\r
90                         //text = one.Right(one.GetLength()-4);\r
91                         text.Empty();\r
92                         g_Git.StringAppend(&text,&log[pos+4],CP_UTF8);\r
93                         mode = log[pos+2];\r
94                         \r
95                         switch(mode)\r
96                         {\r
97                         case LOG_REV_ITEM_BEGIN:\r
98                                 begintime++;\r
99                                 if(begintime>1)\r
100                                         break;\r
101                                 else\r
102                                         this->Clear();\r
103                                 break;\r
104                         case LOG_REV_AUTHOR_NAME:\r
105                                 this->m_AuthorName = text;\r
106                                 break;\r
107                         case LOG_REV_AUTHOR_EMAIL:\r
108                                 this->m_AuthorEmail = text;\r
109                                 break;\r
110                         case LOG_REV_AUTHOR_DATE:\r
111                                 this->m_AuthorDate =ConverFromString(text);\r
112                                 break;\r
113                         case LOG_REV_COMMIT_NAME:\r
114                                 this->m_CommitterName = text;\r
115                                 break;\r
116                         case LOG_REV_COMMIT_EMAIL:\r
117                                 this->m_CommitterEmail = text;\r
118                                 break;\r
119                         case LOG_REV_COMMIT_DATE:\r
120                                 this->m_CommitterDate =ConverFromString(text);\r
121                                 break;\r
122                         case LOG_REV_COMMIT_SUBJECT:\r
123                                 this->m_Subject = text;\r
124                                 break;\r
125                         case LOG_REV_COMMIT_BODY:\r
126                                 this->m_Body = text +_T("\n");\r
127                                 break;\r
128                         case LOG_REV_COMMIT_HASH:\r
129                                 this->m_CommitHash = text.Right(40);\r
130                                 if(text.GetLength()>40)\r
131                                 {\r
132                                         this->m_Mark=text[0];\r
133                                 }\r
134                                 break;\r
135                         case LOG_REV_COMMIT_PARENT:\r
136                                 while(text.GetLength()>0)\r
137                                 {\r
138                                         this->m_ParentHash.insert(this->m_ParentHash.end(),text.Left(40));\r
139                                         if(text.GetLength()>40)\r
140                                                 text=text.Right(text.GetLength()-41);\r
141                                         else\r
142                                                 break;\r
143                                 }\r
144                                 break;\r
145                         case LOG_REV_COMMIT_FILE:\r
146                                 break;\r
147                         }\r
148                 }else\r
149                 {\r
150                         switch(mode)\r
151                         {\r
152 //                      case LOG_REV_COMMIT_BODY:\r
153 //                              this->m_Body += one+_T("\n");\r
154 //                              break;\r
155                         case LOG_REV_COMMIT_FILE:\r
156                                 //filelist += one +_T("\n");\r
157                                 //filelist.append(log,pos,log.find(0,pos));\r
158                                 if(filebegin<0)\r
159                                         filebegin=pos;\r
160                                 break;\r
161                         }\r
162                 }\r
163                 \r
164                 if(begintime>1)\r
165                 {\r
166                         break;\r
167                 }\r
168 \r
169                 //find next string start \r
170                 pos=log.findNextString(pos);\r
171         }\r
172         \r
173         if(filebegin>=0)\r
174         {\r
175                 filelist.append(log,filebegin,pos);     \r
176                 this->m_Files.ParserFromLog(filelist);\r
177                 this->m_Action=this->m_Files.GetAction();\r
178         }\r
179         return pos;\r
180 }\r
181 \r
182 CTime GitRev::ConverFromString(CString input)\r
183 {\r
184         // pick up date from string\r
185         CTime tm(_wtoi(input.Mid(0,4)),\r
186                          _wtoi(input.Mid(5,2)),\r
187                          _wtoi(input.Mid(8,2)),\r
188                          _wtoi(input.Mid(11,2)),\r
189                          _wtoi(input.Mid(14,2)),\r
190                          _wtoi(input.Mid(17,2)),\r
191                          0);\r
192         // pick up utc offset\r
193         CString sign = input.Mid(20,1);         // + or -\r
194         int hoursOffset =  _wtoi(input.Mid(21,2));\r
195         int minsOffset = _wtoi(input.Mid(23,2));\r
196         if ( sign == "-" )\r
197         {\r
198                 hoursOffset = -hoursOffset;\r
199                 minsOffset = -minsOffset;\r
200         }\r
201         // make a timespan object with this value\r
202         CTimeSpan offset( 0, hoursOffset, minsOffset, 0 );\r
203         // we have to subtract this from the time given to get UTC\r
204         tm -= offset;\r
205         // get local timezone\r
206         SYSTEMTIME sysTime;\r
207         tm.GetAsSystemTime( sysTime );\r
208         TIME_ZONE_INFORMATION timeZone;\r
209         if ( GetTimeZoneInformation( &timeZone ) == TIME_ZONE_ID_INVALID )\r
210         {\r
211                 ASSERT(false);\r
212         }\r
213         else\r
214         {\r
215                 SYSTEMTIME local;\r
216                 if ( SystemTimeToTzSpecificLocalTime( &timeZone, &sysTime, &local ) )\r
217                 {\r
218                         sysTime = local;\r
219                 }\r
220                 else\r
221                 {\r
222                         ASSERT(false);\r
223                 }\r
224         }\r
225         tm = CTime( sysTime, 0 );\r
226         return tm;\r
227 }\r
228 \r
229 int GitRev::SafeFetchFullInfo(CGit *git)\r
230 {\r
231         if(InterlockedExchange(&m_IsUpdateing,TRUE) == FALSE)\r
232         {\r
233                 //GitRev rev;\r
234                 BYTE_VECTOR onelog;\r
235                 TCHAR oldmark=this->m_Mark;\r
236         \r
237                 git->GetLog(onelog,m_CommitHash,NULL,1,CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE|CGit::LOG_INFO_DETECT_COPYRENAME);\r
238                 CString oldhash=m_CommitHash;\r
239                 GIT_REV_LIST oldlist=this->m_ParentHash;\r
240                 ParserFromLog(onelog);\r
241                 \r
242                 //ASSERT(oldhash==m_CommitHash);\r
243                 if(oldmark!=0)\r
244                         this->m_Mark=oldmark;  //parser full log will cause old mark overwrited. \r
245                                                                //So we need keep old bound mark.\r
246                 this->m_ParentHash=oldlist;\r
247                 InterlockedExchange(&m_IsUpdateing,FALSE);\r
248                 InterlockedExchange(&m_IsFull,TRUE);\r
249                 return 0;\r
250         }\r
251         return -1;\r
252 }