1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the License.html file in the root of the source tree.
5 */
6
7 // RegressionTest.cpp : Defines the entry point for the console application.
8 //
9
10 #include <iostream>
11 #include "tchar.h"
12 #include "MediaInfoDLL/MediaInfoDLL.h"
13 #include "ZenLib/ZtringListListF.h"
14 #include "ZenLib/File.h"
15 #include "ZenLib/FileName.h"
16 #include "ZenLib/Dir.h"
17 #include "RegressionTest/RegressionTest.h"
18 #include "MediaInfo/MediaInfo_Events.h"
19 #include "ctime"
20 using namespace MediaInfoDLL;
21 using namespace ZenLib;
22 using namespace std;
23
24 /***************************************************************************/
25 /* Events */
26 /***************************************************************************/
27
28
29 struct UserHandle_struct
30 {
31 Ztring Name;
32 int64u Size;
33 File Time_File;
34 time_t Time_Start;
35 Ztring Parser;
36
UserHandle_structUserHandle_struct37 UserHandle_struct()
38 {
39 Size=(int64u)-1;
40 Time_Start=(time_t)-1;
41 }
42 };
43
Basic_General_Start_0(struct MediaInfo_Event_General_Start_0 * Event,struct UserHandle_struct * UserHandle)44 void Basic_General_Start_0 (struct MediaInfo_Event_General_Start_0* Event, struct UserHandle_struct* UserHandle)
45 {
46 if (Event->FileName_Unicode)
47 {
48 UserHandle->Name=Event->FileName_Unicode;
49 UserHandle->Time_File.Write(Ztring(Event->FileName_Unicode)+__T(';'));
50 }
51 UserHandle->Size=Event->Stream_Size;
52 UserHandle->Time_Start=time(NULL);
53 UserHandle->Parser.clear();
54 }
55
Basic_General_End_0(struct MediaInfo_Event_General_End_0 * Event,struct UserHandle_struct * UserHandle)56 void Basic_General_End_0 (struct MediaInfo_Event_General_End_0* Event, struct UserHandle_struct* UserHandle)
57 {
58 time_t Diff;
59 if (UserHandle->Time_Start!=(time_t)-1)
60 Diff=time(NULL)-UserHandle->Time_Start;
61 else
62 Diff=(time_t)-1;
63
64 if (Diff!=(time_t)-1)
65 UserHandle->Time_File.Write(__T(';')+Ztring::ToZtring(UserHandle->Size)+__T(';')+Ztring::ToZtring(Diff)+EOL);
66
67 UserHandle->Time_Start=(time_t)-1;
68 UserHandle->Parser.clear();
69 }
70
Basic_General_Parser_Selected_0(struct MediaInfo_Event_General_Parser_Selected_0 * Event,struct UserHandle_struct * UserHandle)71 void Basic_General_Parser_Selected_0 (struct MediaInfo_Event_General_Parser_Selected_0* Event, struct UserHandle_struct* UserHandle)
72 {
73 if (Event->Name)
74 UserHandle->Parser.From_UTF8(Event->Name);
75 else
76 UserHandle->Parser.clear();
77 }
78
79 /***************************************************************************/
80 /* The callback function */
81 /***************************************************************************/
82
83 #define CASE(_PARSER,_EVENT,_VERSION) \
84 case MediaInfo_Event_##_PARSER##_##_EVENT : if (EventVersion==_VERSION && Data_Size>=sizeof(struct MediaInfo_Event_##_PARSER##_##_EVENT##_##_VERSION)) _PARSER##_##_EVENT##_##_VERSION((struct MediaInfo_Event_##_PARSER##_##_EVENT##_##_VERSION*)Data_Content, UserHandle); break;
85
Basic_Event_CallBackFunction(unsigned char * Data_Content,size_t Data_Size,void * UserHandle_Void)86 void __stdcall Basic_Event_CallBackFunction(unsigned char* Data_Content, size_t Data_Size, void* UserHandle_Void)
87 {
88 /*Retrieving UserHandle*/
89 struct UserHandle_struct* UserHandle=(struct UserHandle_struct*)UserHandle_Void;
90 struct MediaInfo_Event_Generic* Event_Generic=(struct MediaInfo_Event_Generic*) Data_Content;
91 unsigned char ParserID;
92 unsigned short EventID;
93 unsigned char EventVersion;
94
95 /*integrity tests*/
96 if (Data_Size<4)
97 return; //There is a problem
98
99 /*Retrieving EventID*/
100 ParserID =(unsigned char) ((Event_Generic->EventCode&0xFF000000)>>24);
101 EventID =(unsigned short)((Event_Generic->EventCode&0x00FFFF00)>>8 );
102 EventVersion=(unsigned char) ( Event_Generic->EventCode&0x000000FF );
103
104
105 switch (ParserID)
106 {
107 case MediaInfo_Parser_None :
108 switch (EventID)
109 {
110 case MediaInfo_Event_General_Start : if (EventVersion==0 && Data_Size>=sizeof(struct MediaInfo_Event_General_Start_0)) Basic_General_Start_0((struct MediaInfo_Event_General_Start_0*)Data_Content, UserHandle); break;
111 case MediaInfo_Event_General_End : if (EventVersion==0 && Data_Size>=sizeof(struct MediaInfo_Event_General_End_0)) Basic_General_End_0((struct MediaInfo_Event_General_End_0*)Data_Content, UserHandle); break;
112 case MediaInfo_Event_General_Parser_Selected : if (EventVersion==0 && Data_Size>=sizeof(struct MediaInfo_Event_General_Parser_Selected_0)) Basic_General_Parser_Selected_0((struct MediaInfo_Event_General_Parser_Selected_0*)Data_Content, UserHandle); break;
113 default : ;
114 }
115 break;
116 default : ; //ParserID is unknown
117 }
118 }
119
120 /***************************************************************************/
121 /* The callback function */
122 /***************************************************************************/
123
124
RegressionTest_Basic(Ztring Files,Ztring DataBaseDirectory,int32u Scenario)125 void RegressionTest_Basic(Ztring Files, Ztring DataBaseDirectory, int32u Scenario)
126 {
127 /*
128 //One per one
129 ZtringList List=Dir::GetAllFileNames(Files);
130 for (size_t Pos=0; Pos<List.size(); Pos++)
131 {
132 std::cout<<List[Pos].To_Local()<<endl;
133 MediaInfoDLL_Load();
134 MediaInfoList* MIL=new MediaInfoList;
135 MIL->Open(List[Pos]);
136 delete MIL;
137 MediaInfoDLL_UnLoad();
138 File::Move(L"C:\\Temp\\Debug_MemoryLeak.txt", L"C:\\Temp\\"+ZenLib::FileName(List[Pos]).Name_Get()+L"."+ZenLib::FileName(List[Pos]).Extension_Get()+L"."+Ztring::ToZtring(Pos)+L".txt");
139 }
140 */
141
142 /* Old
143 ZtringListListF* Ref=new ZtringListListF[Stream_Max];
144 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
145 if (File::Exists(DataBaseDirectory+__T("\\Basic\\Ref\\")+Ztring::ToZtring(StreamKind)+__T(".csv")))
146 Ref[StreamKind].Load(DataBaseDirectory+__T("\\Basic\\Ref\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
147
148 ZtringListListF* New=new ZtringListListF[Stream_Max];
149
150 MediaInfoList MIL;
151 struct UserHandle_struct UserHandle;
152
153 //Times
154 wostringstream Event_CallBackFunction_Text;
155 Event_CallBackFunction_Text<<__T("CallBack=memory://")<<(MediaInfo_int64u)Basic_Event_CallBackFunction<<__T(";UserHandler=memory://")<<(MediaInfo_int64u)&UserHandle;
156 MIL.Option(__T("File_Event_CallBackFunction"), Event_CallBackFunction_Text.str());
157 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\Diff")))
158 Dir::Create(DataBaseDirectory+__T("\\Basic\\Diff"));
159 File::Delete(DataBaseDirectory+__T("\\Basic\\Diff\\Times.csv"));
160 UserHandle.Time_File.Open(DataBaseDirectory+__T("\\Basic\\Diff\\Times.csv"), File::Access_Write_Append);
161
162 cout<<" Analyzing"<<endl;
163 MIL.Open(Files);
164
165 cout<<" Retrieving new data"<<endl;
166 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
167 {
168 for (size_t FilePos=0; FilePos<MIL.Count_Get(); FilePos++)
169 if (MIL.Count_Get(FilePos, (stream_t)StreamKind))
170 {
171 New[StreamKind].push_back(ZtringList());
172 New[StreamKind].at(New[StreamKind].size()-1).push_back(Ztring()); //CompleteFileName
173 for (size_t LinePos=0; LinePos<MIL.Count_Get(FilePos, (stream_t)StreamKind, 0); LinePos++)
174 New[StreamKind].at(New[StreamKind].size()-1).push_back(MIL.Get(FilePos, (stream_t)StreamKind, 0, LinePos, Info_Name));
175 break;
176 }
177 }
178 for (size_t FilePos=0; FilePos<MIL.Count_Get(); FilePos++)
179 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
180 for (size_t StreamPos=0; StreamPos<MIL.Count_Get(FilePos, (stream_t)StreamKind); StreamPos++)
181 {
182 New[StreamKind].push_back(ZtringList());
183 New[StreamKind].at(New[StreamKind].size()-1).push_back(MIL.Get(FilePos, Stream_General, 0, __T("CompleteName")));
184 for (size_t LinePos=0; LinePos<MIL.Count_Get(FilePos, (stream_t)StreamKind, StreamPos); LinePos++)
185 New[StreamKind].at(New[StreamKind].size()-1).push_back(MIL.Get(FilePos, (stream_t)StreamKind, StreamPos, LinePos));
186 }
187
188 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
189 {
190 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\New")))
191 Dir::Create(DataBaseDirectory+__T("\\Basic\\New"));
192 New[StreamKind].Save(DataBaseDirectory+__T("\\Basic\\New\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
193 }
194
195 cout<<" Diff"<<endl;
196 ZtringListListF* Diff=new ZtringListListF[Stream_Max];
197 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
198 {
199 size_t Ref_Pos=1;
200 size_t New_Pos=1;
201 while (Ref_Pos<Ref[StreamKind].size() && New_Pos<New[StreamKind].size())
202 {
203 if (New[StreamKind](New_Pos, 0)!=Ref[StreamKind](Ref_Pos, 0))
204 {
205 size_t Ref_PosNext=Ref_Pos;
206 while (Ref_PosNext<Ref[StreamKind].size() && New[StreamKind](New_Pos, 0)!=Ref[StreamKind](Ref_PosNext, 0))
207 Ref_PosNext++;
208 if (Ref_PosNext==Ref[StreamKind].size()) //Ref file not found
209 {
210 Diff[StreamKind].push_back(New[StreamKind](New_Pos));
211 New_Pos++;
212 }
213 else
214 {
215 for (; Ref_Pos<Ref_PosNext; Ref_Pos++)
216 Diff[StreamKind].push_back(Ref[StreamKind](Ref_Pos));
217 }
218 }
219 else
220 {
221 bool IsDiff=false;
222 size_t LinePos_Max=max(New[StreamKind](New_Pos).size(), Ref[StreamKind](Ref_Pos).size());
223 for (size_t LinePos=1; LinePos<LinePos_Max; LinePos++)
224 if (New[StreamKind](New_Pos, LinePos)!=Ref[StreamKind](Ref_Pos, LinePos))
225 {
226 if (!IsDiff)
227 {
228 Diff[StreamKind].push_back(ZtringList());
229 Diff[StreamKind](Diff[StreamKind].size()-1, 0)=New[StreamKind](New_Pos, 0);
230 IsDiff=true;
231 }
232 Diff[StreamKind](Diff[StreamKind].size()-1, LinePos)=New[StreamKind](New_Pos, LinePos)+__T(" --- ")+Ref[StreamKind](Ref_Pos, LinePos);
233 }
234
235 Ref_Pos++;
236 New_Pos++;
237 }
238
239 }
240
241 for (; Ref_Pos<Ref[StreamKind].size(); Ref_Pos++)
242 {
243 Diff[StreamKind].push_back(ZtringList());
244 Diff[StreamKind](Diff[StreamKind].size()-1, 0)=Ref[StreamKind](Ref_Pos, 0);
245 for (size_t LinePos=1; LinePos<Ref[StreamKind][Ref_Pos].size(); LinePos++)
246 if (!Ref[StreamKind](Ref_Pos, LinePos).empty())
247 Diff[StreamKind](Diff[StreamKind].size()-1, LinePos)=__T(" --- ")+Ref[StreamKind](Ref_Pos, LinePos);
248 }
249 for (; New_Pos<New[StreamKind].size(); New_Pos++)
250 {
251 Diff[StreamKind].push_back(ZtringList());
252 Diff[StreamKind](Diff[StreamKind].size()-1, 0)=New[StreamKind](New_Pos, 0);
253 for (size_t LinePos=1; LinePos<New[StreamKind][New_Pos].size(); LinePos++)
254 if (!New[StreamKind](New_Pos, LinePos).empty())
255 Diff[StreamKind](Diff[StreamKind].size()-1, LinePos)=New[StreamKind](New_Pos, LinePos)+__T(" --- ");
256 }
257 }
258
259 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
260 {
261 if (!Diff[StreamKind].empty())
262 {
263 Diff[StreamKind].insert(Diff[StreamKind].begin(), New[StreamKind](0));
264 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\Diff")))
265 Dir::Create(DataBaseDirectory+__T("\\Basic\\Diff"));
266 Diff[StreamKind].Save(DataBaseDirectory+__T("\\Basic\\Diff\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
267 }
268 }
269 */
270
271 MediaInfoList MIL;
272 struct UserHandle_struct UserHandle;
273
274 //Times
275 wostringstream Event_CallBackFunction_Text;
276 Event_CallBackFunction_Text<<__T("CallBack=memory://")<<(MediaInfo_int64u)Basic_Event_CallBackFunction<<__T(";UserHandler=memory://")<<(MediaInfo_int64u)&UserHandle;
277 MIL.Option(__T("File_Event_CallBackFunction"), Event_CallBackFunction_Text.str());
278 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\Diff")))
279 Dir::Create(DataBaseDirectory+__T("\\Basic\\Diff"));
280 File::Delete(DataBaseDirectory+__T("\\Basic\\Diff\\Times.csv"));
281 UserHandle.Time_File.Open(DataBaseDirectory+__T("\\Basic\\Diff\\Times.csv"), File::Access_Write_Append);
282
283 cout<<" Analyzing"<<endl;
284 MIL.Open(Files);
285
286
287 for (size_t StreamKind=0; StreamKind<Stream_Max; StreamKind++)
288 {
289 ZtringListListF New;
290 ZtringListListF Ref;
291 ZtringListListF Diff;
292
293 cout<<" Retrieving ref data"<<endl;
294 if (File::Exists(DataBaseDirectory+__T("\\Basic\\Ref\\")+Ztring::ToZtring(StreamKind)+__T(".csv")))
295 Ref.Load(DataBaseDirectory+__T("\\Basic\\Ref\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
296
297 cout<<" Retrieving new data"<<endl;
298 for (size_t FilePos=0; FilePos<MIL.Count_Get(); FilePos++)
299 if (MIL.Count_Get(FilePos, (stream_t)StreamKind))
300 {
301 New.push_back(ZtringList());
302 New.at(New.size()-1).push_back(Ztring()); //CompleteFileName
303 for (size_t LinePos=0; LinePos<MIL.Count_Get(FilePos, (stream_t)StreamKind, 0); LinePos++)
304 New.at(New.size()-1).push_back(MIL.Get(FilePos, (stream_t)StreamKind, 0, LinePos, Info_Name));
305 break;
306 }
307
308 for (size_t FilePos=0; FilePos<MIL.Count_Get(); FilePos++)
309 for (size_t StreamPos=0; StreamPos<MIL.Count_Get(FilePos, (stream_t)StreamKind); StreamPos++)
310 {
311 New.push_back(ZtringList());
312 New.at(New.size()-1).push_back(MIL.Get(FilePos, Stream_General, 0, __T("CompleteName")));
313 for (size_t LinePos=0; LinePos<MIL.Count_Get(FilePos, (stream_t)StreamKind, StreamPos); LinePos++)
314 {
315 Ztring Value=MIL.Get(FilePos, (stream_t)StreamKind, StreamPos, LinePos);
316 if (Value.find(__T('\r')) != string::npos || Value.find(__T('\n')) != string::npos)
317 {
318 Value.FindAndReplace(__T("\r\n"), __T(" / "), 0, Ztring_Recursive);
319 Value.FindAndReplace(__T("\r"), __T(" / "), 0, Ztring_Recursive);
320 Value.FindAndReplace(__T("\n"), __T(" / "), 0, Ztring_Recursive);
321 if (Value.size()>=3 && Value.rfind(__T(" / "))== Value.size()-3)
322 Value.resize(Value.size()-3);
323 }
324 New.at(New.size()-1).push_back(Value);
325 }
326 }
327
328 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\New")))
329 Dir::Create(DataBaseDirectory+__T("\\Basic\\New"));
330 New.Save(DataBaseDirectory+__T("\\Basic\\New\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
331
332 cout<<" Diff"<<endl;
333 size_t Ref_Pos=1;
334 size_t New_Pos=1;
335 while (Ref_Pos<Ref.size() && New_Pos<New.size())
336 {
337 if (New(New_Pos, 0)!=Ref(Ref_Pos, 0))
338 {
339 size_t Ref_PosNext=Ref_Pos;
340 while (Ref_PosNext<Ref.size() && New(New_Pos, 0)!=Ref(Ref_PosNext, 0))
341 Ref_PosNext++;
342 if (Ref_PosNext==Ref.size()) //Ref file not found
343 {
344 Diff.push_back(New(New_Pos));
345 New_Pos++;
346 }
347 else
348 {
349 for (; Ref_Pos<Ref_PosNext; Ref_Pos++)
350 Diff.push_back(Ref(Ref_Pos));
351 }
352 }
353 else
354 {
355 bool IsDiff=false;
356 size_t LinePos_Max=max(New(New_Pos).size(), Ref(Ref_Pos).size());
357 for (size_t LinePos=1; LinePos<LinePos_Max; LinePos++)
358 if (New(New_Pos, LinePos)!=Ref(Ref_Pos, LinePos))
359 {
360 if (!IsDiff)
361 {
362 Diff.push_back(ZtringList());
363 Diff(Diff.size()-1, 0)=New(New_Pos, 0);
364 IsDiff=true;
365 }
366 Diff(Diff.size()-1, LinePos)=New(New_Pos, LinePos)+__T(" --- ")+Ref(Ref_Pos, LinePos);
367 }
368
369 Ref_Pos++;
370 New_Pos++;
371 }
372
373 }
374
375 for (; Ref_Pos<Ref.size(); Ref_Pos++)
376 {
377 Diff.push_back(ZtringList());
378 Diff(Diff.size()-1, 0)=Ref(Ref_Pos, 0);
379 for (size_t LinePos=1; LinePos<Ref[Ref_Pos].size(); LinePos++)
380 if (!Ref(Ref_Pos, LinePos).empty())
381 Diff(Diff.size()-1, LinePos)=__T(" --- ")+Ref(Ref_Pos, LinePos);
382 }
383 for (; New_Pos<New.size(); New_Pos++)
384 {
385 Diff.push_back(ZtringList());
386 Diff(Diff.size()-1, 0)=New(New_Pos, 0);
387 for (size_t LinePos=1; LinePos<New[New_Pos].size(); LinePos++)
388 if (!New(New_Pos, LinePos).empty())
389 Diff(Diff.size()-1, LinePos)=New(New_Pos, LinePos)+__T(" --- ");
390 }
391
392 if (!Diff.empty())
393 {
394 Diff.insert(Diff.begin(), New(0));
395 if (!Dir::Exists(DataBaseDirectory+__T("\\Basic\\Diff")))
396 Dir::Create(DataBaseDirectory+__T("\\Basic\\Diff"));
397 Diff.Save(DataBaseDirectory+__T("\\Basic\\Diff\\")+Ztring::ToZtring(StreamKind)+__T(".csv"));
398 }
399 }
400 }
401