/******************************************************************************* * Copyright 2012 Keith Johnson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.ubergeek42.weechat.relay; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.zip.InflaterInputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ubergeek42.weechat.relay.protocol.Data; import com.ubergeek42.weechat.relay.protocol.RelayObject; /** * Represents a message from the Weechat Relay Server * * @author ubergeek42<kj@ubergeek42.com> */ public class RelayMessage { final private static boolean DEBUG = false; private static Logger logger = LoggerFactory.getLogger("RelayMessage"); private ArrayList<RelayObject> objects = new ArrayList<RelayObject>(); private boolean compressed = false; private int length = 0; private String id = null; public RelayMessage(byte[] data) { Data wd = new Data(data); // Load the data into our consumer // Get total message length length = wd.getUnsignedInt(); // Determine compression ratio int c = wd.getByte(); if (c == 0x00) { compressed = false; } else if (c == 0x01) { compressed = true; try { // System.out.println("[WMessage.constructor] Decompressing data"); ByteArrayOutputStream bout = new ByteArrayOutputStream(); InflaterInputStream is = new InflaterInputStream(new ByteArrayInputStream( wd.getByteArray())); byte b[] = new byte[256]; while (is.available() == 1) { int r = is.read(b); if (r < 0) { break; } bout.write(b, 0, r); } data = bout.toByteArray(); wd = new Data(data); // System.out.format("[WMessage.constructor] Data size: %d/%d\n", length, // data.length+5);// 5 is how much we've already read } catch (IOException e) { System.err.println("[WMessage.constructor] Failed to decompress data stream"); e.printStackTrace(); } } else { throw new RuntimeException("[WMessage.constructor] unknown compression type: " + String.format("%02X", c)); } // Optional data element id = wd.getString(); // One or more objects at this point while (wd.empty() == false) { objects.add(wd.getObject()); } } /** * Debug message for a WMessage */ @Override public String toString() { String msg = String.format( "[WMessage.tostring]\n Length: %d\n Compressed: %s\n ID: %s\n", length, "" + compressed, id); for (RelayObject obj : objects) { msg += obj.toString() + "\n"; } return msg; } /** * @return The ID associated with the message */ public String getID() { return this.id; } /** * @return The set of objects in the message */ public RelayObject[] getObjects() { RelayObject[] ret = new RelayObject[objects.size()]; ret = objects.toArray(ret); return ret; } }