org.syphr.mythtv.protocol.ProtocolPacket Maven / Gradle / Ivy
/*
* Copyright 2011-2012 Gregory P. Moyer
*
* 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 org.syphr.mythtv.protocol;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.syphr.mythtv.util.socket.Packet;
/**
* This class represents the lowest level socket communication between the client and a
* MythTV backend server.
*
* @author Gregory P. Moyer
*/
/* default */class ProtocolPacket implements Packet
{
private static final Charset UTF8 = Charset.forName("UTF-8");
private static final int HEADER_SIZE = 8;
private static final int PAYLOAD_BUFFER_SIZE = 8192;
@Override
public List read(ReadableByteChannel in) throws IOException
{
byte[] headerBytes = new byte[HEADER_SIZE];
ByteBuffer headerBuffer = ByteBuffer.wrap(headerBytes);
int read = 0;
/*
* Read the header, which indicates the size of the payload.
*/
while (headerBuffer.hasRemaining())
{
if (Thread.interrupted())
{
InterruptedIOException e = new InterruptedIOException();
e.bytesTransferred = read;
throw e;
}
read += in.read(headerBuffer);
}
int size = Integer.parseInt(new String(headerBytes,
0,
headerBytes.length,
UTF8).trim());
/*
* Read the payload.
*/
byte[] payloadBytes = new byte[PAYLOAD_BUFFER_SIZE];
ByteBuffer payloadBuffer = ByteBuffer.wrap(payloadBytes);
StringBuilder builder = new StringBuilder();
read = 0;
while (read < size)
{
if (Thread.interrupted())
{
InterruptedIOException e = new InterruptedIOException();
e.bytesTransferred = read + HEADER_SIZE;
throw e;
}
payloadBuffer.clear();
payloadBuffer.limit(Math.min(PAYLOAD_BUFFER_SIZE, size - read));
int justRead = 0;
while (payloadBuffer.hasRemaining())
{
justRead += in.read(payloadBuffer);
}
read += justRead;
builder.append(new String(payloadBytes, 0, justRead, UTF8));
}
List messages = new ArrayList();
messages.add(builder.toString());
return messages;
}
@Override
public void write(WritableByteChannel out, String data) throws IOException
{
byte[] payloadBytes = data.getBytes(UTF8);
String size = String.format("%-" + HEADER_SIZE + "d", payloadBytes.length);
byte[] headerBytes = size.getBytes(UTF8);
ByteBuffer buffer = ByteBuffer.allocate(headerBytes.length + payloadBytes.length);
buffer.put(headerBytes);
buffer.put(payloadBytes);
buffer.flip();
while (buffer.hasRemaining())
{
if (Thread.interrupted())
{
InterruptedIOException e = new InterruptedIOException();
e.bytesTransferred = buffer.position();
throw e;
}
out.write(buffer);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy