static RetainPtr<CFDictionaryRef> encodeSessionHistory(const BackForwardListState& backForwardListState)
{
    ASSERT(!backForwardListState.currentIndex || backForwardListState.currentIndex.value() < backForwardListState.items.size());

    auto sessionHistoryVersionNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sessionHistoryVersion));

    if (!backForwardListState.currentIndex)
        return createDictionary({ { sessionHistoryVersionKey, sessionHistoryVersionNumber.get() } });

    auto entries = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, backForwardListState.items.size(), &kCFTypeArrayCallBacks));

    for (const auto& item : backForwardListState.items) {
        auto url = item.pageState.mainFrameState.urlString.createCFString();
        auto title = item.pageState.title.createCFString();
        auto originalURL = item.pageState.mainFrameState.originalURLString.createCFString();
        auto data = encodeSessionHistoryEntryData(item.pageState.mainFrameState);

        auto entryDictionary = createDictionary({ { sessionHistoryEntryURLKey, url.get() }, { sessionHistoryEntryTitleKey, title.get() }, { sessionHistoryEntryOriginalURLKey, originalURL.get() }, { sessionHistoryEntryDataKey, data.get() } });

        CFArrayAppendValue(entries.get(), entryDictionary.get());
    }

    uint32_t currentIndex = backForwardListState.currentIndex.value();
    auto currentIndexNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &currentIndex));

    return createDictionary({ { sessionHistoryVersionKey, sessionHistoryVersionNumber.get() }, { sessionHistoryCurrentIndexKey, currentIndexNumber.get() }, { sessionHistoryEntriesKey, entries.get() } });
}
Ejemplo n.º 2
0
RefPtr<API::Data> encodeLegacySessionState(const SessionState& sessionState)
{
    auto sessionHistoryDictionary = encodeSessionHistory(sessionState.backForwardListState);
    auto provisionalURLString = sessionState.provisionalURL.isNull() ? nullptr : sessionState.provisionalURL.string().createCFString();
    RetainPtr<CFNumberRef> renderTreeSizeNumber(adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sessionState.renderTreeSize)));

    RetainPtr<CFDictionaryRef> stateDictionary;
    if (provisionalURLString) {
        stateDictionary = createDictionary({
            { sessionHistoryKey, sessionHistoryDictionary.get() },
            { provisionalURLKey, provisionalURLString.get() },
            { renderTreeSizeKey, renderTreeSizeNumber.get() }
        });
    } else {
        stateDictionary = createDictionary({
            { sessionHistoryKey, sessionHistoryDictionary.get() },
            { renderTreeSizeKey, renderTreeSizeNumber.get() }
        });
    }

    auto writeStream = adoptCF(CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, nullptr));
    if (!writeStream)
        return nullptr;

    if (!CFWriteStreamOpen(writeStream.get()))
        return nullptr;

    if (!CFPropertyListWrite(stateDictionary.get(), writeStream.get(), kCFPropertyListBinaryFormat_v1_0, 0, nullptr))
        return nullptr;

    auto data = adoptCF(static_cast<CFDataRef>(CFWriteStreamCopyProperty(writeStream.get(), kCFStreamPropertyDataWritten)));

    CFIndex length = CFDataGetLength(data.get());

    size_t bufferSize = length + sizeof(uint32_t);
    auto buffer = MallocPtr<uint8_t>::malloc(bufferSize);

    // Put the session state version number at the start of the buffer
    buffer.get()[0] = (sessionStateDataVersion & 0xff000000) >> 24;
    buffer.get()[1] = (sessionStateDataVersion & 0x00ff0000) >> 16;
    buffer.get()[2] = (sessionStateDataVersion & 0x0000ff00) >> 8;
    buffer.get()[3] = (sessionStateDataVersion & 0x000000ff);

    // Copy in the actual session state data
    CFDataGetBytes(data.get(), CFRangeMake(0, length), buffer.get() + sizeof(uint32_t));

    return API::Data::createWithoutCopying(buffer.leakPtr(), bufferSize, [] (unsigned char* buffer, const void* context) {
        fastFree(buffer);
    }, nullptr);
}
Ejemplo n.º 3
0
static RetainPtr<CFDictionaryRef> encodeSessionHistory(const BackForwardListState& backForwardListState)
{
    ASSERT(!backForwardListState.currentIndex || backForwardListState.currentIndex.value() < backForwardListState.items.size());

    auto sessionHistoryVersionNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sessionHistoryVersion));

    if (!backForwardListState.currentIndex)
        return createDictionary({ { sessionHistoryVersionKey, sessionHistoryVersionNumber.get() } });

    auto entries = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, backForwardListState.items.size(), &kCFTypeArrayCallBacks));
    size_t totalDataSize = 0;

    for (const auto& item : backForwardListState.items) {
        auto url = item.pageState.mainFrameState.urlString.createCFString();
        auto title = item.pageState.title.createCFString();
        auto originalURL = item.pageState.mainFrameState.originalURLString.createCFString();
        auto data = totalDataSize <= maximumSessionStateDataSize ? encodeSessionHistoryEntryData(item.pageState.mainFrameState) : nullptr;
        auto shouldOpenExternalURLsPolicyValue = static_cast<uint64_t>(item.pageState.shouldOpenExternalURLsPolicy);
        auto shouldOpenExternalURLsPolicy = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &shouldOpenExternalURLsPolicyValue));

        RetainPtr<CFDictionaryRef> entryDictionary;

        if (data) {
            totalDataSize += CFDataGetLength(data.get());

            entryDictionary = createDictionary({
                { sessionHistoryEntryURLKey, url.get() },
                { sessionHistoryEntryTitleKey, title.get() },
                { sessionHistoryEntryOriginalURLKey, originalURL.get() },
                { sessionHistoryEntryDataKey, data.get() },
                { sessionHistoryEntryShouldOpenExternalURLsPolicyKey, shouldOpenExternalURLsPolicy.get() },
            });
        } else {
            entryDictionary = createDictionary({
                { sessionHistoryEntryURLKey, url.get() },
                { sessionHistoryEntryTitleKey, title.get() },
                { sessionHistoryEntryOriginalURLKey, originalURL.get() },
                { sessionHistoryEntryShouldOpenExternalURLsPolicyKey, shouldOpenExternalURLsPolicy.get() },
            });
        }

        CFArrayAppendValue(entries.get(), entryDictionary.get());
    }

    uint32_t currentIndex = backForwardListState.currentIndex.value();
    auto currentIndexNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &currentIndex));

    return createDictionary({ { sessionHistoryVersionKey, sessionHistoryVersionNumber.get() }, { sessionHistoryCurrentIndexKey, currentIndexNumber.get() }, { sessionHistoryEntriesKey, entries.get() } });
}
Ejemplo n.º 4
0
/**
 * Loads dictionary into memory.  Returns true if successful else false.
 */
bool load(const char* dictionary)
{
    // TODO
    /**
     * 0. create a dictionary
     * 1. declare a file pointer and open the dictionary
     * 2. scan every word in the dictionary, load it to the data structure
     * 3. close the file
     * 4. return true
    **/
    
    d = createDictionary(); 
    FILE *fp = fopen(dictionary, "r");
    assert(fp != NULL);
    // temporary storage
    char x[LENGTH+1];
    /* assumes no word exceeds length of 45 */
    while (fscanf(fp, " %45s", x) == 1) {
        // load it to the data structure
        //x[strlen(x)] = '\0';
        int index = hash(x[0]);
        d->letter[index] = insertNode(d->letter[index], createNode(x));
        d->n++;
    }
    
    fclose(fp);

    return true;
}
Ejemplo n.º 5
0
void KeyedEncoder::beginObject(const String& key)
{
    auto dictionary = createDictionary();
    CFDictionarySetValue(m_dictionaryStack.last(), key.createCFString().get(), dictionary.get());

    m_dictionaryStack.append(dictionary.get());
}
Ejemplo n.º 6
0
void KeyedEncoder::beginArrayElement()
{
    auto dictionary = createDictionary();
    CFArrayAppendValue(m_arrayStack.last(), dictionary.get());

    m_dictionaryStack.append(dictionary.get());
}
 inline VariableDictionary *getDictionary()
 {
     if (dictionary == OREF_NULL)
     {
         createDictionary();
     }
     return dictionary;
 }
Ejemplo n.º 8
0
void createArray(ArrayValue* myself, char* xml) {
	Tag* valueTag;
	DictValue* curValue;
	
	myself->values = NULL;
	myself->size = 0;
	while(*xml != '\0') {
		valueTag = getNextTag(&xml);
		if(valueTag == NULL)  {
			break;
		}
		
		myself->size++;
		myself->values = realloc(myself->values, sizeof(DictValue*) * myself->size);
		curValue = (DictValue*) malloc(sizeof(DictValue));

		curValue->key = (char*) malloc(sizeof("arraykey"));
		strcpy(curValue->key, "arraykey");
		curValue->next = NULL;

		if(strcmp(valueTag->name, "dict") == 0) {
			curValue->type = DictionaryType;
			curValue = (DictValue*) realloc(curValue, sizeof(Dictionary));
			createDictionary((Dictionary*) curValue, valueTag->xml);
		} else if(strcmp(valueTag->name, "string") == 0) {
			curValue->type = StringType;
			curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
			((StringValue*)curValue)->value = (char*) malloc(sizeof(char) * (strlen(valueTag->xml) + 1));
			strcpy(((StringValue*)curValue)->value, valueTag->xml);
		} else if(strcmp(valueTag->name, "data") == 0) {
			size_t len;
			curValue->type = StringType;
			curValue = (DictValue*) realloc(curValue, sizeof(DataValue));
			((DataValue*)curValue)->value = decodeBase64(valueTag->xml, &len);
			((DataValue*)curValue)->len = len;
		} else if(strcmp(valueTag->name, "integer") == 0) {
			curValue->type = IntegerType;
			curValue = (DictValue*) realloc(curValue, sizeof(IntegerValue));
			sscanf(valueTag->xml, "%d", &(((IntegerValue*)curValue)->value));
		} else if(strcmp(valueTag->name, "array") == 0) {
			curValue->type = ArrayType;
			curValue = (DictValue*) realloc(curValue, sizeof(ArrayValue));
			createArray((ArrayValue*) curValue, valueTag->xml);
		} else if(strcmp(valueTag->name, "true/") == 0) {
			curValue->type = BoolType;
			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
			((BoolValue*)curValue)->value = TRUE;
		} else if(strcmp(valueTag->name, "false/") == 0) {
			curValue->type = BoolType;
			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
			((BoolValue*)curValue)->value = FALSE;
		}
		
		myself->values[myself->size - 1] = curValue;
		
		releaseTag(valueTag);
	}
}
void IBClient::commissionReport( const CommissionReport& commissionReport)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "commission",             kf(commissionReport.commission) },
        { "currency",               ks((S)commissionReport.currency.c_str()) },
        { "execId",                 ks((S)commissionReport.execId.c_str()) },
        { "realizedPNL",            kf(commissionReport.realizedPNL) },
        { "yield",                  kf(commissionReport.yield) },
        { "yieldRedemptionDate",    kp((S)stringFormat("%i", commissionReport.yieldRedemptionDate).c_str()) }
    });
    receiveData("commissionReport", dict);
}
Ejemplo n.º 10
0
void IBClient::updatePortfolio(const Contract &contract, int position, double marketPrice, double marketValue, double averageCost, double unrealizedPNL, double realizedPNL, const IBString &accountName)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "contract",       kj(contract.conId) },
        { "position",       ki(position) },
        { "marketPrice",    kf(marketPrice) },
        { "marketValue",    kf(marketValue) },
        { "averageCost",    kf(averageCost) },
        { "unrealizedPNL",  kf(unrealizedPNL) },
        { "realizedPNL",    kf(realizedPNL) },
        { "accountName",    kp((S)accountName.c_str()) }
    });
    receiveData("updatePortfolio", dict);
}
Ejemplo n.º 11
0
void IBClient::tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const IBString &formattedBasisPoints, double totalDividends, int holdDays, const IBString &futureExpiry, double dividendImpact, double dividendsToExpiry)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "tickerId",               kj(tickerId) },
        { "tickType",               ki(tickType) },
        { "basisPoints",            kf(basisPoints) },
        { "formattedBasisPoints",   kp((S)formattedBasisPoints.c_str()) },
        { "totalDividends",         kf(totalDividends) },
        { "holdDays",               ki(holdDays) },
        { "futureExpiry",           kp((S)futureExpiry.c_str()) },
        { "dividendImpact",         kf(dividendImpact) },
        { "dividendsToExpiry",      kf(dividendsToExpiry) }
    });
    receiveData("tickEFP", dict);
}
Ejemplo n.º 12
0
Dictionary* createRoot(char* xml) {
	Tag* tag;
	Dictionary* dict;
	
	xml = strstr(xml, "<dict>");
	tag = getNextTag(&xml);
	dict = malloc(sizeof(Dictionary));
	dict->dValue.next = NULL;
	dict->dValue.key = malloc(sizeof("root"));
	strcpy(dict->dValue.key, "root");
	dict->values = NULL;
	createDictionary(dict, tag->xml);
	releaseTag(tag);
	return dict;
}
Ejemplo n.º 13
0
void IBClient::realtimeBar(TickerId reqId, long time, double open, double high, double low, double close, long volume, double wap, int count)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "reqId",  kj(reqId) },
        { "time",   kj(time) }, // TODO: Convert
        { "open",   kf(open) },
        { "high",   kf(high) },
        { "low",    kf(low) },
        { "close",  kf(close) },
        { "volume", kj(volume) },
        { "wap",    kf(wap) },
        { "count",  ki(count) }
    });
    receiveData("realtimeBar", dict);
}
Ejemplo n.º 14
0
TRandomic *createSingletonPoissonRandomic(char *entry){
	static TDictionary *d=NULL;
	TRandomic *p=NULL;
	TKeyDictionary key;
	if (!d)
		d = createDictionary();

	key = d->keyGenesis(entry);
	if (d->has(d,key)){
		p = d->retrieval(d,key);
	}else{
		p = createPoissonRandomic(entry);
		d->insert(d,key,p);
	}
	return p;
}
Ejemplo n.º 15
0
void IBClient::orderStatus(OrderId orderId, const IBString &status, int filled, int remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, const IBString &whyHeld)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "id",                 ki(orderId) },
        { "status",             kp((S)status.c_str()) },
        { "filled",             ki(filled) },
        { "remaining",          ki(remaining) },
        { "avgFillPrice",       kf(avgFillPrice) },
        { "permId",             ki(permId) },
        { "parentId",           ki(parentId) },
        { "lastFilledPrice",    kf(lastFillPrice) },
        { "clientId",           ki(clientId) },
        { "whyHeld",            kp((S)whyHeld.c_str()) }
    });
    receiveData("orderStatus", dict);
}
Ejemplo n.º 16
0
void IBClient::tickOptionComputation(TickerId tickerId, TickType tickType, double impliedVol, double delta, double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice)
{
    auto dict = createDictionary(std::map<std::string, K> {
        { "tickerId",   kj(tickerId) },
        { "tickType",   ki(tickType) },
        { "impliedVol", kf(impliedVol) },
        { "delta",      kf(delta) },
        { "optPrice",   kf(optPrice) },
        { "pvDividend", kf(pvDividend) },
        { "gamma",      kf(gamma) },
        { "vega",       kf(vega) },
        { "theta",      kf(theta) },
        { "undPrice",   kf(undPrice) }
    });
    receiveData("tickOptionComputation", dict);
}
 inline void putVariable(RexxVariable *variable, size_t index)
 {
     // this may be a dynamic addition, so we might not know the index
     if (index != 0)
     {
         locals[index] = variable;
         if (dictionary != OREF_NULL)
         {
             dictionary->addVariable(variable->getName(), variable);
         }
     }
     else
     {
         if (dictionary == OREF_NULL)
         {
             createDictionary();
         }
         dictionary->addVariable(variable->getName(), variable);
     }
 }
Ejemplo n.º 18
0
void IBClient::execDetails(int reqId, const Contract &contract, const Execution &execution)
{
    auto exec = createDictionary(std::map<std::string, K> {
        { "execId",         ks((S)execution.execId.c_str()) },
        { "time",           kp((S)execution.time.c_str()) }, // TODO: Convert
        { "acctNumber",     ks((S)execution.acctNumber.c_str()) },
        { "exchange",       ks((S)execution.exchange.c_str()) },
        { "side",           ks((S)execution.side.c_str()) },
        { "shares",         ki(execution.shares) },
        { "price",          kf(execution.price) },
        { "permId",         ki(execution.permId) },
        { "clientId",       kj(execution.clientId) },
        { "orderId",        kj(execution.orderId) },
        { "liquidation",    ki(execution.liquidation) },
        { "cumQty",         ki(execution.cumQty) },
        { "avgPrice",       kf(execution.avgPrice) },
        { "evRule",         kp((S)execution.evRule.c_str()) },
        { "evMultiplier",   kf(execution.evMultiplier) }
    });
    receiveData("execDetails", knk(3, ki(reqId), kj(contract.conId), exec));
}
Ejemplo n.º 19
0
void MainWindow::createDictionaryAndFrequencyList(QList<rti_book *> books)
{
    if (dictionaryForm->dictionary())
        if (QMessageBox::question(this, tr("Replace Dictionary and Word Frequency List"),
                                  tr("Generating a new dictionary and word frequency list "
                                     "will replace the current ones. Are you sure you want "
                                     "to continue?"))
                == QMessageBox::No)
            return;

    if (books.isEmpty())
    {
        QMessageBox::information(this, tr("No books selected"),
                                 tr("Unable to create dictionary and word frequency list. "
                                    "No books selected."));
        return;
    }

    createFrequencyList(books);
    if (createDictionary(books))
        tabWidget->setCurrentWidget(dictionaryForm);
}
Ejemplo n.º 20
0
KeyedEncoder::KeyedEncoder()
    : m_rootDictionary(createDictionary())
{
    m_dictionaryStack.append(m_rootDictionary.get());
}
Ejemplo n.º 21
0
void createDictionary(Dictionary * myself, char *xml)
{
	Tag *keyTag;
	Tag *valueTag;
	DictValue *curValue;
	DictValue *lastValue;

	curValue = NULL;
	lastValue = NULL;

	while (*xml != '\0' && *xml != '0') {
		keyTag = getNextTag(&xml);
		if (keyTag == NULL) {
			break;
		}

		if (strcmp(keyTag->name, "key") != 0) {
			releaseTag(keyTag);
			continue;
		}

		curValue = (DictValue *) malloc(sizeof(DictValue));
		curValue->key =
		    (char *)malloc(sizeof(char) * (strlen(keyTag->xml) + 1));
		strcpy(curValue->key, keyTag->xml);
		curValue->next = NULL;
		releaseTag(keyTag);

		valueTag = getNextTag(&xml);
		if (valueTag == NULL) {
			break;
		}

		if (strcmp(valueTag->name, "dict") == 0) {
			curValue->type = DictionaryType;
			curValue =
			    (DictValue *) realloc(curValue, sizeof(Dictionary));
			createDictionary((Dictionary *) curValue,
					 valueTag->xml);

		} else if (strcmp(valueTag->name, "string") == 0) {
			curValue->type = StringType;
			curValue =
			    (DictValue *) realloc(curValue,
						  sizeof(StringValue));
			((StringValue *) curValue)->value =
			    (char *)malloc(sizeof(char)
					   * (strlen(valueTag->xml) + 1));
			strcpy(((StringValue *) curValue)->value,
			       valueTag->xml);

		} else if (strcmp(valueTag->name, "data") == 0) {
			curValue->type = DataType;
			curValue =
			    (DictValue *) realloc(curValue, sizeof(DataValue));
			((DataValue *) curValue)->value =
			    (char *)malloc(sizeof(char)
					   * (strlen(valueTag->xml) + 1));
			strcpy(((DataValue *) curValue)->value, valueTag->xml);

		} else if (strcmp(valueTag->name, "integer") == 0) {
			curValue->type = IntegerType;
			curValue =
			    (DictValue *) realloc(curValue,
						  sizeof(IntegerValue));
			sscanf(valueTag->xml, "%d",
			       &(((IntegerValue *) curValue)->value));

		} else if (strcmp(valueTag->name, "array") == 0) {
			curValue->type = ArrayType;
			curValue =
			    (DictValue *) realloc(curValue, sizeof(ArrayValue));
			createArray((ArrayValue *) curValue, valueTag->xml);

		} else if (strcmp(valueTag->name, "true/") == 0) {
			curValue->type = BoolType;
			curValue =
			    (DictValue *) realloc(curValue, sizeof(BoolValue));
			((BoolValue *) curValue)->value = TRUE;

		} else if (strcmp(valueTag->name, "false/") == 0) {
			curValue->type = BoolType;
			curValue =
			    (DictValue *) realloc(curValue, sizeof(BoolValue));
			((BoolValue *) curValue)->value = FALSE;
		}

		curValue->prev = lastValue;
		if (lastValue == NULL) {
			myself->values = curValue;
		} else {
			lastValue->next = curValue;
		}

		lastValue = curValue;
		releaseTag(valueTag);
	}
}
    size_t DictionaryEncoding::Dictionary::compress(void* dst, const ConstChunk& chunk, size_t chunkSize)
    {
        uint8_t *readPtr = (uint8_t *)chunk.getData();
        TypeId type = chunk.getAttributeDesc().getType();        
        size_t elementSize = TypeLibrary::getType(type).byteSize();
        size_t nElems;

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

        size_t i;
        uint64_t value = 0;
        uint8_t code = 0;
        ByteOutputItr out((uint8_t *) dst, chunkSize - 1);
        BitOutputItr outBits(&out);




        uint32_t uniques = (uint32_t) createDictionary(readPtr, elementSize, nElems, out);
  
        size_t codeLength;
        uniques <= 2 ? codeLength = 1 : codeLength = ceil(log2(uniques-1)) + 1;  // 0-indexed, so values span from 0...uniques-1, log is 0-based, so bring it back to 1...n bits
    
     
  
        // project size and terminate if it will be too large
        size_t codesSize = (nElems * codeLength + 7) >> 3;
        size_t totalCompressed = 1 + uniques * elementSize + codesSize;

        if(totalCompressed*2 >= chunkSize) // if we can't get at least 2:1 it is not worth doing
        {
            return chunkSize;
        }



        if(!nElems || !uniques) 
        {
            return chunkSize;
        }

        for(i = 0; i < nElems; ++i)
        {
            memcpy((uint8_t *) &value, readPtr, elementSize);
            code = _encodeDictionary[value];
            outBits.put(code, codeLength);
            readPtr += elementSize;
        }
  
        outBits.flush();
        size_t compressedSize = out.close();

  
        return compressedSize;

    }
size_t DictionaryEncoding::compress(void* dst, const ConstChunk& chunk, size_t chunkSize)
{
#ifdef FORMAT_SENSITIVE_COMPRESSORS
    uint8_t *src = (uint8_t *)chunk.getData();
    TypeId type = chunk.getAttributeDesc().getType();
    size_t elementSize = TypeLibrary::getType(type).byteSize();
    size_t nElems = chunkSize / elementSize;

    uint32_t i;
    uint32_t uniqueValues;
    std::string toEncode = "";
    uint32_t code;
    uint8_t *readPtr = (uint8_t *)chunk.getData();


    if(!nElems) {
        return chunkSize;
    }


    if(elementSize == 0 || elementSize > 8 || chunk.isRLE() || !chunk.getArrayDesc().isImmutable() || chunk.isSparse()) // too big or too small or sparse = regard it as a string
    {
        nElems = chunkSize;
        elementSize = 1;
    }


    ByteOutputItr out((uint8_t *) dst, chunkSize-1);


    uniqueValues  = createDictionary(src, elementSize, nElems);
    if(uniqueValues == nElems) {
        return chunkSize;
    }

    toEncode.reserve(elementSize);


    // dictionary-specific
    assert(_entriesPerCode);
    uint32_t blocks = floor(nElems / _entriesPerCode);
    uint32_t remainder = nElems % _entriesPerCode;
    size_t blockEntriesSize = _entriesPerCode * elementSize;

    if(uniqueValues == 0) {
        return chunkSize;
    }
    if(out.putArray((uint8_t *) &uniqueValues, 4) == -1) {
        return chunkSize;
    }
    // output a list of unique values; we infer their codes by the order that they are read in
    // i.e., first elementSize bytes translate to code 0 and so on


    for(i = 0; i < uniqueValues; ++i)
    {
        // put value
        if(out.putArray((uint8_t *) _values[i].data(), elementSize) == -1) {
            return chunkSize;
        }
    }// end dictionary output



    // now output encoded data
    for(i = 0; i < blocks; ++i)
    {
        toEncode.assign((char *) readPtr, blockEntriesSize);

        readPtr += blockEntriesSize;
        code = _encodeDictionary[toEncode];

        if(out.putArray((uint8_t *) &code, _codeLength) == -1) {
            return chunkSize;
        }
    }

    if(remainder)
    {
        // output the last few entries --
        toEncode.assign((char *) readPtr, elementSize * remainder);
        // pad it with _value[0]
        for(i = 0; i < _entriesPerCode - remainder; ++i)
        {
            toEncode.append(_values[0]);
        }
        code = _encodeDictionary[toEncode];
        if(out.putArray((uint8_t *) &code, _codeLength) == -1) {
            return chunkSize;
        }
    }

    size_t compressed_size = out.close();

    return compressed_size;
#else
    return chunkSize;
#endif
}