void DataWriterInternal::writeAlphanumeric()

in src/dxapi/native/tickdb/data_writer.cpp [770:841]


void DataWriterInternal::writeAlphanumeric(const char *str, uintptr stringLength, uintptr fieldSize)
{
    assert(fieldSize < 0xFFFF);
    unsigned sizeBits = bsr32((unsigned)fieldSize + 2);
    unsigned numBits = sizeBits + 6 * (unsigned)fieldSize;
    unsigned numBytes = (numBits + 7) >> 3;
    unsigned len;
    bool isNull = NULL == str;
    if (isNull) {
        len = (unsigned)(fieldSize + 1);
    } else {
        if (stringLength > fieldSize) {
            throw std::invalid_argument(string("Alphanumeric value should fit into ").append(::toString(fieldSize)).append(" characters, got ").append(::toString(stringLength)));
        }
    }

    int32_t bitIdx = 0;
    byte v;
    if (sizeBits < 8) {
        v = (len << (8 - sizeBits));
        bitIdx = sizeBits;
    }
    else {
        putByte(len >> (sizeBits - 8));
        v = ((len & 0xff) << (16 - sizeBits));
        bitIdx = sizeBits - 8;
    }
    if (isNull || 0 == len) {
        putByte(v);
        return;
    }

    int8_t v1;
    int charIdx = 0;
    while ((unsigned)charIdx < len) {
        byte ch = str[charIdx];
        if (ch < 0x20 || ch > 0x5F) { // CHAR_MIN, CHAR_MAX
            throw std::invalid_argument(string("Character #").append(toString(ch)).append(" is not in allowed range. String: ").append(string(str, stringLength)));
        }

        unsigned chVal = ch - 0x20; // CHAR_MIN
        int sizeValue = 6;
        if (8 - bitIdx < sizeValue) {
            // split
            // size  - step (8 - bitIdx)
            v |= (int8_t)((uint32_t)chVal >> (sizeValue - (8 - bitIdx))); // shift left to extract upper bits
            // 8 - (size  - step)
            v1 = (int8_t)((chVal << (16 - sizeValue - bitIdx)) & 0xff); // shift right to extract lower bits
        }
        else {
            // append
            v |= (int8_t)(chVal << (8 - sizeValue - bitIdx));
            v1 = 0;
        }
        bitIdx += sizeValue;
        charIdx++;


        if (bitIdx >= 8) {
            putByte(v);
            bitIdx -= 8;
            v = v1;
        }

        if (charIdx == len && v != 0) {
            putByte(v);
            bitIdx = 0;
        }
    }
    if (bitIdx > 0)
        putByte(v);
}