| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview Class to represent a PSML Document. |
| * @see http://www.nbee.org/doku.php?id=netpdl:psml_specification |
| */ |
| |
| 'use strict'; |
| |
| /** |
| * Namespace for the Packet Trace Analyzer app. |
| */ |
| var pcap = pcap || {}; |
| |
| /** |
| * Acts as a container for the PSML Structure and Packets. |
| * |
| * @constructor |
| * @extends {pcap.XmlDocument} |
| */ |
| pcap.PsmlDocument = function() { |
| pcap.XmlDocument.call(this); |
| |
| /** |
| * @type {PsmlStructure} |
| * @private |
| */ |
| this.structure_ = null; |
| |
| /** |
| * @type {Array<PsmlPacket>} |
| * @private |
| */ |
| this.packets_ = []; |
| |
| // End of properties. Seal the object. |
| Object.seal(this); |
| }; |
| |
| pcap.PsmlDocument.prototype = { |
| __proto__: pcap.XmlDocument.prototype |
| }; |
| |
| /** |
| * Method to load the PsmlDocument from PSML. |
| * |
| * @override |
| * @param {XMLDocument} psmlXmlDoc Summary information of a decoded packet. |
| * @return {boolean} True if successfully set; false otherwise. |
| */ |
| pcap.PsmlDocument.prototype.read = function(psmlXmlDoc) { |
| console.log('psml-read: Reading PSML Document.'); |
| |
| this.structure_ = null; |
| this.packets_ = []; |
| |
| if (!psmlXmlDoc || !(psmlXmlDoc instanceof XMLDocument)) { |
| console.error('psml-read: Invalid input type.'); |
| return false; |
| } |
| |
| var psmlXml = psmlXmlDoc.getElementsByTagName('psml'); |
| if (!psmlXml || !psmlXml[0]) { |
| console.error('psml-read: Invalid PSML Document - Missing psml tag.'); |
| return false; |
| } |
| |
| var structuresXml = psmlXml[0].getElementsByTagName('structure'); |
| if (!structuresXml || !structuresXml[0]) { |
| console.error('psml-read: Invalid PSML Document - Missing structure tag.'); |
| return false; |
| } |
| |
| var packetsXml = psmlXml[0].getElementsByTagName('packet'); |
| if (!packetsXml || !packetsXml[0]) { |
| console.error('psml-read: Invalid PSML Document - Missing psml packets.'); |
| return false; |
| } |
| |
| var structure = new pcap.PsmlStructure(); |
| if (!structure.read(structuresXml[0])) { |
| console.error('psml-read: Failed to read PSML structure.'); |
| return false; |
| } |
| |
| this.structure_ = structure; |
| |
| for (var i = 0; i < packetsXml.length; i++) { |
| var packet = new pcap.PsmlPacket(); |
| if (!packet.read(packetsXml[i])) { |
| console.error('psml-read: Failed to read PSML packets.'); |
| return false; |
| } |
| this.packets_.push(packet); |
| } |
| |
| console.log('psml-read: Successfully read PSML Document.'); |
| return true; |
| }; |
| |
| /** |
| * Generates an HTML representation of the PsmlDocument and inserts |
| * it into the target element. |
| * |
| * @override |
| * @throws Error if structure or packets are missing or invalid. |
| */ |
| pcap.PsmlDocument.prototype.display = function() { |
| var targetEl = document.getElementById('psml_display'); |
| |
| if (!this.structure_) { |
| throw new Error('Structure is missing'); |
| } |
| |
| if (!(this.structure_ instanceof pcap.PsmlStructure)) { |
| throw new Error('Invalid Structure type'); |
| } |
| |
| if (!this.packets_ || !this.packets_.length) { |
| throw new Error('Packets are missing'); |
| } |
| |
| var root = document.createElement('div'); |
| root.className = 'psml'; |
| |
| var table = document.createElement('table'); |
| table.className = 'table'; |
| table.id = 'structure'; |
| |
| var thead = document.createElement('thead'); |
| thead.appendChild(this.structure_.html()); |
| |
| var tbody = document.createElement('tbody'); |
| |
| var packetCount = this.packets_.length; |
| for (var i = 0; i < packetCount; i++) { |
| var packet = this.packets_[i]; |
| if (!(packet instanceof pcap.PsmlPacket)) { |
| throw new Error('Invalid Packet type'); |
| } |
| tbody.appendChild(packet.html()); |
| } |
| |
| table.appendChild(thead); |
| table.appendChild(tbody); |
| root.appendChild(table); |
| |
| targetEl.innerText = ''; |
| targetEl.appendChild(root); |
| |
| console.log('psml-display: Successfully displayed PSML Document.'); |
| }; |
| |
| /** |
| * Acts as a container for the PSML Structure Sections. |
| * |
| * @constructor |
| */ |
| pcap.PsmlStructure = function() { |
| /** |
| * @type {Array<string>} |
| * @private |
| */ |
| this.sections_ = []; |
| }; |
| |
| /** |
| * Method to load the Structures from the PSML structure tag. |
| * |
| * @param {Element} structureXml Structure section from the PSML document. |
| * @return {boolean} True if succeeded; false otherwise. |
| */ |
| pcap.PsmlStructure.prototype.read = function(structureXml) { |
| if (!structureXml || !(structureXml instanceof Element)) { |
| return false; |
| } |
| |
| var sectionsXml = structureXml.getElementsByTagName('section'); |
| if (!sectionsXml || !sectionsXml[0]) { |
| return false; |
| } |
| |
| for (var i = 0; i < sectionsXml.length; i++) { |
| var sectionText = sectionsXml[i].textContent; |
| this.sections_.push(sectionText); |
| } |
| |
| return true; |
| }; |
| |
| /** |
| * Method to create an HTML representation of the PsmlStructure. |
| * |
| * @throws Error if the sections are missing or invalid. |
| * @return {Element} The root node of the generated HTML. |
| */ |
| pcap.PsmlStructure.prototype.html = function() { |
| if (!this.sections_ || !this.sections_.length) { |
| throw new Error('Missing sections'); |
| } |
| |
| var tr = document.createElement('tr'); |
| |
| for (var i = 0; i < this.sections_.length; i++) { |
| var sectionText = this.sections_[i]; |
| if (typeof sectionText !== 'string') { |
| throw new Error('Invalid section type'); |
| } |
| |
| var th = document.createElement('th'); |
| th.innerText = sectionText; |
| tr.appendChild(th); |
| } |
| |
| return tr; |
| }; |
| |
| /** |
| * Acts as a container for the PSML Packet Sections. |
| * |
| * @constructor |
| */ |
| pcap.PsmlPacket = function() { |
| /** |
| * @type {Array<string>} |
| * @private |
| */ |
| this.sections_ = []; |
| }; |
| |
| /** |
| * Method to load the Packets from the PSML packet tag. |
| * |
| * @param {Element} packetXml Packet section from the PSML document. |
| * @return {boolean} True if succeeded; false otherwise. |
| */ |
| pcap.PsmlPacket.prototype.read = function(packetXml) { |
| if (!packetXml || !(packetXml instanceof Element)) { |
| return false; |
| } |
| |
| var sectionsXml = packetXml.getElementsByTagName('section'); |
| if (!sectionsXml || !sectionsXml[0]) { |
| return false; |
| } |
| |
| for (var i = 0; i < sectionsXml.length; i++) { |
| var sectionText = sectionsXml[i].textContent; |
| this.sections_.push(sectionText); |
| } |
| |
| return true; |
| }; |
| |
| /** |
| * Method to create an HTML representation of the PsmlPacket. |
| * |
| * @throws Error if the packets are missing or invalid. |
| * @return {Element} The root node of the generated HTML. |
| */ |
| pcap.PsmlPacket.prototype.html = function() { |
| if (!this.sections_ || !this.sections_.length) { |
| throw new Error('Missing sections'); |
| } |
| |
| var root = document.createElement('tr'); |
| |
| for (var i = 0; i < this.sections_.length; i++) { |
| var sectionText = this.sections_[i]; |
| if (typeof sectionText !== 'string') { |
| throw new Error('Invalid section type'); |
| } |
| |
| var td = document.createElement('td'); |
| td.innerText = sectionText; |
| root.appendChild(td); |
| } |
| |
| return root; |
| }; |