trie: implement clone() method (#852)

* Add Clone() for StringMap

* Fix for std::string addition

* trie: broken return key.

* clonetrie: correct handle leakage.

Co-authored-by: Kyle Sanderson <[email protected]>
This commit is contained in:
Headline
2020-07-14 20:11:23 -07:00
committed by GitHub
co-authored by Kyle Sanderson
parent b8ae4e617b
commit 5fa25e70ad
3 changed files with 60 additions and 1 deletions
+51
View File
@@ -636,6 +636,56 @@ static cell_t GetTrieSnapshotKey(IPluginContext *pContext, const cell_t *params)
return written;
}
static cell_t CloneTrie(IPluginContext *pContext, const cell_t *params)
{
HandleError err;
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
CellTrie *pOldTrie;
if ((err = handlesys->ReadHandle(params[1], htCellTrie, &sec, (void **)&pOldTrie))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
}
CellTrie *pNewTrie = new CellTrie;
Handle_t hndl = handlesys->CreateHandle(htCellTrie, pNewTrie, pContext->GetIdentity(), g_pCoreIdent, NULL);
if (!hndl)
{
delete pNewTrie;
return hndl;
}
for (StringHashMap<Entry>::iterator it = pOldTrie->map.iter(); !it.empty(); it.next())
{
const char *key = it->key.c_str();
StringHashMap<Entry>::Insert insert = pNewTrie->map.findForAdd(key);
if (pNewTrie->map.add(insert, key))
{
StringHashMap<Entry>::Result result = pOldTrie->map.find(key);
if (result->value.isCell())
{
insert->value.setCell(result->value.cell());
}
else if (result->value.isString())
{
insert->value.setString(result->value.c_str());
}
else if (result->value.isArray())
{
insert->value.setArray(result->value.array(), result->value.arrayLength());
}
else
{
handlesys->FreeHandle(hndl, NULL);
return pContext->ThrowNativeError("Unhandled data type encountered, file a bug and reference pr #852");
}
}
}
return hndl;
}
REGISTER_NATIVES(trieNatives)
{
{"ClearTrie", ClearTrie},
@@ -666,6 +716,7 @@ REGISTER_NATIVES(trieNatives)
{"StringMap.SetValue", SetTrieValue},
{"StringMap.Size.get", GetTrieSize},
{"StringMap.Snapshot", CreateTrieSnapshot},
{"StringMap.Clone", CloneTrie},
{"StringMapSnapshot.Length.get", TrieSnapshotLength},
{"StringMapSnapshot.KeyBufferSize", TrieSnapshotKeyBufferSize},