template INLINE void DataWriterInternal::putAlphanumeric()

in src/dxapi/native/tickdb/data_writer.cpp [622:685]


template<typename T, typename CHARTYPE> INLINE void DataWriterInternal::putAlphanumeric(uint32 fieldSize, const CHARTYPE *str, size_t stringLength)
{
    if (stringLength > fieldSize) {
        THROW_DBGLOG("Alphanumeric field is too long");
    }

    size_t nSizeBits = _bsr(++fieldSize);
    if (NULL == str) {
        putBE<uint32>(fieldSize << (32 - nSizeBits), (nSizeBits + 7) >> 3);
        return;
    }

    if (stringLength > fieldSize) {
        THROW_DBGLOG("writeAlphanumeric(): String is too long!");
    }

    if (0 == stringLength) {
        putLE<uint32>(0, (nSizeBits + 7) >> 3);
        setNotNull();
        return;
    }

    assert(nSizeBits + 6 <= BITSIZEOF(T));
    // TODO: ensure T is unsigned
    T accumulator = stringLength;// << 6;
    int nBitsFree = (int)(BITSIZEOF(T) - nSizeBits);

    intptr nCharsRemaining = -(intptr)stringLength;
    str += stringLength;
    
    typedef typename make_unsigned<CHARTYPE>::type UCHARTYPE;

    do {
        unsigned ch;
        // Reserve space in the accumulator (6 more bits)
        if ((nBitsFree -= 6) < 0) {
            // We should never get here if the whole value fits into T (10 chars if T=uint64)
            // Write sizeof(T) - 1 bytes
#if 0
            // Version 1
            // we store (sizeof(T) - 1) completely filled bytes and adjust the number of free bits accordingly
            putBE<T>(accumulator << (nBitsFree + 6), sizeof(T) - 1);
            nBitsFree += (sizeof(T) - 1) * 8;
#else
            // Version 2
            putBE<T>((accumulator << (nBitsFree + 6)) | (ch >> -nBitsFree), sizeof(T));
            nBitsFree += BITSIZEOF(T); // possible values:
            accumulator = 0; // Redundant, actually 
#endif
        }

        ch = (UCHARTYPE)str[nCharsRemaining] - (unsigned)' ';
        if (ch >= 0x40 /*ch & -0x40 */) {
            THROW_DBGLOG("writeAlphanumeric(): Invalid character encountered: 0x%02x = '%c'", (unsigned)ch, (unsigned)ch);
        }

        accumulator = (accumulator << 6) | ch;
    } while (0 != ++nCharsRemaining);

    assert(nBitsFree < BITSIZEOF(T)); // At least 1 bit must be used
    // Finally write the number of bytes necessary to hold these remaining bits
    putBE<T>(accumulator << nBitsFree, (BITSIZEOF(T) + 7 - nBitsFree) >> 3);
    setNotNull();
}