私はJavolutionで次の実装をしています:
public class RunScan extends Struct
{
public final Signed32 numOfClusters = new Signed32();
public final ClusterData[] clusters;
public final Signed32 numOfRecons = new Signed32();
public final ReconData[] recons ;
public RunScan (int numOfClusters, int numOfRecons)
{
this.numOfClusters.set(numOfClusters);
this.numOfRecons.set(numOfRecons);
clusters = array(new ClusterData[numOfClusters]);
recons = array(new ReconData[numOfRecons]);
}
}
public class ClusterData extends Struct
{
public final UTF8String scanType = new UTF8String(CommInterfaceFieldConstants.SCAN_TYPE_SIZE);
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
.
.
.
}
public class ReconData extends Struct
{
public final UTF8String patientId = new UTF8String(CommInterfaceFieldConstants.PATIENT_ID_SIZE);
public final UTF8String scanSeriesId = new UTF8String(CommInterfaceFieldConstants.SCAN_SERIES_ID_SIZE);
.
.
.
}
この通信クラスでは、データをソケットに入れる前に、RunScan オブジェクトの bytes[] を取得する必要がありますが、「//<<<<<<<」の行で BufferUnderflowException を取得します。
private byte[] getCmdBytes(Struct scCmd)
{
ByteBuffer cmdBuffer = scCmd.getByteBuffer();
int cmdSize = scCmd.size();
byte[] cmdBytes = new byte[cmdSize];
if (cmdBuffer.hasArray())
{
int offset = cmdBuffer.arrayOffset() + scCmd.getByteBufferPosition();
System.arraycopy(cmdBuffer.array(), offset, cmdBytes, 0, cmdSize);
}
else
{
String msg = "\n\ncmdBufferRemaining=" + cmdBuffer.remaining() + ", cmdBytesSize=" + cmdBytes.length + "\n\n";
System.out.println(msg);
cmdBuffer.position(scCmd.getByteBufferPosition());
cmdBuffer.get(cmdBytes); //<<<<<<<<<< underFlowException
}
return cmdBytes;
}
この方法は、他の場合にも機能します。この行が原因で例外が発生します。
ByteBuffer cmdBuffer = scCmd.getByteBuffer();
これら2つのSigned32フィールドであるRunScanオブジェクトの8バイト(remaining()メソッドから)ByteBufferのみを返します。しかし、この行、
int cmdSize = scCmd.size();
これら 2 つの配列のサイズを含む RunScan オブジェクトの正しい長さを返します。
ハードコーディングされた長さでそれらを宣言するときにこれらの2つの配列を作成すると(コンストラクターで「新しい」ものではない)、例外なく正常に動作します。
私たちの実装の何が問題なのかを理解してくれる人はいますか?