/// <summary> /// Select the new object in the tree /// </summary> /// <param name="newObject"></param> private void SelectObjectInLogicalList(MXFObject selObject) { if (selObject != null) { // Open entire parent tree List <MXFObject> parentList = new List <MXFObject>(); MXFObject parent = selObject.Parent; while (parent != null) { parentList.Add(parent); parent = parent.Parent; } // Now loop backwards through the parent list, expanding each item parentList.Reverse(); foreach (MXFObject obj in parentList) { if (!this.treeListViewLogical.IsExpanded(obj)) { this.treeListViewLogical.Expand(obj); } } // Select the next object this.treeListViewLogical.EnsureModelVisible(selObject); this.treeListViewLogical.SelectObject(selObject); this.treeListViewLogical.RefreshObject(selObject); } }
/// <summary> /// If the newly selected item is of type referenceKey, allow jump on double click /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void propGrid_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e) { m_selectedObject = e.NewSelection.Value as MXFObject; m_currentReference = null; if (m_selectedObject != null) { // Select the reference itself by default m_currentReference = m_selectedObject; // Refkey, then select the reference it points too MXFRefKey refkey = m_selectedObject as MXFRefKey; if (refkey != null) { if (refkey.Reference != null) { m_currentReference = refkey.Reference; } else { m_currentReference = null; // Reset } } } this.btnSelectReference.Enabled = (m_currentReference != null); }
/// <summary> /// User clicked another item in the LOGICAL tree, show the details /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void treeListViewLogical_SelectionChanged(object sender, EventArgs e) { MXFLogicalObject lobj = this.treeListViewLogical.SelectedObject as MXFLogicalObject; if (lobj != null) { MXFObject obj = lobj.Object; if (obj != null) { if (!m_fDoNotSelectOther) { this.propGrid.SelectedObject = obj; // Try to select this item in the main list as well m_fDoNotSelectOther = true; SelectObjectInMainList(obj); m_fDoNotSelectOther = false; // Display the hex data ReadData(obj); } } this.btnNext.Enabled = this.btnPrevious.Enabled = (obj != null); } }
/// <summary> /// Read the data of an mxf object and display it as hex dump /// </summary> /// <param name="obj"></param> public void SetObject(MXFObject obj) { this.ObjectToShow = obj; this.Clear(); long len = GetObjectLength(obj); if (len > DisplayableBytesThreshold) { // TODO Hexdump should be truncated and not entirely omitted this.Text = "Hexdump not shown due to packet size"; } else if (len > 0) { byte[] data = new byte[len]; using (MXFReader reader = new MXFReader((obj.Root() as MXFFile).Filename)) { reader.Seek(obj.Offset); data = reader.ReadArray(reader.ReadByte, data.Length); } int maxNumOfDigits = obj.GetMaxOffsetDigitCount(); this.Text = GetHexDump(obj.Offset, len, maxNumOfDigits, BytesPerLine, data); } }
/// <summary> /// (re)Fill the tree /// </summary> private void AddItemsToTree(bool filterCurrentType) { MXFObject selObject = this.treeListViewMain.SelectedObject as MXFObject; if (filterCurrentType && selObject != null) { Type selectedType = selObject.GetType(); // Create a new list with the selected items only) if (this.HideFillers) { this.m_filterList = this.m_MXFFile.FlatList.Where(a => a.GetType() == selectedType && a.Type != MXFObjectType.Filler).ToList(); } else { this.m_filterList = this.m_MXFFile.FlatList.Where(a => a.GetType() == selectedType).ToList(); } this.treeListViewMain.SetObjects(this.m_filterList); this.txtOverall.Text = string.Format("Number of filtered objects: {0}", this.m_filterList.Count); } else { this.m_filterList = null; if (this.m_MXFFile != null) { this.treeListViewMain.SetObjects(this.m_MXFFile.Children); this.txtOverall.Text = string.Format("Total objects: {0}", this.m_MXFFile.FlatList.Count); } else { this.txtOverall.Text = ""; } } // Set logical tree List <MXFLogicalObject> los = new List <MXFLogicalObject>(); if (this.m_MXFFile != null) { los.Add(this.m_MXFFile.LogicalBase); } this.treeListViewLogical.SetObjects(los); // (Re)-select the selected item if (selObject != null) { SelectObjectInMainList(selObject); } else { // No item selected, just select the first partition if (this.m_MXFFile != null && this.m_MXFFile.Partitions != null && this.m_MXFFile.Partitions.Count > 0) { SelectObjectInMainList(this.m_MXFFile.Partitions[0]); } } }
/// <summary> /// Does this object have children? /// </summary> /// <param name="x"></param> /// <returns></returns> private bool Tree_HasChildren(object x) { MXFObject mxf = x as MXFObject; if (mxf == null) { return(false); } return(mxf.HasChildren); }
/// <summary> /// Tree is expanding, load the partition /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void treeListViewMain_Expanding(object sender, TreeBranchExpandingEventArgs e) { MXFObject selObject = e.Model as MXFObject; if (selObject != null) { if (!selObject.IsLoaded) { Cursor.Current = Cursors.WaitCursor; selObject.Load(); Cursor.Current = Cursors.Default; } } }
private long GetObjectLength(MXFObject obj) { switch (obj) { case MXFKLV klv: return(klv.DataOffset - klv.Offset + klv.Length); case MXFLocalTag tag: return(tag.DataOffset - tag.Offset + tag.Size); default: return(obj.Length); } }
/// <summary> /// Color the stuff /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void treeListViewMain_FormatCell(object sender, FormatCellEventArgs e) { if (e.ColumnIndex == 0) { // Address e.SubItem.ForeColor = Color.Gray; } else if (e.ColumnIndex == 1) { MXFObject obj = e.Model as MXFObject; if (obj != null) { if (obj.Type == MXFObjectType.Partition) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_Partition; } else if (obj.Type == MXFObjectType.Essence) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_Essence; } else if (obj.Type == MXFObjectType.Index) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_IndexTable; } else if (obj.Type == MXFObjectType.SystemItem) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_SystemItem; } else if (obj.Type == MXFObjectType.RIP) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_RIP; } else if (obj.Type == MXFObjectType.Meta) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_MetaData; } else if (obj.Type == MXFObjectType.Filler) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_Filler; } else if (obj.Type == MXFObjectType.Special) { e.SubItem.ForeColor = MXFInspect.Properties.Settings.Default.Color_Special; } } } }
/// <summary> /// Read a list of keys /// </summary> /// <param name="reader"></param> /// <param name="categoryName"></param> /// <returns></returns> protected UInt32 ReadKeyList(MXFReader reader, string categoryName, string singleItem) { UInt32 nofItems = reader.ReadD(); UInt32 objectSize = reader.ReadD(); // useless size of objects, always 16 according to specs MXFObject keylist = new MXFObject(categoryName, reader.Position); if (nofItems < UInt32.MaxValue) { for (int n = 0; n < nofItems; n++) { MXFRefKey key = new MXFRefKey(reader, objectSize, singleItem); keylist.AddChild(key); } } this.AddChild(keylist); return(nofItems); }
/// <summary> /// Find the previous item in this parent /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void SelectPreviousObject() { MXFObject selectedObject = this.treeListViewMain.SelectedObject as MXFObject; if (selectedObject != null) { MXFObject previousObject = selectedObject; if (this.m_filterList != null) { // Filtering is currently active! int index = this.m_filterList.IndexOf(selectedObject); if (index >= 1) { previousObject = this.m_filterList[index - 1]; } } else { previousObject = selectedObject.FindPreviousibling(selectedObject.GetType(), this.HideFillers); } SelectObjectInMainList(previousObject); } }
/// <summary> /// Find the next item with the same key /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void SelectNextObject() { MXFObject selectedObject = this.treeListViewMain.SelectedObject as MXFObject; if (selectedObject != null) { MXFObject nextObject = selectedObject; if (this.m_filterList != null) { // Filtering is currently active! int index = this.m_filterList.IndexOf(selectedObject); if (index >= 0 && index < this.m_filterList.Count - 1) { nextObject = this.m_filterList[index + 1]; } } else { nextObject = selectedObject.FindNextSibling(selectedObject.GetType(), this.HideFillers); } SelectObjectInMainList(nextObject); } }
/// <summary> /// Get the childs! /// </summary> /// <param name="x"></param> /// <returns></returns> private IEnumerable Tree_ChildGetter(object x) { MXFObject mxf = x as MXFObject; if (mxf == null) { return(null); } ArrayList ar = new ArrayList(); foreach (MXFObject child in mxf.Children) { bool add = true; if (this.HideFillers) { add = (child.Type != MXFObjectType.Filler); } if (add) { ar.Add(child); } } return(ar); }
/// <summary> /// Overridden method to process local tags /// </summary> /// <param name="localTag"></param> protected override bool ParseLocalTag(MXFReader reader, MXFLocalTag localTag) { switch (localTag.Tag) { case 0x3F05: this.EditUnitByteCount = reader.ReadD(); return(true); case 0x3F06: this.IndexSID = reader.ReadD(); return(true); case 0x3F07: this.BodySID = reader.ReadD(); return(true); case 0x3F0C: this.IndexStartPosition = reader.ReadL(); return(true); case 0x3F0D: this.IndexDuration = reader.ReadL(); return(true); case 0x3F0B: this.IndexEditRateNum = reader.ReadD(); this.IndexEditRateDen = reader.ReadD(); return(true); case 0x3F0A: // Index entry array { this.NbIndexEntries = reader.ReadD(); UInt32 entryLength = reader.ReadD(); if (this.NbIndexEntries > 0) { MXFObject indexCollection = this.AddChild("IndexEntries"); for (UInt64 i = 0; i < this.NbIndexEntries; i++) { long next = reader.Position + entryLength; indexCollection.AddChild(new MXFIndexEntry(this.IndexStartPosition + i, reader)); reader.Seek(next); } } } return(true); case 0x3F09: // Delta entry array { this.NbDeltaEntries = reader.ReadD(); UInt32 entryLength = reader.ReadD(); if (this.NbDeltaEntries > 0) { MXFObject deltaCollection = this.AddChild("DeltaEntries"); for (int i = 0; i < this.NbDeltaEntries; i++) { long next = reader.Position + entryLength; deltaCollection.AddChild(new MXFDeltaEntry(reader)); reader.Seek(next); } } } return(true); } return(false); // Not parsed, use default parsing }
/// <summary> /// Read the data and display it in the hex window /// </summary> /// <param name="obj"></param> private void ReadData(MXFObject obj) { StringBuilder sb = new StringBuilder(); // Cast to KLV long readerOffset = obj.Offset; long len = (int)obj.Length; MXFKLV klv = obj as MXFKLV; if (klv != null) { // Determine real length including BER + Key len = (klv.DataOffset - readerOffset) + klv.Length; } MXFLocalTag lt = obj as MXFLocalTag; if (lt != null) { len = (lt.DataOffset - readerOffset) + lt.Size; } const int dataLength = 16; if (len > 0) { byte[] data = new byte[len]; using (MXFReader reader = new MXFReader(this.Filename)) { reader.Seek(readerOffset); reader.Read(data, len); } long lines = (len + (dataLength - 1)) / dataLength; long offset = 0; byte[] dataString = new byte[dataLength + 1]; for (int n = 0; n < lines; n++) { long cnt = dataLength; if (len - offset < dataLength) { cnt = len - offset; } string hex = BitConverter.ToString(data, (int)offset, (int)cnt).Replace('-', ' '); hex = hex.PadRight(dataLength * 3); for (int m = 0; m < cnt; m++) { dataString[m] = data[offset + m]; } string ascii = System.Text.Encoding.ASCII.GetString(dataString); string asciisafe = ""; for (int m = 0; m < cnt && m < ascii.Length; m++) { if (ascii[m] < 0x20) { asciisafe += ' '; } else { asciisafe += ascii[m]; } } sb.AppendLine(string.Format("{0:0000000000} {1} {2}", readerOffset + (n * dataLength), hex, asciisafe)); offset += dataLength; } } this.txtHex.Text = sb.ToString(); }