📄 wireformatmessagebinary.java
字号:
if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe(failure.toString()); } throw failure; } // Message version if (buffer.get() != MESSAGE_VERSION) { IOException failure = new IOException("Message not version " + MESSAGE_VERSION); if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, failure.getMessage(), failure); } throw failure; } int namespaceCnt = buffer.getShort(); if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer(MessageFormat.format("Message defines {0} namespaces buffer stats{1}", namespaceCnt, buffer.toString())); } if (namespaceCnt > 253) { IOException failure = new IOException( MessageFormat.format("Message contains too many namespaces ({0} >253)", namespaceCnt)); if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, failure.getMessage(), failure); } throw failure; } HashMap<Integer, String> id2namespace = new HashMap<Integer, String>(2 + namespaceCnt); id2namespace.put(0, ""); id2namespace.put(1, "jxta"); int id = 2; for (int i = 0; i < namespaceCnt; ++i) { try { String namespace = readString(buffer); id2namespace.put(id++, namespace); } catch (IOException caught) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Error Processing namespace", caught); } throw caught; } } if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer("Read Message Header with " + (namespaceCnt + 2) + " namespaces from " + buffer.toString()); } return id2namespace; } /** * Read in a message element from the provided data stream. * * @param dis the data stream to read from * @param is todo * @return object array containing two objects, index[0] contains an * Integer which identifies the namespace to which this element belongs * and index[1] contains a MessageElement. If null is returned then * the DataInputStream reached EOF before reading the first byte of the * element. * @throws IOException if EOF or other IOException is encountered * during the reading of the element. */ private Object[] readMessageElement(DataInputStream dis, InputStream is) throws IOException { // Read message signature char[] elsig = new char[4]; // if we EOF before the first byte, return null. EOF anywhere else // and its an error. try { elsig[0] = (char) dis.readByte(); } catch (EOFException allDone) { return null; } elsig[1] = (char) dis.readByte(); elsig[2] = (char) dis.readByte(); elsig[3] = (char) dis.readByte(); if (elsig[0] != 'j' || elsig[1] != 'x' || elsig[2] != 'e' || elsig[3] != 'l') { IOException failure = new IOException( "Not a message element (incorrect signature '" + elsig[0] + elsig[1] + elsig[2] + elsig[3] + "') "); if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, failure.getMessage(), failure); } throw failure; } // Namespace id int nsid = dis.readByte(); // flags byte flags = dis.readByte(); // Name String name = readString(dis); // Mime type MimeMediaType type; if ((flags & HAS_TYPE) != 0) { String typeString = readString(dis); try { type = new MimeMediaType(typeString); } catch (IllegalArgumentException uhoh) { throw new IOException("Bad MIME type in message element header : " + uhoh.getMessage()); } } else { type = MimeMediaType.AOS; } int dataLen = dis.readInt(); if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer( "element : nsid = " + nsid + " name = \'" + name + "\' type = \'" + type + "\' flags = " + Integer.toBinaryString(flags) + " datalen = " + dataLen); } Object[] res = new Object[2]; res[0] = nsid & 0x000000FF; byte[] value = null; Message submsg = null; // Value if (type.equalsIngoringParams(myTypes[0])) { InputStream subis = new LimitInputStream(is, dataLen); submsg = WireFormatMessageFactory.fromWire(subis, type, null); } else { if (dataLen > Integer.MAX_VALUE) { // FIXME hamada dataLen is an int, the above expression can never be true if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe("WireFormatMessageBinary does not support elements longer than 2GB"); } throw new IllegalStateException("WireFormatMessageBinary does not support elements longer than 2GB"); } value = new byte[dataLen]; String mayFail = null; if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { mayFail = is.toString(); } try { dis.readFully(value); } catch (EOFException failed) { if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.warning("had tried to read " + dataLen + " from " + mayFail + " which is now " + is); } throw failed; } } MessageElement sig = null; if ((flags & HAS_SIGNATURE) != 0) { Object[] sigRes = readMessageElement(dis, is); sig = (MessageElement) sigRes[1]; } if (null != value) { res[1] = new ByteArrayMessageElement(name, type, value, sig); } else { res[1] = new JxtaMessageMessageElement(name, type, submsg, sig); } return res; } /** * Read in a message element from the provided data stream. * * @param buffer the data buffer to read from * @return object array containing two objects, index[0] contains an * Integer which identifies the namespace to which this element belongs * and index[1] contains a MessageElement. If null is returned then * the DataInputStream reached EOF before reading the first byte of the * element. * @throws IOException if EOF or other IOException is encountered * during the reading of the element. */ private Object[] readMessageElement(ByteBuffer buffer) throws IOException { // Read message signature char[] elsig = new char[4]; // if we EOF before the first byte, return null. EOF anywhere else // and its an error. elsig[0] = (char) buffer.get(); elsig[1] = (char) buffer.get(); elsig[2] = (char) buffer.get(); elsig[3] = (char) buffer.get(); if (elsig[0] != 'j' || elsig[1] != 'x' || elsig[2] != 'e' || elsig[3] != 'l') { IOException failure = new IOException( "Not a message element (incorrect signature '" + elsig[0] + elsig[1] + elsig[2] + elsig[3] + "') "); if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, failure.getMessage(), failure); } throw failure; } // Namespace id int nsid = buffer.get(); // flags byte flags = buffer.get(); // Name String name = readString(buffer); // Mime type MimeMediaType type; if ((flags & HAS_TYPE) != 0) { String typeString = readString(buffer); try { type = new MimeMediaType(typeString); } catch (IllegalArgumentException uhoh) { throw new IOException("Bad MIME type in message element header : " + uhoh.getMessage()); } } else { type = MimeMediaType.AOS; } int dataLen = buffer.getInt(); if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer( "element : nsid = " + nsid + " name = \'" + name + "\' type = \'" + type + "\' flags = " + Integer.toBinaryString(flags) + " datalen = " + dataLen); } Object[] res = new Object[2]; res[0] = nsid & 0x000000FF; byte[] value = null; Message submsg = null; // Value if (type.equalsIngoringParams(myTypes[0])) { InputStream subis = new ByteArrayInputStream(buffer.array(), buffer.position(), dataLen); submsg = WireFormatMessageFactory.fromWire(subis, type, null); // buffer.position(buffer.position() + dataLen); } else { if (dataLen > Integer.MAX_VALUE) { if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe("WireFormatMessageBinary does not support elements longer than 2GB"); } throw new IllegalStateException("WireFormatMessageBinary does not support elements longer than 2GB"); } value = new byte[dataLen]; if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer(MessageFormat.format("expecting {0} bytes, Buffer stats {1}", dataLen, buffer.toString())); } buffer.get(value); } MessageElement sig = null; if ((flags & HAS_SIGNATURE) != 0) { Object[] sigRes = readMessageElement(buffer); sig = (MessageElement) sigRes[1]; } if (null != value) { res[1] = new ByteArrayMessageElement(name, type, value, sig); } else { res[1] = new JxtaMessageMessageElement(name, type, submsg, sig); } return res; } /** * Read and construct a string from the data stream. * * @param dis the stream to read from * @return the String which was read. * @throws IOException if EOF or other IOException is encountered * during the reading of the string. */ private static String readString(DataInputStream dis) throws IOException { int len = dis.readShort(); if (len < 0) { throw new IOException("Bad string length in message"); } byte[] bytes = new byte[len]; dis.readFully(bytes); return new String(bytes, "UTF8"); } /** * Read and construct a string from the data stream. * * @param buffer the ByteBuffer to read from * @return the String which was read. * @throws IOException if EOF or other IOException is encountered * during the reading of the string. */ private static String readString(ByteBuffer buffer) throws IOException { int len = buffer.getShort(); if (len < 0) { throw new IOException("Bad string length in message"); } byte[] bytes = new byte[len]; buffer.get(bytes); return new String(bytes, "UTF8"); } } /** * Internal representation for a binary format wire message. Implemented * as an inner class to allow content encodings to be easily mapped on * top of the streams this class produces. */ static class binaryMessageProxy implements WireFormatMessage { final Message message; final MimeMediaType type; final List<binaryElementProxy> elements = new ArrayList<binaryElementProxy>(); final Map<String, Integer> namespaceIDs = new HashMap<String, Integer>(); final List<String> namespaces = new ArrayList<String>(); byte[] header; binaryMessageProxy(Message msg, MimeMediaType type) throws IOException { message = msg; this.type = type; // we may generate different content based upon the type. assignNamespaceIds(); // build the element proxies Message.ElementIterator eachElement = message.getMessageElements(); while (eachElement.hasNext()) { MessageElement anElement = eachElement.next(); byte namespaceid = namespaceIDs.get(eachElement.getNamespace()).byteValue(); elements.add(new binaryElementProxy(namespaceid, anElement)); } buildHeader(); } /** * {@inheritDoc} */ public String getFileExtension() { return "???"; } /** * {@inheritDoc} */ public MimeMediaType getMimeType() { return type; } /** * {@inheritDoc} */ public ByteBuffer[] getByteBuffers() { List<ByteBuffer> partBuffers = new ArrayList<ByteBuffer>(); partBuffers.add(ByteBuffer.wrap(header)); for (binaryElementProxy anElement : elements) { partBuffers.addAll(Arrays.asList(anElement.getByteBuffers())); } if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) { LOG.finer(MessageFormat.format("Returning {0} buffers for {1}", partBuffers.size(), message)); } return partBuffers.toArray(new ByteBuffer[partBuffers.size()]); } /** * {@inheritDoc} */ public InputStream getStream() throws IOException { if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("Getting stream for " + message); } List<InputStream> streamParts = new ArrayList<InputStream>();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -