size_t DictionaryEncoding::decompress(void const* src, size_t size, Chunk& chunk)
{
    size_t chunkSize = chunk.getSize();
    uint8_t* dst = (uint8_t *)chunk.getData();
    ByteInputItr in((uint8_t *) src, size);
    uint32_t i;
    uint32_t code = 0;
    std::string value;
    TypeId type = chunk.getAttributeDesc().getType();
    size_t elementSize = TypeLibrary::getType(type).byteSize();
    size_t nElems = chunkSize / elementSize;


    if(elementSize == 0 || elementSize > 8 || chunk.isRLE() || !chunk.getArrayDesc().isImmutable() || chunk.isSparse())
    {
        nElems = chunkSize;
        elementSize = 1;
    }

    if(!nElems)
    {
        return size;
    }

    rebuildDictionary(in, elementSize);
    assert(_entriesPerCode);

    uint32_t blocks = floor(nElems / _entriesPerCode);
    uint32_t remainderSize = (nElems % _entriesPerCode) * elementSize; // in bytes
    size_t blockValueSize = _entriesPerCode * elementSize;


    for(i = 0; i < blocks; ++i)
    {
        if(in.getArray((uint8_t *) &code, _codeLength) == -1) {
            return 0;
        }
        value = _decodeDictionary[code];
        memcpy(dst, value.data(), blockValueSize);
        dst += blockValueSize;

    }

    // edge case - last few vals
    if(remainderSize) {
        if(in.getArray((uint8_t *) &code, _codeLength) == -1) {
            return 0;
        }
        value = _decodeDictionary[code];
        memcpy(dst, value.data(), remainderSize);
        dst += remainderSize;
    }



    return dst - (uint8_t *) chunk.getData();

} // end decompress
Example #2
0
		Serializer& DefaultSerializer::operator<<(const dtn::data::BundleFragment &obj)
		{
			// rebuild the dictionary
			rebuildDictionary(obj._bundle);

			PrimaryBlock prim = obj._bundle;
			prim.set(dtn::data::PrimaryBlock::FRAGMENT, true);

			// set the application length according to the payload block size
			dtn::data::Bundle::const_iterator it = obj._bundle.find(dtn::data::PayloadBlock::BLOCK_TYPE);

			if (it != obj._bundle.end()) {
				const dtn::data::PayloadBlock &payload = dynamic_cast<const dtn::data::PayloadBlock&>(**it);
				prim.appdatalength = payload.getLength();
			} else {
				prim.appdatalength = 0;
			}

			// set the fragmentation offset
			prim.fragmentoffset += obj._offset;

			// serialize the primary block
			(*this) << prim;

			// serialize all secondary blocks
			bool post_payload = false;

			for (Bundle::const_iterator iter = obj._bundle.begin(); iter != obj._bundle.end(); ++iter)
			{
				const Block &b = (**iter);

				try {
					// test if this is the payload block
					const dtn::data::PayloadBlock &payload = dynamic_cast<const dtn::data::PayloadBlock&>(b);

					// serialize the clipped block
					serialize(payload, obj._offset, obj._length);

					// we had serialized the payload block
					post_payload = true;
				} catch (const std::bad_cast&) {
					// serialize this block if
					// ... this block is before the payload block and marked as replicated in every fragment
					// ... this block is after the payload block and all remaining bytes of the payload block are included
					if (post_payload || b.get(dtn::data::Block::REPLICATE_IN_EVERY_FRAGMENT))
					{
						(*this) << b;
					}
				}
			}

			return (*this);
		}
    size_t DictionaryEncoding::Dictionary::decompress(void const* src, size_t size, Chunk& chunk)
    {
        size_t chunkSize = chunk.getSize();
        uint8_t* writePtr = (uint8_t *)chunk.getData();
        ByteInputItr in((uint8_t *) src, size);
        uint32_t i;
        uint8_t code = 0;
        uint64_t value = 0;
        TypeId type = chunk.getAttributeDesc().getType();        
        size_t elementSize = TypeLibrary::getType(type).byteSize();
        size_t nElems;

        if(elementSize == 0 || elementSize > 8 || chunk.isSparse() || !chunk.getArrayDesc().isImmutable() || chunk.isRLE() || chunk.getAttributeDesc().isNullable())
        {
            nElems = chunkSize;
            elementSize = 1;
        }
        else
        {
            nElems = chunkSize / elementSize;
        }


        uint32_t uniques = (uint32_t ) rebuildDictionary(in, elementSize);
        BitInputItr inBits(&in);
        size_t codeLength;
        uniques <= 2 ? codeLength = 1 : codeLength = ceil(log2(uniques-1))+1;

        size_t codesSize = (nElems * codeLength + 7) >> 3;
        size_t totalCompressed = 1 + uniques * elementSize + codesSize;

        if(totalCompressed != size || !uniques)  // malformed compression, don't work on it
        {
            return 0;
        }

        for(i = 0; i < nElems; ++i)
        {
            inBits.get(code, codeLength);
            value = _decodeDictionary[code];
            memcpy(writePtr, (uint8_t *) &value, elementSize);
            writePtr += elementSize;
        }


        return chunkSize;
    }
Example #4
0
		Length DefaultSerializer::getLength(const dtn::data::Bundle &obj)
		{
			// rebuild the dictionary
			rebuildDictionary(obj);

			Length len = 0;
			len += getLength( (PrimaryBlock&)obj );
			
			// add size of all blocks
			for (Bundle::const_iterator iter = obj.begin(); iter != obj.end(); ++iter)
			{
				const Block &b = (**iter);
				len += getLength( b );
			}

			return len;
		}