payload.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /** @file
  2. This file is cloned from DMTF libredfish library tag v1.0.0 and maintained
  3. by EDKII.
  4. //----------------------------------------------------------------------------
  5. // Copyright Notice:
  6. // Copyright 2017 Distributed Management Task Force, Inc. All rights reserved.
  7. // License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md
  8. //----------------------------------------------------------------------------
  9. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  10. (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  11. SPDX-License-Identifier: BSD-2-Clause-Patent
  12. **/
  13. #include <redfishPayload.h>
  14. static redfishPayload *
  15. getOpResult (
  16. redfishPayload *payload,
  17. const char *propName,
  18. const char *op,
  19. const char *value,
  20. EFI_HTTP_STATUS_CODE **StatusCode
  21. );
  22. static redfishPayload *
  23. collectionEvalOp (
  24. redfishPayload *payload,
  25. const char *propName,
  26. const char *op,
  27. const char *value,
  28. EFI_HTTP_STATUS_CODE **StatusCode
  29. );
  30. static redfishPayload *
  31. arrayEvalOp (
  32. redfishPayload *payload,
  33. const char *propName,
  34. const char *op,
  35. const char *value,
  36. EFI_HTTP_STATUS_CODE **StatusCode
  37. );
  38. static redfishPayload *
  39. createCollection (
  40. redfishService *service,
  41. size_t count,
  42. redfishPayload **payloads
  43. );
  44. static json_t *
  45. json_object_get_by_index (
  46. json_t *json,
  47. size_t index
  48. );
  49. bool
  50. isPayloadCollection (
  51. redfishPayload *payload
  52. )
  53. {
  54. json_t *members;
  55. json_t *count;
  56. if (!payload || !json_is_object (payload->json)) {
  57. return false;
  58. }
  59. members = json_object_get (payload->json, "Members");
  60. count = json_object_get (payload->json, "Members@odata.count");
  61. return ((members != NULL) && (count != NULL));
  62. }
  63. size_t
  64. getCollectionSize (
  65. redfishPayload *payload
  66. )
  67. {
  68. json_t *members;
  69. json_t *count;
  70. if (!payload || !json_is_object (payload->json)) {
  71. return 0;
  72. }
  73. members = json_object_get (payload->json, "Members");
  74. count = json_object_get (payload->json, "Members@odata.count");
  75. if (!members || !count) {
  76. return 0;
  77. }
  78. return (size_t)json_integer_value (count);
  79. }
  80. bool
  81. isPayloadArray (
  82. redfishPayload *payload
  83. )
  84. {
  85. if (!payload || !json_is_array (payload->json)) {
  86. return false;
  87. }
  88. return true;
  89. }
  90. char *
  91. payloadToString (
  92. redfishPayload *payload,
  93. bool prettyPrint
  94. )
  95. {
  96. size_t flags = 0;
  97. if (!payload) {
  98. return NULL;
  99. }
  100. if (prettyPrint) {
  101. flags = JSON_INDENT (2);
  102. }
  103. return json_dumps (payload->json, flags);
  104. }
  105. redfishPayload *
  106. createRedfishPayload (
  107. json_t *value,
  108. redfishService *service
  109. )
  110. {
  111. redfishPayload *payload;
  112. payload = (redfishPayload *)malloc (sizeof (redfishPayload));
  113. if (payload != NULL) {
  114. payload->json = value;
  115. payload->service = service;
  116. }
  117. return payload;
  118. }
  119. redfishPayload *
  120. getPayloadByNodeName (
  121. redfishPayload *payload,
  122. const char *nodeName,
  123. EFI_HTTP_STATUS_CODE **StatusCode
  124. )
  125. {
  126. json_t *value;
  127. json_t *odataId;
  128. const char *uri;
  129. if (!payload || !nodeName || (StatusCode == NULL)) {
  130. return NULL;
  131. }
  132. *StatusCode = NULL;
  133. value = json_object_get (payload->json, nodeName);
  134. if (value == NULL) {
  135. return NULL;
  136. }
  137. json_incref (value);
  138. if (json_object_size (value) == 1) {
  139. odataId = json_object_get (value, "@odata.id");
  140. if (odataId != NULL) {
  141. json_incref (odataId);
  142. uri = json_string_value (odataId);
  143. json_decref (value);
  144. value = getUriFromService (payload->service, uri, StatusCode);
  145. json_decref (odataId);
  146. if ((value == NULL) || (*StatusCode == NULL)) {
  147. return NULL;
  148. }
  149. }
  150. }
  151. if ((*StatusCode == NULL) || ((**StatusCode >= HTTP_STATUS_200_OK) && (**StatusCode <= HTTP_STATUS_206_PARTIAL_CONTENT))) {
  152. if (json_is_string (value)) {
  153. odataId = json_object ();
  154. json_object_set (odataId, nodeName, value);
  155. json_decref (value);
  156. value = odataId;
  157. }
  158. }
  159. return createRedfishPayload (value, payload->service);
  160. }
  161. redfishPayload *
  162. getPayloadByIndex (
  163. redfishPayload *payload,
  164. size_t index,
  165. EFI_HTTP_STATUS_CODE **StatusCode
  166. )
  167. {
  168. json_t *value = NULL;
  169. json_t *odataId;
  170. const char *uri;
  171. BOOLEAN FromServerFlag = FALSE;
  172. if (!payload || (StatusCode == NULL)) {
  173. return NULL;
  174. }
  175. *StatusCode = NULL;
  176. if (isPayloadCollection (payload)) {
  177. redfishPayload *members = getPayloadByNodeName (payload, "Members", StatusCode);
  178. if (((*StatusCode == NULL) && (members == NULL)) ||
  179. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  180. {
  181. return members;
  182. }
  183. if (*StatusCode != NULL) {
  184. //
  185. // The Payload (members) are retrived from server.
  186. //
  187. FreePool (*StatusCode);
  188. *StatusCode = NULL;
  189. FromServerFlag = TRUE;
  190. }
  191. redfishPayload *ret = getPayloadByIndex (members, index, StatusCode);
  192. if ((*StatusCode == NULL) && (ret != NULL) && FromServerFlag) {
  193. //
  194. // In such a case, the Redfish resource is parsed from the input payload (members) directly.
  195. // Since the members are retrived from server, we still return HTTP_STATUS_200_OK.
  196. //
  197. *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE));
  198. if (*StatusCode == NULL) {
  199. ret = NULL;
  200. } else {
  201. **StatusCode = HTTP_STATUS_200_OK;
  202. }
  203. }
  204. cleanupPayload (members);
  205. return ret;
  206. }
  207. if (json_is_array (payload->json)) {
  208. //
  209. // The valid range for index is from 0 to the return value of json_array_size() minus 1
  210. //
  211. value = json_array_get (payload->json, index);
  212. } else if (json_is_object (payload->json)) {
  213. value = json_object_get_by_index (payload->json, index);
  214. }
  215. if (value == NULL) {
  216. return NULL;
  217. }
  218. json_incref (value);
  219. if (json_object_size (value) == 1) {
  220. odataId = json_object_get (value, "@odata.id");
  221. if (odataId != NULL) {
  222. uri = json_string_value (odataId);
  223. json_decref (value);
  224. value = getUriFromService (payload->service, uri, StatusCode);
  225. if (value == NULL) {
  226. return NULL;
  227. }
  228. }
  229. }
  230. return createRedfishPayload (value, payload->service);
  231. }
  232. redfishPayload *
  233. getPayloadForPath (
  234. redfishPayload *payload,
  235. redPathNode *redpath,
  236. EFI_HTTP_STATUS_CODE **StatusCode
  237. )
  238. {
  239. redfishPayload *ret = NULL;
  240. redfishPayload *tmp;
  241. if (!payload || !redpath || (StatusCode == NULL)) {
  242. return NULL;
  243. }
  244. *StatusCode = NULL;
  245. BOOLEAN FromServerFlag = FALSE;
  246. if (redpath->nodeName) {
  247. ret = getPayloadByNodeName (payload, redpath->nodeName, StatusCode);
  248. if (((*StatusCode == NULL) && (ret == NULL)) ||
  249. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  250. {
  251. //
  252. // Any error happen, return directly.
  253. //
  254. return ret;
  255. }
  256. } else if (redpath->isIndex) {
  257. ASSERT (redpath->index >= 1);
  258. ret = getPayloadByIndex (payload, redpath->index - 1, StatusCode);
  259. if (((*StatusCode == NULL) && (ret == NULL)) ||
  260. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  261. {
  262. //
  263. // Any error happen, return directly.
  264. //
  265. return ret;
  266. }
  267. } else if (redpath->op) {
  268. ret = getOpResult (payload, redpath->propName, redpath->op, redpath->value, StatusCode);
  269. if (((*StatusCode == NULL) && (ret == NULL)) ||
  270. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  271. {
  272. //
  273. // Any error happen, return directly.
  274. //
  275. return ret;
  276. }
  277. } else {
  278. return NULL;
  279. }
  280. if ((redpath->next == NULL) || (ret == NULL)) {
  281. return ret;
  282. } else {
  283. if (*StatusCode != NULL) {
  284. FreePool (*StatusCode);
  285. *StatusCode = NULL;
  286. FromServerFlag = TRUE;
  287. }
  288. tmp = getPayloadForPath (ret, redpath->next, StatusCode);
  289. if ((*StatusCode == NULL) && (tmp != NULL) && FromServerFlag) {
  290. //
  291. // In such a case, the Redfish resource is parsed from the input payload (ret) directly.
  292. // Since the ret are retrived from server, we still return HTTP_STATUS_200_OK.
  293. //
  294. *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE));
  295. if (*StatusCode == NULL) {
  296. tmp = NULL;
  297. } else {
  298. **StatusCode = HTTP_STATUS_200_OK;
  299. }
  300. }
  301. cleanupPayload (ret);
  302. return tmp;
  303. }
  304. }
  305. redfishPayload *
  306. getPayloadForPathString (
  307. redfishPayload *payload,
  308. const char *string,
  309. EFI_HTTP_STATUS_CODE **StatusCode
  310. )
  311. {
  312. redPathNode *redpath;
  313. redfishPayload *ret;
  314. if (!string || (StatusCode == NULL)) {
  315. return NULL;
  316. }
  317. *StatusCode = NULL;
  318. redpath = parseRedPath (string);
  319. if (redpath == NULL) {
  320. return NULL;
  321. }
  322. ret = getPayloadForPath (payload, redpath, StatusCode);
  323. cleanupRedPath (redpath);
  324. return ret;
  325. }
  326. redfishPayload *
  327. patchPayload (
  328. redfishPayload *target,
  329. redfishPayload *payload,
  330. EFI_HTTP_STATUS_CODE **StatusCode
  331. )
  332. {
  333. json_t *json;
  334. char *content;
  335. char *uri;
  336. if (!target || !payload || (StatusCode == NULL)) {
  337. return NULL;
  338. }
  339. *StatusCode = NULL;
  340. json = json_object_get (target->json, "@odata.id");
  341. if (json == NULL) {
  342. return NULL;
  343. }
  344. uri = strdup (json_string_value (json));
  345. content = json_dumps (payload->json, 0);
  346. json_decref (json);
  347. json = patchUriFromService (target->service, uri, content, StatusCode);
  348. free (uri);
  349. free (content);
  350. if (json == NULL) {
  351. return NULL;
  352. }
  353. return createRedfishPayload (json, target->service);
  354. }
  355. redfishPayload *
  356. postContentToPayload (
  357. redfishPayload *target,
  358. const char *data,
  359. size_t dataSize,
  360. const char *contentType,
  361. EFI_HTTP_STATUS_CODE **StatusCode
  362. )
  363. {
  364. json_t *json;
  365. char *uri;
  366. if (!target || !data || (StatusCode == NULL)) {
  367. return NULL;
  368. }
  369. *StatusCode = NULL;
  370. json = json_object_get (target->json, "@odata.id");
  371. if (json == NULL) {
  372. json = json_object_get (target->json, "target");
  373. if (json == NULL) {
  374. return NULL;
  375. }
  376. }
  377. uri = strdup (json_string_value (json));
  378. json = postUriFromService (target->service, uri, data, dataSize, contentType, StatusCode);
  379. free (uri);
  380. if (json == NULL) {
  381. return NULL;
  382. }
  383. return createRedfishPayload (json, target->service);
  384. }
  385. redfishPayload *
  386. postPayload (
  387. redfishPayload *target,
  388. redfishPayload *payload,
  389. EFI_HTTP_STATUS_CODE **StatusCode
  390. )
  391. {
  392. char *content;
  393. redfishPayload *ret;
  394. if (!target || !payload || (StatusCode == NULL)) {
  395. return NULL;
  396. }
  397. *StatusCode = NULL;
  398. if (!json_is_object (payload->json)) {
  399. return NULL;
  400. }
  401. content = payloadToString (payload, false);
  402. ret = postContentToPayload (target, content, strlen (content), NULL, StatusCode);
  403. free (content);
  404. return ret;
  405. }
  406. void
  407. cleanupPayload (
  408. redfishPayload *payload
  409. )
  410. {
  411. if (!payload) {
  412. return;
  413. }
  414. json_decref (payload->json);
  415. // Don't free payload->service, let the caller handle cleaning up the service
  416. free (payload);
  417. }
  418. static redfishPayload *
  419. getOpResult (
  420. redfishPayload *payload,
  421. const char *propName,
  422. const char *op,
  423. const char *value,
  424. EFI_HTTP_STATUS_CODE **StatusCode
  425. )
  426. {
  427. const char *propStr;
  428. json_t *stringProp;
  429. bool ret = false;
  430. redfishPayload *prop;
  431. long long intVal, intPropVal;
  432. json_type jsonType;
  433. if (isPayloadCollection (payload)) {
  434. return collectionEvalOp (payload, propName, op, value, StatusCode);
  435. }
  436. if (isPayloadArray (payload)) {
  437. return arrayEvalOp (payload, propName, op, value, StatusCode);
  438. }
  439. prop = getPayloadByNodeName (payload, propName, StatusCode);
  440. if (((*StatusCode == NULL) && (prop == NULL)) ||
  441. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  442. {
  443. return prop;
  444. }
  445. stringProp = prop->json;
  446. jsonType = prop->json->type;
  447. switch (jsonType) {
  448. case JSON_OBJECT:
  449. stringProp = json_object_get (prop->json, propName);
  450. case JSON_STRING:
  451. if (strcmp (op, "=") == 0) {
  452. propStr = json_string_value (stringProp);
  453. if (propStr == NULL) {
  454. cleanupPayload (prop);
  455. return NULL;
  456. }
  457. ret = (strcmp (propStr, value) == 0);
  458. } else if (strcmp (op, "~") == 0) {
  459. propStr = json_string_value (stringProp);
  460. if (propStr == NULL) {
  461. cleanupPayload (prop);
  462. return NULL;
  463. }
  464. ret = (strcasecmp (propStr, value) == 0);
  465. }
  466. break;
  467. case JSON_TRUE:
  468. if (strcmp (op, "=") == 0) {
  469. ret = (strcmp (value, "true") == 0);
  470. }
  471. break;
  472. case JSON_FALSE:
  473. if (strcmp (op, "=") == 0) {
  474. ret = (strcmp (value, "false") == 0);
  475. }
  476. break;
  477. case JSON_INTEGER:
  478. intPropVal = json_integer_value (prop->json);
  479. intVal = strtoll (value, NULL, 0);
  480. if (strcmp (op, "=") == 0) {
  481. ret = (intPropVal == intVal);
  482. } else if (strcmp (op, "<") == 0) {
  483. ret = (intPropVal < intVal);
  484. } else if (strcmp (op, ">") == 0) {
  485. ret = (intPropVal > intVal);
  486. } else if (strcmp (op, "<=") == 0) {
  487. ret = (intPropVal <= intVal);
  488. } else if (strcmp (op, ">=") == 0) {
  489. ret = (intPropVal >= intVal);
  490. }
  491. break;
  492. default:
  493. break;
  494. }
  495. cleanupPayload (prop);
  496. if (ret) {
  497. return payload;
  498. } else {
  499. return NULL;
  500. }
  501. }
  502. static redfishPayload *
  503. collectionEvalOp (
  504. redfishPayload *payload,
  505. const char *propName,
  506. const char *op,
  507. const char *value,
  508. EFI_HTTP_STATUS_CODE **StatusCode
  509. )
  510. {
  511. redfishPayload *ret;
  512. redfishPayload *tmp;
  513. redfishPayload *members;
  514. redfishPayload **valid;
  515. size_t validMax;
  516. size_t validCount = 0;
  517. size_t i;
  518. validMax = getCollectionSize (payload);
  519. if (validMax == 0) {
  520. return NULL;
  521. }
  522. valid = (redfishPayload **)calloc (validMax, sizeof (redfishPayload *));
  523. if (valid == NULL) {
  524. return NULL;
  525. }
  526. /*Technically getPayloadByIndex would do this, but this optimizes things*/
  527. members = getPayloadByNodeName (payload, "Members", StatusCode);
  528. if (((*StatusCode == NULL) && (members == NULL)) ||
  529. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  530. {
  531. return members;
  532. }
  533. for (i = 0; i < validMax; i++) {
  534. if (*StatusCode != NULL) {
  535. FreePool (*StatusCode);
  536. *StatusCode = NULL;
  537. }
  538. tmp = getPayloadByIndex (members, i, StatusCode);
  539. if (((*StatusCode == NULL) && (tmp == NULL)) ||
  540. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  541. {
  542. return tmp;
  543. }
  544. if (*StatusCode != NULL) {
  545. FreePool (*StatusCode);
  546. *StatusCode = NULL;
  547. }
  548. valid[validCount] = getOpResult (tmp, propName, op, value, StatusCode);
  549. /*
  550. if ((*StatusCode == NULL && valid[validCount] == NULL) ||
  551. (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) {
  552. return valid[validCount];
  553. }
  554. */
  555. if (valid[validCount] != NULL) {
  556. validCount++;
  557. } else {
  558. cleanupPayload (tmp);
  559. }
  560. }
  561. cleanupPayload (members);
  562. if (validCount == 0) {
  563. free (valid);
  564. return NULL;
  565. }
  566. if (validCount == 1) {
  567. ret = valid[0];
  568. free (valid);
  569. return ret;
  570. } else {
  571. ret = createCollection (payload->service, validCount, valid);
  572. free (valid);
  573. return ret;
  574. }
  575. }
  576. static redfishPayload *
  577. arrayEvalOp (
  578. redfishPayload *payload,
  579. const char *propName,
  580. const char *op,
  581. const char *value,
  582. EFI_HTTP_STATUS_CODE **StatusCode
  583. )
  584. {
  585. redfishPayload *ret;
  586. redfishPayload *tmp;
  587. redfishPayload **valid;
  588. size_t validMax;
  589. size_t validCount = 0;
  590. size_t i;
  591. validMax = json_array_size (payload->json);
  592. if (validMax == 0) {
  593. return NULL;
  594. }
  595. valid = (redfishPayload **)calloc (validMax, sizeof (redfishPayload *));
  596. if (valid == NULL) {
  597. return NULL;
  598. }
  599. for (i = 0; i < validMax; i++) {
  600. if (*StatusCode != NULL) {
  601. FreePool (*StatusCode);
  602. *StatusCode = NULL;
  603. }
  604. tmp = getPayloadByIndex (payload, i, StatusCode);
  605. if (((*StatusCode == NULL) && (tmp == NULL)) ||
  606. ((*StatusCode != NULL) && ((**StatusCode < HTTP_STATUS_200_OK) || (**StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))))
  607. {
  608. return tmp;
  609. }
  610. if (*StatusCode != NULL) {
  611. FreePool (*StatusCode);
  612. *StatusCode = NULL;
  613. }
  614. valid[validCount] = getOpResult (tmp, propName, op, value, StatusCode);
  615. /*
  616. if ((*StatusCode == NULL && valid[validCount] == NULL) ||
  617. (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) {
  618. return valid[validCount];
  619. }
  620. */
  621. if (valid[validCount] != NULL) {
  622. validCount++;
  623. } else {
  624. cleanupPayload (tmp);
  625. }
  626. }
  627. if (validCount == 0) {
  628. free (valid);
  629. return NULL;
  630. }
  631. if (validCount == 1) {
  632. ret = valid[0];
  633. free (valid);
  634. return ret;
  635. } else {
  636. ret = createCollection (payload->service, validCount, valid);
  637. free (valid);
  638. return ret;
  639. }
  640. }
  641. static redfishPayload *
  642. createCollection (
  643. redfishService *service,
  644. size_t count,
  645. redfishPayload **payloads
  646. )
  647. {
  648. redfishPayload *ret;
  649. json_t *collectionJson = json_object ();
  650. json_t *jcount = json_integer ((json_int_t)count);
  651. json_t *members = json_array ();
  652. size_t i;
  653. if (!collectionJson) {
  654. return NULL;
  655. }
  656. if (!members) {
  657. json_decref (collectionJson);
  658. return NULL;
  659. }
  660. json_object_set (collectionJson, "Members@odata.count", jcount);
  661. json_decref (jcount);
  662. for (i = 0; i < count; i++) {
  663. json_array_append (members, payloads[i]->json);
  664. cleanupPayload (payloads[i]);
  665. }
  666. json_object_set (collectionJson, "Members", members);
  667. json_decref (members);
  668. ret = createRedfishPayload (collectionJson, service);
  669. return ret;
  670. }
  671. static json_t *
  672. json_object_get_by_index (
  673. json_t *json,
  674. size_t index
  675. )
  676. {
  677. void *iter;
  678. size_t i;
  679. iter = json_object_iter (json);
  680. for (i = 0; i < index; i++) {
  681. iter = json_object_iter_next (json, iter);
  682. if (iter == NULL) {
  683. break;
  684. }
  685. }
  686. if (iter == NULL) {
  687. return NULL;
  688. }
  689. return json_object_iter_value (iter);
  690. }
  691. /* vim: set tabstop=4 shiftwidth=4 expandtab: */