What do you think about next task's implementation (for Poco::Json lib)...
(Task) - Poco::Json lib rerurns Poco::JSON::Object::Ptr obj, after JSON parsing,
we need (for example) fetch value from [3th-element of "ARR1" array, from "Obj3" obj, from "Obj2" obj, from "Obj1" obj],
by JSON chain (path) "Obj1"->"Obj2"->"Obj3"->"ARR1".[3]
What do you think about next solution
(solution) -
- Code: Select all
//--------------- here we have obj of Poco::JSON::Object::Ptr type
// Function getField, gets Poco::JSON::Object::Ptr obj as JSON object and std::vector<Poco::Dynamic::Var> as path of searching element.
// getField returns Poco::Dynamic::Var with empty value, if element wasn't find, or with real value of finding element
//-----------------------------------------------------------------
std::vector<Poco::Dynamic::Var> varPath;
Poco::Dynamic::Var retVal;
varPath.push_back(Poco::Dynamic::Var("Obj1"));
varPath.push_back(Poco::Dynamic::Var("Obj2"));
varPath.push_back(Poco::Dynamic::Var("Obj3"));
varPath.push_back(Poco::Dynamic::Var("ARR1"));
varPath.push_back(Poco::Dynamic::Var(3));
retVal = getField(obj, varPath);
//------------------------------------------------------------------
//-------------------- AND -----------------------------------------
//------- getField simple implementation ---------------------------
Poco::Dynamic::Var getField(Poco::JSON::Object::Ptr &obj, std::vector<Poco::Dynamic::Var> &varPath)
{
Poco::JSON::Object::Ptr localObj = obj;
Poco::JSON::Array::Ptr localArray = NULL;
Poco::Dynamic::Var ret;
int arrayIndex = 0;
if(!obj.isNull())
{
for(unsigned int i = 0; i < varPath.size(); i++)
{
if(varPath[i].isInteger())
{
if(localArray.isNull())
{
// throw bad varPath
break;
}
arrayIndex = varPath[i].extract<int>();
if(arrayIndex >= localArray->size())
{
// throw out of range
break;
}
if(localArray->isObject(arrayIndex))
{
localObj = localArray->getObject(arrayIndex);
localArray = NULL;
}
else if(localArray->isArray(arrayIndex))
{
localArray = localArray->getArray(arrayIndex);
localObj = NULL;
}
else
{
ret = localArray->get(varPath[i].extract<int>());
}
}
else if(varPath[i].isString())
{
// There i didn't make local variable objIndex aka arrayIndex, because copy operation for -=std::string=- more exensive
// than for -=int=-
if(localObj.isNull())
{
// throw bad varPath
break;
}
if(localObj->isObject(varPath[i].extract<std::string>()))
{
localObj = localObj->getObject(varPath[i].extract<std::string>());
localArray = NULL;
}
else if(localObj->isArray(varPath[i].extract<std::string>()))
{
localArray = localObj->getArray(varPath[i].extract<std::string>());
localObj = NULL;
}
else
{
ret = localObj->get(varPath[i].extract<std::string>());
}
}
else
{
// throw bad varPath value
}
}
}
return ret;
}
//----------------- It raw implementation, but it compile and work fine --------------------





