From 00cb8a4abd7a11e94b6f6b0b9552b2001f25ecfa Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Fri, 25 Nov 2011 10:12:29 +0000 Subject: [PATCH] Make bitcoinSerialize() return a copy by default, provide an unsafeBitcoinSerialize() method for high performance applications that are willing to deal with the extra API complexity. --- src/com/google/bitcoin/core/Message.java | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/com/google/bitcoin/core/Message.java b/src/com/google/bitcoin/core/Message.java index b574bcf2..e2dcc339 100644 --- a/src/com/google/bitcoin/core/Message.java +++ b/src/com/google/bitcoin/core/Message.java @@ -98,7 +98,8 @@ public abstract class Message implements Serializable { * as the length will be provided as part of the header. If unknown then set to Message.UNKNOWN_LENGTH * @throws ProtocolException */ - Message(NetworkParameters params, byte[] msg, int offset, int protocolVersion, final boolean parseLazy, final boolean parseRetain, int length) throws ProtocolException { + Message(NetworkParameters params, byte[] msg, int offset, int protocolVersion, final boolean parseLazy, + final boolean parseRetain, int length) throws ProtocolException { this.parseLazy = parseLazy; this.parseRetain = parseRetain; this.protocolVersion = protocolVersion; @@ -262,6 +263,19 @@ public abstract class Message implements Serializable { this.checksum = checksum; } + /** + * Returns a copy of the array returned by {@link Message#unsafeBitcoinSerialize()}, which is safe to mutate. + * If you need extra performance and can guarantee you won't write to the array, you can use the unsafe version. + * + * @return a freshly allocated serialized byte array + */ + public byte[] bitcoinSerialize() { + byte[] bytes = unsafeBitcoinSerialize(); + byte[] copy = new byte[bytes.length]; + System.arraycopy(bytes, 0, copy, 0, bytes.length); + return copy; + } + /** * Serialize this message to a byte array that conforms to the bitcoin wire protocol. *
@@ -274,11 +288,12 @@ public abstract class Message implements Serializable { * * * If condition 3 is not met then an copy of the relevant portion of the array will be returned. - * Otherwise a full serialize will occur. + * Otherwise a full serialize will occur. For this reason you should only use this API if you can guarantee you + * will treat the resulting array as read only. * - * @return + * @return a byte array owned by this object, do NOT mutate it. */ - public byte[] bitcoinSerialize() { + public byte[] unsafeBitcoinSerialize() { // 1st attempt to use a cached array. if (bytes != null) { if (offset == 0 && length == bytes.length) {