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