Пример #1
0
const char* IndexMetaDataKey::decode(const char* start, const char* limit, IndexMetaDataKey* result)
{
    KeyPrefix prefix;
    const char* p = KeyPrefix::decode(start, limit, &prefix);
    if (!p)
        return 0;
    ASSERT(prefix.m_databaseId);
    ASSERT(!prefix.m_objectStoreId);
    ASSERT(!prefix.m_indexId);
    if (p == limit)
        return 0;
    unsigned char typeByte = 0;
    p = decodeByte(p, limit, typeByte);
    ASSERT_UNUSED(typeByte, typeByte == IndexMetaDataTypeByte);
    if (p == limit)
        return 0;
    p = decodeVarInt(p, limit, result->m_objectStoreId);
    if (!p)
        return 0;
    p = decodeVarInt(p, limit, result->m_indexId);
    if (!p)
        return 0;
    if (p == limit)
        return 0;
    return decodeByte(p, limit, result->m_metaDataType);
}
Пример #2
0
int compareEncodedStringsWithLength(const char*& p, const char* limitP, const char*& q, const char* limitQ)
{
    ASSERT(&p != &q);
    ASSERT(limitP >= p);
    ASSERT(limitQ >= q);
    int64_t lenP, lenQ;
    p = decodeVarInt(p, limitP, lenP);
    q = decodeVarInt(q, limitQ, lenQ);
    ASSERT(p && q);
    ASSERT(lenP >= 0);
    ASSERT(lenQ >= 0);
    ASSERT(p + lenP * 2 <= limitP);
    ASSERT(q + lenQ * 2 <= limitQ);

    const char* startP = p;
    const char* startQ = q;
    p += lenP * 2;
    q += lenQ * 2;

    if (p > limitP || q > limitQ)
        return 0;

    const size_t lmin = static_cast<size_t>(lenP < lenQ ? lenP : lenQ);
    if (int x = memcmp(startP, startQ, lmin * 2))
        return x;

    if (lenP == lenQ)
        return 0;

    return (lenP > lenQ) ? 1 : -1;
}
Пример #3
0
int compareEncodedIDBKeys(const char*& p, const char* limitA, const char*& q, const char* limitB)
{
    ASSERT(&p != &q);
    ASSERT(p < limitA);
    ASSERT(q < limitB);
    unsigned char typeA = *p++;
    unsigned char typeB = *q++;

    if (int x = IDBKey::compareTypes(keyTypeByteToKeyType(typeA), keyTypeByteToKeyType(typeB)))
        return x;

    switch (typeA) {
    case kIDBKeyNullTypeByte:
    case kIDBKeyMinKeyTypeByte:
        // Null type or max type; no payload to compare.
        return 0;
    case kIDBKeyArrayTypeByte:
        {
            int64_t lengthA, lengthB;
            p = decodeVarInt(p, limitA, lengthA);
            if (!p)
                return 0;
            q = decodeVarInt(q, limitB, lengthB);
            if (!q)
                return 0;
            if (lengthA < 0 || lengthB < 0)
                return 0;
            for (int64_t i = 0; i < lengthA && i < lengthB; ++i) {
                if (int cmp = compareEncodedIDBKeys(p, limitA, q, limitB))
                    return cmp;
            }
            if (lengthA < lengthB)
                return -1;
            if (lengthA > lengthB)
                return 1;
            return 0;
        }
    case kIDBKeyStringTypeByte:
        return compareEncodedStringsWithLength(p, limitA, q, limitB);
    case kIDBKeyDateTypeByte:
    case kIDBKeyNumberTypeByte:
        {
            double d, e;
            p = decodeDouble(p, limitA, &d);
            ASSERT(p);
            q = decodeDouble(q, limitB, &e);
            ASSERT(q);
            if (d < e)
                return -1;
            if (d > e)
                return 1;
            return 0;
        }
    }

    ASSERT_NOT_REACHED();
    return 0;
}
Пример #4
0
const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result)
{
    ASSERT(result);
    const char* p = start;
    if (p >= limit)
        return 0;

    unsigned char type = *p++;

    switch (type) {
    case kIDBKeyNullTypeByte:
    case kIDBKeyMinKeyTypeByte:
        *result = encodeByte(type);
        return p;
    case kIDBKeyArrayTypeByte:
        {
            int64_t length;
            p = decodeVarInt(p, limit, length);
            if (!p)
                return 0;
            if (length < 0)
                return 0;
            result->clear();
            result->append(start, p - start);
            while (length--) {
                Vector<char> subkey;
                p = extractEncodedIDBKey(p, limit, &subkey);
                if (!p)
                    return 0;
                result->append(subkey);
            }
            return p;
        }
    case kIDBKeyStringTypeByte:
        {
            int64_t length;
            p = decodeVarInt(p, limit, length);
            if (!p)
                return 0;
            if (p + length * 2 > limit)
                return 0;
            result->clear();
            result->append(start, p - start + length * 2);
            return p + length * 2;
        }
    case kIDBKeyDateTypeByte:
    case kIDBKeyNumberTypeByte:
        if (p + sizeof(double) > limit)
            return 0;
        result->clear();
        result->append(start, 1 + sizeof(double));
        return p + sizeof(double);
    }
    ASSERT_NOT_REACHED();
    return 0;
}
        void ProtoDeserializerVisitor::read(const uint32_t &id, unsigned char &v) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::VARINT);

            uint64_t _v = 0;
            m_size -= decodeVarInt(m_buffer, _v);
            v = static_cast<unsigned char>(_v);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &id, uint64_t &v) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::VARINT);

            uint64_t _v = 0;
            m_size -= decodeVarInt(m_buffer, _v);
            v = _v;
        }
        void ProtoDeserializerVisitor::read(const uint32_t &fourByteID, const uint8_t &oneByteID, const string &/*longName*/, const string &/*shortName*/, uint64_t &v) {
            m_size -= readAndValidateKey( (oneByteID > 0 ? oneByteID : fourByteID) , ProtoSerializerVisitor::VARINT);

            uint64_t _v = 0;
            m_size -= decodeVarInt(m_buffer, _v);
            v = _v;
        }
Пример #8
0
FullContainerKey::FullContainerKey(const KeyConstraint &constraint,
								   const void *data) :
	constraint_(constraint), body_(NULL), size_(0) {
	try {
		if (data == NULL) {
			GS_THROW_USER_ERROR(GS_ERROR_DS_DS_CONTAINER_NAME_INVALID,
				"container/table name is empty");
		}

		ContainerKeyInStream in(util::ArrayInStream(data, sizeof(uint32_t)));
		if (ValueProcessor::varSizeIs1Byte(static_cast<const uint8_t*>(data)[0])
			|| ValueProcessor::varSizeIs4Byte(static_cast<const uint8_t*>(data)[0])) {
			size_ = static_cast<size_t>(decodeVarInt(in));
		}
		else {
			GS_THROW_USER_ERROR(GS_ERROR_DS_DS_CONTAINER_NAME_INVALID,
				"failed to decode container/table name size");
		}

		body_ = static_cast<const uint8_t*>(data) + in.base().position();

	}
	catch (std::exception &e) {
		GS_RETHROW_USER_ERROR(e,
			GS_EXCEPTION_MERGE_MESSAGE(e, "failed to construct container/table name"));
	}
}
Пример #9
0
const char* IndexDataKey::decode(const char* start, const char* limit, IndexDataKey* result)
{
    KeyPrefix prefix;
    const char* p = KeyPrefix::decode(start, limit, &prefix);
    if (!p)
        return 0;
    ASSERT(prefix.m_databaseId);
    ASSERT(prefix.m_objectStoreId);
    ASSERT(prefix.m_indexId >= MinimumIndexId);
    result->m_databaseId = prefix.m_databaseId;
    result->m_objectStoreId = prefix.m_objectStoreId;
    result->m_indexId = prefix.m_indexId;
    result->m_sequenceNumber = -1;
    result->m_encodedPrimaryKey = minIDBKey();

    p = extractEncodedIDBKey(p, limit, &result->m_encodedUserKey);
    if (!p)
        return 0;

    // [optional] sequence number
    if (p == limit)
        return p;
    p =  decodeVarInt(p, limit, result->m_sequenceNumber);
    if (!p)
        return 0;

    // [optional] primary key
    if (p == limit)
        return p;
    p = extractEncodedIDBKey(p, limit, &result->m_encodedPrimaryKey);
    if (!p)
        return 0;

    return p;
}
Пример #10
0
const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey)
{
    ASSERT(limit >= p);
    if (p >= limit)
        return 0;

    unsigned char type = *p++;

    switch (type) {
    case IDBKeyNullTypeByte:
        foundKey = IDBKey::createInvalid();
        return p;

    case IDBKeyArrayTypeByte: {
        int64_t length;
        p = decodeVarInt(p, limit, length);
        if (!p)
            return 0;
        if (length < 0)
            return 0;
        IDBKey::KeyArray array;
        while (length--) {
            RefPtr<IDBKey> key;
            p = decodeIDBKey(p, limit, key);
            if (!p)
                return 0;
            array.append(key);
        }
        foundKey = IDBKey::createArray(array);
        return p;
    }
    case IDBKeyStringTypeByte: {
        String s;
        p = decodeStringWithLength(p, limit, s);
        if (!p)
            return 0;
        foundKey = IDBKey::createString(s);
        return p;
    }
    case IDBKeyDateTypeByte: {
        double d;
        p = decodeDouble(p, limit, &d);
        if (!p)
            return 0;
        foundKey = IDBKey::createDate(d);
        return p;
    }
    case IDBKeyNumberTypeByte: {
        double d;
        p = decodeDouble(p, limit, &d);
        if (!p)
            return 0;
        foundKey = IDBKey::createNumber(d);
        return p;
    }
    }

    ASSERT_NOT_REACHED();
    return 0;
}
Пример #11
0
const char* decodeStringWithLength(const char* p, const char* limit, String& foundString)
{
    ASSERT(limit >= p);
    int64_t len;
    p = decodeVarInt(p, limit, len);
    if (!p)
        return 0;
    if (p + len * 2 > limit)
        return 0;

    foundString = decodeString(p, p + len * 2);
    p += len * 2;
    return p;
}
        uint32_t ProtoDeserializerVisitor::readAndValidateKey(const uint32_t &id, const ProtoSerializerVisitor::PROTOBUF_TYPE &expectedType) {
            uint64_t key = 0;
            const uint32_t size = decodeVarInt(m_buffer, key);
            const uint32_t fieldId = static_cast<uint32_t>(key >> 3);
            const ProtoSerializerVisitor::PROTOBUF_TYPE protoType = static_cast<ProtoSerializerVisitor::PROTOBUF_TYPE>(key & 0x7);

            if (fieldId != id) {
                clog << "[core::base::ProtoDeserializerVisitor]: ERROR! Field ids do not match: Found " << fieldId << ", expected: " << id << endl;
            }
            if (protoType != expectedType) {
                clog << "[core::base::ProtoDeserializerVisitor]: ERROR! Expected type does not match: Found " << protoType << ", expected " << expectedType << endl;
            }

            return size;
        }
Пример #13
0
const char* DatabaseFreeListKey::decode(const char* start, const char* limit, DatabaseFreeListKey* result)
{
    KeyPrefix prefix;
    const char *p = KeyPrefix::decode(start, limit, &prefix);
    if (!p)
        return 0;
    ASSERT(!prefix.m_databaseId);
    ASSERT(!prefix.m_objectStoreId);
    ASSERT(!prefix.m_indexId);
    if (p == limit)
        return 0;
    unsigned char typeByte = *p++;
    ASSERT_UNUSED(typeByte, typeByte == kDatabaseFreeListTypeByte);
    if (p == limit)
        return 0;
    return decodeVarInt(p, limit, result->m_databaseId);
}
        void ProtoDeserializerVisitor::read(const uint32_t &fourByteID, const uint8_t &oneByteID, const string &/*longName*/, const string &/*shortName*/, void *data, const uint32_t &size) {
            m_size -= readAndValidateKey( (oneByteID > 0 ? oneByteID : fourByteID) , ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read data.
            char *_data = new char[length];
            m_buffer.read(_data, length);
            m_size -= length;

            // Move data.
            memset(data, 0, size);
            memcpy(data, _data, (size < length ? size : length));
            OPENDAVINCI_CORE_DELETE_ARRAY(_data);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &fourByteID, const uint8_t &oneByteID, const string &/*longName*/, const string &/*shortName*/, string &v) {
            m_size -= readAndValidateKey( (oneByteID > 0 ? oneByteID : fourByteID) , ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read string.
            char *str = new char[length+1];
            m_buffer.read(str, length);
            m_size -= length;

            // Create string.
            str[length] = 0;
            v = string(str, length);
            OPENDAVINCI_CORE_DELETE_ARRAY(str);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &id, void *data, const uint32_t &size) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read data.
            char *_data = new char[length];
            m_buffer.read(_data, length);
            m_size -= length;

            // Move data.
            memset(data, 0, size);
            memcpy(data, _data, (size < length ? size : length));
            OPENDAVINCI_CORE_DELETE_ARRAY(_data);
        }
        void ProtoDeserializerVisitor::read(const uint32_t &id, string &v) {
            m_size -= readAndValidateKey(id, ProtoSerializerVisitor::LENGTH_DELIMITED);

            // Read length.
            uint64_t length = 0;
            m_size -= decodeVarInt(m_buffer, length);

            // Read string.
            char *str = new char[length+1];
            m_buffer.read(str, length);
            m_size -= length;

            // Create string.
            str[length] = 0;
            v = string(str, length);
            OPENDAVINCI_CORE_DELETE_ARRAY(str);
        }
Пример #18
0
// FIXME: We never use this to look up index ids, because a mapping
// is kept at a higher level.
const char* IndexNamesKey::decode(const char* start, const char* limit, IndexNamesKey* result)
{
    KeyPrefix prefix;
    const char* p = KeyPrefix::decode(start, limit, &prefix);
    if (!p)
        return 0;
    ASSERT(prefix.m_databaseId);
    ASSERT(!prefix.m_objectStoreId);
    ASSERT(!prefix.m_indexId);
    if (p == limit)
        return 0;
    unsigned char typeByte = *p++;
    ASSERT_UNUSED(typeByte, typeByte == kIndexNamesKeyTypeByte);
    if (p == limit)
        return 0;
    p = decodeVarInt(p, limit, result->m_objectStoreId);
    if (!p)
        return 0;
    return decodeStringWithLength(p, limit, result->m_indexName);
}
Пример #19
0
IDBKeyPath decodeIDBKeyPath(const char* p, const char* limit)
{
    // May be typed, or may be a raw string. An invalid leading
    // byte sequence is used to identify typed coding. New records are
    // always written as typed.
    if (p == limit || (limit - p >= 2 && (*p != IDBKeyPathTypeCodedByte1 || *(p + 1) != IDBKeyPathTypeCodedByte2)))
        return IDBKeyPath(decodeString(p, limit));
    p += 2;

    ASSERT(p != limit);
    IDBKeyPath::Type type = static_cast<IDBKeyPath::Type>(*p++);
    switch (type) {
    case IDBKeyPath::NullType:
        ASSERT(p == limit);
        return IDBKeyPath();
    case IDBKeyPath::StringType: {
        String string;
        p = decodeStringWithLength(p, limit, string);
        ASSERT(p == limit);
        return IDBKeyPath(string);
    }
    case IDBKeyPath::ArrayType: {
        Vector<String> array;
        int64_t count;
        p = decodeVarInt(p, limit, count);
        ASSERT(p);
        ASSERT(count >= 0);
        while (count--) {
            String string;
            p = decodeStringWithLength(p, limit, string);
            ASSERT(p);
            array.append(string);
        }
        ASSERT(p == limit);
        return IDBKeyPath(array);
    }
    }
    ASSERT_NOT_REACHED();
    return IDBKeyPath();
}
Пример #20
0
void FullContainerKey::deserialize(util::StackAllocator &alloc,
								   FullContainerKeyComponents &components,
								   BitArray &upperCaseBit,
								   bool unNormalized) const {
	try {
		if (isEmpty()) {
			GS_THROW_USER_ERROR(GS_ERROR_DS_DS_CONTAINER_NAME_INVALID,
				"container/table name is empty");
		}

		components.clear();
		upperCaseBit.clear();

		ContainerKeyInStream in(util::ArrayInStream(body_, size_));

		const char8_t *normalizedStr[3] = { NULL, NULL, NULL };

		uint8_t flag;
		in >> flag;

		if (flag & DBID_EXISTS) {
			in >> components.dbId_;
		}
		else {
			components.dbId_ = GS_PUBLIC_DB_ID;
		}

		components.baseNameSize_ = decodeVarInt(in);
		normalizedStr[0] = reinterpret_cast<const char8_t*>(body_ + in.base().position());
		in.base().position(in.base().position() + components.baseNameSize_);

		if (flag & LARGE_CONTAINERID_EXISTS) {
			components.largeContainerId_ = decodeVarLong(in);
		}

		if (flag & NODE_AFFINITY_NUM) {
			components.affinityNumber_ = decodeVarLong(in);
		}
		else if (flag & NODE_AFFINITY_STR) {
			components.affinityStringSize_ = decodeVarInt(in);
			normalizedStr[1] = reinterpret_cast<const char8_t*>(body_ + in.base().position());
			in.base().position(in.base().position() + components.affinityStringSize_);
		}

		if (flag & SYSTEM_PART_ID_NUM) {
			components.systemPartId_ = decodeVarLong(in);
		}
		else if (flag & SYSTEM_PART_ID_STR) {
			components.systemPartSize_ = decodeVarInt(in);
			normalizedStr[2] = reinterpret_cast<const char8_t*>(body_ + in.base().position());
			in.base().position(in.base().position() + components.systemPartSize_);
		}

		const uint64_t strLength = components.baseNameSize_
			+ components.affinityStringSize_
			+ components.systemPartSize_;

		if (in.base().remaining() != strLengthToBitLength(strLength)) {
			GS_THROW_USER_ERROR(GS_ERROR_DS_DS_CONTAINER_NAME_INVALID,
				"size of container/table name is invalid");
		}
		else {
			upperCaseBit.reserve(strLength);
			upperCaseBit.putAll(body_ + in.base().position(), strLength);
			in.base().position(in.base().position() + in.base().remaining());
		}

		if (in.base().position() != size_) {
			GS_THROW_USER_ERROR(GS_ERROR_DS_DS_CONTAINER_NAME_INVALID,
				"size of container/table name is invalid");
		}


		if (unNormalized) {
			util::XArray<char8_t> buf(alloc);
			buf.resize(static_cast<size_t>(strLength), '\0');
			uint64_t startPos = 0;

			createOriginalString(normalizedStr[0], components.baseNameSize_,
				buf.data()+startPos, upperCaseBit, startPos);
			components.baseName_ = buf.data()+startPos;
			startPos += components.baseNameSize_;

			if (components.affinityStringSize_ > 0) {
				createOriginalString(normalizedStr[1], components.affinityStringSize_,
					buf.data()+startPos, upperCaseBit, startPos);
				components.affinityString_ = buf.data()+startPos;
				startPos += components.affinityStringSize_;
			}

			if (components.systemPartSize_ > 0) {
				createOriginalString(normalizedStr[2], components.systemPartSize_,
					buf.data()+startPos, upperCaseBit, startPos);
				components.systemPart_ = buf.data()+startPos;
				startPos += components.systemPartSize_;
			}
		}
		else {
			components.baseName_ = normalizedStr[0];
			if (components.affinityStringSize_ > 0) {
				components.affinityString_ = normalizedStr[1];
			}
			if (components.systemPartSize_ > 0) {
				components.systemPart_ = normalizedStr[2];
			}
		}

	}