//--------------------------------------------------------------------------- // Write void ZtringListList::Write(const Ztring &ToWrite) { clear(); if (ToWrite.empty()) return; size_type PosC=0; bool Fini=false; Ztring C1; ZtringList ZL1; ZL1.Separator_Set(0, Separator[1]); ZL1.Quote_Set(Quote); ZL1.Max_Set(0, Max[1]); //Detecting carriage return format Ztring WriteSeparator; if (Separator[0]==EOL) { size_t CarriageReturn_Pos=ToWrite.find_first_of(__T("\r\n")); if (CarriageReturn_Pos!=string::npos) { if (ToWrite[CarriageReturn_Pos]==__T('\r')) { if (CarriageReturn_Pos+1<ToWrite.size() && ToWrite[CarriageReturn_Pos+1]==__T('\n')) WriteSeparator=__T("\r\n"); else WriteSeparator=__T("\r"); } else WriteSeparator=__T("\n"); } else WriteSeparator=Separator[0]; } else WriteSeparator=Separator[0]; do { //Searching end of line, but it must not be in quotes bool InQuotes=false; Ztring CharsToFind=WriteSeparator+Quote; size_t Pos_End=PosC; while (Pos_End<ToWrite.size()) { Pos_End=ToWrite.find(WriteSeparator, Pos_End); if (Pos_End!=string::npos) { if (Pos_End+Quote.size()<ToWrite.size() && ToWrite[Pos_End]==Quote[0] && ToWrite[Pos_End+1]!=Quote[0]) { InQuotes=!InQuotes; //This is not double quotes, so this is a normal quote /*if (!InQuotes) { C1=ToWrite.substr(PosC, Pos_End-PosC); break; }*/ } if (!InQuotes && Pos_End+WriteSeparator.size()<=ToWrite.size() && ToWrite[Pos_End]==WriteSeparator[0]) { C1=ToWrite.substr(PosC, Pos_End-PosC); break; } if (InQuotes && Pos_End+Quote.size()*2<ToWrite.size() && ToWrite[Pos_End]==Quote[0] && ToWrite[Pos_End+1]==Quote[0]) Pos_End+=2; else Pos_End++; } } if (Pos_End>=ToWrite.size()) C1=ToWrite.substr(PosC, string::npos); ZL1.Write(C1); push_back(ZL1); PosC+=C1.size()+WriteSeparator.size(); if (PosC>=ToWrite.size()) Fini=true; } while (!Fini); }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-STREAM-INF"))==0) IsGroup=true; else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { File__ReferenceFilesHelper::reference ReferenceStream; ReferenceStream.FileNames.push_back(Lines[Line]); ReferenceStream.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceStream); IsGroup=false; #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t)*2; #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (ReferenceFiles->References.empty()) { ReferenceFiles->References.push_back(ReferenceFile); ReferenceFiles->TestContinuousFileNames=true; } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-KEY:"))==0) { ZtringListList List; List.Separator_Set(0, __T(",")); List.Separator_Set(1, __T("=")); List.Write(Lines[Line].substr(11, string::npos)); for (size_t Pos=0; Pos<List.size(); ++Pos) { if (List[Pos](0)==__T("METHOD")) { if (List[Pos](1).find(__T("AES-128"))==0) { Fill(Stream_General, 0, General_Encryption_Format, "AES"); Fill(Stream_General, 0, General_Encryption_Length, "128"); Fill(Stream_General, 0, General_Encryption_Method, "Segment"); Fill(Stream_General, 0, General_Encryption_Mode, "CBC"); Fill(Stream_General, 0, General_Encryption_Padding, "PKCS7"); Fill(Stream_General, 0, General_Encryption_InitializationVector, "Sequence number"); #if MEDIAINFO_AES //Trying to get the key from FileName.FileExt.key if (Config->Encryption_Key_Get().empty()) { File KeyFile; if (KeyFile.Open(File_Name+__T(".key"))) { if (KeyFile.Size_Get()==16) { int8u Key[16]; if (KeyFile.Read(Key, 16)==16) Config->Encryption_Key_Set(Key, 16); } else Fill(Stream_General, 0, "Encryption_Key_Problem", KeyFile.Size_Get()); } } #endif } Fill(Stream_General, 0, General_Encryption, List[Pos](1)); } } } else if (Lines[Line].find(__T("#EXT-X-STREAM-INF:"))==0) { IsGroup=true; } else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { ReferenceFile.FileNames.push_back(Lines[Line]); ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); IsGroup=false; ReferenceFile=File__ReferenceFilesHelper::reference(); #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t); #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (!ReferenceFile.FileNames.empty()) { ReferenceFiles->References.push_back(ReferenceFile); Fill(Stream_General, 0, General_Format_Profile, "Media"); } else { Fill(Stream_General, 0, General_Format_Profile, "Master"); } Element_Offset=File_Size; //All should be OK... return true; }