/* * Copyright 2008, 2009 Free Software Foundation, Inc. * * SPDX-License-Identifier: AGPL-3.0+ * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifndef FECVECTORS_H #define FECVECTORS_H #include "Vector.h" #include class BitVector : public Vector { public: /**@name Constructors. */ //@{ /**@name Casts of Vector constructors. */ //@{ BitVector(char* wData, char* wStart, char* wEnd) :Vector(wData,wStart,wEnd) { } BitVector(size_t len=0):Vector(len) {} BitVector(const Vector& source):Vector(source) {} BitVector(Vector& source):Vector(source) {} BitVector(const Vector& source1, const Vector source2):Vector(source1,source2) {} //@} /** Construct from a string of "0" and "1". */ BitVector(const char* valString); //@} /** Index a single bit. */ bool bit(size_t index) const { // We put this code in .h for fast inlining. const char *dp = mStart+index; assert(dp::segment(start,span)); } BitVector head(size_t span) { return segment(0,span); } const BitVector head(size_t span) const { return segment(0,span); } BitVector tail(size_t start) { return segment(start,size()-start); } const BitVector tail(size_t start) const { return segment(start,size()-start); } //@} void zero() { fill(0); } /** Invert 0<->1. */ void invert(); /**@name Byte-wise operations. */ //@{ /** Reverse an 8-bit vector. */ void reverse8(); /** Reverse groups of 8 within the vector (byte reversal). */ void LSB8MSB(); //@} /**@name Serialization and deserialization. */ //@{ uint64_t peekField(size_t readIndex, unsigned length) const; uint64_t peekFieldReversed(size_t readIndex, unsigned length) const; uint64_t readField(size_t& readIndex, unsigned length) const; uint64_t readFieldReversed(size_t& readIndex, unsigned length) const; void fillField(size_t writeIndex, uint64_t value, unsigned length); void fillFieldReversed(size_t writeIndex, uint64_t value, unsigned length); void writeField(size_t& writeIndex, uint64_t value, unsigned length); void writeFieldReversed(size_t& writeIndex, uint64_t value, unsigned length); void write0(size_t& writeIndex) { writeField(writeIndex,0,1); } void write1(size_t& writeIndex) { writeField(writeIndex,1,1); } //@} /** Sum of bits. */ unsigned sum() const; /** Reorder bits, dest[i] = this[map[i]]. */ void map(const unsigned *map, size_t mapSize, BitVector& dest) const; /** Reorder bits, dest[map[i]] = this[i]. */ void unmap(const unsigned *map, size_t mapSize, BitVector& dest) const; /** Pack into a char array. */ void pack(unsigned char*) const; /** Unpack from a char array. */ void unpack(const unsigned char*); /** Make a hexdump string. */ void hex(std::ostream&) const; std::string hexstr() const; /** Unpack from a hexdump string. * @returns true on success, false on error. */ bool unhex(const char*); void set(BitVector other) // That's right. No ampersand. { clear(); mData=other.mData; mStart=other.mStart; mEnd=other.mEnd; other.mData=NULL; } void settfb(int i, int j) const { mStart[i] = j; } }; std::ostream& operator<<(std::ostream&, const BitVector&); /** The SoftVector class is used to represent a soft-decision signal. Values 0..1 represent probabilities that a bit is "true". */ class SoftVector: public Vector { public: /** Build a SoftVector of a given length. */ SoftVector(size_t wSize=0):Vector(wSize) {} /** Construct a SoftVector from a C string of "0", "1", and "X". */ SoftVector(const char* valString); /** Construct a SoftVector from a BitVector. */ SoftVector(const BitVector& source); /** Wrap a SoftVector around a block of floats. The block will be delete[]ed upon desctuction. */ SoftVector(float *wData, unsigned length) :Vector(wData,length) {} SoftVector(float* wData, float* wStart, float* wEnd) :Vector(wData,wStart,wEnd) { } /** Casting from a Vector. Note that this is NOT pass-by-reference. */ SoftVector(Vector source) :Vector(source) {} /**@name Casts and overrides of Vector operators. */ //@{ SoftVector segment(size_t start, size_t span) { float* wStart = mStart + start; float* wEnd = wStart + span; assert(wEnd<=mEnd); return SoftVector(NULL,wStart,wEnd); } SoftVector alias() { return segment(0,size()); } const SoftVector segment(size_t start, size_t span) const { return (SoftVector)(Vector::segment(start,span)); } SoftVector head(size_t span) { return segment(0,span); } const SoftVector head(size_t span) const { return segment(0,span); } SoftVector tail(size_t start) { return segment(start,size()-start); } const SoftVector tail(size_t start) const { return segment(start,size()-start); } //@} // How good is the SoftVector in the sense of the bits being solid? // Result of 1 is perfect and 0 means all the bits were 0.0 // If plow is non-NULL, also return the lowest energy bit. float getEnergy(float *low=0) const; /** Fill with "unknown" values. */ void unknown() { fill(0.0F); } /** Return a hard bit value from a given index by slicing. */ bool bit(size_t index) const { const float *dp = mStart+index; assert(dp0.0F; } /** Slice the whole signal into bits. */ BitVector sliced() const; }; std::ostream& operator<<(std::ostream&, const SoftVector&); #endif // vim: ts=4 sw=4