Skip to content

Commit

Permalink
Require strings sent via RoboViz Draw to be UTF-8 encoded
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesbraun committed Jul 22, 2023
1 parent e8c288c commit 5f92d0d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 28 deletions.
65 changes: 42 additions & 23 deletions examples/java/RVDraw.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.awt.Color;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
Expand All @@ -28,7 +29,7 @@ public class RVDraw
/** Writes a float formatted in 6 ASCII characters to a buffer */
public static void writeFloatToBuffer(ByteBuffer buf, float value)
{
buf.put(String.format(Locale.US, "%6f", value).substring(0, 6).getBytes());
buf.put(String.format(Locale.US, "%6f", value).substring(0, 6).getBytes(StandardCharsets.UTF_8));
}

/** Writes RGB values of a Color object to a buffer */
Expand All @@ -42,9 +43,9 @@ public static void writeColorToBuffer(ByteBuffer buf, Color color, boolean alpha
}

/** Writes a string to a buffer */
public static void writeStringToBuffer(ByteBuffer buf, String s)
public static void writeStringToBuffer(ByteBuffer buf, byte[] s)
{
buf.put(s.getBytes());
buf.put(s);
buf.put((byte) 0);
}

Expand All @@ -64,13 +65,18 @@ public static float readFloatFromBuffer(ByteBuffer buf)
*/
public static byte[] newBufferSwap(String group)
{
int numBytes = 3 + ((group != null) ? group.length() : 0);
int numBytes = 3;
byte[] groupEncoded = null;
if (group != null) {
groupEncoded = group.getBytes(StandardCharsets.UTF_8);
numBytes += groupEncoded.length;
}
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 0);
buf.put((byte) 0);
if (group != null)
buf.put(group.getBytes());
buf.put(groupEncoded);
buf.put((byte) 0);

return buf.array();
Expand All @@ -92,7 +98,8 @@ public static byte[] newBufferSwap(String group)
*/
public static byte[] newCircle(float[] center, float radius, float thickness, Color color, String group)
{
int numBytes = 30 + group.length();
byte[] groupEncoded = group.getBytes(StandardCharsets.UTF_8);
int numBytes = 30 + groupEncoded.length;
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 1);
Expand All @@ -102,7 +109,7 @@ public static byte[] newCircle(float[] center, float radius, float thickness, Co
writeFloatToBuffer(buf, radius);
writeFloatToBuffer(buf, thickness);
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, group);
writeStringToBuffer(buf, groupEncoded);

return buf.array();
}
Expand All @@ -123,7 +130,8 @@ public static byte[] newCircle(float[] center, float radius, float thickness, Co
*/
public static byte[] newLine(float[] a, float[] b, float thickness, Color color, String group)
{
int numBytes = 48 + group.length();
byte[] groupEncoded = group.getBytes(StandardCharsets.UTF_8);
int numBytes = 48 + groupEncoded.length;
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 1);
Expand All @@ -136,7 +144,7 @@ public static byte[] newLine(float[] a, float[] b, float thickness, Color color,
writeFloatToBuffer(buf, b[2]);
writeFloatToBuffer(buf, thickness);
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, group);
writeStringToBuffer(buf, groupEncoded);

return buf.array();
}
Expand All @@ -155,7 +163,8 @@ public static byte[] newLine(float[] a, float[] b, float thickness, Color color,
*/
public static byte[] newPoint(float[] p, float size, Color color, String group)
{
int numBytes = 30 + group.length();
byte[] groupEncoded = group.getBytes(StandardCharsets.UTF_8);
int numBytes = 30 + groupEncoded.length;
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 1);
Expand All @@ -165,7 +174,7 @@ public static byte[] newPoint(float[] p, float size, Color color, String group)
writeFloatToBuffer(buf, p[2]);
writeFloatToBuffer(buf, size);
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, group);
writeStringToBuffer(buf, groupEncoded);

return buf.array();
}
Expand All @@ -184,7 +193,8 @@ public static byte[] newPoint(float[] p, float size, Color color, String group)
*/
public static byte[] newSphere(float[] p, float radius, Color color, String group)
{
int numBytes = 30 + group.length();
byte[] groupEncoded = group.getBytes(StandardCharsets.UTF_8);
int numBytes = 30 + groupEncoded.length;
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 1);
Expand All @@ -194,14 +204,15 @@ public static byte[] newSphere(float[] p, float radius, Color color, String grou
writeFloatToBuffer(buf, p[2]);
writeFloatToBuffer(buf, radius);
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, group);
writeStringToBuffer(buf, groupEncoded);

return buf.array();
}

public static byte[] newPolygon(float[][] v, Color color, String set)
{
int numBytes = 18 * v.length + 8 + set.length();
byte[] setEncoded = set.getBytes(StandardCharsets.UTF_8);
int numBytes = 18 * v.length + 8 + setEncoded.length;

ByteBuffer buf = ByteBuffer.allocate(numBytes);

Expand All @@ -218,20 +229,23 @@ public static byte[] newPolygon(float[][] v, Color color, String set)
writeFloatToBuffer(buf, v[i][2]);
}

// set.length + 1 bytes
writeStringToBuffer(buf, set);
// setEncoded.length + 1 bytes
writeStringToBuffer(buf, setEncoded);

return buf.array();
}

public static byte[] newAnnotation(String text, float[] pos, Color color, String set)
{
byte[] textEncoded = text.getBytes(StandardCharsets.UTF_8);
byte[] setEncoded = set.getBytes(StandardCharsets.UTF_8);

// header bytes = 2
// pos = 3 floats * 6 bytes per float = 18
// color = 3
// text = text.length + 1
// set = set.length + 1
int numBytes = 25 + text.length() + set.length();
// text = textEncoded.length + 1
// set = setEncoded.length + 1
int numBytes = 25 + textEncoded.length + setEncoded.length;
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 2);
Expand All @@ -240,8 +254,8 @@ public static byte[] newAnnotation(String text, float[] pos, Color color, String
writeFloatToBuffer(buf, pos[1]);
writeFloatToBuffer(buf, pos[2]);
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, text);
writeStringToBuffer(buf, set);
writeStringToBuffer(buf, textEncoded);
writeStringToBuffer(buf, setEncoded);

return buf.array();
}
Expand All @@ -252,7 +266,12 @@ public static byte[] newAnnotation(String text, float[] pos, Color color, String
*/
public static byte[] newAgentAnnotation(String text, boolean leftTeam, int agentNum, Color color)
{
int numBytes = (text == null) ? 3 : 7 + text.length();
int numBytes = 3;
byte[] textEncoded = null;
if (text != null) {
textEncoded = text.getBytes(StandardCharsets.UTF_8);
numBytes += 4 + textEncoded.length;
}
ByteBuffer buf = ByteBuffer.allocate(numBytes);

buf.put((byte) 2);
Expand All @@ -263,7 +282,7 @@ public static byte[] newAgentAnnotation(String text, boolean leftTeam, int agent
buf.put((byte) 1);
buf.put((byte) (leftTeam ? agentNum - 1 : agentNum + 127));
writeColorToBuffer(buf, color, false);
writeStringToBuffer(buf, text);
writeStringToBuffer(buf, text.getBytes(StandardCharsets.UTF_8));
}

return buf.array();
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/rv/comm/drawing/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package rv.comm.drawing.commands;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import jsgl.io.ByteUtil;
import jsgl.math.vector.Vec3f;
Expand Down Expand Up @@ -49,11 +50,14 @@ public abstract class Command
*/
public static String getString(ByteBuffer buf)
{
StringBuilder sb = new StringBuilder();
char c;
while ((c = (char) ByteUtil.uValue(buf.get())) != 0)
sb.append(c);
return sb.toString();
ByteBuffer str = buf.slice();
int i = 0;
while (buf.hasRemaining() && buf.get() != 0x00) {
// Count bytes until null
i++;
}
str.limit(i);
return StandardCharsets.UTF_8.decode(str).toString();
}

/**
Expand Down

0 comments on commit 5f92d0d

Please sign in to comment.