make bitSet more comnpatible with Java implementation.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include <iostream>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
@@ -199,6 +200,8 @@ namespace epics { namespace pvData {
|
||||
}
|
||||
|
||||
BitSet& BitSet::operator&=(const BitSet& set) {
|
||||
// Check for self-assignment!
|
||||
if (this == &set) return *this;
|
||||
|
||||
while (wordsInUse > set.wordsInUse)
|
||||
words[--wordsInUse] = 0;
|
||||
@@ -213,76 +216,49 @@ namespace epics { namespace pvData {
|
||||
}
|
||||
|
||||
BitSet& BitSet::operator|=(const BitSet& set) {
|
||||
|
||||
uint32 wordsInCommon;
|
||||
// Check for self-assignment!
|
||||
if (this == &set) return *this;
|
||||
uint32 wordsInCommon = wordsInUse;
|
||||
if(wordsInUse>set.wordsInUse) wordsInCommon = set.wordsInUse;
|
||||
if (wordsInUse < set.wordsInUse) {
|
||||
wordsInCommon = wordsInUse;
|
||||
//ensureCapacity(set.wordsInUse);
|
||||
//wordsInUse = set.wordsInUse;
|
||||
ensureCapacity(set.wordsInUse);
|
||||
wordsInUse = set.wordsInUse;
|
||||
}
|
||||
else
|
||||
wordsInCommon = set.wordsInUse;
|
||||
|
||||
// Perform logical OR on words in common
|
||||
uint32 i = 0;
|
||||
for (; i < wordsInCommon; i++)
|
||||
for (uint32 i =0; i < wordsInCommon; i++) {
|
||||
words[i] |= set.words[i];
|
||||
|
||||
// TODO what to do if BitSets are not the same size !!!
|
||||
|
||||
}
|
||||
// Copy any remaining words
|
||||
for(uint32 i=wordsInCommon; i<set.wordsInUse; ++i) {
|
||||
words[i] = set.words[i];
|
||||
}
|
||||
// recalculateWordsInUse() is not needed
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitSet& BitSet::operator^=(const BitSet& set) {
|
||||
|
||||
uint32 wordsInCommon;
|
||||
uint32 wordsInCommon = wordsInUse;
|
||||
if(wordsInUse>set.wordsInUse) wordsInCommon = set.wordsInUse;
|
||||
if (wordsInUse < set.wordsInUse) {
|
||||
wordsInCommon = wordsInUse;
|
||||
//ensureCapacity(set.wordsInUse);
|
||||
//wordsInUse = set.wordsInUse;
|
||||
ensureCapacity(set.wordsInUse);
|
||||
wordsInUse = set.wordsInUse;
|
||||
}
|
||||
else
|
||||
wordsInCommon = set.wordsInUse;
|
||||
|
||||
// Perform logical XOR on words in common
|
||||
uint32 i = 0;
|
||||
for (; i < wordsInCommon; i++)
|
||||
// Perform logical OR on words in common
|
||||
for (uint32 i =0; i < wordsInCommon; i++) {
|
||||
words[i] ^= set.words[i];
|
||||
|
||||
// TODO what to do if BitSets are not the same size !!!
|
||||
|
||||
recalculateWordsInUse();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitSet& BitSet::operator-=(const BitSet& set) {
|
||||
|
||||
uint32 wordsInCommon;
|
||||
if (wordsInUse < set.wordsInUse) {
|
||||
wordsInCommon = wordsInUse;
|
||||
//ensureCapacity(set.wordsInUse);
|
||||
//wordsInUse = set.wordsInUse;
|
||||
}
|
||||
// Copy any remaining words
|
||||
for(uint32 i=wordsInCommon; i<set.wordsInUse; ++i) {
|
||||
words[i] = set.words[i];
|
||||
}
|
||||
else
|
||||
wordsInCommon = set.wordsInUse;
|
||||
|
||||
// Perform logical (a & !b) on words in common
|
||||
uint32 i = 0;
|
||||
for (; i < wordsInCommon; i++)
|
||||
words[i] &= ~set.words[i];
|
||||
|
||||
recalculateWordsInUse();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BitSet& BitSet::operator=(const BitSet &set) {
|
||||
// Check for self-assignment!
|
||||
if (this == &set)
|
||||
return *this;
|
||||
if (this == &set) return *this;
|
||||
|
||||
// we ensure that words array size is adequate (and not wordsInUse to ensure capacity to the future)
|
||||
if (wordsLength < set.wordsLength)
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace epics { namespace pvData {
|
||||
class BitSet : public Serializable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(BitSet);
|
||||
static BitSet::shared_pointer create(uint32 nbits);
|
||||
static BitSetPtr create(uint32 nbits);
|
||||
/**
|
||||
* Creates a new bit set. All bits are initially {@code false}.
|
||||
*/
|
||||
@@ -201,15 +201,6 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
BitSet& operator^=(const BitSet& set);
|
||||
|
||||
/**
|
||||
* Clears all of the bits in this {@code BitSet} whose corresponding
|
||||
* bit is set in the specified {@code BitSet}.
|
||||
*
|
||||
* @param set the {@code BitSet} with which to mask this
|
||||
* {@code BitSet}
|
||||
*/
|
||||
BitSet& operator-=(const BitSet& set);
|
||||
|
||||
/**
|
||||
* Assigment operator.
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,9 @@ testTimer_SRCS += testTimer.cpp
|
||||
PROD_HOST += testBitSet
|
||||
testBitSet_SRCS += testBitSet.cpp
|
||||
|
||||
PROD_HOST += testOverrunBitSet
|
||||
testOverrunBitSet_SRCS += testOverrunBitSet.cpp
|
||||
|
||||
PROD_HOST += testByteOrder
|
||||
testByteOrder_SRCS += testByteOrder.cpp
|
||||
|
||||
@@ -22,6 +25,10 @@ testByteBuffer_SRCS += testByteBuffer.cpp
|
||||
PROD_HOST += testBaseException
|
||||
testBaseException_SRCS += testBaseException.cpp
|
||||
|
||||
TESTPROD += testSharedVector
|
||||
testSharedVector_SRCS += testSharedVector.cpp
|
||||
TESTS += testSharedVector
|
||||
|
||||
TESTPROD += testSerialization
|
||||
testSerialization_SRCS += testSerialization.cpp
|
||||
TESTS += testSerialization
|
||||
@@ -39,10 +46,6 @@ TESTPROD += testTypeCast
|
||||
testTypeCast_SRCS += testTypeCast.cpp
|
||||
TESTS += testTypeCast
|
||||
|
||||
TESTPROD += testSharedVector
|
||||
testSharedVector_SRCS += testSharedVector.cpp
|
||||
TESTS += testSharedVector
|
||||
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
/* Author: Matej Sekoranja Date: 2010.10.18 */
|
||||
|
||||
#include <iostream>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -96,12 +97,16 @@ void testOperators(FILE *fd) {
|
||||
assert(b1 == b2);
|
||||
|
||||
// OR test
|
||||
b1.set(65);
|
||||
b1.set(106);
|
||||
b2.set(65);
|
||||
b2.set(106);
|
||||
b2.set(105);
|
||||
b1 |= b2;
|
||||
std::string str; b1.toString(&str);
|
||||
assert(str == "{1, 65, 105, 106}");
|
||||
b1.clear();
|
||||
b1 |= b2;
|
||||
str.clear(); b1.toString(&str);
|
||||
assert(str == "{1, 65, 105, 106}");
|
||||
|
||||
// AND test
|
||||
b1.set(128);
|
||||
@@ -112,15 +117,13 @@ void testOperators(FILE *fd) {
|
||||
b1.set(128);
|
||||
b1 ^= b2;
|
||||
assert(b1.cardinality() == 1 && b1.get(128) == true);
|
||||
|
||||
// a AND (NOT b)
|
||||
b2 -= b1;
|
||||
str.clear(); b2.toString(&str);
|
||||
assert(str == "{1, 105}");
|
||||
b1.clear();
|
||||
b2.clear();
|
||||
b1.set(1);
|
||||
b2 -= b1;
|
||||
str.clear(); b2.toString(&str);
|
||||
assert(b2.cardinality() == 1 && b2.get(105) == true);
|
||||
b2.set(256);
|
||||
b1 ^= b2;
|
||||
assert(b1.cardinality() == 2 && b1.get(1) == true && b1.get(256) == true);
|
||||
|
||||
|
||||
// assign
|
||||
b1 = b2;
|
||||
|
||||
141
testApp/misc/testOverrunBitSet.cpp
Normal file
141
testApp/misc/testOverrunBitSet.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/* testOverrunBitSet.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/* Author: Marty Kraimer Date: 2013.09.16 */
|
||||
|
||||
#include <iostream>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/bitSetUtil.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
#include <epicsAssert.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
static StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
|
||||
void test()
|
||||
{
|
||||
String buffer;
|
||||
String properties("alarm,timeStamp,display");
|
||||
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,properties);
|
||||
PVDoublePtr pvValue = pvStructure->getDoubleField("value");
|
||||
uint32 valueOffset = pvValue->getFieldOffset();
|
||||
PVStructurePtr pvAlarm = pvStructure->getStructureField("alarm");
|
||||
PVIntPtr pvSeverity = pvAlarm->getIntField("severity");
|
||||
PVStringPtr pvMessage = pvAlarm->getStringField("message");
|
||||
uint32 severityOffset = pvSeverity->getFieldOffset();
|
||||
uint32 messageOffset = pvMessage->getFieldOffset();
|
||||
PVStructurePtr pvTimeStamp = pvStructure->getStructureField("timeStamp");
|
||||
PVLongPtr pvSeconds = pvTimeStamp->getLongField("secondsPastEpoch");
|
||||
PVIntPtr pvNanoSeconds = pvTimeStamp->getIntField("nanoSeconds");
|
||||
PVIntPtr pvUserTag = pvTimeStamp->getIntField("userTag");
|
||||
uint32 timeStampOffset = pvTimeStamp->getFieldOffset();
|
||||
uint32 secondsOffset = pvSeconds->getFieldOffset();
|
||||
uint32 nanoSecondsOffset = pvNanoSeconds->getFieldOffset();
|
||||
uint32 userTagOffset = pvUserTag->getFieldOffset();
|
||||
uint32 nfields = pvStructure->getNumberFields();
|
||||
BitSetPtr changeBitSet = BitSet::create(nfields);
|
||||
BitSetPtr userChangeBitSet = BitSet::create(nfields);
|
||||
BitSetPtr userOverrunBitSet = BitSet::create(nfields);
|
||||
pvValue->put(1.0); changeBitSet->set(valueOffset);
|
||||
pvSeverity->put(2); changeBitSet->set(severityOffset);
|
||||
pvMessage->put("error"); changeBitSet->set(messageOffset);
|
||||
pvSeconds->put(1); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(1000000); changeBitSet->set(nanoSecondsOffset);
|
||||
pvUserTag->put(1); changeBitSet->set(userTagOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
changeBitSet->clear();
|
||||
pvValue->put(2.0); changeBitSet->set(valueOffset);
|
||||
pvSeverity->put(0); changeBitSet->set(severityOffset);
|
||||
pvMessage->put(""); changeBitSet->set(messageOffset);
|
||||
pvSeconds->put(2); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(0); changeBitSet->set(nanoSecondsOffset);
|
||||
pvUserTag->put(0); changeBitSet->set(userTagOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
testOk1(userChangeBitSet->cardinality()==6);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(severityOffset));
|
||||
testOk1(userChangeBitSet->get(messageOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userChangeBitSet->get(userTagOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==6);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
testOk1(userOverrunBitSet->get(severityOffset));
|
||||
testOk1(userOverrunBitSet->get(messageOffset));
|
||||
testOk1(userOverrunBitSet->get(secondsOffset));
|
||||
testOk1(userOverrunBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userOverrunBitSet->get(userTagOffset));
|
||||
|
||||
BitSetUtil::compress(userChangeBitSet,pvStructure);
|
||||
BitSetUtil::compress(userOverrunBitSet,pvStructure);
|
||||
testOk1(userChangeBitSet->cardinality()==4);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(severityOffset));
|
||||
testOk1(userChangeBitSet->get(messageOffset));
|
||||
testOk1(userChangeBitSet->get(timeStampOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==4);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
testOk1(userOverrunBitSet->get(severityOffset));
|
||||
testOk1(userOverrunBitSet->get(messageOffset));
|
||||
testOk1(userOverrunBitSet->get(timeStampOffset));
|
||||
|
||||
changeBitSet->clear();
|
||||
userChangeBitSet->clear();
|
||||
userOverrunBitSet->clear();
|
||||
pvValue->put(1.0); changeBitSet->set(valueOffset);
|
||||
pvSeconds->put(3); changeBitSet->set(secondsOffset);
|
||||
pvNanoSeconds->put(0); changeBitSet->set(nanoSecondsOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==0);
|
||||
|
||||
changeBitSet->clear();
|
||||
pvValue->put(2.0); changeBitSet->set(valueOffset);
|
||||
userOverrunBitSet->or_and(*changeBitSet.get(),*userChangeBitSet.get());
|
||||
(*userChangeBitSet)|=(*changeBitSet.get());
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==1);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
|
||||
BitSetUtil::compress(userChangeBitSet,pvStructure);
|
||||
BitSetUtil::compress(userOverrunBitSet,pvStructure);
|
||||
testOk1(userChangeBitSet->cardinality()==3);
|
||||
testOk1(userChangeBitSet->get(valueOffset));
|
||||
testOk1(userChangeBitSet->get(secondsOffset));
|
||||
testOk1(userChangeBitSet->get(nanoSecondsOffset));
|
||||
testOk1(userOverrunBitSet->cardinality()==1);
|
||||
testOk1(userOverrunBitSet->get(valueOffset));
|
||||
}
|
||||
|
||||
|
||||
MAIN(testOverrunBitSet`)
|
||||
{
|
||||
testPlan(41);
|
||||
testDiag("Tests for changeBitSet and overrunBitSet");
|
||||
test();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user