//---------------------------------------------------------------------------
void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, size_t Parameter, const Ztring &Value, bool Replace)
{
    //Integrity
    if (StreamKind>Stream_Max)
        return;

    //Handling values with \r\n inside
    if (Value.find(_T('\r'))!=string::npos || Value.find(_T('\n'))!=string::npos)
    {
        Ztring NewValue=Value;
        NewValue.FindAndReplace(_T("\r\n"), _T(" / "), 0, Ztring_Recursive);
        NewValue.FindAndReplace(_T("\r"), _T(" / "), 0, Ztring_Recursive);
        NewValue.FindAndReplace(_T("\n"), _T(" / "), 0, Ztring_Recursive);
        if (NewValue.size()>=3 && NewValue.rfind(_T(" / "))==NewValue.size()-3)
            NewValue.resize(NewValue.size()-3);
        Fill(StreamKind, StreamPos, Parameter, NewValue, Replace);
        return;
    }

    //Handle Value before StreamKind
    if (StreamKind==Stream_Max || StreamPos>=(*Stream)[StreamKind].size())
    {
        ZtringList NewList;
        NewList.push_back(Ztring().From_Number(Parameter));
        NewList.push_back(Value);
        Fill_Temp.push_back(NewList);
        return; //No streams
    }

    Ztring &Target=(*Stream)[StreamKind][StreamPos](Parameter);
    if (Target.empty() || Replace)
        Target=Value; //First value
    else if (Value.empty())
        Target.clear(); //Empty value --> clear other values
    else
    {
        Target+=MediaInfoLib::Config.TagSeparator_Get();
        Target+=Value;
    }
}
//---------------------------------------------------------------------------
void File_Dsdiff::DSD__PROP_CHNL()
{
    Element_Name("Channels");

    //Parsing
    int16u numChannels;
    vector<int32u> chIDs;
    Get_B2 (numChannels,                                        "numChannels");
    while (Element_Offset<Element_Size)
    {
        int32u chID;
        Get_C4 (chID,                                           "chID");
        chIDs.push_back(chID);
    }

    FILLING_BEGIN();
        Fill(Stream_Audio, 0, Audio_Channel_s_, numChannels);
        int32u ChannelPositions=0;
        int32u ChannelPositions2=0;
        ZtringList ChannelLayout;
        ChannelLayout.Separator_Set(0, __T(" "));
        for (size_t i=0; i<chIDs.size(); i++)
        {
            DSDIFF_CHNL_chID_ChannelPositions(chIDs[i], ChannelPositions);
            DSDIFF_CHNL_chID_ChannelPositions2(chIDs[i], ChannelPositions2);
            ChannelLayout.push_back(DSDIFF_CHNL_chID(chIDs[i]));
        }
        Ztring ChannelPositions_New=DSDIFF_CHNL_chID_ChannelPositions(ChannelPositions);
        const Ztring& ChannelPositions_Old=Retrieve_Const(Stream_Audio, 0, Audio_ChannelPositions);
        if (ChannelPositions_New!=ChannelPositions_Old)
            Fill(Stream_Audio, 0, Audio_ChannelPositions, ChannelPositions_New);
        Ztring ChannelPositions2_New=DSDIFF_CHNL_chID_ChannelPositions2(ChannelPositions2);
        const Ztring& ChannelPositions2_Old=Retrieve_Const(Stream_Audio, 0, Audio_ChannelPositions_String2);
        if (ChannelPositions2_New!=ChannelPositions2_Old)
            Fill(Stream_Audio, 0, Audio_ChannelPositions_String2, ChannelPositions2_New);
        const Ztring& ChannelLayout_New=ChannelLayout.Read();
        const Ztring& ChannelLayout_Old=Retrieve_Const(Stream_Audio, 0, Audio_ChannelLayout);
        if (ChannelLayout_New!=ChannelLayout_Old)
            Fill(Stream_Audio, 0, Audio_ChannelLayout, ChannelLayout_New);
    FILLING_END();
}
Exemple #3
0
ZtringList Dir::GetAllFileNames(const Ztring &Dir_Name_, dirlist_t Options)
{
    ZtringList ToReturn;
    Ztring Dir_Name=Dir_Name_;

    #ifdef ZENLIB_USEWX
        int Flags=wxDIR_FILES | wxDIR_DIRS;

        //Search for files
        wxArrayString Liste;
        wxFileName FullPath; FullPath=Dir_Name.c_str();
        //-File
        if (FullPath.FileExists())
        {
            FullPath.Normalize();
            Liste.Add(FullPath.GetFullPath());
        }
        //-Directory
        else if (FullPath.DirExists())
        {
            FullPath.Normalize();
            wxDir::GetAllFiles(FullPath.GetFullPath(), &Liste, Ztring(), Flags);
        }
        //-WildCards
        else
        {
            wxString FileName=FullPath.GetFullName();
            FullPath.SetFullName(Ztring()); //Supress filename
            FullPath.Normalize();
            if (FullPath.DirExists())
                wxDir::GetAllFiles(FullPath.GetPath(), &Liste, FileName, Flags);
        }

        //Compatible array
        ToReturn.reserve(Liste.GetCount());
        for (size_t Pos=0; Pos<Liste.GetCount(); Pos++)
            ToReturn.push_back(Liste[Pos].c_str());
    #else //ZENLIB_USEWX
        #ifdef WINDOWS
            //Is a dir?
            if (Exists(Dir_Name))
                Dir_Name+=_T("\\*");

            //Path
            Ztring Path=FileName::Path_Get(Dir_Name);
            if (Path.empty())
            {
                #ifdef UNICODE
                    #ifndef ZENLIB_NO_WIN9X_SUPPORT
                    if (IsWin9X_Fast())
                    {
                        DWORD Path_Size=GetFullPathNameA(Dir_Name.To_Local().c_str(), 0, NULL, NULL);
                        char* PathTemp=new char[Path_Size+1];
                        if (GetFullPathNameA(Dir_Name.To_Local().c_str(), Path_Size+1, PathTemp, NULL))
                            Path=FileName::Path_Get(PathTemp);
                        delete [] PathTemp; //PathTemp=NULL;
                    }
                    else
                    #endif //ZENLIB_NO_WIN9X_SUPPORT
                    {
                        DWORD Path_Size=GetFullPathName(Dir_Name.c_str(), 0, NULL, NULL);
                        Char* PathTemp=new Char[Path_Size+1];
                        if (GetFullPathNameW(Dir_Name.c_str(), Path_Size+1, PathTemp, NULL))
                            Path=FileName::Path_Get(PathTemp);
                        delete [] PathTemp; //PathTemp=NULL;
                    }
                #else
                    DWORD Path_Size=GetFullPathName(Dir_Name.c_str(), 0, NULL, NULL);
                    Char* PathTemp=new Char[Path_Size+1];
                    if (GetFullPathName(Dir_Name.c_str(), Path_Size+1, PathTemp, NULL))
                        Path=FileName::Path_Get(PathTemp);
                    delete [] PathTemp; //PathTemp=NULL;
                #endif //UNICODE
            }

            #ifdef UNICODE
                WIN32_FIND_DATAW FindFileDataW;
                HANDLE hFind;
                #ifndef ZENLIB_NO_WIN9X_SUPPORT
                WIN32_FIND_DATAA FindFileDataA;
                if (IsWin9X_Fast())
                    hFind=FindFirstFileA(Dir_Name.To_Local().c_str(), &FindFileDataA);
                else
                #endif //ZENLIB_NO_WIN9X_SUPPORT
                    hFind=FindFirstFileW(Dir_Name.c_str(), &FindFileDataW);
            #else
                WIN32_FIND_DATA FindFileData;
                HANDLE hFind=FindFirstFile(Dir_Name.c_str(), &FindFileData);
            #endif //UNICODE

            if (hFind==INVALID_HANDLE_VALUE)
                return ZtringList();

            BOOL ReturnValue;
            do
            {
                #ifdef UNICODE
                    Ztring File_Name;
                    #ifndef ZENLIB_NO_WIN9X_SUPPORT
                    if (IsWin9X_Fast())
                        File_Name=FindFileDataA.cFileName;
                    else
                    #endif //ZENLIB_NO_WIN9X_SUPPORT
                        File_Name=FindFileDataW.cFileName;
                #else
                    Ztring File_Name(FindFileData.cFileName);
                #endif //UNICODE
                if (File_Name!=_T(".") && File_Name!=_T("..")) //Avoid . an ..
                {
                    Ztring File_Name_Complete=Path+_T("\\")+File_Name;
                    if (Exists(File_Name_Complete))
                    {
                        if (Options&Parse_SubDirs)
                            ToReturn+=GetAllFileNames(File_Name_Complete, Options); //A SubDir
                    }
                    else if ((Options&Include_Hidden) || (!File_Name.empty() && File_Name[0]!=_T('.')))
                        ToReturn.push_back(File_Name_Complete); //A file
                }
                #ifdef UNICODE
                    #ifndef ZENLIB_NO_WIN9X_SUPPORT
                    if (IsWin9X_Fast())
                        ReturnValue=FindNextFileA(hFind, &FindFileDataA);
                    else
                    #endif //ZENLIB_NO_WIN9X_SUPPORT
                        ReturnValue=FindNextFileW(hFind, &FindFileDataW);
                #else
                    ReturnValue=FindNextFile(hFind, &FindFileData);
                #endif //UNICODE
            }
            while (ReturnValue);

            FindClose(hFind);
        #else //WINDOWS
            //A file?
            if (File::Exists(Dir_Name))
            {
               ToReturn.push_back(Dir_Name); //TODO
               return ToReturn;
            }

            //A dir?
            if (!Dir::Exists(Dir_Name))
                return ToReturn; //Does not exist

            //open
            #ifdef UNICODE
                DIR* Dir=opendir(Dir_Name.To_Local().c_str());
            #else
                DIR* Dir=opendir(Dir_Name.c_str());
            #endif //UNICODE
            if (Dir)
            {
                //This is a dir
                //Normalizing dir (the / at the end)
                size_t Dir_Pos=Dir_Name.rfind(FileName_PathSeparator);
                if (Dir_Pos==std::string::npos)
                    Dir_Name+=FileName_PathSeparator;
                else if (Dir_Pos+Ztring(FileName_PathSeparator).size()!=Dir_Name.size())
                    Dir_Name+=FileName_PathSeparator;

                struct dirent *DirEnt;
                while((DirEnt=readdir(Dir))!=NULL)
                {
                    //A file
                    Ztring File_Name(DirEnt->d_name);
                    if (File_Name!=_T(".") && File_Name!=_T("..")) //Avoid . an ..
                    {
                        Ztring File_Name_Complete=Dir_Name+File_Name;
                        if (Exists(File_Name_Complete))
                        {
                            if (Options&Parse_SubDirs)
                                ToReturn+=GetAllFileNames(File_Name_Complete, Options); //A SubDir
                        }
                        else if ((Options&Include_Hidden) || (!File_Name.empty() && File_Name[0]!=_T('.')))
                            ToReturn.push_back(File_Name_Complete); //A file
                    }
                }

                //Close it
                closedir(Dir);
            }
            else
            {
                glob_t globbuf;
                if (glob(Dir_Name.To_Local().c_str(), GLOB_NOSORT, NULL, &globbuf)==0)
                {
                    for (int Pos=0; Pos<globbuf.gl_pathc; Pos++)
                        ToReturn.push_back(Ztring().From_Local(globbuf.gl_pathv[Pos]));
                }
            }
        #endif
    #endif //ZENLIB_USEWX

    return ToReturn;
}
//---------------------------------------------------------------------------
size_t MediaInfoList_Internal::Open(const String &File_Name, const fileoptions_t Options)
{
    //Option FileOption_Close
    if (Options & FileOption_CloseAll)
        Close(All);

    //Option Recursive
    //TODO

    //Get all filenames
    ZtringList List;
    if ((File_Name.size()>=7
      && File_Name[0]==_T('h')
      && File_Name[1]==_T('t')
      && File_Name[2]==_T('t')
      && File_Name[3]==_T('p')
      && File_Name[4]==_T(':')
      && File_Name[5]==_T('/')
      && File_Name[6]==_T('/'))
     || (File_Name.size()>=6
      && File_Name[0]==_T('f')
      && File_Name[1]==_T('t')
      && File_Name[2]==_T('p')
      && File_Name[3]==_T(':')
      && File_Name[4]==_T('/')
      && File_Name[5]==_T('/'))
     || (File_Name.size()>=6
      && File_Name[0]==_T('m')
      && File_Name[1]==_T('m')
      && File_Name[2]==_T('s')
      && File_Name[3]==_T(':')
      && File_Name[4]==_T('/')
      && File_Name[5]==_T('/'))
     || (File_Name.size()>=7
      && File_Name[0]==_T('m')
      && File_Name[1]==_T('m')
      && File_Name[2]==_T('s')
      && File_Name[3]==_T('h')
      && File_Name[4]==_T(':')
      && File_Name[5]==_T('/')
      && File_Name[6]==_T('/')))
        List.push_back(File_Name);
    else if (File::Exists(File_Name))
        List.push_back(File_Name);
    else
        List=Dir::GetAllFileNames(File_Name, (Options&FileOption_NoRecursive)?Dir::Nothing:Dir::Parse_SubDirs);

    Reader_Directory::Directory_Cleanup(List);

    //Registering files
    CS.Enter();
    if (ToParse.empty())
        CountValid=0;
    for (ZtringList::iterator L=List.begin(); L!=List.end(); L++)
        ToParse.push(*L);
    ToParse_Total+=List.size();
    if (ToParse_Total)
        State=ToParse_AlreadyDone*10000/ToParse_Total;
    else
        State=10000;
    CS.Leave();

    //Parsing
    if (BlockMethod==1)
    {
        CS.Enter();
        if (!IsRunning()) //If already created, the routine will read the new files
        {
            RunAgain();
            IsInThread=true;
        }
        CS.Leave();
        return 0;
    }
    else
    {
        Entry(); //Normal parsing
        return Count_Get();
    }
}
Exemple #5
0
//---------------------------------------------------------------------------
void File_Ptx::Read_Buffer_Continue()
{
    if (File_Offset || Buffer_Offset)
    {
        if (Buffer_Size)
            Reject(); //Problem
        return;
    }

    //Parsing
    ZtringList Names;
    Ztring LibraryName, LibraryVersion, Format, Directory;
    int32u LibraryName_Length, LibraryVersion_Length, LibraryRelease_Length, Format_Length, Platform_Length, Info_Count, Names_Count, Info_Length, Name_Length, FileName_Count, Directory_Length;
    int32u Unknown_Length;
    int16u Audio_Count;
    Element_Begin1("Header");
        Skip_B1(                                                "Magic");
        Skip_Local(16,                                          "Magic");
        Skip_L2(                                                "0x0500");
        Skip_L1(                                                "Unknown");
        Skip_L1(                                                "0x5A");
        Skip_L2(                                                "0x0001");
        Skip_L2(                                                "0x0004");
        Skip_L2(                                                "0x0000");
        Skip_L4(                                                "Unknown");
        Skip_L2(                                                "0x035A");
        Skip_L2(                                                "0x6400");
        Skip_L2(                                                "0x0000");
        Skip_L2(                                                "0x0300");
        Skip_L2(                                                "0x0000");
        Get_L4 (LibraryName_Length,                             "WritingLibrary name length");
        Get_UTF8(LibraryName_Length, LibraryName,               "Library name");
        Skip_L4(                                                "0x00000003");
        Skip_L4(                                                "Library version, major");
        Skip_L4(                                                "Library version, minor");
        Skip_L4(                                                "Library version, revision");
        Get_L4 (LibraryVersion_Length,                          "Library version length");
        Get_UTF8(LibraryVersion_Length, LibraryVersion,         "Library version");
        Skip_L1(                                                "0x01");
        Get_L4 (LibraryRelease_Length,                          "Library release length");
        Skip_UTF8(LibraryRelease_Length,                        "Library release");
        Skip_L1(                                                "0x00");
        Get_L4 (Format_Length,                                  "Format length");
        Get_UTF8(Format_Length, Format,                         "Format");
        if (Format!=__T("Pro Tools Session File"))
        {
            Element_End();
            Reject("Ptx");
            return;
        }
        Skip_L2(                                                "0x0006");
        Get_L4 (Platform_Length,                                "Platform length");
        Skip_UTF8(Platform_Length,                              "Platform");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x00085A05");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "0x00002067");
        Skip_L4(                                                "0x002A0000");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "Unknown");
    Element_End();
    Element_Begin1("Info list");
        Get_L4 (Info_Count,                                     "Info count");
        if (4*Info_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int32u Pos=0; Pos<Info_Count; Pos++)
        {
            Element_Begin1("Info");
            Get_L4 (Info_Length,                                "Info length");
            if (Info_Length)
            {
                Info_UTF8(Info_Length, Info,                    "Name"); Element_Info1(Info);
            }
            Element_End();
        }
    Element_End();
    Element_Begin1("Unknown");
        Skip_L4(                                                "0x00000000");
        Element_Begin1("Names list 1");
        Get_L4 (Names_Count,                                    "Names count minus 1");
        if (4*Names_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int16u Pos=0; Pos<1+Names_Count; Pos++)
        {
            Element_Begin1("Name");
            Get_L4 (Name_Length,                                "Name length");
            if (Name_Length)
            {
                Info_UTF8(Name_Length, Name,                    "Name"); Element_Name(Name);
            }
            Element_End();
        }
        Element_End();
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "Unknown");
        Element_Begin1("Names list 2");
        Get_L4 (Names_Count,                                    "Names count");
        if (4*Names_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int16u Pos=0; Pos<Names_Count; Pos++)
        {
            Element_Begin1("Name");
            Get_L4 (Name_Length,                                "Name length");
            if (Name_Length)
            {
                Info_UTF8(Name_Length, Name,                    "Name"); Element_Name(Name);
            }
            Element_End();
        }
        Element_End();
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "0x00000101");
        Skip_L4(                                                "0x00055A00");
        Skip_L4(                                                "Unknown");
        Skip_L4(                                                "0x00012519");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x00000001");
        Skip_L2(                                                "0x0003");
    Element_End();
    Get_L2 (Audio_Count,                                        "Audio count");
    if (111*Audio_Count>Element_Size)
    {
        Reject();
        return;
    }
    Element_Begin1("Audio tracks list 1");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        Skip_L4(                                                "0x00000000");
        Get_L4 (Unknown_Length,                                 "Name length");
        Info_UTF8(Unknown_Length, Name,                         "Name");
        Skip_L2(                                                "0x0000");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Info_L1(Number,                                         "Ordered number"); Element_Info1(Number);
        Element_Info1(Name);
        Element_End();

        Names.push_back(Name);
    }
    Element_End();
    Skip_L2(                                                    "0x0000");
    Element_Begin1("Audio tracks list 2");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        int32u Size;
        Skip_L3(                                                "0x00025A");
        Get_L4 (Size,                                           "Size");
        Skip_L4(                                                "0x0000251A");
        Get_L4 (Unknown_Length,                                 "Name length");
        Info_UTF8(Unknown_Length, Name,                         "Name");
        Skip_L2(                                                "0x0000");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Info_L1(Number,                                         "Ordered number"); Element_Info1(Number);
        Skip_L4(                                                "0x00000000");
        Element_Info1(Name);
        if (Unknown_Length+31!=Size)
        {
            Reject();
            return;
        }
        Element_End();
    }
    Element_End();
    Get_L2 (Audio_Count,                                        "Audio count");
    if (4*Audio_Count>Element_Size)
    {
        Reject();
        return;
    }
    Skip_L2(                                                    "0x00");
    Element_Begin1("Audio tracks list 3");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        int32u Size;
        Skip_L3(                                                "0x00025A");
        Get_L4 (Size,                                           "Size");
        Skip_L4(                                                "0x0000251A");
        Get_L4 (Unknown_Length,                                 "Name length");
        Info_UTF8(Unknown_Length, Name,                         "Name");
        Skip_L2(                                                "0x0000");
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Skip_L4(                                                "Unknown (same 1/2/3)");
        Info_L1(Number,                                         "Ordered number"); Element_Info1(Number);
        Skip_L4(                                                "0x00000000");
        Element_Info1(Name);
        if (Unknown_Length+31!=Size)
        {
            Reject();
            return;
        }
        Element_End();
    }
    Element_End();
    Skip_L2(                                                    "0x0000");
    Skip_L2(                                                    "0x0018");
    Skip_L4(                                                    "0x00000001");
    Skip_L2(                                                    "0x0018");
    Skip_L4(                                                    "0x00000001");
    Skip_L2(                                                    "0x0001");
    Skip_L3(                                                    "0x00095A");
    Get_L4 (Unknown_Length,                                     "Opaque length");
    Skip_XX(Unknown_Length,                                     "Opaque");
    Skip_L3(                                                    "0x00045A");
    Skip_L4(                                                    "0x00000016");
    Skip_L4(                                                    "0x06002026");
    Skip_L4(                                                    "0x00000000");
    Skip_L2(                                                    "0x0000");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "0x00000000");
    Skip_L3(                                                    "0x00025A");
    Skip_L4(                                                    "0x00000015");
    Skip_L4(                                                    "0x075A2032");
    Skip_L4(                                                    "0x00000C00");
    Skip_L4(                                                    "0x01204200");
    Skip_L4(                                                    "0x01000000");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "0x00025A00");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "0x015A0000");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "Unknown");
    Skip_L4(                                                    "0x01000000");
    Get_L4 (FileName_Count,                                     "File name count");
    if (13*FileName_Count>Element_Size)
    {
        Reject();
        return;
    }
    Get_L4 (Directory_Length,                                   "Directory length");
    Get_UTF8(Directory_Length, Directory,                       "Directory");
    Skip_L4(                                                    "0x00000000");
    Element_Begin1("File names");
    size_t Pos_Offset=0;
    for (int32u Pos=0; Pos<FileName_Count; Pos++)
    {
        Ztring Name;
        int32u Name_Length, Purpose;
        Element_Begin1("File names");
        Skip_L1(                                                "0x0002");
        Skip_L4(                                                "Ordered number except WAV files and -1");
        Get_L4 (Name_Length,                                    "Name length");
        Get_UTF8(Name_Length, Name,                             "Name"); Element_Name(Name);
        Get_C4 (Purpose,                                        "Purpose (e.g. EVAW for .wav files)");
        Element_End();

        switch (Purpose)
        {
            case 0x45564157:
                            if (Pos-Pos_Offset<Names.size()
                             && (Name.find(Names[Pos-Pos_Offset])==0
                              || Name.find(Names[Pos-Pos_Offset]+__T(".wav"))+5==Name.size()))
                            {
                                File__ReferenceFilesHelper::reference ReferenceFile;
                                ReferenceFile.StreamKind=Stream_Audio;
                                ReferenceFile.FileNames.push_back(Directory+PathSeparator+Name);
                                ReferenceFiles->References.push_back(ReferenceFile);
                            }
                            else if (ReferenceFiles->References.empty())
                                Pos_Offset++;
            default:        ;
        }

    }
    Element_End();
    Skip_XX(Element_Size-Element_Offset,                        "Unknown");

    FILLING_BEGIN();
        Accept("Ptx"); //Could be Ptf (former formatn but not supported, so we don't care currently
        Fill("Ptx");
        Fill(Stream_General, 0, General_Format, "Pro Tools Session");
        Fill(Stream_General, 0, General_Format_Version, "Version 10");
        Fill(Stream_General, 0, General_Encoded_Library_Name, LibraryName);
        Fill(Stream_General, 0, General_Encoded_Library_Version, LibraryVersion);
    FILLING_END();
}
Exemple #6
0
//---------------------------------------------------------------------------
void File_Ptx::Read_Buffer_Continue()
{
    if (File_Offset || Buffer_Offset)
    {
        if (Buffer_Size)
            Reject(); //Problem
        return;
    }

    //Parsing
    ZtringList Names;
    Ztring LibraryName, LibraryVersion, Format, Directory;
    int32u LibraryName_Length, LibraryVersion_Length, LibraryRelease_Length, Format_Length, Platform_Length, Info_Count, Names_Count, Info_Length, Name_Length, FileName_Count, Directory_Length;
    int32u Opaque2_Length, Audio_Count;
    int16u Opaque1_Length;
    Element_Begin1("Header");
        Skip_B1(                                                "Magic");
        Skip_Local(16,                                          "Magic");
        Skip_L2(                                                "0x0500");
        Skip_L1(                                                "Unknown [1]");
        Skip_L1(                                                "0x5A [1]");
        Skip_L2(                                                "0x0001");
        Skip_L2(                                                "0x0004");
        Skip_L2(                                                "0x0000 [1]");
        Skip_L4(                                                "Unknown [2]");
        Skip_L2(                                                "0x035A");
        Skip_L2(                                                "0x6400");
        Skip_L2(                                                "0x0000 [1]");
        Skip_L2(                                                "0x0300");
        Skip_L2(                                                "0x0000 [1]");
        Get_L4 (LibraryName_Length,                             "WritingLibrary name length");
        Get_UTF8(LibraryName_Length, LibraryName,               "Library name");
        Skip_L4(                                                "0x00000003");
        Skip_L4(                                                "Library version, major");
        Skip_L4(                                                "Library version, minor");
        Skip_L4(                                                "Library version, revision");
        Get_L4 (LibraryVersion_Length,                          "Library version length");
        Get_UTF8(LibraryVersion_Length, LibraryVersion,         "Library version");
        Skip_L1(                                                "0x01");
        Get_L4 (LibraryRelease_Length,                          "Library release length");
        Skip_UTF8(LibraryRelease_Length,                        "Library release");
        Skip_L1(                                                "0x00 [1]");
        Get_L4 (Format_Length,                                  "Format length");
        Get_UTF8(Format_Length, Format,                         "Format");
        if (Format!=__T("Pro Tools Session File"))
        {
            Element_End();
            Reject();
            return;
        }
        Skip_L2(                                                "0x0006");
        Get_L4 (Platform_Length,                                "Platform length");
        Skip_UTF8(Platform_Length,                              "Platform");
        Skip_L4(                                                "0x00000000");
        Skip_L2(                                                "0x5A05");
        Get_L2 (Opaque1_Length,                                 "Info list, Opaque length"); //0x0006 (10.2-) or 0x0008 (10.3+)
        Skip_L4(                                                "Unknown [3]");
        Skip_L4(                                                "0x00002067");
        Skip_L2(                                                "0x0000 [1]");
        Skip_L2(                                                "0x0000 (once) or 0x002A");
        Skip_L2(                                                "0x0000 [1]");
        Skip_L2(                                                "Unknown [4]");
        Skip_L4(                                                "Unknown [5]");
        Skip_L4(                                                "Unknown [6]");
    Element_End();
    Element_Begin1("Info list");
        Get_L4 (Info_Count,                                     "Info count");
        if (4*Info_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int32u Pos=0; Pos<Info_Count; Pos++)
        {
            Element_Begin1("Info");
            Get_L4 (Info_Length,                                "Info length");
            if (Info_Length)
            {
                Info_UTF8(Info_Length, Info,                    "Name"); Element_Info1(Info);
            }
            Element_End();
        }
    Element_End();
    Element_Begin1("Unknown");
        Skip_L4(                                                "0x00000000");
        Element_Begin1("Names list 1");
        Get_L4 (Names_Count,                                    "Names count minus 1");
        if (4*Names_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int16u Pos=0; Pos<1+Names_Count; Pos++)
        {
            Element_Begin1("Name");
            Get_L4 (Name_Length,                                "Name length");
            if (Name_Length)
            {
                Info_UTF8(Name_Length, Name,                    "Name"); Element_Name(Name);
            }
            Element_End();
        }
        Element_End();
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x00000000 or 0x0000002A");
        Skip_L4(                                                "Unknown [7]");
        Skip_L4(                                                "Unknown [8]");
        Element_Begin1("Names list 2");
        Get_L4 (Names_Count,                                    "Names count");
        if (4*Names_Count>Element_Size)
        {
            Element_End();
            Reject();
            return;
        }
        for (int16u Pos=0; Pos<Names_Count; Pos++)
        {
            Element_Begin1("Name");
            Get_L4 (Name_Length,                                "Name length");
            if (Name_Length)
            {
                Info_UTF8(Name_Length, Name,                    "Name"); Element_Name(Name);
            }
            Element_End();
        }
        Element_End();
        Skip_L4(                                                "0x00000000");
        Skip_L4(                                                "0x0000002A [1]");
        Skip_L4(                                                "Unknown [9]");
        Skip_L4(                                                "Unknown [10]");
        Skip_L4(                                                "0x00000000");
        Skip_L1(                                                "0x00 or 0x01 [2]");
        Skip_L1(                                                "0x01");
        Skip_L1(                                                "0x00 or 0x01 or 0x02");
        Skip_L1(                                                "0x00 [2]");
        Skip_L1(                                                "0x01");
        Skip_L1(                                                "0x00 (once) or 0x01");
        Skip_L1(                                                "0x00 or 0x01 (once)");
        Skip_L1(                                                "0x00 or 0x01 (once) or 0x5A");
        if (Opaque1_Length<6)
        {
            if (Opaque1_Length)
                Skip_XX(Opaque1_Length,                         "Opaque1");
        }
        else
        {
            Skip_L4(                                            "Opaque1 - Unknown [1]");
            Skip_L2(                                            "Opaque1 - Unknown [2]");
            if (Opaque1_Length<8)
            {
                if (Opaque1_Length-6)
                    Skip_XX(Opaque1_Length-6,                   "Opaque1 - Unknown [3]");
            }
            else
            {
                Skip_L2(                                        "Opaque1 - 0x0000");
                if (Opaque1_Length>8)
                    Skip_XX(Opaque1_Length-8,                   "Opaque1 - Unknown [3]");
            }
        }
        Skip_L2(                                                "0x2519");
        Skip_L2(                                                "0x0001");
        Skip_L4(                                                "0x00000000 or B5112287");
        Skip_L4(                                                "0x00000000 or 4037F9DC");
        Skip_L4(                                                "0x00000001 [1]");
        Skip_L2(                                                "0x0003");
    Element_End();
    Get_L4 (Audio_Count,                                        "Audio count");
    if (111*Audio_Count>Element_Size)
    {
        Reject();
        return;
    }
    Element_Begin1("Audio tracks list 1");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        Skip_L2(                                                "0x0000 [New]");
        Get_L4 (Name_Length,                                    "(Same 1/2/3) Name length");
        Info_UTF8(Name_Length, Name,                            "(Same 1/2/3) Name");
        Skip_L2(                                                "(Same 1/2/3) 0x0000 ");
        Skip_L4(                                                "(Same 1/2/3) 0x00000000");
        Skip_L4(                                                "(Same 1/2/3) 0x0000002A");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Info_L3(Number,                                         "(Same 1/2/3) Ordered number"); Element_Info1(Number);
        Element_Info1(Name);
        Element_End();

        if (Name==__T("Lf")) //Exception? Typo?
            Name=__T("Lfe");
        Name.MakeLowerCase();
        Names.push_back(Name);
    }
    Element_End();
    Element_Begin1("Audio tracks list 2");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        int32u Size;
        Skip_L3(                                                "(Same   2/3) 0x00025A [1]");
        Get_L4 (Size,                                           "(Same   2/3) Size");
        Skip_L4(                                                "(Same   2/3) 0x0000251A");
        Get_L4 (Name_Length,                                    "(Same 1/2/3) Name length");
        Info_UTF8(Name_Length, Name,                            "(Same 1/2/3) Name");
        Skip_L2(                                                "(Same 1/2/3) 0x0000 ");
        Skip_L4(                                                "(Same 1/2/3) 0x00000000");
        Skip_L4(                                                "(Same 1/2/3) 0x0000002A");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Info_L3(Number,                                         "(Same 1/2/3) Ordered number"); Element_Info1(Number);
        Skip_L2(                                                "(Same   2/3) 0x0000");
        Element_Info1(Name);
        if (Name_Length+31!=Size)
        {
            Element_End();
            Element_End();
            Reject();
            return;
        }
        Element_End();
    }
    Element_End();
    Get_L4 (Audio_Count,                                        "Audio count");
    if (4*Audio_Count>Element_Size)
    {
        Reject();
        return;
    }
    Element_Begin1("Audio tracks list 3");
    for (int16u Pos=0; Pos<Audio_Count; Pos++)
    {
        Element_Begin1("Name");
        int32u Size;
        Skip_L3(                                                "(Same   2/3) 0x00025A [2]");
        Get_L4 (Size,                                           "(Same   2/3) Size");
        if (Size>0x10000)
        {
            Element_End();
            Element_End();
            Reject();
            return;
        }
        Skip_L4(                                                "(Same   2/3) 0x0000251A");
        Get_L4 (Name_Length,                                    "(Same 1/2/3) Name length");
        Info_UTF8(Name_Length, Name,                            "(Same 1/2/3) Name");
        Skip_L2(                                                "(Same 1/2/3) 0x0000 ");
        Skip_L4(                                                "(Same 1/2/3) 0x00000000");
        Skip_L4(                                                "(Same 1/2/3) 0x0000002A");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Skip_L4(                                                "(Same 1/2/3) Unknown");
        Info_L3(Number,                                         "(Same 1/2/3) Ordered number"); Element_Info1(Number);
        Skip_L2(                                                "(Same   2/3) 0x0000");
        Element_Info1(Name);
        if (Name_Length+31!=Size)
        {
            Element_End();
            Element_End();
            Reject();
            return;
        }
        Element_End();
    }
    Element_End();
    Skip_L2(                                                    "0x0000 [4]");
    Skip_L2(                                                    "0x0018");
    Skip_L4(                                                    "0x00000001 [2]");
    Skip_L2(                                                    "0x0018");
    Skip_L4(                                                    "0x00000001 [2]");
    Skip_L2(                                                    "0x0001 [3]");
    Skip_L3(                                                    "0x00095A");
    Get_L4 (Opaque2_Length,                                     "Opaque2 length");
    Skip_XX(Opaque2_Length,                                     "Opaque2");
    Skip_L1(                                                    "0x5A [2]");
    Skip_L2(                                                    "0x0003 (10.0) or 0x0004 (10.2+)");
    Get_L4 (Opaque2_Length,                                     "Opaque3 length"); //0x0012 (10.0) or 0x0016 (10.2+)
    if (Opaque2_Length<0x12)
        Skip_XX(Opaque2_Length,                                 "Opaque3");
    else
    {
        Skip_L4(                                                "Opaque3 - 0x06002026");
        Skip_L4(                                                "Opaque3 - 0x00000000 [1]");
        Skip_L2(                                                "Opaque3 - 0x0000");
        Skip_L4(                                                "Opaque3 - Unknown [1]");
        Skip_L4(                                                "Opaque3 - Unknown [2]");
        if (Opaque2_Length<0x16)
        {
            if (Opaque2_Length-0x12)
                Skip_XX(Opaque2_Length-0x12,                    "Opaque3 - Unknown [3]");
        }
        else
        {
            Skip_L4(                                            "Opaque3 - 0x00000000 [2]");
            if (Opaque2_Length>0x16)
                Skip_XX(Opaque2_Length-0x16,                    "Opaque3 - Unknown  [4]");
        }
    }
    Skip_L3(                                                    "0x00025A [3]");
    Get_L4 (Opaque2_Length,                                     "0x00000015 (Opaque4 length?) or something else");
    if (Opaque2_Length==0x00000015)
    {
        Skip_L4(                                                "0x075A2032");
        Skip_L4(                                                "0x00000C00");
        Skip_L4(                                                "0x01204200");
        Skip_L4(                                                "0x00000000 or 0x01000000");
        Skip_L4(                                                "Unknown [13]");
        Skip_L1(                                                "0x00 [3]");
        Skip_L3(                                                "0x00025A [4]");
        Skip_L4(                                                "Unknown [14]");
    }
    Skip_L4(                                                    "Unknown [15]");
    Skip_L4(                                                    "0x015A0000");
    Skip_L4(                                                    "Unknown [16]");
    Skip_L4(                                                    "Unknown [17]");
    Skip_L4(                                                    "0x01000000");
    Get_L4 (FileName_Count,                                     "File name count");
    if (13*FileName_Count>Element_Size)
    {
        Reject();
        return;
    }
    Get_L4 (Directory_Length,                                   "Directory length");
    Get_UTF8(Directory_Length, Directory,                       "Directory");
    Skip_L4(                                                    "0x00000000 [11]");
    Element_Begin1("File names");
    vector<int8u> Roles;
    vector<Ztring> FileNames;
    vector<Ztring> FileNamesLowerCase;
    vector<int32u> Purposes;
    for (int32u Pos=0; Pos<FileName_Count; Pos++)
    {
        Ztring FileName;
        int32u FileName_Length, Purpose;
        int8u  Role; //
        Element_Begin1("File names");
        Get_L1 (Role,                                           "role? (0x02 for WAV files)");
        Skip_L4(                                                "Ordered number except WAV files and -1");
        Get_L4 (FileName_Length,                                "File Name length");
        Get_UTF8(FileName_Length, FileName,                     "File Name"); Element_Name(FileName);
        Get_C4 (Purpose,                                        "Purpose (e.g. EVAW for .wav files)"); //Found 1 .wav file without "EWAV".
        Element_End();

        Roles.push_back(Role);
        FileNames.push_back(FileName);
        FileName.MakeLowerCase();
        FileNamesLowerCase.push_back(FileName);
        Purposes.push_back(Purpose);
    }
    Element_End();
    Skip_XX(Element_Size-Element_Offset,                        "Unknown");

    FILLING_BEGIN();
        Accept("Ptx"); //Could be Ptf (former format but not supported, so we don't care currently)
        Fill("Ptx");
        Fill(Stream_General, 0, General_Format, "Pro Tools Session");
        Fill(Stream_General, 0, General_Format_Version, "Version 10");
        Fill(Stream_General, 0, General_Encoded_Library_Name, LibraryName);
        Fill(Stream_General, 0, General_Encoded_Library_Version, LibraryVersion);

        // Role==2 + Purpose==EWAV + listed
        if (Names.size()>1 || FileNames.size()==1)
        {
            size_t Pos_Offset=0;
            for (int32u Pos=0; Pos<FileName_Count; Pos++)
            {
                if (Roles[Pos]==0x02
                 && Purposes[Pos]==0x45564157 //"EWAV"
                 && Pos-Pos_Offset<Names.size()
                 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception?
                 && FileNames[Pos].find(__T("_1KTONE_"))==string::npos //Exception?
                 && FileNamesLowerCase[Pos].find(Names[Pos-Pos_Offset]+__T(".wav"))!=string::npos
                 && FileNamesLowerCase[Pos].find(Names[Pos-Pos_Offset]+__T(".wav"))+Names[Pos-Pos_Offset].size()+4==FileNames[Pos].size())
                {
                    sequence* Sequence=new sequence;
                    Sequence->StreamKind=Stream_Audio;
                    Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]);
                    ReferenceFiles->AddSequence(Sequence);
                }
                else if (!ReferenceFiles->Sequences_Size())
                    Pos_Offset++;
            }

            if (Names.size()!=ReferenceFiles->Sequences_Size())
                ReferenceFiles->Clear(); //Failed to detect correctly
        }

        // Role==2 + listed
        if (!ReferenceFiles->Sequences_Size() && (Names.size()>1 || FileNames.size()==1))
        {
            size_t Pos_Offset=0;
            for (int32u Pos=0; Pos<FileName_Count; Pos++)
            {
                if (Roles[Pos]==0x02
                    && Pos-Pos_Offset<Names.size()
                 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception?
                 && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception?
                {
                     Ztring FileName=FileNames[Pos];
                     Ztring Name=Names[Pos-Pos_Offset];
                     FileName.MakeLowerCase();
                     Name.MakeLowerCase();
                     if (FileName.find(Name)==0
                        || FileName.find(Name+__T(".wav"))+5==Name.size())
                    {
                        sequence* Sequence=new sequence;
                        Sequence->StreamKind=Stream_Audio;
                        Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]);
                        ReferenceFiles->AddSequence(Sequence);
                    }
                    else if (!ReferenceFiles->Sequences_Size())
                        Pos_Offset++;
                }
                else if (!ReferenceFiles->Sequences_Size())
                    Pos_Offset++;
            }

            if (Names.size()!=ReferenceFiles->Sequences_Size())
                ReferenceFiles->Clear(); //Failed to detect correctly
        }

        // Role==2 + Purpose==EWAV + listed, special case with specific file names
        if (!ReferenceFiles->Sequences_Size() && (Names.size()>1 || FileNames.size()==1))
        {
            for (int32u Pos=0; Pos<FileName_Count; Pos++)
            {
                if (Roles[Pos]==0x02
                 && Purposes[Pos]==0x45564157 //"EWAV"
                 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception?
                 && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception?
                {
                    for (int32u Pos2=0; Pos2<Names.size(); Pos2++)
                        if (FileNamesLowerCase[Pos].find(Names[Pos2])==0)
                        {
                            sequence* Sequence=new sequence;
                            Sequence->StreamKind=Stream_Audio;
                            Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]);
                            ReferenceFiles->AddSequence(Sequence);
                            break;
                        }
                }
            }
        }

        // Role==2 + Purpose==EWAV
        if (!ReferenceFiles->Sequences_Size())
        {
            for (int32u Pos=0; Pos<FileName_Count; Pos++)
            {
                if (Roles[Pos]==0x02
                 && Purposes[Pos]==0x45564157 //"EWAV"
                 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception?
                 && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception?
                {
                    sequence* Sequence=new sequence;
                    Sequence->StreamKind=Stream_Audio;
                    Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]);
                    ReferenceFiles->AddSequence(Sequence);
                }
            }
        }

        // Role==2
        if (!ReferenceFiles->Sequences_Size())
        {
            for (int32u Pos=0; Pos<FileName_Count; Pos++)
            {
                if (Roles[Pos]==0x02
                 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception?
                 && FileNames[Pos]!=__T("*****@*****.**") //Exception?
                 && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception?
                 && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception?
                {
                    sequence* Sequence=new sequence;
                    Sequence->StreamKind=Stream_Audio;
                    Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]);
                    ReferenceFiles->AddSequence(Sequence);
                }
            }
        }
    FILLING_END();
}
//---------------------------------------------------------------------------
void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, const char* Parameter, const Ztring &Value, bool Replace)
{
    //Integrity
    if (StreamKind>Stream_Max || Parameter==NULL || Parameter[0]=='\0')
        return;

    //Handling values with \r\n inside
    if (Value.find(_T('\r'))!=string::npos || Value.find(_T('\n'))!=string::npos)
    {
        Ztring NewValue=Value;
        NewValue.FindAndReplace(_T("\r\n"), _T(" / "), 0, Ztring_Recursive);
        NewValue.FindAndReplace(_T("\r"), _T(" / "), 0, Ztring_Recursive);
        NewValue.FindAndReplace(_T("\n"), _T(" / "), 0, Ztring_Recursive);
        if (NewValue.size()>=3 && NewValue.rfind(_T(" / "))==NewValue.size()-3)
            NewValue.resize(NewValue.size()-3);
        Fill(StreamKind, StreamPos, Parameter, NewValue, Replace);
        return;
    }

    //Handle Value before StreamKind
    if (StreamKind==Stream_Max || StreamPos>=(*Stream)[StreamKind].size())
    {
        ZtringList NewList;
        NewList.push_back(Ztring().From_UTF8(Parameter));
        NewList.push_back(Value);
        Fill_Temp.push_back(NewList);
        return; //No streams
    }

    //Handling of well known parameters
    size_t Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Ztring().From_Local(Parameter));
    if (Pos!=Error)
    {
        Fill(StreamKind, StreamPos, Pos, Value, Replace);
        return;
    }

    //Handling of unknown parameters
    if (Value.empty())
    {
        if (!Replace)
        {
            size_t Pos=(*Stream_More)[StreamKind][StreamPos].Find(Ztring().From_UTF8(Parameter), Info_Name);
            if (Pos!=(size_t)-1)
                (*Stream_More)[StreamKind][StreamPos][Pos].clear(); //Empty value --> clear other values
        }
    }
    else
    {
        Ztring &Target=(*Stream_More)[StreamKind][StreamPos](Ztring().From_UTF8(Parameter), Info_Text);
        if (Target.empty() || Replace)
        {
            Target=Value; //First value
            (*Stream_More)[StreamKind][StreamPos](Ztring().From_UTF8(Parameter), Info_Options)=_T("Y NT");
        }
        else
        {
            Target+=MediaInfoLib::Config.TagSeparator_Get();
            Target+=Value;
        }
    }
}