From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web10.9113.1608216024911377794 for ; Thu, 17 Dec 2020 06:40:25 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@hpe.com header.s=pps0720 header.b=Ou2fvdm4; spf=pass (domain: hpe.com, ip: 148.163.143.35, mailfrom: prvs=0620e511af=abner.chang@hpe.com) Received: from pps.filterd (m0148664.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 0BHEXRPB021785; Thu, 17 Dec 2020 14:40:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pps0720; bh=Jfv7vqbMy49011gTJnWrMc2aZ3/t8IUcyPlAj5Z8CHU=; b=Ou2fvdm4rOEpaE8wZ7AapWiccef9fxRVDPpHzwlQ253/wKK976QQ8kOZhHxllDbQ/8Mr 0unje7h8o/mqmYnuPIyuBg9eL40vg6DytgN/WY6Z2zvjsSxkWltVRLOY/DkvY2OrHwZh se25XMoJxSkTjHt1dlMx2WhcnFnYDWyf4iMqTW4XJsYh60YcnDYqZLtbz439TCx+RrsZ ZFFJe+vRqpWuguHs/9iHWOijmyuZ6wWk8ins2zSRJP/Zt7Vn8JrNwIlM2HcFeQqVuyn+ qQET0dJWdHzmaZwmB19yjFw0q5sWVjouBnW+RSXY+CsvL7wyUWZdeJNMeh+lB6e9So3N XA== Received: from g4t3426.houston.hpe.com (g4t3426.houston.hpe.com [15.241.140.75]) by mx0b-002e3701.pphosted.com with ESMTP id 35f0g92s9j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 17 Dec 2020 14:40:23 +0000 Received: from G4W9120.americas.hpqcorp.net (exchangepmrr1.us.hpecorp.net [16.210.21.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g4t3426.houston.hpe.com (Postfix) with ESMTPS id 2412367; Thu, 17 Dec 2020 14:40:23 +0000 (UTC) Received: from G9W8453.americas.hpqcorp.net (2002:10d8:a0d3::10d8:a0d3) by G4W9120.americas.hpqcorp.net (2002:10d2:150f::10d2:150f) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 17 Dec 2020 14:40:22 +0000 Received: from NAM02-CY1-obe.outbound.protection.outlook.com (15.241.52.13) by G9W8453.americas.hpqcorp.net (16.216.160.211) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Thu, 17 Dec 2020 14:40:22 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=STrpawOp7QML44jJzXVTditzFdrATY4cGB97Zo6INhww+O6aGZXX5+E8V1mg0S4I118mOAwcv6c01RrfzCaUSPhvyN7SfCtp73L2vHtts6c/X3qCzNPZNoCUGbTWrCNhe99x6qgO+1ylEtljbAg0JaOlLR1RPuEpsXvw0u7R02CguPDOhDmwj608FhMPa3nOgG+qeABeHTln/W3s2Ncmla3tn82U3Q9DnEUGmx26B7E2KdphXu/v6CidpF6RG8mUKL/a0QHiGqofuEw8ioBrUHqQq0UBagQEo5/VxYOthcdNUHrzWKo/Fag/cPebFq6OhhtcrN80oaT0rVNy/CvGUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xEBa7tyjTXho9aJyFUJIA/R1Yu9v5PIppSUf0uOR1RE=; b=NSU+brPkB3fakKUSV3i5W6r97u2Ppr6C90CzZaZ8s6zw02gjUUNsmrPpuod0Eooq98j4NVwhvO6ukJD/l1gw3zkRGDVfow93Q5fsB68gPJkwVSFD+gnlh9YdcP4J78Dst2Led6qtb0My+TA1AZl+agqP6myZ4EKZChpFeAOPyUsqMXA+Weot/n5EGjW2O7d5+odmjBIOq0+GzjEgBm+QTwkVITKpURoBA8FJfW4Ob0YcOCTovn3P5rcOHa1e3qFJL/tPhEt3QezWPIdMF+m/ZNEfPvNsh0630s6QByD50Hr3p5JbReNUPMaRX1cATjMlRIZY1UHa3NicpVYW/cMGCw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hpe.com; dmarc=pass action=none header.from=hpe.com; dkim=pass header.d=hpe.com; arc=none Received: from CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7508::16) by CS1PR8401MB1141.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:750a::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12; Thu, 17 Dec 2020 14:40:20 +0000 Received: from CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM ([fe80::a094:ed67:fb40:340e]) by CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM ([fe80::a094:ed67:fb40:340e%10]) with mapi id 15.20.3654.025; Thu, 17 Dec 2020 14:40:20 +0000 From: "Abner Chang" To: "devel@edk2.groups.io" , "leif@nuviainc.com" CC: "Wang, Nickle (HPS SW)" , "O'Hanley, Peter (EXL)" Subject: Re: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port of jansson library Thread-Topic: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port of jansson library Thread-Index: AQHW1HGrIH03oj1/zUiJ89t5Siiwt6n7WtMQ Date: Thu, 17 Dec 2020 14:40:20 +0000 Message-ID: References: <20201216031406.7136-1-abner.chang@hpe.com> <20201216031406.7136-5-abner.chang@hpe.com> <20201217123933.GM1664@vanye> In-Reply-To: <20201217123933.GM1664@vanye> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=hpe.com; x-originating-ip: [165.225.116.142] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 486e6376-007d-49ee-f639-08d8a299ae21 x-ms-traffictypediagnostic: CS1PR8401MB1141: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:1824; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: a83a+k7BPQG9p91vZKUrNDKOpfRADBN8QEsf+3cLx1t/VP9d5JOCcZruIPHZkXAOS78CfqQTaVF3LwiYt6LwEi+TKNOL6hnNHbPMFOS5rG90lU3+D7rbnMciezYYsP2C020y/aC13ZRUeFePJkKPJMlUtOBFMkPLVeHZMz+ZCyIFv0P9n1XX+svRTWP8Q6f5rfZgHAR/KvaWc07c5Ch/L6ralY+USLy0+oFfbSra3afDv96HwZIAlsD5KOQd+luDfNVPgSk5IBEaf0wNSlqHG2dqBX3Q9/I8TMM9tHxYLPA9CoL71pS0zU64/sgSZn0duH5bFuTA2XDrDczqXfjphpRBvRN7b6QwK7LExu0D5XZq1pqSJqE/eltzMgwM6x9zf+PTwL2V0BTLn2PVP8HYSSAyfOXbtAUhdviMtgLjZFr02DgLThnwURyFH2ssM37Q x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(346002)(366004)(376002)(39860400002)(396003)(136003)(4326008)(52536014)(55236004)(6506007)(45080400002)(66556008)(71200400001)(8676002)(186003)(2906002)(86362001)(76116006)(478600001)(33656002)(8936002)(53546011)(55016002)(66446008)(316002)(7696005)(26005)(5660300002)(110136005)(966005)(19627235002)(64756008)(30864003)(54906003)(83380400001)(66946007)(9686003)(66476007)(2004002)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?6s4rv1K881xJNNSF8379b0mqEy3i7On3HtilK+QDvjvvxXG5Eo9Wx/DqpoVg?= =?us-ascii?Q?FhEvBESbtPk59sEP9wlfPp21/pOviwQ+e+yrO09wbeze+5Rpu8BbqjfJsJK5?= =?us-ascii?Q?DCRMdKM4j5cq3V1nbrLSIB5dZ4GwO87g6ODHyGj2H6TLR8nSXmbSUJ0wQskx?= =?us-ascii?Q?y/ZfGd38n+/Z5SvD/3/wY0DQSSQ94/90f8ExHmLDUUopVy9i2+2NlzjcQaVe?= =?us-ascii?Q?IaRuHTs12HR2ZaCYRtWOp7UmW38mpcxxL8pd21yAqO9qeXwhYKfKaVeHAMg1?= =?us-ascii?Q?cFYmwGu91jV/hhcYIhsnkF1P3P7aTqIYyu4I0Hy14rTeBoqFX+oDM02QuF5G?= =?us-ascii?Q?Bs6tb+Fo2i/wvX2BBdYNdiHkTpxrDA7GnkFMlYV/KahzZFt+/Rhfo02C0+yj?= =?us-ascii?Q?PxYHdRsHE0KPuIg/Aba6aylXMXerXQn5ZvPamTppidAYNm++BeK2FRd6CF2f?= =?us-ascii?Q?eCK1QJOUqenIrCJwlCRhc43Wo+MSWNHeg3L3LlxVTqf8aSEjvEYxqFZKJcCE?= =?us-ascii?Q?PJ2lbxkcdUoG5WuZWeOrt8pZu37ZKGZ8JAs6OH3OoF/5icf3+ipsNizEUDnU?= =?us-ascii?Q?z4Q2zhudCgfciYPpTFHvdw2wJB/aFpntSrAx661yhUCIqxtiuCKmZKTC/5aT?= =?us-ascii?Q?CANs6tG8MtbgJVBrHsYMHaGRU4THgWlhItfIpRGH1/57kPD9RKnrV9/st1+s?= =?us-ascii?Q?1GZgAkVQYI037RZ0hmynx5BTHEapnySh47ieTdbLicXy+uUxX9yjmiC6RtPB?= =?us-ascii?Q?qZuDWRk5sBepUatwTDzIxl026pLY3SrQbeJ5skv3fy676x/9xIbDZj7NCtST?= =?us-ascii?Q?2hyg/91pxXzhknuxQSkNfZY8kt7gJ8G6vpyVwDxWlbdnqxb6GSeKl5WTxKjm?= =?us-ascii?Q?ISBM++IA2zN7N6f8T5avoVpS79bTZqUWKdF7GpWp8xGKkpzy8kkf6bZdAKUK?= =?us-ascii?Q?sRgYCP1QrlgEvtSxPWhcPE278uBmjIrXxuGXwg25nmk=3D?= X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-Network-Message-Id: 486e6376-007d-49ee-f639-08d8a299ae21 X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Dec 2020 14:40:20.6173 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: gbmOOF/3vuDS8MbIf9oFBnPP1kcK7IfINyMZELerA5b437Hxdhs3arD4rgyWruj+8CcKtfFCuv4cNGjdgKrC7Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CS1PR8401MB1141 X-OriginatorOrg: hpe.com X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343,18.0.737 definitions=2020-12-17_09:2020-12-15,2020-12-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 adultscore=0 suspectscore=0 mlxlogscore=999 clxscore=1015 priorityscore=1501 lowpriorityscore=0 phishscore=0 malwarescore=0 spamscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2012170103 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Leif Lindholm > Sent: Thursday, December 17, 2020 8:40 PM > To: Chang, Abner (HPS SW/FW Technologist) > Cc: devel@edk2.groups.io; Wang, Nickle (HPS SW) ; > O'Hanley, Peter (EXL) > Subject: Re: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port o= f > jansson library >=20 > On Wed, Dec 16, 2020 at 11:14:04 +0800, Abner Chang wrote: > > edk2 JsonLib which is the edk2 port of open source jansson library. > > (https://github.com/akheron/jansson) > > jansson library is the open source project to manipulate JSON data > > structure. > > > > Signed-off-by: Abner Chang > > > > Cc: Leif Lindholm > > Cc: Nickle Wang > > Cc: Peter O'Hanley > > --- > > RedfishPkg/Include/Library/JsonLib.h | 763 +++++++++++ > > RedfishPkg/Library/JsonLib/JsonLib.c | 964 ++++++++++++++ > > RedfishPkg/Library/JsonLib/JsonLib.inf | 89 ++ > > RedfishPkg/Library/JsonLib/Readme.rst | 40 + > > RedfishPkg/Library/JsonLib/jansson_config.h | 41 + > > .../Library/JsonLib/jansson_private_config.h | 19 + > > RedfishPkg/Library/JsonLib/load.c | 1111 ++++++++++++++++= + > > RedfishPkg/RedfishPkg.ci.yaml | 8 +- > > RedfishPkg/RedfishPkg.dec | 11 + > > 9 files changed, 3045 insertions(+), 1 deletion(-) >=20 > Please configure your git to use an orderfile for diffs. > This can be done by running BaseTools/Scripts/SetupGit.py in your reposi= tory > or manually by following > https://github.com/tianocore/tianocore.github.io/wiki/Laszlo%27s- > unkempt-git-guide-for-edk2-contributors-and-maintainers Will check it, I thought I have that configured. >=20 > > create mode 100644 RedfishPkg/Include/Library/JsonLib.h > > create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c > > create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf > > create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst > > create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h > > create mode 100644 > > RedfishPkg/Library/JsonLib/jansson_private_config.h > > create mode 100644 RedfishPkg/Library/JsonLib/load.c > > >=20 > > diff --git a/RedfishPkg/Library/JsonLib/load.c > > b/RedfishPkg/Library/JsonLib/load.c > > new file mode 100644 > > index 0000000000..92063e63cb > > --- /dev/null > > +++ b/RedfishPkg/Library/JsonLib/load.c > > @@ -0,0 +1,1111 @@ > > +/* > > + * Copyright (c) 2009-2016 Petri Lehtinen > > + * > > + * Jansson is free software; you can redistribute it and/or modify > > + * it under the terms of the MIT license. See LICENSE for details. > > + > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > This is not accurate. > You are adding the BSD-2-Clause-Patent license on top of the MIT license= for > this contribution. The statement should be >=20 > SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT >=20 > The way you're keeping the original header, then adding HPE copyright, a= nd > then adding the SPDX tag is ideal though. Makes it clear who did the lic= ense > addition and when. Leif, not quite sure which way is accurate, looks like below? Or could ple= ase you give me the right one? :) Thanks Copyright (c) 2009-2016 Petri Lehtinen (C) Copyright 2020 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT >=20 > / > Leif >=20 > > + */ > > + > > +#ifndef _GNU_SOURCE > > +#define _GNU_SOURCE > > +#endif > > + > > +#include "jansson_private.h" > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#ifdef HAVE_UNISTD_H > > +#include > > +#endif > > + > > +#include "jansson.h" > > +#include "strbuffer.h" > > +#include "utf.h" > > + > > +#define STREAM_STATE_OK 0 > > +#define STREAM_STATE_EOF -1 > > +#define STREAM_STATE_ERROR -2 > > + > > +#define TOKEN_INVALID -1 > > +#define TOKEN_EOF 0 > > +#define TOKEN_STRING 256 > > +#define TOKEN_INTEGER 257 > > +#define TOKEN_REAL 258 > > +#define TOKEN_TRUE 259 > > +#define TOKEN_FALSE 260 > > +#define TOKEN_NULL 261 > > + > > +/* Locale independent versions of isxxx() functions */ #define > > +l_isupper(c) ('A' <=3D (c) && (c) <=3D 'Z') #define l_islower(c) ('a'= <=3D > > +(c) && (c) <=3D 'z') #define l_isalpha(c) (l_isupper(c) || > > +l_islower(c)) #define l_isdigit(c) ('0' <=3D (c) && (c) <=3D '9') > > +#define l_isxdigit(c) = \ > > + (l_isdigit(c) || ('A' <=3D (c) && (c) <=3D 'F') || ('a' <=3D (c) = && (c) > > +<=3D 'f')) > > + > > +/* Read one byte from stream, convert to unsigned char, then int, and > > + return. return EOF on end of file. This corresponds to the > > + behaviour of fgetc(). */ > > +typedef int (*get_func)(void *data); > > + > > +typedef struct { > > + get_func get; > > + void *data; > > + char buffer[5]; > > + size_t buffer_pos; > > + int state; > > + int line; > > + int column, last_column; > > + size_t position; > > +} stream_t; > > + > > +typedef struct { > > + stream_t stream; > > + strbuffer_t saved_text; > > + size_t flags; > > + size_t depth; > > + int token; > > + union { > > + struct { > > + char *val; > > + size_t len; > > + } string; > > + json_int_t integer; > > + double real; > > + } value; > > +} lex_t; > > + > > +#define stream_to_lex(stream) container_of(stream, lex_t, stream) > > + > > +/*** error reporting ***/ > > + > > +static void error_set(json_error_t *error, const lex_t *lex, enum > json_error_code code, > > + const char *msg, ...) { > > + va_list ap; > > + char msg_text[JSON_ERROR_TEXT_LENGTH]; > > + char msg_with_context[JSON_ERROR_TEXT_LENGTH]; > > + > > + int line =3D -1, col =3D -1; > > + size_t pos =3D 0; > > + const char *result =3D msg_text; > > + > > + if (!error) > > + return; > > + > > + va_start(ap, msg); > > + vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); > > + msg_text[JSON_ERROR_TEXT_LENGTH - 1] =3D '\0'; > > + va_end(ap); > > + > > + if (lex) { > > + const char *saved_text =3D strbuffer_value(&lex->saved_text); > > + > > + line =3D lex->stream.line; > > + col =3D lex->stream.column; > > + pos =3D lex->stream.position; > > + > > + if (saved_text && saved_text[0]) { > > + if (lex->saved_text.length <=3D 20) { > > + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%= s > near '%s'", > > + msg_text, saved_text); > > + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] =3D '\0'= ; > > + result =3D msg_with_context; > > + } > > + } else { > > + if (code =3D=3D json_error_invalid_syntax) { > > + /* More specific error code for premature end of file= . */ > > + code =3D json_error_premature_end_of_input; > > + } > > + if (lex->stream.state =3D=3D STREAM_STATE_ERROR) { > > + /* No context for UTF-8 decoding errors */ > > + result =3D msg_text; > > + } else { > > + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%= s > near end of file", > > + msg_text); > > + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] =3D '\0'= ; > > + result =3D msg_with_context; > > + } > > + } > > + } > > + > > + jsonp_error_set(error, line, col, pos, code, "%s", result); } > > + > > +/*** lexical analyzer ***/ > > + > > +static void stream_init(stream_t *stream, get_func get, void *data) { > > + stream->get =3D get; > > + stream->data =3D data; > > + stream->buffer[0] =3D '\0'; > > + stream->buffer_pos =3D 0; > > + > > + stream->state =3D STREAM_STATE_OK; > > + stream->line =3D 1; > > + stream->column =3D 0; > > + stream->position =3D 0; > > +} > > + > > +static int stream_get(stream_t *stream, json_error_t *error) { > > + int c; > > + > > + if (stream->state !=3D STREAM_STATE_OK) > > + return stream->state; > > + > > + if (!stream->buffer[stream->buffer_pos]) { > > + c =3D stream->get(stream->data); > > + if (c =3D=3D EOF) { > > + stream->state =3D STREAM_STATE_EOF; > > + return STREAM_STATE_EOF; > > + } > > + > > + stream->buffer[0] =3D c; > > + stream->buffer_pos =3D 0; > > + > > + if (0x80 <=3D c && c <=3D 0xFF) { > > + /* multi-byte UTF-8 sequence */ > > + size_t i, count; > > + > > + count =3D utf8_check_first(c); > > + if (!count) > > + goto out; > > + > > + assert(count >=3D 2); > > + > > + for (i =3D 1; i < count; i++) > > + stream->buffer[i] =3D stream->get(stream->data); > > + > > + if (!utf8_check_full(stream->buffer, count, NULL)) > > + goto out; > > + > > + stream->buffer[count] =3D '\0'; > > + } else > > + stream->buffer[1] =3D '\0'; > > + } > > + > > + c =3D stream->buffer[stream->buffer_pos++]; > > + > > + stream->position++; > > + if (c =3D=3D '\n') { > > + stream->line++; > > + stream->last_column =3D stream->column; > > + stream->column =3D 0; > > + } else if (utf8_check_first(c)) { > > + /* track the Unicode character column, so increment only if > > + this is the first character of a UTF-8 sequence */ > > + stream->column++; > > + } > > + > > + return c; > > + > > +out: > > + stream->state =3D STREAM_STATE_ERROR; > > + error_set(error, stream_to_lex(stream), json_error_invalid_utf8, > > + "unable to decode byte 0x%x", c); > > + return STREAM_STATE_ERROR; > > +} > > + > > +static void stream_unget(stream_t *stream, int c) { > > + if (c =3D=3D STREAM_STATE_EOF || c =3D=3D STREAM_STATE_ERROR) > > + return; > > + > > + stream->position--; > > + if (c =3D=3D '\n') { > > + stream->line--; > > + stream->column =3D stream->last_column; > > + } else if (utf8_check_first(c)) > > + stream->column--; > > + > > + assert(stream->buffer_pos > 0); > > + stream->buffer_pos--; > > + assert(stream->buffer[stream->buffer_pos] =3D=3D c); } > > + > > +static int lex_get(lex_t *lex, json_error_t *error) { > > + return stream_get(&lex->stream, error); } > > + > > +static void lex_save(lex_t *lex, int c) { > > +strbuffer_append_byte(&lex->saved_text, c); } > > + > > +static int lex_get_save(lex_t *lex, json_error_t *error) { > > + int c =3D stream_get(&lex->stream, error); > > + if (c !=3D STREAM_STATE_EOF && c !=3D STREAM_STATE_ERROR) > > + lex_save(lex, c); > > + return c; > > +} > > + > > +static void lex_unget(lex_t *lex, int c) { stream_unget(&lex->stream, > > +c); } > > + > > +static void lex_unget_unsave(lex_t *lex, int c) { > > + if (c !=3D STREAM_STATE_EOF && c !=3D STREAM_STATE_ERROR) { > > +/* Since we treat warnings as errors, when assertions are turned > > + * off the "d" variable would be set but never used. Which is > > + * treated as an error by GCC. > > + */ > > +#ifndef NDEBUG > > + char d; > > +#endif > > + stream_unget(&lex->stream, c); #ifndef NDEBUG > > + d =3D > > +#endif > > + strbuffer_pop(&lex->saved_text); > > + assert(c =3D=3D d); > > + } > > +} > > + > > +static void lex_save_cached(lex_t *lex) { > > + while (lex->stream.buffer[lex->stream.buffer_pos] !=3D '\0') { > > + lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); > > + lex->stream.buffer_pos++; > > + lex->stream.position++; > > + } > > +} > > + > > +static void lex_free_string(lex_t *lex) { > > + jsonp_free(lex->value.string.val); > > + lex->value.string.val =3D NULL; > > + lex->value.string.len =3D 0; > > +} > > + > > +/* assumes that str points to 'u' plus at least 4 valid hex digits */ > > +static int32_t decode_unicode_escape(const char *str) { > > + int i; > > + int32_t value =3D 0; > > + > > + assert(str[0] =3D=3D 'u'); > > + > > + for (i =3D 1; i <=3D 4; i++) { > > + char c =3D str[i]; > > + value <<=3D 4; > > + if (l_isdigit(c)) > > + value +=3D c - '0'; > > + else if (l_islower(c)) > > + value +=3D c - 'a' + 10; > > + else if (l_isupper(c)) > > + value +=3D c - 'A' + 10; > > + else > > + return -1; > > + } > > + > > + return value; > > +} > > + > > +static void lex_scan_string(lex_t *lex, json_error_t *error) { > > + int c; > > + const char *p; > > + char *t; > > + int i; > > + > > + lex->value.string.val =3D NULL; > > + lex->token =3D TOKEN_INVALID; > > + > > + c =3D lex_get_save(lex, error); > > + > > + while (c !=3D '"') { > > + if (c =3D=3D STREAM_STATE_ERROR) > > + goto out; > > + > > + else if (c =3D=3D STREAM_STATE_EOF) { > > + error_set(error, lex, json_error_premature_end_of_input, > > + "premature end of input"); > > + goto out; > > + } > > + > > + else if (0 <=3D c && c <=3D 0x1F) { > > + /* control character */ > > + lex_unget_unsave(lex, c); > > + if (c =3D=3D '\n') > > + error_set(error, lex, json_error_invalid_syntax, "une= xpected > newline"); > > + else > > + error_set(error, lex, json_error_invalid_syntax, "con= trol character > 0x%x", > > + c); > > + goto out; > > + } > > + > > + else if (c =3D=3D '\\') { > > + c =3D lex_get_save(lex, error); > > + if (c =3D=3D 'u') { > > + c =3D lex_get_save(lex, error); > > + for (i =3D 0; i < 4; i++) { > > + if (!l_isxdigit(c)) { > > + error_set(error, lex, json_error_invalid_synt= ax, > > + "invalid escape"); > > + goto out; > > + } > > + c =3D lex_get_save(lex, error); > > + } > > + } else if (c =3D=3D '"' || c =3D=3D '\\' || c =3D=3D '/' = || c =3D=3D 'b' || c =3D=3D 'f' || > > + c =3D=3D 'n' || c =3D=3D 'r' || c =3D=3D 't') > > + c =3D lex_get_save(lex, error); > > + else { > > + error_set(error, lex, json_error_invalid_syntax, "inv= alid escape"); > > + goto out; > > + } > > + } else > > + c =3D lex_get_save(lex, error); > > + } > > + > > + /* the actual value is at most of the same length as the source > > + string, because: > > + - shortcut escapes (e.g. "\t") (length 2) are converted to 1= byte > > + - a single \uXXXX escape (length 6) is converted to at most = 3 bytes > > + - two \uXXXX escapes (length 12) forming an UTF-16 surrogate= pair > > + are converted to 4 bytes > > + */ > > + t =3D jsonp_malloc(lex->saved_text.length + 1); > > + if (!t) { > > + /* this is not very nice, since TOKEN_INVALID is returned */ > > + goto out; > > + } > > + lex->value.string.val =3D t; > > + > > + /* + 1 to skip the " */ > > + p =3D strbuffer_value(&lex->saved_text) + 1; > > + > > + while (*p !=3D '"') { > > + if (*p =3D=3D '\\') { > > + p++; > > + if (*p =3D=3D 'u') { > > + size_t length; > > + int32_t value; > > + > > + value =3D decode_unicode_escape(p); > > + if (value < 0) { > > + error_set(error, lex, json_error_invalid_syntax, > > + "invalid Unicode escape '%.6s'", p - 1)= ; > > + goto out; > > + } > > + p +=3D 5; > > + > > + if (0xD800 <=3D value && value <=3D 0xDBFF) { > > + /* surrogate pair */ > > + if (*p =3D=3D '\\' && *(p + 1) =3D=3D 'u') { > > + int32_t value2 =3D decode_unicode_escape(++p)= ; > > + if (value2 < 0) { > > + error_set(error, lex, json_error_invalid_= syntax, > > + "invalid Unicode escape '%.6s'"= , p - 1); > > + goto out; > > + } > > + p +=3D 5; > > + > > + if (0xDC00 <=3D value2 && value2 <=3D 0xDFFF)= { > > + /* valid second surrogate */ > > + value =3D > > + ((value - 0xD800) << 10) + (value2 - = 0xDC00) + 0x10000; > > + } else { > > + /* invalid second surrogate */ > > + error_set(error, lex, json_error_invalid_= syntax, > > + "invalid Unicode '\\u%04X\\u%04= X'", value, value2); > > + goto out; > > + } > > + } else { > > + /* no second surrogate */ > > + error_set(error, lex, json_error_invalid_synt= ax, > > + "invalid Unicode '\\u%04X'", value)= ; > > + goto out; > > + } > > + } else if (0xDC00 <=3D value && value <=3D 0xDFFF) { > > + error_set(error, lex, json_error_invalid_syntax, > > + "invalid Unicode '\\u%04X'", value); > > + goto out; > > + } > > + > > + if (utf8_encode(value, t, &length)) > > + assert(0); > > + t +=3D length; > > + } else { > > + switch (*p) { > > + case '"': > > + case '\\': > > + case '/': > > + *t =3D *p; > > + break; > > + case 'b': > > + *t =3D '\b'; > > + break; > > + case 'f': > > + *t =3D '\f'; > > + break; > > + case 'n': > > + *t =3D '\n'; > > + break; > > + case 'r': > > + *t =3D '\r'; > > + break; > > + case 't': > > + *t =3D '\t'; > > + break; > > + default: > > + assert(0); > > + } > > + t++; > > + p++; > > + } > > + } else > > + *(t++) =3D *(p++); > > + } > > + *t =3D '\0'; > > + lex->value.string.len =3D t - lex->value.string.val; > > + lex->token =3D TOKEN_STRING; > > + return; > > + > > +out: > > + lex_free_string(lex); > > +} > > + > > +#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ #if > > +JSON_INTEGER_IS_LONG_LONG #ifdef _MSC_VER /* Microsoft Visual > Studio > > +*/ #define json_strtoint _strtoi64 #else #define json_strtoint > > +strtoll #endif #else #define json_strtoint strtol #endif #endif > > + > > +static int lex_scan_number(lex_t *lex, int c, json_error_t *error) { > > + const char *saved_text; > > + char *end; > > + double doubleval; > > + > > + lex->token =3D TOKEN_INVALID; > > + > > + if (c =3D=3D '-') > > + c =3D lex_get_save(lex, error); > > + > > + if (c =3D=3D '0') { > > + c =3D lex_get_save(lex, error); > > + if (l_isdigit(c)) { > > + lex_unget_unsave(lex, c); > > + goto out; > > + } > > + } else if (l_isdigit(c)) { > > + do > > + c =3D lex_get_save(lex, error); > > + while (l_isdigit(c)); > > + } else { > > + lex_unget_unsave(lex, c); > > + goto out; > > + } > > + > > + if (!(lex->flags & JSON_DECODE_INT_AS_REAL) && c !=3D '.' && c != =3D 'E' && > c !=3D 'e') { > > + json_int_t intval; > > + > > + lex_unget_unsave(lex, c); > > + > > + saved_text =3D strbuffer_value(&lex->saved_text); > > + > > + errno =3D 0; > > + intval =3D json_strtoint(saved_text, &end, 10); > > + if (errno =3D=3D ERANGE) { > > + if (intval < 0) > > + error_set(error, lex, json_error_numeric_overflow, > > + "too big negative integer"); > > + else > > + error_set(error, lex, json_error_numeric_overflow, "t= oo big > integer"); > > + goto out; > > + } > > + > > + assert(end =3D=3D saved_text + lex->saved_text.length); > > + > > + lex->token =3D TOKEN_INTEGER; > > + lex->value.integer =3D intval; > > + return 0; > > + } > > + > > + if (c =3D=3D '.') { > > + c =3D lex_get(lex, error); > > + if (!l_isdigit(c)) { > > + lex_unget(lex, c); > > + goto out; > > + } > > + lex_save(lex, c); > > + > > + do > > + c =3D lex_get_save(lex, error); > > + while (l_isdigit(c)); > > + } > > + > > + if (c =3D=3D 'E' || c =3D=3D 'e') { > > + c =3D lex_get_save(lex, error); > > + if (c =3D=3D '+' || c =3D=3D '-') > > + c =3D lex_get_save(lex, error); > > + > > + if (!l_isdigit(c)) { > > + lex_unget_unsave(lex, c); > > + goto out; > > + } > > + > > + do > > + c =3D lex_get_save(lex, error); > > + while (l_isdigit(c)); > > + } > > + > > + lex_unget_unsave(lex, c); > > + > > + if (jsonp_strtod(&lex->saved_text, &doubleval)) { > > + error_set(error, lex, json_error_numeric_overflow, "real numb= er > overflow"); > > + goto out; > > + } > > + > > + lex->token =3D TOKEN_REAL; > > + lex->value.real =3D doubleval; > > + return 0; > > + > > +out: > > + return -1; > > +} > > + > > +static int lex_scan(lex_t *lex, json_error_t *error) { > > + int c; > > + > > + strbuffer_clear(&lex->saved_text); > > + > > + if (lex->token =3D=3D TOKEN_STRING) > > + lex_free_string(lex); > > + > > + do > > + c =3D lex_get(lex, error); > > + while (c =3D=3D ' ' || c =3D=3D '\t' || c =3D=3D '\n' || c =3D=3D= '\r'); > > + > > + if (c =3D=3D STREAM_STATE_EOF) { > > + lex->token =3D TOKEN_EOF; > > + goto out; > > + } > > + > > + if (c =3D=3D STREAM_STATE_ERROR) { > > + lex->token =3D TOKEN_INVALID; > > + goto out; > > + } > > + > > + lex_save(lex, c); > > + > > + if (c =3D=3D '{' || c =3D=3D '}' || c =3D=3D '[' || c =3D=3D ']' = || c =3D=3D ':' || c =3D=3D ',') > > + lex->token =3D c; > > + > > + else if (c =3D=3D '"') > > + lex_scan_string(lex, error); > > + > > + else if (l_isdigit(c) || c =3D=3D '-') { > > + if (lex_scan_number(lex, c, error)) > > + goto out; > > + } > > + > > + else if (l_isalpha(c)) { > > + /* eat up the whole identifier for clearer error messages */ > > + const char *saved_text; > > + > > + do > > + c =3D lex_get_save(lex, error); > > + while (l_isalpha(c)); > > + lex_unget_unsave(lex, c); > > + > > + saved_text =3D strbuffer_value(&lex->saved_text); > > + > > + if (strcmp(saved_text, "true") =3D=3D 0) > > + lex->token =3D TOKEN_TRUE; > > + else if (strcmp(saved_text, "false") =3D=3D 0) > > + lex->token =3D TOKEN_FALSE; > > + else if (strcmp(saved_text, "null") =3D=3D 0) > > + lex->token =3D TOKEN_NULL; > > + else > > + lex->token =3D TOKEN_INVALID; > > + } > > + > > + else { > > + /* save the rest of the input UTF-8 sequence to get an error > > + message of valid UTF-8 */ > > + lex_save_cached(lex); > > + lex->token =3D TOKEN_INVALID; > > + } > > + > > +out: > > + return lex->token; > > +} > > + > > +static char *lex_steal_string(lex_t *lex, size_t *out_len) { > > + char *result =3D NULL; > > + if (lex->token =3D=3D TOKEN_STRING) { > > + result =3D lex->value.string.val; > > + *out_len =3D lex->value.string.len; > > + lex->value.string.val =3D NULL; > > + lex->value.string.len =3D 0; > > + } > > + return result; > > +} > > + > > +static int lex_init(lex_t *lex, get_func get, size_t flags, void *dat= a) { > > + stream_init(&lex->stream, get, data); > > + if (strbuffer_init(&lex->saved_text)) > > + return -1; > > + > > + lex->flags =3D flags; > > + lex->token =3D TOKEN_INVALID; > > + return 0; > > +} > > + > > +static void lex_close(lex_t *lex) { > > + if (lex->token =3D=3D TOKEN_STRING) > > + lex_free_string(lex); > > + strbuffer_close(&lex->saved_text); > > +} > > + > > +/*** parser ***/ > > + > > +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t > > +*error); > > + > > +static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *e= rror) { > > + json_t *object =3D json_object(); > > + if (!object) > > + return NULL; > > + > > + lex_scan(lex, error); > > + if (lex->token =3D=3D '}') > > + return object; > > + > > + while (1) { > > + char *key; > > + size_t len; > > + json_t *value; > > + > > + if (lex->token !=3D TOKEN_STRING) { > > + error_set(error, lex, json_error_invalid_syntax, "string = or '}' > expected"); > > + goto error; > > + } > > + > > + key =3D lex_steal_string(lex, &len); > > + if (!key) > > + return NULL; > > + if (memchr(key, '\0', len)) { > > + jsonp_free(key); > > + error_set(error, lex, json_error_null_byte_in_key, > > + "NUL byte in object key not supported"); > > + goto error; > > + } > > + > > + if (flags & JSON_REJECT_DUPLICATES) { > > + if (json_object_get(object, key)) { > > + jsonp_free(key); > > + error_set(error, lex, json_error_duplicate_key, "dupl= icate object > key"); > > + goto error; > > + } > > + } > > + > > + lex_scan(lex, error); > > + if (lex->token !=3D ':') { > > + jsonp_free(key); > > + error_set(error, lex, json_error_invalid_syntax, "':' exp= ected"); > > + goto error; > > + } > > + > > + lex_scan(lex, error); > > + value =3D parse_value(lex, flags, error); > > + if (!value) { > > + jsonp_free(key); > > + goto error; > > + } > > + > > + if (json_object_set_new_nocheck(object, key, value)) { > > + jsonp_free(key); > > + goto error; > > + } > > + > > + jsonp_free(key); > > + > > + lex_scan(lex, error); > > + if (lex->token !=3D ',') > > + break; > > + > > + lex_scan(lex, error); > > + } > > + > > + if (lex->token !=3D '}') { > > + error_set(error, lex, json_error_invalid_syntax, "'}' expecte= d"); > > + goto error; > > + } > > + > > + return object; > > + > > +error: > > + json_decref(object); > > + return NULL; > > +} > > + > > +static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *er= ror) { > > + json_t *array =3D json_array(); > > + if (!array) > > + return NULL; > > + > > + lex_scan(lex, error); > > + if (lex->token =3D=3D ']') > > + return array; > > + > > + while (lex->token) { > > + json_t *elem =3D parse_value(lex, flags, error); > > + if (!elem) > > + goto error; > > + > > + if (json_array_append_new(array, elem)) { > > + goto error; > > + } > > + > > + lex_scan(lex, error); > > + if (lex->token !=3D ',') > > + break; > > + > > + lex_scan(lex, error); > > + } > > + > > + if (lex->token !=3D ']') { > > + error_set(error, lex, json_error_invalid_syntax, "']' expecte= d"); > > + goto error; > > + } > > + > > + return array; > > + > > +error: > > + json_decref(array); > > + return NULL; > > +} > > + > > +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *er= ror) { > > + json_t *json; > > + > > + lex->depth++; > > + if (lex->depth > JSON_PARSER_MAX_DEPTH) { > > + error_set(error, lex, json_error_stack_overflow, "maximum par= sing > depth reached"); > > + return NULL; > > + } > > + > > + switch (lex->token) { > > + case TOKEN_STRING: { > > + const char *value =3D lex->value.string.val; > > + size_t len =3D lex->value.string.len; > > + > > + if (!(flags & JSON_ALLOW_NUL)) { > > + if (memchr(value, '\0', len)) { > > + error_set(error, lex, json_error_null_character, > > + "\\u0000 is not allowed without JSON_AL= LOW_NUL"); > > + return NULL; > > + } > > + } > > + > > + json =3D jsonp_stringn_nocheck_own(value, len); > > + lex->value.string.val =3D NULL; > > + lex->value.string.len =3D 0; > > + break; > > + } > > + > > + case TOKEN_INTEGER: { > > + json =3D json_integer(lex->value.integer); > > + break; > > + } > > + > > + case TOKEN_REAL: { > > + json =3D json_real(lex->value.real); > > + break; > > + } > > + > > + case TOKEN_TRUE: > > + json =3D json_true(); > > + break; > > + > > + case TOKEN_FALSE: > > + json =3D json_false(); > > + break; > > + > > + case TOKEN_NULL: > > + json =3D json_null(); > > + break; > > + > > + case '{': > > + json =3D parse_object(lex, flags, error); > > + break; > > + > > + case '[': > > + json =3D parse_array(lex, flags, error); > > + break; > > + > > + case TOKEN_INVALID: > > + error_set(error, lex, json_error_invalid_syntax, "invalid= token"); > > + return NULL; > > + > > + default: > > + error_set(error, lex, json_error_invalid_syntax, "unexpec= ted > token"); > > + return NULL; > > + } > > + > > + if (!json) > > + return NULL; > > + > > + lex->depth--; > > + return json; > > +} > > + > > +static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *err= or) { > > + json_t *result; > > + > > + lex->depth =3D 0; > > + > > + lex_scan(lex, error); > > + if (!(flags & JSON_DECODE_ANY)) { > > + if (lex->token !=3D '[' && lex->token !=3D '{') { > > + error_set(error, lex, json_error_invalid_syntax, "'[' or = '{' expected"); > > + return NULL; > > + } > > + } > > + > > + result =3D parse_value(lex, flags, error); > > + if (!result) > > + return NULL; > > + > > + if (!(flags & JSON_DISABLE_EOF_CHECK)) { > > + lex_scan(lex, error); > > + if (lex->token !=3D TOKEN_EOF) { > > + error_set(error, lex, json_error_end_of_input_expected, > > + "end of file expected"); > > + json_decref(result); > > + return NULL; > > + } > > + } > > + > > + if (error) { > > + /* Save the position even though there was no error */ > > + error->position =3D (int)lex->stream.position; > > + } > > + > > + return result; > > +} > > + > > +typedef struct { > > + const char *data; > > + size_t pos; > > +} string_data_t; > > + > > +static int string_get(void *data) { > > + char c; > > + string_data_t *stream =3D (string_data_t *)data; > > + c =3D stream->data[stream->pos]; > > + if (c =3D=3D '\0') > > + return EOF; > > + else { > > + stream->pos++; > > + return (unsigned char)c; > > + } > > +} > > + > > +json_t *json_loads(const char *string, size_t flags, json_error_t *er= ror) { > > + lex_t lex; > > + json_t *result; > > + string_data_t stream_data; > > + > > + jsonp_error_init(error, ""); > > + > > + if (string =3D=3D NULL) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + stream_data.data =3D string; > > + stream_data.pos =3D 0; > > + > > + if (lex_init(&lex, string_get, flags, (void *)&stream_data)) > > + return NULL; > > + > > + result =3D parse_json(&lex, flags, error); > > + > > + lex_close(&lex); > > + return result; > > +} > > + > > +typedef struct { > > + const char *data; > > + size_t len; > > + size_t pos; > > +} buffer_data_t; > > + > > +static int buffer_get(void *data) { > > + char c; > > + buffer_data_t *stream =3D data; > > + if (stream->pos >=3D stream->len) > > + return EOF; > > + > > + c =3D stream->data[stream->pos]; > > + stream->pos++; > > + return (unsigned char)c; > > +} > > + > > +json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, > json_error_t *error) { > > + lex_t lex; > > + json_t *result; > > + buffer_data_t stream_data; > > + > > + jsonp_error_init(error, ""); > > + > > + if (buffer =3D=3D NULL) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + stream_data.data =3D buffer; > > + stream_data.pos =3D 0; > > + stream_data.len =3D buflen; > > + > > + if (lex_init(&lex, buffer_get, flags, (void *)&stream_data)) > > + return NULL; > > + > > + result =3D parse_json(&lex, flags, error); > > + > > + lex_close(&lex); > > + return result; > > +} > > + > > +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { > > + lex_t lex; > > + const char *source; > > + json_t *result; > > +#ifdef HAVE_UNISTD_H > > + if (input =3D=3D stdin) > > + source =3D ""; > > + else > > +#endif > > + source =3D ""; > > + > > + jsonp_error_init(error, source); > > + > > + if (input =3D=3D NULL) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + if (lex_init(&lex, (get_func)fgetc, flags, input)) > > + return NULL; > > + > > + result =3D parse_json(&lex, flags, error); > > + > > + lex_close(&lex); > > + return result; > > +} > > + > > +static int fd_get_func(int *fd) { > > +#ifdef HAVE_UNISTD_H > > + uint8_t c; > > + if (read(*fd, &c, 1) =3D=3D 1) > > + return c; > > +#endif > > + return EOF; > > +} > > + > > +json_t *json_loadfd(int input, size_t flags, json_error_t *error) { > > + lex_t lex; > > + const char *source; > > + json_t *result; > > + > > +#ifdef HAVE_UNISTD_H > > + if (input =3D=3D STDIN_FILENO) > > + source =3D ""; > > + else > > +#endif > > + source =3D ""; > > + > > + jsonp_error_init(error, source); > > + > > + if (input < 0) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + if (lex_init(&lex, (get_func)fd_get_func, flags, &input)) > > + return NULL; > > + > > + result =3D parse_json(&lex, flags, error); > > + > > + lex_close(&lex); > > + return result; > > +} > > + > > +json_t *json_load_file(const char *path, size_t flags, json_error_t *= error) > { > > + json_t *result; > > + FILE *fp; > > + > > + jsonp_error_init(error, path); > > + > > + if (path =3D=3D NULL) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + fp =3D fopen(path, "rb"); > > + if (!fp) { > > + error_set(error, NULL, json_error_cannot_open_file, "unable t= o > open %s: %s", path, > > + strerror(errno)); > > + return NULL; > > + } > > + > > + result =3D json_loadf(fp, flags, error); > > + > > + fclose(fp); > > + return result; > > +} > > + > > +#define MAX_BUF_LEN 1024 > > + > > +typedef struct { > > + char data[MAX_BUF_LEN]; > > + size_t len; > > + size_t pos; > > + json_load_callback_t callback; > > + void *arg; > > +} callback_data_t; > > + > > +static int callback_get(void *data) { > > + char c; > > + callback_data_t *stream =3D data; > > + > > + if (stream->pos >=3D stream->len) { > > + stream->pos =3D 0; > > + stream->len =3D stream->callback(stream->data, MAX_BUF_LEN, > stream->arg); > > + if (stream->len =3D=3D 0 || stream->len =3D=3D (size_t)-1) > > + return EOF; > > + } > > + > > + c =3D stream->data[stream->pos]; > > + stream->pos++; > > + return (unsigned char)c; > > +} > > + > > +json_t *json_load_callback(json_load_callback_t callback, void *arg, > size_t flags, > > + json_error_t *error) { > > + lex_t lex; > > + json_t *result; > > + > > + callback_data_t stream_data; > > + > > + memset(&stream_data, 0, sizeof(stream_data)); > > + stream_data.callback =3D callback; > > + stream_data.arg =3D arg; > > + > > + jsonp_error_init(error, ""); > > + > > + if (callback =3D=3D NULL) { > > + error_set(error, NULL, json_error_invalid_argument, "wrong > arguments"); > > + return NULL; > > + } > > + > > + if (lex_init(&lex, (get_func)callback_get, flags, &stream_data)) > > + return NULL; > > + > > + result =3D parse_json(&lex, flags, error); > > + > > + lex_close(&lex); > > + return result; > > +} > > diff --git a/RedfishPkg/RedfishPkg.ci.yaml > > b/RedfishPkg/RedfishPkg.ci.yaml index 9895fdac99..2a26769536 100644 > > --- a/RedfishPkg/RedfishPkg.ci.yaml > > +++ b/RedfishPkg/RedfishPkg.ci.yaml > > @@ -35,7 +35,13 @@ > > "Include/Crt/string.h", > > "Include/Crt/time.h", > > "Include/Library/CrtLib.h", > > - "Library/CrtLib/CrtLib.c" > > + "Library/CrtLib/CrtLib.c", > > + ## > > + ## For jansson library open source > > + ## load.c is overrided from open source. > > + "Library/JsonLib/load.c", > > + "Library/JsonLib/jansson_config.h", > > + "Library/JsonLib/jansson_private_config.h" > > ] > > }, > > "CompilerPlugin": { > > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec > > index 9a9a1190fb..6499d77f3e 100644 > > --- a/RedfishPkg/RedfishPkg.dec > > +++ b/RedfishPkg/RedfishPkg.dec > > @@ -18,6 +18,12 @@ > > > > [Includes.Common.Private] > > Include/Crt # Header files for C RTL. > > + Library/JsonLib # Header files for jansson configurat= ion files. > > + # - jansson_config.h > > + # - jansson_private_config.h > > + # jansson.h refers to above two confi= guration > > + # files for building platform jansson= library. > > + Library/JsonLib/jansson/src # For referring to jannson.h > > > > [LibraryClasses] > > ## @libraryclass Platform Redfish Host Interface Library @@ -39,6 > > +45,11 @@ > > # project). > > CrtLib|Include/Library/CrtLib.h > > > > + ## @libraryclass Provides the library functions based on third > > + party # jansson library to manipulate JSON data structure. > > + # > > + JsonLib|Include/Library/JsonLib.h > > + > > [Protocols] > > ## Include/Protocol/RedfishDiscover.h > > gEfiRedfishDiscoverProtocolGuid =3D { 0x5db12509, 0x4550, 0x43= 47, { 0x96, > 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }} > > -- > > 2.17.1 > > >=20 >=20 >=20 >=20