私は、パケットのペイロード内の特定のバイトをチェックし、それらが >,<,!, = 指定された値に等しいかどうかをテストしようとして遊んでいます。境界点は動的ですが、それらの間のバイトを評価する最良の方法は何ですか?
たとえば、ペイロードを持つパケット (もちろんヘッダーに続きます) があり、バイト 5 とバイト 10 の間を評価して、指定された値よりも大きいかどうかを確認したいと考えています。
私は、パケットのペイロード内の特定のバイトをチェックし、それらが >,<,!, = 指定された値に等しいかどうかをテストしようとして遊んでいます。境界点は動的ですが、それらの間のバイトを評価する最良の方法は何ですか?
たとえば、ペイロードを持つパケット (もちろんヘッダーに続きます) があり、バイト 5 とバイト 10 の間を評価して、指定された値よりも大きいかどうかを確認したいと考えています。
の戻り値memcmp()
は、符号なしのリトル エンディアン比較を適切に行います。
return memcmp(&packet[IndexLo], &Reference, IndexHi - IndexLo + 1);
移植可能なメソッドは、一度に 1 バイトを単純に比較します。
簡単な方法ですが、いくつかの仮定があります:
. パケット データとプラットフォームは同じエンディアンとリトルです。
. Boundary_width <= sizeof inttype
.
. 符号なし算術。
. に最適化されていPacket_CompareMask()
ます。
. 任意のバイト境界で幅の整数にアクセスしても OK。
. の最後を過ぎたメモリへのアクセスはOKですpacket
。
typedef uint64_t inttype;
int Packet_CompareMask(const char *packet, size_t IndexLo, unint64_t Mask, inttype Reference) {
// This fails on machine with alignment restricts on wide integers.
inttype x = *((inttype *) &packet[IndexLo]);
x &= Mask;
if (x < Reference) return -1;
return x > 0;
}
int Packet_CompareRange(const void *packet, size_t IndexLo, size_t IndexHi, inttype Reference) {
inttype Mask = 0;
ssize_t Diff = IndexHi - IndexLo;
if ((Diff <= 0) || (Diff > (sizeof(Mask) - 1))) {
; // handle error
}
// This only works on little endian machines. A variant would work with Big endian.
while (--Diff >= 0) {
Mask <<= 8;
Mask |= 0xFF;
}
return Packet_CompareRange(packet, IndexLo, Mask, Reference);
}