Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUACAMOLE-2036: Refactor away public constructor accepting internal char array. #1064

Merged
merged 1 commit into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,34 +93,6 @@ public GuacamoleInstruction(String opcode, List<String> args) {
this.args = Collections.unmodifiableList(args);
}

/**
* Creates a new GuacamoleInstruction having the given opcode, list of
* argument values, and underlying protocol representation. The list given
* will be used to back the internal list of arguments and the list
* returned by {@link #getArgs()}. The provided protocol representation
* will be used to back the internal protocol representation and values
* returned by {@link #toCharArray()} and {@link #toString()}.
* <p>
* Neither the provided argument list nor the provided protocol
* representation may be modified in any way after being provided to this
* constructor. Doing otherwise will result in undefined behavior.
*
* @param opcode
* The opcode of the instruction to create.
*
* @param args
* The list of argument values to provide in the new instruction, if
* any.
*
* @param raw
* The underlying representation of this instruction as would be sent
* over the network via the Guacamole protocol.
*/
public GuacamoleInstruction(String opcode, List<String> args, char[] raw) {
this(opcode, args);
this.rawChars = raw;
}

/**
* Returns the opcode associated with this GuacamoleInstruction.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleServerException;

Expand Down Expand Up @@ -120,6 +121,62 @@ private enum State {
*/
private int rawInstructionOffset = 0;

/**
* GuacamoleInstruction that efficiently exposes the originally parsed
* character buffer for calls to {@link #toString()} and {@link #toCharArray()}
* rather than regenerate the buffer from scratch.
*/
private static class ParsedGuacamoleInstruction extends GuacamoleInstruction {

/**
* The original data parsed to produce this GuacamoleInstruction.
*/
private final char[] rawChars;

/**
* A String containing the original data parsed to produce this
* GuacamoleInstruction.
*/
private String rawString = null;

/**
* Creates a new GuacamoleInstruction that efficiently exposes the
* originally parsed character buffer rather than regenerating that
* buffer from scratch for {@link #toString()} and {@link #toCharArray()}.
*
* @param opcode
* The opcode of the instruction to create.
*
* @param args
* The list of argument values to provide in the new instruction, if
* any.
*
* @param raw
* The underlying representation of this instruction as would be sent
* over the network via the Guacamole protocol.
*/
public ParsedGuacamoleInstruction(String opcode, List<String> args, char[] raw) {
super(opcode, args);
this.rawChars = raw;
}

@Override
public String toString() {

if (rawString == null)
rawString = new String(rawChars);

return rawString;

}

@Override
public char[] toCharArray() {
return rawChars;
}

}

/**
* Appends data from the given buffer to the current instruction.
*
Expand Down Expand Up @@ -167,7 +224,8 @@ public int append(char chunk[], int offset, int length) throws GuacamoleExceptio
// If the instruction is now complete, we're good to store the
// parsed instruction for future retrieval via next()
if (state == State.COMPLETE) {
parsedInstruction = new GuacamoleInstruction(elements[0], Arrays.asList(elements).subList(1, elementCount),
parsedInstruction = new ParsedGuacamoleInstruction(elements[0],
Arrays.asList(elements).subList(1, elementCount),
Arrays.copyOf(rawInstruction, rawInstructionOffset));
rawInstructionOffset = 0;
}
Expand Down