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 <stdio.h>
12 #include <map>
13 #include "tchar.h"
14 #include "MediaInfoDLL/MediaInfoDLL.h"
15 #include "MediaInfo/MediaInfo_Events.h"
16 #include "ZenLib/ZtringListListF.h"
17 #include "ZenLib/Dir.h"
18 #include "ZenLib/File.h"
19 #include "ZenLib/FileName.h"
20 #include "RegressionTest/RegressionTest.h"
21 using namespace MediaInfoDLL;
22 using namespace ZenLib;
23 using namespace std;
24
25 const char* F_FileName;
26 #define echoF(_format) Events_UserHandle_struct::perevent &PerEvent=UserHandle->PerEvent[Event->EventCode]; if (!PerEvent.F_MoreThanOnce) {fprintf(PerEvent.F, _format); PerEvent.F_MoreThanOnce=true; } fprintf(PerEvent.F, "\n");
27 #define echo0(_format) fprintf(PerEvent.F, _format)
28 #define echo1(_format, Arg1) fprintf(PerEvent.F, _format, Arg1)
29 #define echo2(_format, Arg1, Arg2) fprintf(PerEvent.F, _format, Arg1, Arg2)
30 #define echo4(_format, Arg1, Arg2, Arg3, Arg4) fprintf(PerEvent.F, _format, Arg1, Arg2, Arg3, Arg4)
31
32 struct Events_UserHandle_struct
33 {
34 FileName Name;
35 Ztring Files;
36 Ztring DataBaseDirectory;
37 struct perevent
38 {
39 FILE* F;
40 bool F_MoreThanOnce;
41 };
42 map<int32u, perevent> PerEvent;
43 int32u Scenario;
44 bool Custom;
45 bool ParseSpeed;
46 bool NextPacket;
47 bool DemuxContainerOnly;
48 bool Seek;
49
Events_UserHandle_structEvents_UserHandle_struct50 Events_UserHandle_struct()
51 {
52 Custom=false;
53 ParseSpeed=false;
54 NextPacket=false;
55 DemuxContainerOnly=false;
56 Seek=false;
57 }
58
ClearEvents_UserHandle_struct59 void Clear()
60 {
61 for (map<int32u, perevent>::iterator Item=PerEvent.begin(); Item!=PerEvent.end(); ++Item)
62 fclose (Item->second.F);
63 PerEvent.clear();
64 }
65
66 };
67
General_Start_0(struct MediaInfo_Event_General_Start_0 * Event,struct Events_UserHandle_struct * UserHandle)68 void General_Start_0 (struct MediaInfo_Event_General_Start_0* Event, struct Events_UserHandle_struct* UserHandle)
69 {
70 echoF("MediaInfo starts\n");
71
72 echo1("Stream_Size=%i\n", Event->Stream_Size);
73 }
74
General_End_0(struct MediaInfo_Event_General_End_0 * Event,struct Events_UserHandle_struct * UserHandle)75 void General_End_0 (struct MediaInfo_Event_General_End_0* Event, struct Events_UserHandle_struct* UserHandle)
76 {
77 echoF("MediaInfo ends\n");
78
79 echo1("Stream_Bytes_Analyzed=%i\n", Event->Stream_Bytes_Analyzed);
80 }
81
General_Parser_Selected_0(struct MediaInfo_Event_General_Parser_Selected_0 * Event,struct Events_UserHandle_struct * UserHandle)82 void General_Parser_Selected_0 (struct MediaInfo_Event_General_Parser_Selected_0* Event, struct Events_UserHandle_struct* UserHandle)
83 {
84 echoF("MediaInfo has selected the parser\n");
85
86 echo1("Name=%s\n", Event->Name);
87 }
88
General_Move_Request_0(struct MediaInfo_Event_General_Move_Request_0 * Event,struct Events_UserHandle_struct * UserHandle)89 void General_Move_Request_0 (struct MediaInfo_Event_General_Move_Request_0* Event, struct Events_UserHandle_struct* UserHandle)
90 {
91 echoF("MediaInfo has requested to seek\n");
92
93 echo1("StreamOffset=%08x\n", Event->StreamOffset);
94 }
95
General_Move_Done_0(struct MediaInfo_Event_General_Move_Done_0 * Event,struct Events_UserHandle_struct * UserHandle)96 void General_Move_Done_0 (struct MediaInfo_Event_General_Move_Done_0* Event, struct Events_UserHandle_struct* UserHandle)
97 {
98 echoF("MediaInfo has seek\n");
99
100 echo1("StreamOffset=%08x\n", Event->StreamOffset);
101 }
102
General_SubFile_Start_0(struct MediaInfo_Event_General_SubFile_Start_0 * Event,struct Events_UserHandle_struct * UserHandle)103 void General_SubFile_Start_0 (struct MediaInfo_Event_General_SubFile_Start_0* Event, struct Events_UserHandle_struct* UserHandle)
104 {
105 echoF("MediaInfo is parsing a new file from the source file\n");
106
107 echo1("FileName_Relative=%s\n", Event->FileName_Relative);
108 echo1("FileName_Absolute=%s\n", Event->FileName_Absolute);
109 }
110
General_SubFile_End_0(struct MediaInfo_Event_General_SubFile_End_0 * Event,struct Events_UserHandle_struct * UserHandle)111 void General_SubFile_End_0 (struct MediaInfo_Event_General_SubFile_End_0* Event, struct Events_UserHandle_struct* UserHandle)
112 {
113 echoF("MediaInfo has finished the parsing a new file from the source file\n");
114 }
115
Global_Demux_4(struct MediaInfo_Event_Global_Demux_4 * Event,struct Events_UserHandle_struct * UserHandle)116 void Global_Demux_4(struct MediaInfo_Event_Global_Demux_4 *Event, struct Events_UserHandle_struct* UserHandle)
117 {
118 if (!UserHandle->DemuxContainerOnly)
119 return;
120
121 echoF("MediaInfo Demux\n");
122
123 echo1("StreamOffset=%08x,", Event->StreamOffset);
124 echo1(" Frame_Number=%u\n", Event->FrameNumber);
125 echo0("IDs=");
126 for (size_t Pos=0; Pos<Event->StreamIDs_Size; Pos++)
127 switch (Event->StreamIDs_Width[Pos])
128 {
129 case 2: echo1("%02x, ", Event->StreamIDs[Pos]); break;
130 case 4: echo1("%04x, ", Event->StreamIDs[Pos]); break;
131 case 8: echo1("%08x, ", Event->StreamIDs[Pos]); break;
132 default: echo1("%08x, ", Event->StreamIDs[Pos]); break;
133 }
134 echo0("\n");
135 if (Event->PCR!=(int64u)-1)
136 echo1("PCR=%s, ", Ztring().Duration_From_Milliseconds(Event->PCR/1000000).To_Local().c_str());
137 if (Event->PTS!=(int64u)-1)
138 echo1("PTS=%s, ", Ztring().Duration_From_Milliseconds(Event->PTS/1000000).To_Local().c_str());
139 if (Event->DTS!=(int64u)-1)
140 echo1("DTS=%s, ", Ztring().Duration_From_Milliseconds(Event->DTS/1000000).To_Local().c_str());
141 if (Event->DUR!=(int64u)-1)
142 echo1("DUR=%s, ", Ztring().Duration_From_Milliseconds(Event->DUR/1000000).To_Local().c_str());
143 if (Event->PCR!=(int64u)-1 || Event->PTS!=(int64u)-1 || Event->DTS!=(int64u)-1 || Event->DUR!=(int64u)-1)
144 echo0("\n");
145 echo1("Content_Type=%i,", Event->Content_Type);
146 echo1(" Content_Size=%i,", Event->Content_Size);
147 echo1(" Flags=%08x\n", Event->Flags);
148 }
149
Video_SliceInfo_0(struct MediaInfo_Event_Video_SliceInfo_0 * Event,struct Events_UserHandle_struct * UserHandle)150 void Video_SliceInfo_0(struct MediaInfo_Event_Video_SliceInfo_0 *Event, struct Events_UserHandle_struct* UserHandle)
151 {
152 if (!UserHandle->DemuxContainerOnly)
153 return;
154
155 echoF("MediaInfo Demux\n");
156
157 echo1("StreamOffset=%08x,", Event->StreamOffset);
158 echo1(" FramePosition=%u,", Event->FrameNumber);
159 echo1(" FieldPosition=%u,", Event->FieldPosition);
160 echo1(" SlicePosition=%u,", Event->SlicePosition);
161 echo0("IDs=");
162 for (size_t Pos=0; Pos<Event->StreamIDs_Size; Pos++)
163 switch (Event->StreamIDs_Width[Pos])
164 {
165 case 2: echo1("%02x, ", Event->StreamIDs[Pos]); break;
166 case 4: echo1("%04x, ", Event->StreamIDs[Pos]); break;
167 case 8: echo1("%08x, ", Event->StreamIDs[Pos]); break;
168 default: echo1("%08x, ", Event->StreamIDs[Pos]); break;
169 }
170 echo0("\n");
171 if (Event->PCR!=(int64u)-1)
172 echo1("PCR=%s, ", Ztring().Duration_From_Milliseconds(Event->PCR/1000000).To_Local().c_str());
173 if (Event->PTS!=(int64u)-1)
174 echo1("PTS=%s, ", Ztring().Duration_From_Milliseconds(Event->PTS/1000000).To_Local().c_str());
175 if (Event->DTS!=(int64u)-1)
176 echo1("DTS=%s, ", Ztring().Duration_From_Milliseconds(Event->DTS/1000000).To_Local().c_str());
177 if (Event->DUR!=(int64u)-1)
178 echo1("DUR=%s, ", Ztring().Duration_From_Milliseconds(Event->DUR/1000000).To_Local().c_str());
179 if (Event->PCR!=(int64u)-1 || Event->PTS!=(int64u)-1 || Event->DTS!=(int64u)-1 || Event->DUR!=(int64u)-1)
180 echo0("\n");
181 echo1("SliceType=%i,", Event->SliceType);
182 echo1(" Flags=%08x\n", Event->Flags);
183 }
184
185 /***************************************************************************/
186 /* The callback function */
187 /***************************************************************************/
188
189 #define CASE(_PARSER,_EVENT,_VERSION) \
190 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;
191
Event_CallBackFunction(unsigned char * Data_Content,size_t Data_Size,void * UserHandle_Void)192 void __stdcall Event_CallBackFunction(unsigned char* Data_Content, size_t Data_Size, void* UserHandle_Void)
193 {
194 /*Retrieving UserHandle*/
195 struct Events_UserHandle_struct* UserHandle=(struct Events_UserHandle_struct*)UserHandle_Void;
196 struct MediaInfo_Event_Generic* Event_Generic=(struct MediaInfo_Event_Generic*) Data_Content;
197 unsigned char ParserID;
198 unsigned short EventID;
199 unsigned char EventVersion;
200
201 /*integrity tests*/
202 if (Data_Size<4)
203 return; //There is a problem
204
205 if (UserHandle->PerEvent[Event_Generic->EventCode].F==NULL)
206 {
207 Ztring Number; Number.From_Number(Event_Generic->EventCode, 16);
208 while (Number.size()<8)
209 Number.insert(0, 1, __T('0'));
210 Ztring Name=Ztring(UserHandle->DataBaseDirectory+__T("\\Events\\New\\")+Ztring::ToZtring(UserHandle->Scenario)+__T("\\")+Number+__T("\\")+UserHandle->Name.Name_Get()+__T(".txt"));
211 if (!Dir::Exists(UserHandle->DataBaseDirectory+__T("\\Events\\New")))
212 Dir::Create(UserHandle->DataBaseDirectory+__T("\\Events\\New"));
213 if (!Dir::Exists(UserHandle->DataBaseDirectory+__T("\\Events\\New\\")+Ztring::ToZtring(UserHandle->Scenario)))
214 Dir::Create(UserHandle->DataBaseDirectory+__T("\\Events\\New\\")+Ztring::ToZtring(UserHandle->Scenario));
215 if (!Dir::Exists(UserHandle->DataBaseDirectory+__T("\\Events\\New\\")+Ztring::ToZtring(UserHandle->Scenario)+__T("\\")+Number))
216 Dir::Create(UserHandle->DataBaseDirectory+__T("\\Events\\New\\")+Ztring::ToZtring(UserHandle->Scenario)+__T("\\")+Number);
217 if (!Dir::Exists(FileName(Name).Path_Get()))
218 Dir::Create(FileName(Name).Path_Get());
219 UserHandle->PerEvent[Event_Generic->EventCode].F=fopen(Name.To_Local().c_str(), "w");
220 }
221
222 /*Retrieving EventID*/
223 ParserID =(unsigned char) ((Event_Generic->EventCode&0xFF000000)>>24);
224 EventID =(unsigned short)((Event_Generic->EventCode&0x00FFFF00)>>8 );
225 EventVersion=(unsigned char) ( Event_Generic->EventCode&0x000000FF );
226
227
228 //*Global to all parsers
229 switch (EventID)
230 {
231 CASE (Global, Demux, 4)
232 CASE (Video, SliceInfo, 0)
233 default : ;
234 }
235
236 switch (ParserID)
237 {
238 case MediaInfo_Parser_None :
239 switch (EventID)
240 {
241 case MediaInfo_Event_General_Start : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_Start_0)) General_Start_0((struct MediaInfo_Event_General_Start_0*)Data_Content, UserHandle); break;
242 case MediaInfo_Event_General_End : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_End_0)) General_End_0((struct MediaInfo_Event_General_End_0*)Data_Content, UserHandle); break;
243 case MediaInfo_Event_General_Parser_Selected : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_Parser_Selected_0)) General_Parser_Selected_0((struct MediaInfo_Event_General_Parser_Selected_0*)Data_Content, UserHandle); break;
244 case MediaInfo_Event_General_Move_Request : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_Move_Request_0)) General_Move_Request_0((struct MediaInfo_Event_General_Move_Request_0*)Data_Content, UserHandle); break;
245 case MediaInfo_Event_General_Move_Done : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_Move_Done_0)) General_Move_Done_0((struct MediaInfo_Event_General_Move_Done_0*)Data_Content, UserHandle); break;
246 case MediaInfo_Event_General_SubFile_Start : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_SubFile_Start_0)) General_SubFile_Start_0((struct MediaInfo_Event_General_SubFile_Start_0*)Data_Content, UserHandle); break;
247 case MediaInfo_Event_General_SubFile_End : if (EventVersion==0 && Data_Size==sizeof(struct MediaInfo_Event_General_SubFile_End_0)) General_SubFile_End_0((struct MediaInfo_Event_General_SubFile_End_0*)Data_Content, UserHandle); break;
248 default : ;
249 }
250 break;
251 default : ; //ParserID is unknown
252 }
253 }
254
RegressionTest_Events(Ztring Files,Ztring DataBaseDirectory,int32u Scenario)255 void RegressionTest_Events(Ztring Files, Ztring DataBaseDirectory, int32u Scenario)
256 {
257 // Scenarios:
258 // bit 0 : quick parsing / full parsing
259 // bit 1 : next packet interface
260 // bit 2 : demux (by container only)
261 // bit 3 : do some seeks
262
263
264 cout<<" Analyzing"<<endl;
265 ZtringListListF FilesList_Source;
266 if (FileName(Files).Extension_Get()==__T("csv"))
267 FilesList_Source.Load(DataBaseDirectory+__T("\\Events\\FilesList.csv"));
268 else
269 {
270 if (File::Exists(Files))
271 FilesList_Source.push_back(Files);
272 else
273 FilesList_Source.push_back(Files+__T("\\*.*"));
274 }
275 vector<Events_UserHandle_struct> FilesList;
276 for (size_t FilesList_Source_Pos=0; FilesList_Source_Pos<FilesList_Source.size(); FilesList_Source_Pos++)
277 {
278 ZtringList Temp=Dir::GetAllFileNames(FilesList_Source[FilesList_Source_Pos](0));
279 for (size_t Temp_Pos=0; Temp_Pos<Temp.size(); Temp_Pos++)
280 {
281 struct Events_UserHandle_struct ToAdd;
282 ToAdd.Name=Temp[Temp_Pos];
283 ToAdd.DataBaseDirectory=DataBaseDirectory;
284 ToAdd.Files=Files;
285 ToAdd.Scenario=Scenario;
286 if (Scenario&(1<<0))
287 ToAdd.ParseSpeed=true;
288 if (Scenario&(1<<1))
289 ToAdd.NextPacket=true;
290 if (Scenario&(1<<2))
291 ToAdd.DemuxContainerOnly=true;
292 if (Scenario&(1<<3))
293 ToAdd.Seek=true;
294
295 FilesList.push_back(ToAdd);
296 }
297 }
298
299
300 for (size_t FilesList_Pos=0; FilesList_Pos<FilesList.size(); FilesList_Pos++)
301 {
302 cout<<" "<<FilesList_Pos+1<<"/"<<FilesList.size()<<" "<<FilesList[FilesList_Pos].Name.To_Local()<<endl;
303
304 MediaInfo MI;
305 Ztring MI_Result;
306
307 //**********************************************************************
308 // Configuring
309 //**********************************************************************
310
311 // CallBack configuration
312 // MediaInfo need pointer as text (for compatibility with older version) + 64-bit OS handling
313 // form is "CallBack=memory://handlerInDecimal;UserHandler=memory://handlerInDecimal"
314 // UserHandler is a unique value wich will be provided to the callback function, in order to know which MediaInfo instance send the event
315 wostringstream Event_CallBackFunction_Text;
316 Event_CallBackFunction_Text<<__T("CallBack=memory://")<<(MediaInfo_int64u)Event_CallBackFunction<<__T(";UserHandler=memory://")<<(MediaInfo_int64u)&FilesList[FilesList_Pos];
317 MI_Result=MI.Option(__T("File_Event_CallBackFunction"), Event_CallBackFunction_Text.str());
318 if (!MI_Result.empty())
319 {
320 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
321 return;
322 }
323
324 //Retrieiving basic data
325 MI.Open(FilesList[FilesList_Pos].Name);
326 Ztring Delay_10s=Ztring().Duration_From_Milliseconds(Ztring(MI.Get(Stream_Video, 0, __T("Delay"))).To_int64u()+10000);
327
328 if (FilesList[FilesList_Pos].ParseSpeed)
329 {
330 MI_Result=MI.Option(__T("ParseSpeed"), __T("1.0"));
331 if (!MI_Result.empty())
332 {
333 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
334 return;
335 }
336 }
337
338 if (FilesList[FilesList_Pos].DemuxContainerOnly)
339 {
340 MI_Result=MI.Option(__T("Demux"), __T("container"));
341 if (!MI_Result.empty())
342 {
343 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
344 return;
345 }
346
347 MI_Result=MI.Option(__T("File_Demux_Unpacketize"), __T("1"));
348 if (!MI_Result.empty())
349 {
350 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
351 return;
352 }
353
354 MI_Result=MI.Option(__T("File_Demux_PCM_20bitTo16bit"), __T("1"));
355 if (!MI_Result.empty())
356 {
357 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
358 return;
359 }
360 }
361
362 if (FilesList[FilesList_Pos].NextPacket)
363 {
364 MI_Result=MI.Option(__T("File_NextPacket"), __T("1"));
365 if (!MI_Result.empty())
366 {
367 wcout<<__T("MediaInfo error: ")<<MI_Result<<endl;
368 return;
369 }
370 }
371
372 MI.Open(FilesList[FilesList_Pos].Name);
373
374 if (FilesList[FilesList_Pos].NextPacket)
375 {
376 int Counter=0;
377 while (MI.Open_NextPacket()&0x100)
378 {
379 if (FilesList[FilesList_Pos].Seek)
380 {
381 Counter++;
382 if (Counter==0)
383 MI.Option(__T("File_Seek"), __T("0"));
384 if (Counter==100)
385 MI.Option(__T("File_Seek"), Delay_10s);
386 if (Counter==200)
387 MI.Option(__T("File_Seek"), __T("Frame=100"));
388 if (Counter==300)
389 MI.Option(__T("File_Seek"), __T("95%"));
390 }
391 }
392 }
393
394 FilesList[FilesList_Pos].Clear();
395 }
396
397 cout<<" Diff"<<endl;
398 ZtringList Ref=Dir::GetAllFileNames(DataBaseDirectory+__T("\\Events\\Ref\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario)+__T("*.*"));
399 ZtringList New=Dir::GetAllFileNames(DataBaseDirectory+__T("\\Events\\New\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario)+__T("*.*"));
400 for (size_t Ref_Pos=0; Ref_Pos<Ref.size(); Ref_Pos++)
401 {
402 Ztring Ref_ToFind=Ref[Ref_Pos];
403 Ref_ToFind.FindAndReplace(__T("\\Events\\Ref\\"), __T("\\Events\\New\\"));
404 size_t New_RefPos=New.Find(Ref_ToFind);
405 bool IsDiff=false;
406 if (New_RefPos!=(size_t)-1)
407 {
408 File F_Ref; F_Ref.Open(Ref[Ref_Pos]);
409 File F_New; F_New.Open(New[New_RefPos]);
410 if (F_Ref.Size_Get()==F_New.Size_Get())
411 {
412 int64u Size=F_Ref.Size_Get();
413 if (Size>100000000)
414 Size=100000000;
415 int8u* F_Ref_Buffer=new int8u[(size_t)Size];
416 F_Ref.Read(F_Ref_Buffer, (size_t)Size);
417 int8u* F_New_Buffer=new int8u[(size_t)Size];
418 F_New.Read(F_New_Buffer, (size_t)Size);
419
420 if (memcmp(F_Ref_Buffer, F_New_Buffer, (size_t)Size))
421 IsDiff=true;
422
423 delete[] F_Ref_Buffer;
424 delete[] F_New_Buffer;
425 }
426 else
427 IsDiff=true;
428 }
429 if (New_RefPos==(size_t)-1 || IsDiff)
430 {
431 //Not in new or is different
432 Ztring Diff_Name=Ref[Ref_Pos];
433 Diff_Name.FindAndReplace(__T("\\Events\\Ref\\"), __T("\\Events\\Diff\\"));
434 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff")))
435 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff"));
436 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()))
437 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get());
438 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario)))
439 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario));
440 if (!Dir::Exists(FileName(Diff_Name).Path_Get()))
441 Dir::Create(FileName(Diff_Name).Path_Get());
442 if (!IsDiff)
443 File::Copy(Ref[Ref_Pos], Diff_Name+__T(".RefAlone.txt")); //Not in new
444 else
445 {
446 File::Copy(Ref[Ref_Pos], Diff_Name+__T(".Ref.txt")); //Diff
447 File::Copy(New[New_RefPos], Diff_Name+__T(".New.txt"));
448 }
449 }
450 if (New_RefPos!=(size_t)-1)
451 New.erase(New.begin()+New_RefPos);
452 }
453 for (size_t New_Pos=0; New_Pos<New.size(); New_Pos++)
454 {
455 //Not in ref
456 Ztring Diff_Name=New[New_Pos];
457 Diff_Name.FindAndReplace(__T("\\Events\\New\\"), __T("\\Events\\Diff\\"));
458 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff")))
459 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff"));
460 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()))
461 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get());
462 if (!Dir::Exists(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario)))
463 Dir::Create(DataBaseDirectory+__T("\\Events\\Diff\\")+FileName(Files).Name_Get()+__T("\\")+Ztring::ToZtring(Scenario));
464 if (!Dir::Exists(FileName(Diff_Name).Path_Get()))
465 Dir::Create(FileName(Diff_Name).Path_Get());
466 File::Copy(New[New_Pos], Diff_Name+__T(".NewAlone.txt")); //Not in new
467 }
468 }
469