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 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // Inform part
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 
13 //---------------------------------------------------------------------------
14 // Pre-compilation
15 #include "MediaInfo/PreComp.h"
16 #ifdef __BORLANDC__
17     #pragma hdrstop
18 #endif
19 //---------------------------------------------------------------------------
20 
21 //---------------------------------------------------------------------------
22 #include "MediaInfo/Setup.h"
23 //---------------------------------------------------------------------------
24 
25 //---------------------------------------------------------------------------
26 #include "ZenLib/Utils.h"
27 #if defined(MEDIAINFO_EBUCORE_YES)
28     #include "MediaInfo/Export/Export_EbuCore.h"
29 #endif //defined(MEDIAINFO_EBUCORE_YES)
30 #if defined(MEDIAINFO_FIMS_YES)
31     #include "MediaInfo/Export/Export_Fims.h"
32 #endif //defined(MEDIAINFO_EBUCORE_YES)
33 #if defined(MEDIAINFO_MPEG7_YES)
34     #include "MediaInfo/Export/Export_Mpeg7.h"
35 #endif //defined(MEDIAINFO_MPEG7_YES)
36 #if defined(MEDIAINFO_REVTMD_YES)
37     #include "MediaInfo/Export/Export_reVTMD.h"
38 #endif //defined(MEDIAINFO_REVTMD_YES)
39 #if defined(MEDIAINFO_PBCORE_YES)
40     #include "MediaInfo/Export/Export_PBCore.h"
41     #include "MediaInfo/Export/Export_PBCore2.h"
42 #endif //defined(MEDIAINFO_PBCORE_YES)
43 #if defined(MEDIAINFO_NISO_YES)
44 #include "MediaInfo/Export/Export_Niso.h"
45 #endif //defined(MEDIAINFO_NISO_YES)
46 #if defined(MEDIAINFO_GRAPH_YES)
47 #include "MediaInfo/Export/Export_Graph.h"
48 #endif //defined(MEDIAINFO_GRAPH_YES)
49 
50 #include "MediaInfo/MediaInfo_Internal.h"
51 #include "MediaInfo/File__Analyze.h"
52 #include "ThirdParty/base64/base64.h"
53 # if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
54 #include "MediaInfo/OutputHelpers.h"
55 #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
56 
57 //---------------------------------------------------------------------------
58 #include <ctime>
59 //---------------------------------------------------------------------------
60 
61 namespace MediaInfoLib
62 {
63 
64 //---------------------------------------------------------------------------
65 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
Xml_Name_Escape_0_7_78(const Ztring & Name)66 Ztring Xml_Name_Escape_0_7_78 (const Ztring &Name)
67 {
68     Ztring ToReturn(Name);
69     ToReturn.FindAndReplace(__T(" "), __T("_"), 0, Ztring_Recursive);
70     ToReturn.FindAndReplace(__T("/"), __T("_"), 0, Ztring_Recursive);
71     ToReturn.FindAndReplace(__T("("), Ztring(), 0, Ztring_Recursive);
72     ToReturn.FindAndReplace(__T(")"), Ztring(), 0, Ztring_Recursive);
73     ToReturn.FindAndReplace(__T("*"), __T("_"), 0, Ztring_Recursive);
74     ToReturn.FindAndReplace(__T(","), __T("_"), 0, Ztring_Recursive);
75     ToReturn.FindAndReplace(__T(":"), __T("_"), 0, Ztring_Recursive);
76     ToReturn.FindAndReplace(__T("@"), __T("_"), 0, Ztring_Recursive);
77     ToReturn.FindAndReplace(__T("."), __T("_"), 0, Ztring_Recursive);
78     size_t ToReturn_Pos=0;
79     while (ToReturn_Pos<ToReturn.size())
80     {
81         if (!(ToReturn[ToReturn_Pos]>=__T('A') && ToReturn[ToReturn_Pos]<=__T('Z'))
82          && !(ToReturn[ToReturn_Pos]>=__T('a') && ToReturn[ToReturn_Pos]<=__T('z'))
83          && !(ToReturn[ToReturn_Pos]>=__T('0') && ToReturn[ToReturn_Pos]<=__T('9'))
84          && !(ToReturn[ToReturn_Pos]==__T('_')))
85             ToReturn.erase(ToReturn_Pos, 1);
86         else
87             ToReturn_Pos++;
88     }
89 
90     if (ToReturn.operator()(0)>='0' && ToReturn.operator()(0)<='9')
91         ToReturn.insert(0, 1, __T('_'));
92 
93     if (ToReturn.empty())
94         ToReturn="Unknown";
95 
96     return ToReturn;
97 }
98 #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
99 
100 //---------------------------------------------------------------------------
101 extern MediaInfo_Config Config;
102 extern const Char* MediaInfo_Version;
103 //---------------------------------------------------------------------------
104 
105 //---------------------------------------------------------------------------
ConvertRetour(Ztring & Retour)106 void MediaInfo_Internal::ConvertRetour(Ztring& Retour)
107 {
108     Retour.FindAndReplace(__T("\\r\\n"), __T("\n"), 0, Ztring_Recursive);
109     Retour.FindAndReplace(__T("\\r"), __T("\n"), 0, Ztring_Recursive);
110     Retour.FindAndReplace(__T("\\n"), __T("\n"), 0, Ztring_Recursive);
111     Retour.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive);
112     Retour.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive);
113     Retour.FindAndReplace(__T("\n"), MediaInfoLib::Config.LineSeparator_Get(), 0, Ztring_Recursive);
114 }
115 
116 //---------------------------------------------------------------------------
ConvertRetourSCX(Ztring & Retour)117 void MediaInfo_Internal::ConvertRetourSCX(Ztring& Retour)
118 {
119     Retour.FindAndReplace(__T("|SC1|"), __T("\\"), 0, Ztring_Recursive);
120     Retour.FindAndReplace(__T("|SC2|"), __T("["), 0, Ztring_Recursive);
121     Retour.FindAndReplace(__T("|SC3|"), __T("]"), 0, Ztring_Recursive);
122     Retour.FindAndReplace(__T("|SC4|"), __T(","), 0, Ztring_Recursive);
123     Retour.FindAndReplace(__T("|SC5|"), __T(";"), 0, Ztring_Recursive);
124     Retour.FindAndReplace(__T("|SC6|"), __T("("), 0, Ztring_Recursive);
125     Retour.FindAndReplace(__T("|SC7|"), __T(")"), 0, Ztring_Recursive);
126     Retour.FindAndReplace(__T("|SC8|"), __T(")"), 0, Ztring_Recursive);
127     Retour.FindAndReplace(__T("|SC9|"), __T("),"), 0, Ztring_Recursive);
128 }
129 
130 //---------------------------------------------------------------------------
Inform()131 Ztring MediaInfo_Internal::Inform()
132 {
133     {
134         CriticalSectionLocker CSL(CS);
135     if (Info && Info->Status[File__Analyze::IsUpdated])
136         Info->Open_Buffer_Update();
137     }
138 
139     #if MEDIAINFO_TRACE
140         if (MediaInfoLib::Config.Inform_Get()!=__T("MAXML") && (MediaInfoLib::Config.Trace_Level_Get() || MediaInfoLib::Config.Inform_Get()==__T("Details")))
141         {
142             if (!Details.empty())
143                 return Ztring().From_UTF8(Details);
144             else if (Info)
145                 return Info->Details_Get();
146             else
147                 return Ztring();
148         }
149     #endif //MEDIAINFO_TRACE
150 
151     #if defined(MEDIAINFO_EBUCORE_YES)
152         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.5"))
153             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_5, Export_EbuCore::AcquisitionDataOutputMode_Default,
154             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
155         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.6"))
156             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_6, Export_EbuCore::AcquisitionDataOutputMode_Default,
157             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
158         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8"))
159             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, (Export_EbuCore::acquisitiondataoutputmode)MediaInfoLib::Config.AcquisitionDataOutputMode_Get(),
160             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
161         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_parameterSegment") || MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_ps"))
162             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, Export_EbuCore::AcquisitionDataOutputMode_parameterSegment,
163             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
164         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_segmentParameter") || MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_sp"))
165             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, Export_EbuCore::AcquisitionDataOutputMode_segmentParameter,
166             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
167         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.5_JSON"))
168             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_5, Export_EbuCore::AcquisitionDataOutputMode_Default,
169             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
170         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.6_JSON"))
171             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_6, Export_EbuCore::AcquisitionDataOutputMode_Default,
172             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
173         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_JSON"))
174             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, (Export_EbuCore::acquisitiondataoutputmode)MediaInfoLib::Config.AcquisitionDataOutputMode_Get(),
175             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
176         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_parameterSegment_JSON") || MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_ps_JSON"))
177             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, Export_EbuCore::AcquisitionDataOutputMode_parameterSegment,
178             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
179         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_segmentParameter_JSON") || MediaInfoLib::Config.Inform_Get()==__T("EBUCore_1.8_sp_JSON"))
180             return Export_EbuCore().Transform(*this, Export_EbuCore::Version_1_8, Export_EbuCore::AcquisitionDataOutputMode_segmentParameter,
181             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
182         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore"))
183             return Export_EbuCore().Transform(*this, Export_EbuCore::version(Export_EbuCore::Version_Max-1), (Export_EbuCore::acquisitiondataoutputmode)MediaInfoLib::Config.AcquisitionDataOutputMode_Get(),
184             Export_EbuCore::Format_XML, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
185         if (MediaInfoLib::Config.Inform_Get()==__T("EBUCore_JSON"))
186             return Export_EbuCore().Transform(*this, Export_EbuCore::version(Export_EbuCore::Version_Max-1), (Export_EbuCore::acquisitiondataoutputmode)MediaInfoLib::Config.AcquisitionDataOutputMode_Get(),
187             Export_EbuCore::Format_JSON, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
188     #endif //defined(MEDIAINFO_EBUCORE_YES)
189     #if defined(MEDIAINFO_EBUCORE_YES)
190         if (MediaInfoLib::Config.Inform_Get()==__T("FIMS_1.1"))
191             return Export_Fims().Transform(*this, Export_Fims::Version_1_1);
192         if (MediaInfoLib::Config.Inform_Get()==__T("FIMS_1.2"))
193             return Export_Fims().Transform(*this, Export_Fims::Version_1_2);
194         if (MediaInfoLib::Config.Inform_Get()==__T("FIMS_1.3"))
195             return Export_Fims().Transform(*this, Export_Fims::Version_1_3);
196         if (MediaInfoLib::Config.Inform_Get()==__T("FIMS"))
197             return Export_Fims().Transform(*this);
198     #endif //defined(MEDIAINFO_FIMS_YES)
199     #if defined(MEDIAINFO_MPEG7_YES)
200         if (MediaInfoLib::Config.Inform_Get()==__T("MPEG-7"))
201             return Export_Mpeg7().Transform(*this);
202     #endif //defined(MEDIAINFO_MPEG7_YES)
203     #if defined(MEDIAINFO_PBCORE_YES)
204         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore_1") || MediaInfoLib::Config.Inform_Get()==__T("PBCore1")) // 1.x
205             return Export_PBCore().Transform(*this);
206         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore_1.2"))
207             return Export_PBCore().Transform(*this);
208         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore_2") ||MediaInfoLib::Config.Inform_Get()==__T("PBCore2")) //2.x
209             return Export_PBCore2().Transform(*this);
210         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore_2.0"))
211             return Export_PBCore2().Transform(*this, Export_PBCore2::Version_2_0);
212         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore_2.1"))
213             return Export_PBCore2().Transform(*this, Export_PBCore2::Version_2_1);
214         if (MediaInfoLib::Config.Inform_Get()==__T("PBCore")) //x.x
215             return Export_PBCore2().Transform(*this);
216     #endif //defined(MEDIAINFO_PBCORE_YES)
217     #if defined(MEDIAINFO_NISO_YES)
218         if (MediaInfoLib::Config.Inform_Get()==__T("NISO_Z39.87"))
219             return Export_Niso().Transform(*this, MediaInfoLib::Config.ExternalMetadata_Get(), MediaInfoLib::Config.ExternalMetaDataConfig_Get());
220     #endif //defined(MEDIAINFO_NISO_YES)
221     #if defined(MEDIAINFO_GRAPH_YES)
222         if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Dot"))
223             return Export_Graph().Transform(*this, Export_Graph::Graph_All, Export_Graph::Format_Dot);
224         #if defined(MEDIAINFO_GRAPHVIZ_YES)
225             if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Svg"))
226                 return Export_Graph().Transform(*this, Export_Graph::Graph_All, Export_Graph::Format_Svg);
227         #endif //defined(MEDIAINFO_GRAPHVIZ_YES)
228     #endif //defined(MEDIAINFO_GRAPH_YES)
229     #if defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_AC4_YES)
230         if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Ac4_Dot"))
231             return Export_Graph().Transform(*this, Export_Graph::Graph_Ac4, Export_Graph::Format_Dot);
232         #if defined(MEDIAINFO_GRAPHVIZ_YES)
233             if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Ac4_Svg"))
234                 return Export_Graph().Transform(*this, Export_Graph::Graph_Ac4, Export_Graph::Format_Svg);
235         #endif //defined(MEDIAINFO_GRAPHVIZ_YES)
236     #endif //defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_AC4_YES)
237     #if defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_DOLBYE_YES)
238         if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Ed2_Dot"))
239             return Export_Graph().Transform(*this, Export_Graph::Graph_Ed2, Export_Graph::Format_Dot);
240         #if defined(MEDIAINFO_GRAPHVIZ_YES)
241             if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Ed2_Svg"))
242                 return Export_Graph().Transform(*this, Export_Graph::Graph_Ed2, Export_Graph::Format_Svg);
243         #endif //defined(MEDIAINFO_GRAPHVIZ_YES)
244     #endif //defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_DOLBYE_YES)
245     #if defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_ADM_YES)
246         if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Adm_Dot"))
247             return Export_Graph().Transform(*this, Export_Graph::Graph_Adm, Export_Graph::Format_Dot);
248         #if defined(MEDIAINFO_GRAPHVIZ_YES)
249             if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Adm_Svg"))
250                 return Export_Graph().Transform(*this, Export_Graph::Graph_Adm, Export_Graph::Format_Svg);
251         #endif //defined(MEDIAINFO_GRAPHVIZ_YES)
252     #endif //defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_ADM_YES)
253     #if defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_MPEGH3DA_YES)
254         if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Mpegh3da_Dot"))
255             return Export_Graph().Transform(*this, Export_Graph::Graph_Mpegh3da, Export_Graph::Format_Dot);
256         #if defined(MEDIAINFO_GRAPHVIZ_YES)
257             if (MediaInfoLib::Config.Inform_Get()==__T("Graph_Mpegh3da_Svg"))
258                 return Export_Graph().Transform(*this, Export_Graph::Graph_Mpegh3da, Export_Graph::Format_Svg);
259         #endif //defined(MEDIAINFO_GRAPHVIZ_YES)
260     #endif //defined(MEDIAINFO_GRAPH_YES) && defined(MEDIAINFO_MPEGH3DA_YES)
261     #if defined(MEDIAINFO_REVTMD_YES)
262         if (MediaInfoLib::Config.Inform_Get()==__T("reVTMD"))
263             return __T("reVTMD is disabled due to its non-free licensing."); //return Export_reVTMD().Transform(*this);
264     #endif //defined(MEDIAINFO_REVTMD_YES)
265 
266     #if defined(MEDIAINFO_CUSTOM_YES)
267 
268     if (!(
269         MediaInfoLib::Config.Inform_Get(__T("General")).empty()
270      && MediaInfoLib::Config.Inform_Get(__T("Video")).empty()
271      && MediaInfoLib::Config.Inform_Get(__T("Audio")).empty()
272      && MediaInfoLib::Config.Inform_Get(__T("Text")).empty()
273      && MediaInfoLib::Config.Inform_Get(__T("Other")).empty()
274      && MediaInfoLib::Config.Inform_Get(__T("Image")).empty()
275      && MediaInfoLib::Config.Inform_Get(__T("Menu")).empty()
276      ))
277     {
278         Ztring Retour;
279         Retour+=MediaInfoLib::Config.Inform_Get(__T("File_Begin"));
280         Retour+=MediaInfoLib::Config.Inform_Get(__T("General_Begin"));
281         Retour+=Inform(Stream_General, 0, false);
282         Retour+=MediaInfoLib::Config.Inform_Get(__T("General_End"));
283         if (Count_Get(Stream_Video))
284             Retour+=MediaInfoLib::Config.Inform_Get(__T("Video_Begin"));
285         for (size_t I1=0; I1<Count_Get(Stream_Video); I1++)
286         {
287             Retour+=Inform(Stream_Video, I1, false);
288             if (I1!=Count_Get(Stream_Video)-1)
289                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Video_Middle"));
290         }
291         if (Count_Get(Stream_Video))
292             Retour+=MediaInfoLib::Config.Inform_Get(__T("Video_End"));
293         if (Count_Get(Stream_Audio))
294             Retour+=MediaInfoLib::Config.Inform_Get(__T("Audio_Begin"));
295         for (size_t I1=0; I1<Count_Get(Stream_Audio); I1++)
296         {
297             Retour+=Inform(Stream_Audio, I1, false);
298             if (I1!=Count_Get(Stream_Audio)-1)
299                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Audio_Middle"));
300         }
301         if (Count_Get(Stream_Audio))
302             Retour+=MediaInfoLib::Config.Inform_Get(__T("Audio_End"));
303         if (Count_Get(Stream_Text))
304             Retour+=MediaInfoLib::Config.Inform_Get(__T("Text_Begin"));
305         for (size_t I1=0; I1<Count_Get(Stream_Text); I1++)
306         {
307             Retour+=Inform(Stream_Text, I1, false);
308             if (I1!=Count_Get(Stream_Text)-1)
309                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Text_Middle"));
310         }
311         if (Count_Get(Stream_Text))
312             Retour+=MediaInfoLib::Config.Inform_Get(__T("Text_End"));
313         if (Count_Get(Stream_Other))
314             Retour+=MediaInfoLib::Config.Inform_Get(__T("Other_Begin"));
315         for (size_t I1=0; I1<Count_Get(Stream_Other); I1++)
316         {
317             Retour+=Inform(Stream_Other, I1, false);
318             if (I1!=Count_Get(Stream_Other)-1)
319                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Other_Middle"));
320         }
321         if (Count_Get(Stream_Other))
322             Retour+=MediaInfoLib::Config.Inform_Get(__T("Other_End"));
323         if (Count_Get(Stream_Image))
324             Retour+=MediaInfoLib::Config.Inform_Get(__T("Image_Begin"));
325         for (size_t I1=0; I1<Count_Get(Stream_Image); I1++)
326         {
327             Retour+=Inform(Stream_Image, I1, false);
328             if (I1!=Count_Get(Stream_Image)-1)
329                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Image_Middle"));
330         }
331         if (Count_Get(Stream_Image))
332             Retour+=MediaInfoLib::Config.Inform_Get(__T("Image_End"));
333         if (Count_Get(Stream_Menu))
334             Retour+=MediaInfoLib::Config.Inform_Get(__T("Menu_Begin"));
335         for (size_t I1=0; I1<Count_Get(Stream_Menu); I1++)
336         {
337             Retour+=Inform(Stream_Menu, I1, false);
338             if (I1!=Count_Get(Stream_Menu)-1)
339                 Retour+=MediaInfoLib::Config.Inform_Get(__T("Menu_Middle"));
340         }
341         if (Count_Get(Stream_Menu))
342             Retour+=MediaInfoLib::Config.Inform_Get(__T("Menu_End"));
343         Retour+=MediaInfoLib::Config.Inform_Get(__T("File_End"));
344 
345         ConvertRetour(Retour);
346 
347         //Special characters
348         ConvertRetourSCX(Retour);
349 
350         return Retour;
351     }
352     #endif //defined(MEDIAINFO_CUSTOM_YES)
353 
354     #if defined(MEDIAINFO_TEXT_YES) || defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES)
355 
356     //Informations
357     #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
358     Node* Node_Main=NULL;
359     Node* Node_MI=NULL;
360     #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
361     Ztring Retour;
362     bool HTML=false;
363     bool XML=false;
364     bool XML_0_7_78_MA=false;
365     bool XML_0_7_78_MI=false;
366     bool JSON=false;
367     bool CSV=false;
368     #if defined(MEDIAINFO_HTML_YES)
369     if (MediaInfoLib::Config.Inform_Get()==__T("HTML"))
370         HTML=true;
371     #endif //defined(MEDIAINFO_HTML_YES)
372     #if defined(MEDIAINFO_XML_YES)
373     if (MediaInfoLib::Config.Inform_Get()==__T("OLDXML"))
374         XML=true;
375     if (MediaInfoLib::Config.Inform_Get()==__T("MAXML"))
376         XML_0_7_78_MA=true;
377     if (MediaInfoLib::Config.Inform_Get()==__T("MIXML") || MediaInfoLib::Config.Inform_Get()==__T("XML"))
378         XML_0_7_78_MI=true;
379     #endif //defined(MEDIAINFO_XML_YES)
380      #if defined(MEDIAINFO_JSON_YES)
381     if (MediaInfoLib::Config.Inform_Get()==__T("JSON"))
382         JSON=true;
383     #endif //defined(MEDIAINFO_JSON_YES)
384     #if defined(MEDIAINFO_CSV_YES)
385     if (MediaInfoLib::Config.Inform_Get()==__T("CSV"))
386         CSV=true;
387     #endif //defined(MEDIAINFO_CSV_YES)
388 
389     if (HTML)
390         Retour+=__T("<html>\n\n<head>\n<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head>\n<body>\n");
391     #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
392     if (XML_0_7_78_MA || XML_0_7_78_MI || JSON)
393     {
394         Node_Main=new Node("media");
395         Ztring Options=Get(Stream_General, 0, General_CompleteName, Info_Options);
396         if (InfoOption_ShowInInform<Options.size() && Options[InfoOption_ShowInInform]==__T('Y'))
397             Node_Main->Add_Attribute("ref", Get(Stream_General, 0, General_CompleteName));
398         if (Info && !Info->ParserName.empty())
399             Node_Main->Add_Attribute("parser", Info->ParserName);
400     }
401     if (XML_0_7_78_MA)
402     {
403         Node_MI=new Node("MediaInfo");
404         Node_MI->Add_Attribute("xmlns", __T("http")+(MediaInfoLib::Config.Https_Get()?Ztring(__T("s")):Ztring())+__T("://mediaarea.net/mediainfo"));
405         Node_MI->Add_Attribute("version", "2.0");
406         Node_Main->Childs.push_back(Node_MI);
407     }
408     if (XML)
409     {
410         if (Node_MI)
411             Node_Main=Node_MI->Add_Child("File");
412         else
413             Node_Main=new Node("File");
414     }
415     #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
416 
417     for (size_t StreamKind=(size_t)Stream_General; StreamKind<Stream_Max; StreamKind++)
418     {
419         //Pour chaque type de flux
420         for (size_t StreamPos=0; StreamPos<(size_t)Count_Get((stream_t)StreamKind); StreamPos++)
421         {
422             //Pour chaque stream
423             if (HTML) Retour+=__T("<table width=\"100%\" border=\"0\" cellpadding=\"1\" cellspacing=\"2\" style=\"border:1px solid Navy\">\n<tr>\n    <td width=\"150\"><h2>");
424             #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
425             Node* Node_Current=NULL;
426             if (XML || XML_0_7_78_MA || XML_0_7_78_MI || JSON) Node_Current=Node_MI?Node_MI->Add_Child("track", true):Node_Main->Add_Child("track", true);
427             #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
428             Ztring B=Get((stream_t)StreamKind, StreamPos, __T("StreamKindPos"));
429             if (!XML && !XML_0_7_78_MA && !XML_0_7_78_MI && !JSON)
430             {
431                 Ztring A=Get((stream_t)StreamKind, StreamPos, __T("StreamKind/String"));
432 
433                 if (!B.empty())
434                 {
435                     if (CSV)
436                         A+=__T(",");
437                     else
438                         A+=MediaInfoLib::Config.Language_Get(__T("  Config_Text_NumberTag"));
439                     A+=B;
440                 }
441                 Retour+=A;
442             }
443             if (HTML) Retour+=__T("</h2></td>\n  </tr>");
444             #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
445             if (XML || XML_0_7_78_MA || XML_0_7_78_MI || JSON)
446             {
447                 Ztring A=Get((stream_t)StreamKind, StreamPos, __T("StreamKind"));
448 
449                 Node_Current->Add_Attribute("type", A);
450                 if (!B.empty()) Node_Current->Add_Attribute("typeorder", B);
451                 Node* Track=new Node();
452                 Track->RawContent=Inform((stream_t)StreamKind, StreamPos, false).To_UTF8();
453                 Node_Current->Childs.push_back(Track);
454             }
455             else
456             #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
457             {
458                 Retour+=MediaInfoLib::Config.LineSeparator_Get();
459                 Retour+=Inform((stream_t)StreamKind, StreamPos, false);
460             }
461 
462             if (HTML) Retour+=__T("</table>\n<br />");
463             if (!XML && !XML_0_7_78_MA && !XML_0_7_78_MI && !JSON) Retour+=MediaInfoLib::Config.LineSeparator_Get();
464         }
465     }
466 
467     if (HTML) Retour+=__T("\n</body>\n</html>\n");
468 
469     if (!CSV && !HTML && !XML && !XML_0_7_78_MA && !XML_0_7_78_MI && !JSON)
470     {
471         if (MediaInfoLib::Config.Inform_Version_Get())
472         {
473             Ztring Name=MediaInfoLib::Config.Language_Get(__T("ReportBy"));
474             int8u Name_Size=MediaInfoLib::Config.Language_Get(__T("  Config_Text_ColumnSize")).To_int8u();
475             if (Name_Size==0)
476                 Name_Size=32; //Default
477             Name.resize(Name_Size, ' ');
478 
479             Retour+=Name;
480             Retour+=MediaInfoLib::Config.Language_Get(__T("  Config_Text_Separator"));
481             Retour+=MediaInfo_Version;
482             Retour+=MediaInfoLib::Config.LineSeparator_Get();
483         }
484 
485         if (MediaInfoLib::Config.Inform_Timestamp_Get())
486         {
487             Ztring Name=MediaInfoLib::Config.Language_Get(__T("CreatedOn"));
488 
489             int8u Name_Size=MediaInfoLib::Config.Language_Get(__T("  Config_Text_ColumnSize")).To_int8u();
490             if (Name_Size==0)
491                 Name_Size=32; //Default
492             Name.resize(Name_Size, ' ');
493 
494             Ztring Date=Ztring().Date_From_Seconds_1970((int64s)time(NULL));
495 
496             Retour+=Name;
497             Retour+=MediaInfoLib::Config.Language_Get(__T("  Config_Text_Separator"));
498             Retour+=Date;
499             Retour+=MediaInfoLib::Config.LineSeparator_Get();
500         }
501     }
502 
503     #if defined(MEDIAINFO_XML_YES)
504         if (XML || XML_0_7_78_MA || XML_0_7_78_MI)
505         {
506             Retour=Ztring().From_UTF8(To_XML(*Node_Main, 0, false, false));
507             delete Node_Main;
508             delete Node_MI;
509         }
510     #endif //MEDIAINFO_XML_YES
511     #if defined(MEDIAINFO_JSON_YES)
512         if (JSON)
513         {
514             Retour=__T("{\n");
515             Node Node_Version("creatingLibrary");
516             Node_Version.Add_Child("name", Ztring("MediaInfoLib"));
517             Node_Version.Add_Child("version", Ztring(MediaInfo_Version).SubString(__T(" - v"), Ztring()));
518             Node_Version.Add_Child("url", Ztring(__T("http")+(MediaInfoLib::Config.Https_Get()?Ztring(__T("s")):Ztring())+__T("://mediaarea.net/MediaInfo")));
519             Retour+=Ztring().From_UTF8(To_JSON(Node_Version, 0, false, false))+__T(",\n");
520 
521             Retour+=Ztring().From_UTF8(To_JSON(*Node_Main, 0, false, false));
522             Retour+=__T("\n}");
523             delete Node_Main;
524             delete Node_MI;
525         }
526     #endif //MEDIAINFO_JSON_YES
527 
528     Retour.FindAndReplace(__T("\\"), __T("|SC1|"), 0, Ztring_Recursive);
529     ConvertRetour(Retour);
530 
531     //Special characters
532     ConvertRetourSCX(Retour);
533 
534     #if MEDIAINFO_TRACE
535         if (XML_0_7_78_MA)
536         {
537             if (MediaInfoLib::Config.Trace_Level_Get() || MediaInfoLib::Config.Inform_Get()==__T("Details"))
538             {
539                 Retour+=__T("<MediaTrace xmlns=\"http")+(MediaInfoLib::Config.Https_Get()?Ztring(__T("s")):Ztring())+__T("://mediaarea.net/mediatrace\" version=\"0.1\">\n");
540                 if (!Details.empty())
541                     Retour+=Ztring().From_UTF8(Details);
542                 else if (Info)
543                     Retour+=Info->Details_Get();
544                 Retour+=__T("\n");
545                 Retour+=__T("</MediaTrace>\n");
546             }
547         }
548     #endif //MEDIAINFO_TRACE
549 
550     return Retour;
551 
552     #else //defined(MEDIAINFO_TEXT_YES) || defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES)
553 
554     return Ztring(); //Disabled
555 
556     #endif //defined(MEDIAINFO_TEXT_YES) || defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES)
557 }
558 
559 //---------------------------------------------------------------------------
560 #if defined(MEDIAINFO_TEXT_YES) || defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES) || defined(MEDIAINFO_CUSTOM_YES)
561 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
562 namespace
563 {
564 struct nested
565 {
566     std::vector<Node*>* Target;
567     Ztring Name;
568 };
569 }
570 #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
Inform(stream_t StreamKind,size_t StreamPos,bool IsDirect)571 Ztring MediaInfo_Internal::Inform (stream_t StreamKind, size_t StreamPos, bool IsDirect)
572 {
573     //Integrity
574     if (StreamKind>=Stream_Max || StreamPos>=Stream[StreamKind].size())
575         return Ztring();
576 
577     if (MediaInfoLib::Config.Inform_Get(__T("General")).empty()
578      && MediaInfoLib::Config.Inform_Get(__T("Video")).empty()
579      && MediaInfoLib::Config.Inform_Get(__T("Audio")).empty()
580      && MediaInfoLib::Config.Inform_Get(__T("Text")).empty()
581      && MediaInfoLib::Config.Inform_Get(__T("Other")).empty()
582      && MediaInfoLib::Config.Inform_Get(__T("Image")).empty()
583      && MediaInfoLib::Config.Inform_Get(__T("Menu")).empty())
584     {
585         Ztring Retour;
586         #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
587         bool XML=false;
588         bool XML_0_7_78=false;
589         bool JSON=false;
590         #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
591 
592         #if defined(MEDIAINFO_HTML_YES)
593         bool HTML=MediaInfoLib::Config.Inform_Get()==__T("HTML")?true:false;
594         #endif //defined(MEDIAINFO_HTML_YES)
595         #if defined(MEDIAINFO_XML_YES)
596         XML=MediaInfoLib::Config.Inform_Get()==__T("OLDXML")?true:false;
597         XML_0_7_78=(MediaInfoLib::Config.Inform_Get()==__T("MAXML") || MediaInfoLib::Config.Inform_Get()==__T("MIXML") || MediaInfoLib::Config.Inform_Get() == __T("XML"))?true:false;
598         if (XML_0_7_78)
599             XML=true;
600         #endif //defined(MEDIAINFO_XML_YES)
601         #if defined(MEDIAINFO_JSON_YES)
602         JSON=MediaInfoLib::Config.Inform_Get()==__T("JSON")?true:false;
603         #endif //defined(MEDIAINFO_JSON_YES)
604         #if defined(MEDIAINFO_CSV_YES)
605         bool CSV=MediaInfoLib::Config.Inform_Get()==__T("CSV")?true:false;
606         #endif //defined(MEDIAINFO_CSV_YES)
607         #if defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES))
608         bool Text=true;
609         #if defined(MEDIAINFO_HTML_YES)
610          if (HTML)
611              Text=false;
612         #endif //defined(MEDIAINFO_HTML_YES)
613         #if defined(MEDIAINFO_XML_YES)
614          if (XML)
615              Text=false;
616         #endif //defined(MEDIAINFO_XML_YES)
617         #if defined(MEDIAINFO_JSON_YES)
618          if (JSON)
619              Text=false;
620         #endif //defined(MEDIAINFO_JSON_YES)
621         #if defined(MEDIAINFO_CSV_YES)
622          if (CSV)
623              Text=false;
624         #endif //defined(MEDIAINFO_CSV_YES)
625         #endif //defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES))
626 
627         #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
628         std::vector<Node*> Fields;
629         std::vector<Node*>* Fields_Current=&Fields;
630         std::vector<Node*>* Extra=NULL;
631         std::vector<nested> Nested;
632         bool ExpandSub=Config.File_ExpandSubs_Get();
633         if ((XML_0_7_78 || JSON) && ExpandSub)
634             Config.File_ExpandSubs_Set(false);
635         #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
636 
637         size_t Size = Count_Get(StreamKind, StreamPos);
638         for (size_t Champ_Pos=0; Champ_Pos<Size; Champ_Pos++)
639         {
640             //Pour chaque champ
641             //Ztring A=Get((stream_t)4, 2, 0, Info_Measure_Text); // TODO Bug sinon? voir Ztring
642             Ztring A=Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Measure_Text); // TODO Bug sinon? voir Ztring
643             bool Shouldshow=false;
644             #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
645             if (XML_0_7_78 || JSON)
646             {
647                 Ztring Options=Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Options);
648                 if (Champ_Pos>=Stream[StreamKind][StreamPos].size())
649                 {
650                     if (InfoOption_ShowInXml>=Options.size() || Options[InfoOption_ShowInXml]==__T('Y'))
651                         Shouldshow=true;
652                 }
653                 else
654                 {
655                     if (InfoOption_ShowInXml<Options.size() && Options[InfoOption_ShowInXml]==__T('Y'))
656                         Shouldshow=true;
657                 }
658             }
659             else
660             #endif //defined(MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
661             if (Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Options)[InfoOption_ShowInInform]==__T('Y'))
662                 Shouldshow=true;
663             if (!Shouldshow && MediaInfoLib::Config.Complete_Get())
664                 Shouldshow=true;
665             if (Shouldshow && !Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Text).empty())
666             {
667                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
668                 //Extra
669                 if ((XML_0_7_78 || JSON) && !Extra && Champ_Pos>=Stream[StreamKind][StreamPos].size())
670                 {
671                     Node* Node_Extra=new Node("extra");
672                     Fields.push_back(Node_Extra);
673                     Fields_Current=Extra=&Node_Extra->Childs;
674                 }
675                 #endif //defined(MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
676 
677                 Ztring Nom=Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Name_Text);
678                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
679                 if (Nom.empty() || XML_0_7_78 || JSON)
680                 #else
681                 if (Nom.empty())
682                 #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
683 
684                     Nom=Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Name); //Texte n'existe pas
685 
686                 //Subs
687                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
688                 if (XML || JSON)
689                 {
690                     const Ztring& NextName=Get((stream_t)StreamKind, StreamPos, Champ_Pos+1, Info_Name);
691                     size_t Nom_ToErase=0;
692 
693                     if (!Nested.empty())
694                     {
695                         nested* LastNested=&Nested[Nested.size()-1];
696                         while(!Nested.empty()
697                          && !(Nom.size()>LastNested->Name.size() && !Nom.rfind(LastNested->Name, LastNested->Name.size()) && Nom[LastNested->Name.size()]==__T(' ')))
698                         {
699                             Fields_Current=LastNested->Target;
700                             Nested.pop_back();
701                             if (Nested.empty())
702                                 break;
703                             LastNested=&Nested[Nested.size()-1];
704                         }
705                         if (Nested.empty())
706                         {
707                             if (Extra)
708                                 Fields_Current=Extra;
709                             else
710                                 Fields_Current=&Fields;
711                         }
712                         else
713                             Nom_ToErase=LastNested->Name.size()+1;
714                     }
715 
716                     if (NextName.size()>Nom.size() && !NextName.rfind(Nom, Nom.size()) && NextName[Nom.size()]==__T(' '))
717                     {
718                         string SubName=Nom.To_UTF8();
719                         size_t Space=SubName.rfind(' ');
720                         if (Space!=(size_t)-1)
721                             SubName.erase(0, Space+1);
722                         size_t NumbersPos=SubName.find_last_not_of("0123456789");
723                         if (NumbersPos!=(size_t)-1)
724                             SubName.resize(NumbersPos+1);
725                         bool IsArray=(NextName.size()==Nom.size()+4 && NextName.find(__T(" Pos"), Nom.size())==Nom.size());
726                         Node* Node_Sub=new Node(SubName.c_str(), IsArray);
727                         Fields_Current->push_back(Node_Sub);
728                         Nested.resize(Nested.size()+1);
729                         nested& LastNested=Nested[Nested.size()-1];
730                         LastNested.Name=Nom;
731                         LastNested.Target=Fields_Current;
732                         Fields_Current=&Node_Sub->Childs;
733                         continue;
734                     }
735                     Nom.erase(0, Nom_ToErase);
736                 }
737                 #endif // defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
738 
739                 #if defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
740                 if (Text)
741                 #endif //defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
742                 {
743                      int8u Nom_Size=MediaInfoLib::Config.Language_Get(__T("  Config_Text_ColumnSize")).To_int8u();
744                      if (Nom_Size==0)
745                         Nom_Size=32; //Default
746                      Nom.resize(Nom_Size, ' ');
747                 }
748                 Ztring Valeur=Get((stream_t)StreamKind, StreamPos, Champ_Pos, Info_Text);
749 
750                 //Handling values with \r\n inside
751                 #if defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
752                 if (Text)
753                 #endif //defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
754                 {
755                     if (Valeur.find(__T('\r'))!=string::npos || Valeur.find(__T('\n'))!=string::npos)
756                     {
757                         Valeur.FindAndReplace(__T("\r\n"), __T(" / "), 0, Ztring_Recursive);
758                         Valeur.FindAndReplace(__T("\r"), __T(" / "), 0, Ztring_Recursive);
759                         Valeur.FindAndReplace(__T("\n"), __T(" / "), 0, Ztring_Recursive);
760                         if (Valeur.size()>=3 && Valeur.rfind(__T(" / "))== Valeur.size()-3)
761                             Valeur.resize(Valeur.size()-3);
762                     }
763                 }
764 
765                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
766                     if ((XML_0_7_78 || JSON) && MediaInfoLib::Config.Info_Get(StreamKind).Read(Champ_Pos, Info_Measure)==__T(" ms"))
767                     {
768                         size_t Decimal = Valeur.find(__T('.'));
769                         size_t Precision=3;
770                         if (Decimal != (size_t)-1)
771                             Precision+=Valeur.size()-Decimal-1;
772                         float64 Ms=Valeur.To_float64();
773                         Valeur.From_Number(Ms/1000, Precision);
774                     }
775                 #endif // defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
776                 Valeur.FindAndReplace(__T("\\"), __T("|SC1|"), 0, Ztring_Recursive);
777                 #if defined(MEDIAINFO_HTML_YES)
778                 if (HTML)
779                 {
780                     size_t Level=Nom.find_first_not_of(__T(" "));
781                     Ztring Prefix;
782                     for (size_t Pos=0; Pos<Level; Pos++)
783                         Prefix+=__T("&nbsp;");
784 
785                     Retour+=__T("  <tr>\n    <td><i>");
786                     Retour+=Prefix+Nom.TrimLeft();
787                     Retour+=__T(" :</i></td>\n    <td colspan=\"3\">");
788                     Retour+=Valeur;
789                     Retour+=__T("</td>\n  </tr>");
790                 }
791                 #endif //defined(MEDIAINFO_HTML_YES)
792                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
793                 if (XML || JSON)
794                 {
795                     if (XML_0_7_78 || JSON)
796                         Nom=Xml_Name_Escape_0_7_78(Nom);
797                     else
798                         Nom=Xml_Name_Escape(Nom);
799                     size_t Modified;
800                     Content_Encode_Modifying(Valeur, Modified);
801                     if ((XML_0_7_78 || JSON) && Nom.size()>8 && Nom.rfind(__T("_Version"))==Nom.size()-8 && Valeur.size()>8 && Valeur.rfind(__T("Version "), 0)==0)
802                     {
803                         Valeur.erase(0, 8); // Remove useless "Version "
804                         size_t SlashPos = Valeur.find(__T(" / "));
805                         if (SlashPos!=string::npos)
806                             Valeur.erase(SlashPos);
807                     }
808                     Ztring Format_Profile_More;
809                     if ((XML_0_7_78 || JSON) && Nom==__T("Format_Profile"))
810                     {
811                         size_t SeparatorPos=Valeur.find(__T('@'));
812                         if (SeparatorPos!=string::npos && Valeur.find(__T(" / "))==string::npos) //TODO: better support of compatibility modes (e.g. "Multiview") and sequences (e.g. different profiles in different files "BCS@L3 / BCS@L2 / BCS@L3")
813                         {
814                             Format_Profile_More=Valeur.substr(SeparatorPos+1);
815                             Valeur.erase(SeparatorPos);
816                         }
817                     }
818                     if ((XML_0_7_78 || JSON) && (Nom==__T("Format_Profile") || Nom==__T("SamplingRate") || Nom==__T("Channel(s)") || Nom==__T("ChannelPositions") || Nom==__T("ChannelLayout")))
819                     {
820                         size_t SlashPos = Valeur.find(__T(" / "));
821                         if (SlashPos!=string::npos)
822                             Valeur.erase(SlashPos);
823                     }
824 
825                     Node* Node_Current=NULL;
826                     Node_Current=new Node(Nom.To_UTF8());
827                     if (Modified==1 && !MediaInfoLib::Config.SkipBinaryData_Get()) //Base64
828                         Node_Current->Add_Attribute("dt", "binary.base64");
829 
830                     if (Modified==1 && MediaInfoLib::Config.SkipBinaryData_Get())
831                         Node_Current->Value="(Binary data)";
832                     else
833                         Node_Current->Value=Valeur.To_UTF8();
834                     Fields_Current->push_back(Node_Current);
835 
836                     if (!Format_Profile_More.empty())
837                     {
838                         if (Format_Profile_More.size()>=2 && Format_Profile_More[0]==__T('L') && Format_Profile_More[1]>=__T('0') && Format_Profile_More[1]<=__T('9'))
839                             Format_Profile_More.erase(0, 1);
840                         size_t SeparatorPos=Format_Profile_More.find(__T('@'));
841                         if (SeparatorPos!=string::npos)
842                         {
843                             Node_Current=new Node("Format_Level", Ztring(Format_Profile_More.substr(0, SeparatorPos)).To_UTF8());
844                             Fields_Current->push_back(Node_Current);
845                             Node_Current=new Node("Format_Tier", Ztring(Format_Profile_More.substr(SeparatorPos+1)).To_UTF8());
846                             Fields_Current->push_back(Node_Current);
847                         }
848                         else
849                         {
850                             Node_Current=new Node("Format_Level", Format_Profile_More.To_UTF8());
851                             Fields_Current->push_back(Node_Current);
852                         }
853                     }
854                 }
855 
856                 #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
857                 #if defined(MEDIAINFO_CSV_YES)
858                 if (CSV)
859                 {
860                     Retour+=Nom;
861                     Retour+=__T(",");
862                     Retour+=Valeur;
863                 }
864                 #endif //defined(MEDIAINFO_CSV_YES)
865                 #if defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
866                 if (Text)
867                 #endif //defined(MEDIAINFO_TEXT_YES) && (defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES) || defined(MEDIAINFO_CSV_YES))
868                     Retour+=Nom + MediaInfoLib::Config.Language_Get(__T("  Config_Text_Separator")) + Valeur;
869                 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
870                 if (!XML && !JSON)
871                 #endif //MEDIAINFO_XML_YES || MEDIAINFO_JSON_YES
872                     Retour+=MediaInfoLib::Config.LineSeparator_Get();
873             }
874         }
875         #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
876         if (ExpandSub)
877             Config.File_ExpandSubs_Set(true);
878         for (size_t Field=0; Field < Fields.size(); Field++)
879         {
880             if (XML)
881                 Retour+=Ztring().From_UTF8(To_XML(*(Fields[Field]), 1, false, false));
882             else if (JSON)
883                 Retour+=Ztring().From_UTF8(To_JSON(*(Fields[Field]), 1, false, false)+(Field<Fields.size()-1?",\n":""));
884             delete Fields[Field];
885         }
886         #endif //defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
887         ConvertRetour(Retour);
888 
889         #if defined(MEDIAINFO_JSON_YES)
890             if (JSON)
891                 Retour.FindAndReplace(__T("|SC1|"), __T("\\\\"), 0, Ztring_Recursive);
892             else
893                 Retour.FindAndReplace(__T("|SC1|"), __T("\\"), 0, Ztring_Recursive);
894         #else
895             Retour.FindAndReplace(__T("|SC1|"), __T("\\"), 0, Ztring_Recursive);
896         #endif
897 
898         return Retour;
899     }
900 
901     Ztring Retour=MediaInfoLib::Config.Inform_Get(Get(StreamKind, 0, __T("StreamKind"), Info_Text));
902 
903     //Special characters
904     Retour.FindAndReplace(__T("\\\\"), __T("|SC1|"), 0, Ztring_Recursive);
905     Retour.FindAndReplace(__T("\\["), __T("|SC2|"), 0, Ztring_Recursive);
906     Retour.FindAndReplace(__T("\\]"), __T("|SC3|"), 0, Ztring_Recursive);
907     Retour.FindAndReplace(__T("\\,"), __T("|SC4|"), 0, Ztring_Recursive);
908     Retour.FindAndReplace(__T("\\;"), __T("|SC5|"), 0, Ztring_Recursive);
909     Retour.FindAndReplace(__T("\\("), __T("|SC6|"), 0, Ztring_Recursive);
910     Retour.FindAndReplace(__T("\\)"), __T("|SC7|"), 0, Ztring_Recursive);
911 
912     //Gestion $xx$
913     size_t PosX=0;
914     while (Retour.find(__T('$'), PosX)!=(size_t)-1)
915     {
916         PosX=Retour.find(__T('$'), PosX);
917         if (Retour.size()>PosX+2 && !(Retour(PosX+1)==__T('i') && Retour(PosX+2)==__T('f') && Retour(PosX+3)==__T('('))) //To keep out "%" without any signification, or "$if(..."
918         {
919             Ztring ARemplacer=Ztring(__T("$")+Retour.SubString(__T("$"), __T("$"), PosX))+__T("$");
920             Ztring RemplacerPar=MediaInfoLib::Config.Language_Get(Retour.SubString(__T("$"), __T("$"), PosX)); //TODO : case sensitive
921             Retour.FindAndReplace(ARemplacer, RemplacerPar);
922         }
923         else if (PosX == (size_t)-1)
924             break;
925         else
926             PosX++;
927     }
928 
929     //Gestion $if()
930     size_t Position=Retour.find(__T("$if("));
931     while (Position!=Error && Position>0)
932     {
933         ZtringList Elements;
934         size_t Elements_Index;
935         Elements.Separator_Set(0, __T(","));
936         Elements.Write(Retour.SubString(__T("$if("), __T(")"), Position));
937         Elements(0)=Elements(0).SubString(__T("%"), __T("%"));
938 
939         //Test if there is something to replace
940         size_t Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Elements(0));
941         if (Pos!=std::string::npos)
942         {
943             if (Get(StreamKind, StreamPos, Pos).size()>0)
944                 Elements_Index=1;
945             else
946                 Elements_Index=2;
947         }
948         else
949             Elements_Index=2;
950 
951         //Replace
952         while (Elements(Elements_Index).SubString(__T("%"), __T("%")).size()>0)
953         {
954             Ztring ToReplace=Elements(Elements_Index).SubString(__T("%"), __T("%"));
955             Ztring ReplacedBy=Get(StreamKind, StreamPos, ToReplace);
956             ReplacedBy.FindAndReplace(__T("\\"), __T("|SC1|"), 0, Ztring_Recursive);
957             ReplacedBy.FindAndReplace(__T("["), __T("|SC2|"), 0, Ztring_Recursive);
958             ReplacedBy.FindAndReplace(__T("]"), __T("|SC3|"), 0, Ztring_Recursive);
959             ReplacedBy.FindAndReplace(__T(","), __T("|SC4|"), 0, Ztring_Recursive);
960             ReplacedBy.FindAndReplace(__T(";"), __T("|SC5|"), 0, Ztring_Recursive);
961             ReplacedBy.FindAndReplace(__T("("), __T("|SC6|"), 0, Ztring_Recursive);
962             ReplacedBy.FindAndReplace(__T(")"), __T("|SC7|"), 0, Ztring_Recursive);
963             ToReplace=Ztring(__T("%"))+ToReplace+Ztring(__T("%"));
964             Elements(Elements_Index).FindAndReplace(ToReplace, ReplacedBy);
965         }
966 
967         Ztring ToReplace=Ztring(__T("$if("))+Retour.SubString(__T("$if("), __T(")"), Position)+__T(")");
968         Retour.FindAndReplace(ToReplace, Elements(Elements_Index));
969         Position=Retour.find(__T("$if("));
970     }
971 
972     //Gestion []
973     while (!Retour.SubString(__T("["), __T("]")).empty())
974     {
975         Ztring Crochets=Retour.SubString(__T("["), __T("]"));
976         Ztring ValueToFind=Crochets.SubString(__T("%"), __T("%"));
977         Ztring ARemplacer=Ztring(__T("[")+Crochets+__T("]"));
978         {
979             Ztring RemplacerPar= Get(StreamKind, StreamPos, ValueToFind);
980             if (RemplacerPar.empty())
981                 Retour.FindAndReplace(ARemplacer, Ztring());
982             else
983             {
984                 //Formate l'interieur
985                 Ztring ATraiter=Crochets;
986                 Ztring Crochets_ARemplacer=__T("%")+ValueToFind+__T("%");
987                 ATraiter.FindAndReplace(Crochets_ARemplacer, RemplacerPar);
988                 Retour.FindAndReplace(ARemplacer, ATraiter);
989             }
990         }
991     }
992 
993     //Gestion %xxx%
994     PosX=0;
995     while (Retour.find(__T('%'), PosX)!=(size_t)-1)
996     {
997         PosX=Retour.find(__T('%'), PosX);
998         if (Retour.size() > PosX + 2
999          && ((Retour[PosX + 1] >= __T('a') && Retour[PosX + 1] <= __T('z'))
1000           || (Retour[PosX + 1] >= __T('A') && Retour[PosX + 1] <= __T('Z')))) //To keep out "%" without any signification
1001         {
1002             Ztring ARemplacer = Ztring(__T("%") + Retour.SubString(__T("%"), __T("%"), PosX)) + __T("%");
1003             Ztring RemplacerPar = Get(StreamKind, StreamPos, Retour.SubString(__T("%"), __T("%"), PosX));
1004             RemplacerPar.FindAndReplace(__T("\\"), __T("|SC1|"), 0, Ztring_Recursive);
1005             RemplacerPar.FindAndReplace(__T("),"), __T("|SC9|"), 0, Ztring_Recursive);
1006             RemplacerPar.FindAndReplace(__T(")"), __T("|SC8|"), 0, Ztring_Recursive);
1007             Retour.FindAndReplace(ARemplacer, RemplacerPar);
1008         }
1009         else if (PosX == (size_t)-1)
1010             break;
1011         else
1012             PosX++;
1013     }
1014 
1015     //Retour=__T("<table width=\"100%\" border=\"0\" cellpadding=\"1\" cellspacing=\"2\" style=\"border:1px solid Navy\">\n<tr>\n    <td width=\"150\">Video #0</td>\n  </tr>\r\n  <tr>\n    <td><i>Codec :</i></td>\n    <td colspan=\"3\">WMV1</td>\n  </tr>\r\n  <tr>\n    <td><i>Codec/Info :</i></td>\n    <td colspan=\"3\">Windows Media Video 7</td>\n  </tr>\r\n  <tr>\n    <td><i>Width :</i></td>\n    <td colspan=\"3\">200 pixels</td>\n  </tr>\r\n  <tr>\n    <td><i>Height :</i></td>\n    <td colspan=\"3\">150 pixels</td>\n  </tr>\r\n  <tr>\n    <td><i>Aspect ratio :</i></td>\n    <td colspan=\"3\">4/3</td>\n  </tr>\r\n  <tr>\n    <td><i>Resolution :</i></td>\n    <td colspan=\"3\">24 bits</td>\n  </tr>\r\n</table>\n");
1016     ConvertRetour(Retour);
1017 
1018     //Special characters
1019     if (IsDirect)
1020     {
1021         ConvertRetourSCX(Retour);
1022     }
1023 
1024     return Retour;
1025 }
1026 #endif //defined(MEDIAINFO_TEXT_YES) || defined(MEDIAINFO_HTML_YES) || defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_CSV_YES) || defined(MEDIAINFO_CUSTOM_YES)
1027 
1028 //---------------------------------------------------------------------------
1029 #if defined(MEDIAINFO_CUSTOM_YES)
Traiter(Ztring & C)1030 void MediaInfo_Internal::Traiter(Ztring &C)
1031 {
1032     //$if(%a%,zezeze%a%,rrere)
1033     size_t Position=C.find(__T("$if("));
1034     while (Position>0)
1035     {
1036         //Recuperation de la chaine entiere
1037         Ztring Total;
1038         Ztring ARemplacer;
1039         ZtringList Total1;
1040         Total1.Separator_Set(0, __T("),"));
1041         Total=C.SubString(__T("$if("), __T(")"), Position);
1042         ARemplacer=Ztring(__T("$if(")+Total+__T(")"));
1043         Total1.Write(Total);
1044         if (Total1(0).empty()) //mettre champ2
1045             C.FindAndReplace(ARemplacer, Total1(2), Position);
1046         else
1047             C.FindAndReplace(ARemplacer, Total1(1), Position);
1048         Position=C.find(__T("$if("), Position);
1049     }
1050 
1051     //reformatage
1052     C.FindAndReplace(__T("|SC8|"), __T(")"), 0, Ztring_Recursive);
1053     C.FindAndReplace(__T("|SC9|"), __T("),"), 0, Ztring_Recursive);
1054     //C.FindAndReplace(__T("\\r\\n"), __T("\n"), 0, Ztring_Recursive);
1055 }
1056 #endif //defined(MEDIAINFO_CUSTOM_YES)
1057 
1058 //---------------------------------------------------------------------------
1059 #if defined(MEDIAINFO_XML_YES)  || defined(MEDIAINFO_JSON_YES)
Xml_Name_Escape(const Ztring & Name)1060 Ztring MediaInfo_Internal::Xml_Name_Escape (const Ztring &Name)
1061 {
1062     Ztring ToReturn(Name);
1063 
1064     if (ToReturn.operator()(0)>='0' && ToReturn.operator()(0)<='9')
1065         ToReturn.insert(0, 1, __T('_'));
1066     ToReturn.FindAndReplace(__T(" "), __T("_"), 0, Ztring_Recursive);
1067     ToReturn.FindAndReplace(__T("/"), __T("_"), 0, Ztring_Recursive);
1068     ToReturn.FindAndReplace(__T("("), __T("_"), 0, Ztring_Recursive);
1069     ToReturn.FindAndReplace(__T(")"), __T("_"), 0, Ztring_Recursive);
1070     ToReturn.FindAndReplace(__T("*"), __T("_"), 0, Ztring_Recursive);
1071     ToReturn.FindAndReplace(__T(","), __T("_"), 0, Ztring_Recursive);
1072     ToReturn.FindAndReplace(__T(":"), __T("_"), 0, Ztring_Recursive);
1073     ToReturn.FindAndReplace(__T("@"), __T("_"), 0, Ztring_Recursive);
1074     size_t ToReturn_Pos=0;
1075     while (ToReturn_Pos<ToReturn.size())
1076     {
1077         if (!(ToReturn[ToReturn_Pos]>=__T('A') && ToReturn[ToReturn_Pos]<=__T('Z'))
1078          && !(ToReturn[ToReturn_Pos]>=__T('a') && ToReturn[ToReturn_Pos]<=__T('z'))
1079          && !(ToReturn[ToReturn_Pos]>=__T('0') && ToReturn[ToReturn_Pos]<=__T('9'))
1080          && !(ToReturn[ToReturn_Pos]==__T('_')))
1081             ToReturn.erase(ToReturn_Pos, 1);
1082         else
1083             ToReturn_Pos++;
1084     }
1085     if (ToReturn.empty())
1086         ToReturn="Unknown";
1087 
1088     return ToReturn;
1089 }
1090 #endif //defined(MEDIAINFO_XML_YES)  || defined(MEDIAINFO_JSON_YES)
1091 
1092 #if defined(MEDIAINFO_XML_YES)
1093 //---------------------------------------------------------------------------
Xml_Content_Escape(const Ztring & Content,size_t & Modified)1094 Ztring MediaInfo_Internal::Xml_Content_Escape (const Ztring &Content, size_t &Modified)
1095 {
1096     Ztring ToReturn(Content);
1097     return Xml_Content_Escape_Modifying(ToReturn, Modified);
1098 }
1099 
1100 //---------------------------------------------------------------------------
Xml_Content_Escape_MustEscape(const Ztring & Content)1101 size_t Xml_Content_Escape_MustEscape(const Ztring &Content)
1102 {
1103     size_t Pos=0;
1104     size_t Size=Content.size();
1105     for (; Pos<Size; Pos++)
1106     {
1107         switch (Content[Pos])
1108         {
1109             case __T('\"'):
1110             case __T('&') :
1111             case __T('\''):
1112             case __T('<') :
1113             case __T('>') :
1114                             return Pos;
1115             default      :
1116                             if (Content[Pos]>=0x0 && Content[Pos]<0x20)
1117                                 return Pos;
1118         }
1119     }
1120 
1121     return Pos;
1122 }
1123 
1124 //---------------------------------------------------------------------------
Xml_Content_Escape_Modifying(Ztring & Content,size_t & Modified)1125 Ztring &MediaInfo_Internal::Xml_Content_Escape_Modifying (Ztring &Content, size_t &Modified)
1126 {
1127     size_t Pos=Xml_Content_Escape_MustEscape(Content);
1128     Ztring Content_Save=Content;
1129     Modified=0;
1130     if (Pos>=Content.size())
1131         return Content;
1132 
1133     for (; Pos<Content.size(); Pos++)
1134     {
1135         switch (Content[Pos])
1136         {
1137             case __T('\"'):
1138                             Content[Pos]=__T('&');
1139                             Content.insert(Pos+1, __T("quot;"));
1140                             Pos+=5;
1141                             break;
1142             case __T('&'):
1143                             Content[Pos]=__T('&');
1144                             Content.insert(Pos+1, __T("amp;"));
1145                             Pos+=4;
1146                             break;
1147             case __T('\''):
1148                             Content[Pos]=__T('&');
1149                             Content.insert(Pos+1, __T("apos;"));
1150                             Pos+=5;
1151                             break;
1152             case __T('<'):
1153                             Content[Pos]=__T('&');
1154                             Content.insert(Pos+1, __T("lt;"));
1155                             Pos+=3;
1156                             break;
1157             case __T('>'):
1158                             Content[Pos]=__T('&');
1159                             Content.insert(Pos+1, __T("gt;"));
1160                             Pos+=3;
1161                             break;
1162             case __T('\r'):
1163             case __T('\n'):
1164                             break;
1165             default:
1166                         if (Content[Pos]>=0x0 && Content[Pos]<0x20)
1167                         {
1168                             /* Is still invalid XML
1169                             Ztring Character=__T("#x")+Ztring::ToZtring(Content[Pos]/16, 16)+Ztring::ToZtring(Content[Pos]%16, 16)+__T(";");
1170                             Content[Pos]=__T('&');
1171                             Content.insert(Pos+1, Character);
1172                             Pos+=5;
1173                             */
1174                             string Content_Utf8=Content_Save.To_UTF8(); //TODO: shouldn't we never convert to Unicode?
1175                             string Content_Base64=Base64::encode(Content_Utf8);
1176                             Content.From_UTF8(Content_Base64);
1177                             Modified=1; //Base64
1178                             Pos=Content.size(); //End
1179                         }
1180         }
1181     }
1182 
1183     return Content;
1184 }
1185 #endif //defined(MEDIAINFO_XML_YES)
1186 
1187 #if defined(MEDIAINFO_XML_YES) || defined(MEDIAINFO_JSON_YES)
1188 //---------------------------------------------------------------------------
Content_MustEncode(const Ztring & Content)1189 size_t Content_MustEncode (const Ztring &Content)
1190 {
1191     size_t Pos=0;
1192     size_t Size=Content.size();
1193     for (; Pos<Size; Pos++)
1194         if (Content[Pos]>=0x0 && Content[Pos]<0x20)
1195             return Pos;
1196 
1197     return Pos;
1198 }
1199 
1200 //---------------------------------------------------------------------------
Content_Encode_Modifying(Ztring & Content,size_t & Modified)1201 Ztring &MediaInfo_Internal::Content_Encode_Modifying (Ztring &Content, size_t &Modified)
1202 {
1203     size_t Pos=Content_MustEncode(Content);
1204     Ztring Content_Save=Content;
1205     Modified=0;
1206     if (Pos>=Content.size())
1207         return Content;
1208 
1209     for (; Pos<Content.size(); Pos++)
1210     {
1211         if (Content[Pos]>=0x0 && Content[Pos]<0x20)
1212         {
1213             string Content_Utf8=Content_Save.To_UTF8(); //TODO: shouldn't we never convert to Unicode?
1214             string Content_Base64=Base64::encode(Content_Utf8);
1215             Content.From_UTF8(Content_Base64);
1216             Modified=1; //Base64
1217             Pos=Content.size(); //End
1218         }
1219     }
1220 
1221     return Content;
1222 }
1223 #endif
1224 
1225 } //NameSpace
1226