/*******************************************************************************
* Copyright (c) 2016 Rogue Wave Software, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Rogue Wave Software, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.zdb.server.connection;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.AddBreakpointResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.AddFilesResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.AssignValueResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.DeleteAllBreakpointsResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.DeleteBreakpointResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.EvalResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.GetCWDResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.GetCallStackResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.GetStackVariableValueResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.GetVariableValueResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.GoResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.IDbgEngineResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.PauseDebuggerResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.SetProtocolResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.StartResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.StepIntoResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.StepOutResponse;
import org.eclipse.che.plugin.zdb.server.connection.ZendDbgEngineMessages.StepOverResponse;
import org.eclipse.che.plugin.zdb.server.utils.ZendDbgConnectionUtils;
/**
* Zend debug client messages container.
*
* @author Bartlomiej Laczkowski
*/
public class ZendDbgClientMessages {
// Notification types
public static final int NOTIFICATION_CONTINUE_PROCESS_FILE = 2010;
public static final int NOTIFICATION_CLOSE_SESSION = 3;
// Request types
public static final int REQUEST_START = 1;
public static final int REQUEST_PAUSE_DEBUGGER = 2;
public static final int REQUEST_STEP_INTO = 11;
public static final int REQUEST_STEP_OVER = 12;
public static final int REQUEST_STEP_OUT = 13;
public static final int REQUEST_GO = 14;
public static final int REQUEST_ADD_BREAKPOINT = 21;
public static final int REQUEST_DELETE_BREAKPOINT = 22;
public static final int REQUEST_DELETE_ALL_BREAKPOINTS = 23;
public static final int REQUEST_EVAL = 31;
public static final int REQUEST_GET_VARIABLE_VALUE = 32;
public static final int REQUEST_ASSIGN_VALUE = 33;
public static final int REQUEST_GET_CALL_STACK = 34;
public static final int REQUEST_GET_STACK_VARIABLE_VALUE = 35;
public static final int REQUEST_GET_CWD = 36;
public static final int REQUEST_ADD_FILES = 38;
public static final int REQUEST_SET_PROTOCOL = 10000;
// Response types
public static final int RESPONSE_GET_LOCAL_FILE_CONTENT = 11001;
public interface IDbgClientMessage extends IDbgMessage {
/**
* Serializes this debug message to an output stream
*
* @param out
* output stream this message is going to be written to
*/
public void serialize(DataOutputStream out) throws IOException;
}
public interface IDbgClientNotification extends IDbgClientMessage {
}
public interface IDbgClientRequest<T extends IDbgEngineResponse> extends IDbgClientMessage {
/**
* Set the client request id.
*/
public void setID(int id);
/**
* Return the client request id.
*/
public int getID();
}
public interface IDbgClientResponse extends IDbgClientMessage {
/**
* Return the engine response id.
*/
public int getID();
/**
* Return the engine response status.
*/
public int getStatus();
}
private static abstract class AbstractClientRequest<T extends IDbgEngineResponse> extends AbstractDbgMessage
implements IDbgClientRequest<T> {
private int id;
@Override
public void setID(int id) {
this.id = id;
}
@Override
public int getID() {
return this.id;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
out.writeShort(getType());
out.writeInt(getID());
}
}
private static abstract class AbstractClientResponse extends AbstractDbgMessage implements IDbgClientResponse {
protected int id;
protected int status;
public AbstractClientResponse(int id) {
this.id = id;
}
@Override
public int getID() {
return this.id;
}
@Override
public int getStatus() {
return status;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
out.writeShort(getType());
out.writeInt(getID());
out.writeInt(getStatus());
}
}
private ZendDbgClientMessages() {
}
// Client notifications
public static class ContinueProcessFileNotification extends AbstractDbgMessage implements IDbgClientNotification {
@Override
public int getType() {
return NOTIFICATION_CONTINUE_PROCESS_FILE;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
out.writeShort(getType());
}
}
public static class CloseSessionNotification extends AbstractDbgMessage implements IDbgClientNotification {
@Override
public int getType() {
return NOTIFICATION_CLOSE_SESSION;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
out.writeShort(getType());
}
}
// Client requests
public static class AddBreakpointRequest extends AbstractClientRequest<AddBreakpointResponse> {
private int kind;
private int lifeTime;
private int lineNumber;
private String fileName;
public AddBreakpointRequest(int kind, int lifeTime, int line, String fileName) {
this.kind = kind;
this.lifeTime = lifeTime;
this.lineNumber = line;
this.fileName = fileName;
}
@Override
public int getType() {
return REQUEST_ADD_BREAKPOINT;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
out.writeShort(kind);
out.writeShort(lifeTime);
ZendDbgConnectionUtils.writeString(out, fileName);
out.writeInt(lineNumber);
}
}
public static class AddFilesRequest extends AbstractClientRequest<AddFilesResponse> {
private Set<String> paths;
public AddFilesRequest(Set<String> paths) {
this.paths = paths;
}
@Override
public int getType() {
return REQUEST_ADD_FILES;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
out.writeInt(paths.size());
for (String path : paths) {
ZendDbgConnectionUtils.writeString(out, path);
}
}
}
public static class AssignValueRequest extends AbstractClientRequest<AssignValueResponse> {
private String var;
private String value;
private int depth;
private List<String> path;
public AssignValueRequest(String var, String value, int depth, List<String> path) {
this.var = var;
this.value = value;
this.depth = depth;
this.path = path;
}
@Override
public int getType() {
return REQUEST_ASSIGN_VALUE;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
ZendDbgConnectionUtils.writeEncodedString(out, var, getTransferEncoding());
ZendDbgConnectionUtils.writeEncodedString(out, value, getTransferEncoding());
out.writeInt(depth);
out.writeInt(path.size());
for (String p : path) {
ZendDbgConnectionUtils.writeString(out, p);
}
}
}
public static class DeleteAllBreakpointsRequest extends AbstractClientRequest<DeleteAllBreakpointsResponse> {
@Override
public int getType() {
return REQUEST_DELETE_ALL_BREAKPOINTS;
}
}
public static class DeleteBreakpointRequest extends AbstractClientRequest<DeleteBreakpointResponse> {
private int breakpointId;
public DeleteBreakpointRequest(int breakpointId) {
this.breakpointId = breakpointId;
}
@Override
public int getType() {
return REQUEST_DELETE_BREAKPOINT;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
out.writeInt(breakpointId);
}
}
public static class EvalRequest extends AbstractClientRequest<EvalResponse> {
private String command;
public EvalRequest(String command) {
this.command = command;
}
@Override
public int getType() {
return REQUEST_EVAL;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
ZendDbgConnectionUtils.writeEncodedString(out, command, getTransferEncoding());
}
}
public static class GetCallStackRequest extends AbstractClientRequest<GetCallStackResponse> {
@Override
public int getType() {
return REQUEST_GET_CALL_STACK;
}
}
public static class GetCWDRequest extends AbstractClientRequest<GetCWDResponse> {
@Override
public int getType() {
return REQUEST_GET_CWD;
}
}
public static class GetStackVariableValueRequest extends AbstractClientRequest<GetStackVariableValueResponse> {
private String var;
private int depth;
private int layerDepth;
private List<String> path;
public GetStackVariableValueRequest(String var, int depth, int layerDepth, List<String> path) {
this.var = var;
this.depth = depth;
this.layerDepth = layerDepth;
this.path = path;
}
@Override
public int getType() {
return REQUEST_GET_STACK_VARIABLE_VALUE;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
out.writeInt(layerDepth);
ZendDbgConnectionUtils.writeEncodedString(out, var, getTransferEncoding());
out.writeInt(depth);
out.writeInt(path.size());
for (String p : path) {
ZendDbgConnectionUtils.writeString(out, p);
}
}
}
public static class GetVariableValueRequest extends AbstractClientRequest<GetVariableValueResponse> {
private String var;
private int depth;
private List<String> path;
public GetVariableValueRequest(String var, int depth, List<String> path) {
this.var = var;
this.depth = depth;
this.path = path;
}
@Override
public int getType() {
return REQUEST_GET_VARIABLE_VALUE;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
ZendDbgConnectionUtils.writeEncodedString(out, var, getTransferEncoding());
out.writeInt(depth);
out.writeInt(path.size());
for (String p : path) {
ZendDbgConnectionUtils.writeString(out, p);
}
}
}
public static class GoRequest extends AbstractClientRequest<GoResponse> {
@Override
public int getType() {
return REQUEST_GO;
}
}
public static class PauseDebuggerRequest extends AbstractClientRequest<PauseDebuggerResponse> {
@Override
public int getType() {
return REQUEST_PAUSE_DEBUGGER;
}
}
public static class SetProtocolRequest extends AbstractClientRequest<SetProtocolResponse> {
private int protocolID;
public SetProtocolRequest(int protocolID) {
this.protocolID = protocolID;
}
@Override
public int getType() {
return REQUEST_SET_PROTOCOL;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
out.writeInt(protocolID);
}
}
public static class StartRequest extends AbstractClientRequest<StartResponse> {
@Override
public int getType() {
return REQUEST_START;
}
}
public static class StepIntoRequest extends AbstractClientRequest<StepIntoResponse> {
@Override
public int getType() {
return REQUEST_STEP_INTO;
}
}
public static class StepOutRequest extends AbstractClientRequest<StepOutResponse> {
@Override
public int getType() {
return REQUEST_STEP_OUT;
}
}
public static class StepOverRequest extends AbstractClientRequest<StepOverResponse> {
@Override
public int getType() {
return REQUEST_STEP_OVER;
}
}
// Client responses
public static class GetLocalFileContentResponse extends AbstractClientResponse {
public static final int STATUS_FAILURE = -1;
public static final int STATUS_SUCCESS = 0;
public static final int STATUS_FILES_IDENTICAL = 302;
private byte content[] = null;
public GetLocalFileContentResponse(int id, int status, byte[] content) {
super(id);
this.status = status;
this.content = content;
}
@Override
public void serialize(DataOutputStream out) throws IOException {
super.serialize(out);
if (content != null) {
out.write(content.length);
out.write(content);
} else {
out.writeInt(0);
}
}
@Override
public int getType() {
return RESPONSE_GET_LOCAL_FILE_CONTENT;
}
}
}