datetime_t EBML_DateTime(const ebml_date *Element) { assert(Node_IsPartOf(Element,EBML_DATE_CLASS)); if (!Element->Base.bValueIsSet) return 0; return (datetime_t)Scale32(Element->Value,1,1000000000); // nanoseconds to seconds }
bool_t EBML_VoidSetFullSize(ebml_element *Void, filepos_t DataSize) { assert(Node_IsPartOf(Void,EBML_VOID_CLASS)); Void->DataSize = DataSize - 1 - EBML_CodedSizeLength(DataSize,0,1); // 1 is the length of the Void ID Void->bValueIsSet = 1; Void->bNeedDataSizeUpdate = 0; return Void->DataSize >= 0; }
NOINLINE nodetree* NodeTree_ChildByClass(const void *p, fourcc_t Class) { if (Node_IsPartOf(p,Class)) return (nodetree*)p; for (p=NodeTree_Children(p);p;p=NodeTree_Next(p)) { nodetree *Result = NodeTree_ChildByClass(p,Class); if (Result) return Result; } return NULL; }
filepos_t EBML_VoidReplaceWith(ebml_element *Void, ebml_element *ReplacedWith, stream *Output, bool_t ComeBackAfterward, bool_t bWithDefault) { filepos_t CurrentPosition; assert(Node_IsPartOf(Void,EBML_VOID_CLASS)); EBML_ElementUpdateSize(ReplacedWith,bWithDefault,0); if (EBML_ElementFullSize(Void,1) < EBML_ElementFullSize(ReplacedWith,1)) // the element can't be written here ! return INVALID_FILEPOS_T; if (EBML_ElementFullSize(Void,1) - EBML_ElementFullSize(ReplacedWith,1) == 1) // there is not enough space to put a filling element return INVALID_FILEPOS_T; CurrentPosition = Stream_Seek(Output,0,SEEK_CUR); Stream_Seek(Output,Void->ElementPosition,SEEK_SET); EBML_ElementRender(ReplacedWith,Output,bWithDefault,0,1,NULL); if (EBML_ElementFullSize(Void,1) - EBML_ElementFullSize(ReplacedWith,1) > 1) { // fill the rest with another void element ebml_element *aTmp = EBML_ElementCreate(Void,Void->Context,0,NULL); if (aTmp) { filepos_t HeadBefore,HeadAfter; EBML_VoidSetFullSize(aTmp, EBML_ElementFullSize(Void,1) - EBML_ElementFullSize(ReplacedWith,1)); HeadBefore = EBML_ElementFullSize(aTmp,1) - aTmp->DataSize; aTmp->DataSize = aTmp->DataSize - EBML_CodedSizeLength(aTmp->DataSize, aTmp->SizeLength, EBML_ElementIsFiniteSize(aTmp)); HeadAfter = EBML_ElementFullSize(aTmp,1) - aTmp->DataSize; if (HeadBefore != HeadAfter) aTmp->SizeLength = (int8_t)(EBML_CodedSizeLength(aTmp->DataSize, aTmp->SizeLength, EBML_ElementIsFiniteSize(aTmp)) - (HeadAfter - HeadBefore)); EBML_ElementRenderHead(aTmp,Output,0,NULL); NodeDelete((node*)aTmp); } } if (ComeBackAfterward) Stream_Seek(Output,CurrentPosition,SEEK_SET); return EBML_ElementFullSize(Void,1); }
nodetree* NodeTree_ChildByName(const void* p,const tchar_t* Name, fourcc_t Class, bool_t Recursive) { if (p && Name && Name[0]) { nodetree* i; for (i=NodeTree_Children(p);i;i=NodeTree_Next(i)) if (Node_IsPartOf(i,Class)) { const tchar_t* s = (const tchar_t*)Node_GetData((node*)i,NODE_ID,TYPE_STRING); if (s && tcsisame_ascii(s,Name)) return i; } if (Recursive) { nodetree* j; for (i=NodeTree_Children(p);i;i=NodeTree_Next(i)) if ((j = NodeTree_ChildByName(i,Name,Class,1))!=NULL) return j; } } return NULL; }