Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package libepg.epg.section; import libepg.util.bytearray.ByteConverter; import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.Arrays; import java.util.Objects; import org.apache.commons.codec.binary.Hex; import org.apache.commons.logging.Log; import epgtools.loggerfactory.LoggerFactory; import libepg.util.bytearray.ByteDataBlock; //sub_table??table_id???? //?? //NIT?? ??network_id??? //BAT?? ??bouquet_id??? //SDT?? ??transport_stream_id? //??????? //EIT?? ??service_id? //???? //??????? //table_id_extension?? //section_syntax_indicator??1????????4 ?? //5 ??? //table??table_id????? //? /** * ?? * * @author normal */ public class Section { /** * false????????????? */ public static final boolean CLASS_LOG_OUTPUT_MODE = true; private static final Log LOG; static { final Class<?> myClass = MethodHandles.lookup().lookupClass(); LOG = new LoggerFactory(myClass, Section.CLASS_LOG_OUTPUT_MODE).getLOG(); } private final ByteDataBlock data; private final TABLE_ID tableId; /** * ??????ID????+3????????????? * * @param data ? * @throws IllegalArgumentException * 1:???????ID????3???????<br> * 2:?2?0?????<br> * 3:???????preferedTableID???????????<br> */ public Section(byte[] data) throws IllegalArgumentException { byte[] temp = Arrays.copyOf(data, data.length); final int id = ByteConverter.byteToInt(temp[0]); tableId = TABLE_ID.reverseLookUp(id); String hexValue = Hex.encodeHexString(data); //ID??ID????????????ID?????????????(?????ID???????????) if (tableId == null) { MessageFormat msg2 = new MessageFormat( "????? ???={0}"); Object[] parameters2 = { hexValue }; LOG.trace(msg2.format(parameters2)); throw new IllegalArgumentException(msg2.format(parameters2)); } byte[] t = new byte[2]; System.arraycopy(temp, 1, t, 0, t.length); int sectionLength = ByteConverter.bytesToInt(t); if (LOG.isTraceEnabled()) { LOG.trace("b1 = " + Integer.toHexString(sectionLength)); } sectionLength = sectionLength & 0x0FFF; if (LOG.isTraceEnabled()) { LOG.trace("b2 = " + Integer.toHexString(sectionLength)); } //??????? if (sectionLength > tableId.getMaxSectionLength().getMaxSectionBodyLength()) { MessageFormat msg3 = new MessageFormat( "?????????={0} ?={1} ???={2}"); Object[] parameters3 = { tableId.getMaxSectionLength().getMaxSectionBodyLength(), sectionLength, hexValue }; LOG.trace(msg3.format(parameters3)); throw new IllegalArgumentException(msg3.format(parameters3)); } //??????????? int targetLength = sectionLength + 3; byte[] sectionByteArray = new byte[targetLength]; System.arraycopy(temp, 0, sectionByteArray, 0, sectionByteArray.length); if (LOG.isTraceEnabled()) { MessageFormat msg1 = new MessageFormat("\n??={0}\n?={1}"); Object[] parameters1 = { Hex.encodeHexString(temp), Hex.encodeHexString(sectionByteArray) }; LOG.trace(msg1.format(parameters1)); } this.data = new ByteDataBlock(sectionByteArray); } /** * ??? * * @return */ public final synchronized byte[] getData() { return data.getData(); } /** * @return (ID) */ public final synchronized TABLE_ID getTable_id_const() { return tableId; } /** * 8bit(ID) * * @return (ID) * */ public final synchronized int getTable_id() { int id = ByteConverter.byteToInt(this.getData()[0]); return id; } /** * 1bit1 * * @return */ public final synchronized int getSection_syntax_indicator() { int temp; temp = ByteConverter.byteToInt(this.getData()[1]); temp = temp >>> 7; return temp; } /** * ??????? ??????ARIB * STD-B10?????????????? 1bit * * @return 1 */ public final synchronized int getReservedFutureUse1() { int temp; temp = ByteConverter.byteToInt(this.getData()[1]); temp = temp & 0x40; temp = temp >>> 6; return temp; } /** * ????????????ISO ?????????????? 2bit * * @return 3 */ public final synchronized int getReserved1() { int temp; temp = ByteConverter.byteToInt(this.getData()[1]); temp = temp & 0x30; temp = temp >>> 4; return temp; } /* * 12bit????2??00??? * ?????CRC????????? * ???1024?????4096???????????1021?????4093???????*/ public final synchronized int getSectionLength() { byte[] t = new byte[2]; System.arraycopy(this.getData(), 1, t, 0, t.length); int temp = ByteConverter.bytesToInt(t); if (LOG.isTraceEnabled()) { LOG.trace("b1 = " + Integer.toHexString(temp)); } temp = temp & 0x0FFF; if (LOG.isTraceEnabled()) { LOG.trace("b2 = " + Integer.toHexString(temp)); } return temp; } /** * (????????4??CRC?????)?? * * @return (????????4???-4?)???<br> * ?ID????<br> * ????????????<br> * */ public final synchronized SectionBody getSectionBody() { int sectionlength; sectionlength = this.getSectionLength() - 4; if (LOG.isTraceEnabled()) { LOG.trace("=" + sectionlength); LOG.trace("????-4=" + (this.getData().length - 4)); } byte[] t = new byte[sectionlength]; System.arraycopy(this.getData(), 3, t, 0, sectionlength); SectionBody temp = new SectionBody(this.getTable_id_const(), t); try { Object[] args = { temp }; Class<?>[] params = { SectionBody.class }; Constructor<? extends SectionBody> constructor = this.tableId.getDataType() .getDeclaredConstructor(params); SectionBody target = constructor.newInstance(args); return target; } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException ex) { LOG.fatal( "??????????? = " + temp.toString(), ex); return temp; } } /** * table_id_extension16bit???section_syntax_indicator??1???????<br> * ?4 ??5???<br> * * @return ?4 ??5 ? */ public final synchronized int getTable_id_extension() throws IllegalStateException { byte[] t = new byte[2]; System.arraycopy(this.getData(), 3, t, 0, t.length); int temp = ByteConverter.bytesToInt(t); if (this.getSection_syntax_indicator() != 1) { throw new IllegalStateException( "section_syntax_indicator??1?????"); } return temp; } /** * CRC(4?)?? * * @return (?????????4?)??? */ public final synchronized int getCRC() { int crcStartPoint; //?crc4?????3??????????????crc?? crcStartPoint = this.getSectionLength() - 4 + 3; byte[] t = new byte[4]; System.arraycopy(this.getData(), crcStartPoint, t, 0, t.length); return ByteConverter.bytesToInt(t); } /** * CRC? */ public static enum CRC_STATUS { /** * CRC????? */ NO_CRC_ERROR(true), /** * CRC???? */ CRC_ERROR(false); private final boolean value; private CRC_STATUS(boolean value) { this.value = value; } public boolean isValue() { return value; } } /** * ?CRC? * * @return ? */ public final synchronized CRC_STATUS checkCRC() { SectionCrcChecker checker = new SectionCrcChecker(); int res = checker.checkCrc(this.getData()); if (res == 0) { return CRC_STATUS.NO_CRC_ERROR; } else { if (LOG.isWarnEnabled()) { MessageFormat msg = new MessageFormat("CRC???0?????={0}"); Object[] parameters = { res }; LOG.warn(msg.format(parameters)); } return CRC_STATUS.CRC_ERROR; } } private static final MessageFormat TABLE_DESC = new MessageFormat( "? = {0}\n" + " = {1}\n" + " = {2}\n" + "section_syntax_indicator = {3}\n" + "1 = {4}\n" + "2 = {5}\n" + " = {6}\n" + " = {7}\n" + " = {8}\n" + "CRC = {9}\n" + "CRC? = {10}\n"); @Override /** * ????????? */ public String toString() { Object[] parameters = { this.data.toString(), this.getTable_id_const(), Integer.toHexString(this.getTable_id()), this.getSection_syntax_indicator(), this.getReservedFutureUse1(), this.getReserved1(), this.getSectionLength(), this.getSectionBody(), Integer.toHexString(this.getTable_id_extension()), Integer.toHexString(this.getCRC()), this.checkCRC() }; return TABLE_DESC.format(parameters); } /** * @return ???????? */ @Override public final int hashCode() { int hash = 7; hash = 73 * hash + Objects.hashCode(this.data.hashCode()); hash = 73 * hash + Objects.hashCode(this.tableId); return hash; } /** * @return 3??????????true<br> * 1.??????????<br> * 2.??????????????????????????<br> * 3.??????ID?????????ID?????<br> */ @Override public final boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Section other = (Section) obj; if (!Objects.equals(this.getData(), other.getData())) { return false; } if (this.tableId != other.tableId) { return false; } return true; } }