static int flattenIterEntry( FlattenIter *pIter, /* Iterator handle */ JsonNode **ppKey, /* OUT: Current key value */ JsonNode **ppVal /* OUT: Current payload value */ ){ struct FlattenIterElem *p = &pIter->aIter[pIter->nIter-1]; assert( p->pVal->eJType==XJD1_STRUCT || p->pVal->eJType==XJD1_ARRAY ); if( p->pVal->eJType==XJD1_STRUCT ){ *ppVal = xjd1JsonRef(p->current.pElem->pValue); }else{ *ppVal = xjd1JsonRef(p->pVal->u.ar.apElem[p->current.iElem-1]); } if( ppKey ){ JsonNode *pKey = 0; JsonNode *pList = 0; int i; if( pIter->isRecursive ){ pList = xjd1JsonNew(0); pList->eJType = XJD1_ARRAY; pList->u.ar.nElem = pIter->nIter; pList->u.ar.apElem = xjd1MallocZero(pIter->nIter*sizeof(JsonNode *)); } for(i=pIter->nIter-1; i>=0; i--){ p = &pIter->aIter[i]; if( p->pVal->eJType==XJD1_STRUCT ){ pKey = newStringValue(p->current.pElem->zLabel); }else{ pKey = newIntValue(p->current.iElem-1); } if( pIter->isRecursive==0 ) break; pList->u.ar.apElem[i] = pKey; } *ppKey = (pIter->isRecursive ? pList : pKey); } return XJD1_OK; }
Value *valueAdd(Value *v1, Value *v2) { switch (v1->type) { case INT_VALUE_TYPE: switch (v2->type) { case INT_VALUE_TYPE: return newIntValue((long)v1->data + (long)v2->data); default: error("int can only add to int\n"); } case LIST_VALUE_TYPE: { List *res = listCopy(v1->data); int i; assert(v2->type == LIST_VALUE_TYPE); List *l = v2->data; for (i = 0; i < listSize(l); i++) { listPush(res, listGet(l, i)); } return newListValue(res); } case STRING_VALUE_TYPE: { if (v2->type == STRING_VALUE_TYPE) { char *s1 = (char *)v1->data, *s2 = (char *)v2->data; char *res = (char *)tlMalloc(strlen(s1) + strlen(s2) + 1); *res = 0; strcat(res, s1); strcat(res, s2); return newStringValue(res); } else { error("can only add string to string\n"); } } case CLOSURE_VALUE_TYPE: error("Closure value cannot add to anything\n"); case ENV_VALUE_TYPE: error("Environment value cannot add to anything\n"); default: error("unknown value type passed to valueAdd: %d\n", v1->type); } return 0; // never reach here }