From 88cfe5045d77d433ce02b0ef10ee84c9d4fb15e2 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 23 May 2014 15:17:15 +0000
Subject: [PATCH] (CR-3599) Convert all protocols message to use ByteArrayBuilder + ByteArrayScanner
---
opends/src/server/org/opends/server/replication/protocol/ByteArrayBuilder.java | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 100 insertions(+), 14 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/protocol/ByteArrayBuilder.java b/opends/src/server/org/opends/server/replication/protocol/ByteArrayBuilder.java
index 9431c35..faef4bf 100644
--- a/opends/src/server/org/opends/server/replication/protocol/ByteArrayBuilder.java
+++ b/opends/src/server/org/opends/server/replication/protocol/ByteArrayBuilder.java
@@ -26,9 +26,15 @@
import java.io.UnsupportedEncodingException;
import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.opends.server.protocols.asn1.ASN1;
+import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.replication.common.CSN;
+import org.opends.server.replication.common.ServerState;
import org.opends.server.types.ByteStringBuilder;
+import org.opends.server.types.DN;
/**
* Byte array builder class encodes data into byte arrays to send messages over
@@ -42,8 +48,6 @@
public class ByteArrayBuilder
{
- /** This is the null byte, also known as zero byte. */
- public static final byte NULL_BYTE = 0;
private final ByteStringBuilder builder;
/**
@@ -51,7 +55,7 @@
*/
public ByteArrayBuilder()
{
- builder = new ByteStringBuilder();
+ builder = new ByteStringBuilder(256);
}
/**
@@ -165,7 +169,8 @@
*/
public ByteArrayBuilder appendStrings(Collection<String> col)
{
- append(col.size());
+ //append(int) would have been safer, but byte is compatible with legacy code
+ append((byte) col.size());
for (String s : col)
{
append(s);
@@ -174,23 +179,28 @@
}
/**
- * Append a String to this ByteArrayBuilder.
+ * Append a String with a zero separator to this ByteArrayBuilder,
+ * or only the zero separator if the string is null
+ * or if the string length is zero.
*
* @param s
- * the String to append.
+ * the String to append. Can be null.
* @return this ByteArrayBuilder
*/
public ByteArrayBuilder append(String s)
{
try
{
- append(s.getBytes("UTF-8"));
+ if (s != null && s.length() > 0)
+ {
+ append(s.getBytes("UTF-8"));
+ }
+ return appendZeroSeparator();
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException("Should never happen", e);
}
- return this;
}
/**
@@ -220,17 +230,93 @@
return this;
}
- private ByteArrayBuilder append(byte[] sBytes)
+ /**
+ * Append a DN to this ByteArrayBuilder by converting it to a String then
+ * encoding that string to a UTF-8 byte array.
+ *
+ * @param dn
+ * the DN to append.
+ * @return this ByteArrayBuilder
+ */
+ public ByteArrayBuilder append(DN dn)
{
- for (byte b : sBytes)
- {
- append(b);
- }
- append((byte) 0); // zero separator
+ append(dn.toString());
return this;
}
/**
+ * Append all the bytes from the byte array to this ByteArrayBuilder.
+ *
+ * @param bytes
+ * the byte array to append.
+ * @return this ByteArrayBuilder
+ */
+ public ByteArrayBuilder append(byte[] bytes)
+ {
+ builder.append(bytes);
+ return this;
+ }
+
+ /**
+ * Append all the bytes from the byte array to this ByteArrayBuilder
+ * and then append a final zero byte separator for compatibility
+ * with legacy implementations.
+ *
+ * @param bytes
+ * the byte array to append.
+ * @return this ByteArrayBuilder
+ */
+ public ByteArrayBuilder appendZeroTerminated(byte[] bytes)
+ {
+ builder.append(bytes);
+ return appendZeroSeparator();
+ }
+
+ private ByteArrayBuilder appendZeroSeparator()
+ {
+ builder.append((byte) 0);
+ return this;
+ }
+
+ /**
+ * Append the byte representation of a ServerState to this ByteArrayBuilder
+ * and then append a final zero byte separator.
+ * <p>
+ * Caution: ServerState MUST be the last field. Because ServerState can
+ * contain null character (string termination of serverId string ..) it cannot
+ * be decoded using {@link ByteArrayScanner#nextString()} like the other
+ * fields. The only way is to rely on the end of the input buffer: and that
+ * forces the ServerState to be the last field. This should be changed if we
+ * want to have more than one ServerState field.
+ *
+ * @param serverState
+ * the ServerState to append.
+ * @return this ByteArrayBuilder
+ */
+ public ByteArrayBuilder append(ServerState serverState)
+ {
+ final Map<Integer, CSN> serverIdToCSN = serverState.getServerIdToCSNMap();
+ for (Entry<Integer, CSN> entry : serverIdToCSN.entrySet())
+ {
+ // FIXME JNR: why append the serverId in addition to the CSN
+ // since the CSN already contains the serverId?
+ appendUTF8(entry.getKey()); // serverId
+ appendUTF8(entry.getValue()); // CSN
+ }
+ return appendZeroSeparator(); // stupid legacy zero separator
+ }
+
+ /**
+ * Returns a new ASN1Writer that will append bytes to this ByteArrayBuilder.
+ *
+ * @return a new ASN1Writer that will append bytes to this ByteArrayBuilder.
+ */
+ public ASN1Writer getASN1Writer()
+ {
+ return ASN1.getWriter(builder);
+ }
+
+ /**
* Converts the content of this ByteStringBuilder to a byte array.
*
* @return the content of this ByteStringBuilder converted to a byte array.
--
Gitblit v1.10.0