Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_offset) {

	int size = _size(p_offset);
	int pos = p_iter;
	if (pos < 0 || pos >= size)
		return Variant();

	PoolVector<uint8_t>::Read rd = data.read();
	const uint8_t *r = &rd[p_offset];
	uint32_t type = decode_uint32(r);

	bool err = false;
	if (type == TYPE_ARRAY) {

		uint32_t vpos = decode_uint32(rd.ptr() + p_offset + 8 + pos * 4);
		return _get_at_ofs(vpos, rd.ptr(), err);

	} else if (type == TYPE_DICT) {

		uint32_t vpos = decode_uint32(rd.ptr() + p_offset + 8 + pos * 12 + 4);
		return _get_at_ofs(vpos, rd.ptr(), err);
	} else {
		ERR_FAIL_V(Variant());
	}
}
Example #2
0
Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs,const Variant& p_key,bool &err) const {

	DVector<uint8_t>::Read rd=data.read();
	const uint8_t *r=&rd[p_ofs];
	uint32_t type = decode_uint32(r);


	if (type==TYPE_ARRAY) {

		if (p_key.is_num()) {

			int idx=p_key;
			uint32_t len = decode_uint32(r+4);
			if (idx<0 || idx>=len) {
				err=true;
				return Variant();
			}
			uint32_t ofs = decode_uint32(r+8+4*idx);
			return _get_at_ofs(ofs,rd.ptr(),err);

		} else {
			err=true;
			return Variant();
		}
		
	} else if (type==TYPE_DICT) {

		uint32_t hash=p_key.hash();
		uint32_t len = decode_uint32(r+4);
		
		bool found=false;
		for(int i=0;i<len;i++) {
			uint32_t khash=decode_uint32(r+8+i*12+0);
			if (khash==hash) {
				Variant key = _get_at_ofs(decode_uint32(r+8+i*12+4),rd.ptr(),err);
				if (err)
					return Variant();
				if (key==p_key) {
					//key matches, return value
					return _get_at_ofs(decode_uint32(r+8+i*12+8),rd.ptr(),err);
				}
				found=true;
			} else {
				if (found)
					break;
			}
		}

		err=true;
		return Variant();

	} else {

		err=true;
		return Variant();
	}
 

}