diff --git a/.github/workflows/sonar_check.yml b/.github/workflows/sonar_check.yml index 6a7c60478..87c480b35 100644 --- a/.github/workflows/sonar_check.yml +++ b/.github/workflows/sonar_check.yml @@ -28,7 +28,4 @@ jobs: uses: SonarSource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - with: - args: > - --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/docs/Modbus-Entity-Registers.md b/docs/Modbus-Entity-Registers.md index 7537555b8..0bfb8c00d 100644 --- a/docs/Modbus-Entity-Registers.md +++ b/docs/Modbus-Entity-Registers.md @@ -4446,7 +4446,7 @@ | hc1.seltemp | selected room temperature | int16 (>=0<=30) | C | true | HC | 0 | 1 | 1/2 | | hc1.currtemp | current room temperature | int16 (>=-3199<=3199) | C | false | HC | 1 | 1 | 1/10 | | hc1.haclimate | mqtt discovery current room temperature | enum [selTemp\|roomTemp] (>=5<=30) | | false | HC | 2 | 1 | 1 | -| hc1.mode | operating mode | enum [manual\|auto] | | false | HC | 3 | 1 | 1 | +| hc1.mode | operating mode | enum [off\|manual] | | true | HC | 3 | 1 | 1 | | hc1.targetflowtemp | target flow temperature | uint8 (>=0<=254) | C | false | HC | 18 | 1 | 1 | | hc1.heatingtype | heating type | enum [off\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 | @@ -4680,6 +4680,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -4719,6 +4721,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -4953,6 +4957,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -4992,6 +4998,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -5031,6 +5039,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -5070,6 +5080,8 @@ | errorcode | error code | string | | false | DEVICE_DATA | 0 | 8 | 1 | | lastcode | last error code | string | | false | DEVICE_DATA | 8 | 25 | 1 | | datetime | date/time | string | | true | DEVICE_DATA | 33 | 13 | 1 | +| display | display | enum [dhw temperature\|date\|external temperature] | | true | DEVICE_DATA | 65 | 1 | 1 | +| language | language | enum [german\|italian\|french\|dutch] | | true | DEVICE_DATA | 66 | 1 | 1 | | hybridstrategy | hybrid control strategy | enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix] | | true | DEVICE_DATA | 54 | 1 | 1 | | switchovertemp | outside switchover temperature | int8 (>=-20<=20) | C | true | DEVICE_DATA | 55 | 1 | 1 | | energycostratio | energy cost ratio | uint8 (>=0<=20) | | true | DEVICE_DATA | 56 | 1 | 1/10 | @@ -5243,7 +5255,7 @@ | hc1.seltemp | selected room temperature | int16 (>=0<=30) | C | true | HC | 0 | 1 | 1/2 | | hc1.currtemp | current room temperature | int16 (>=-3199<=3199) | C | false | HC | 1 | 1 | 1/10 | | hc1.haclimate | mqtt discovery current room temperature | enum [selTemp\|roomTemp] (>=5<=30) | | false | HC | 2 | 1 | 1 | -| hc1.mode | operating mode | enum [manual\|auto] | | false | HC | 3 | 1 | 1 | +| hc1.mode | operating mode | enum [off\|manual] | | true | HC | 3 | 1 | 1 | | hc1.targetflowtemp | target flow temperature | uint8 (>=0<=254) | C | false | HC | 18 | 1 | 1 | | hc1.heatingtype | heating type | enum [off\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 | diff --git a/docs/dump_entities.csv b/docs/dump_entities.csv index 6d65ece48..afe3a00a9 100644 --- a/docs/dump_entities.csv +++ b/docs/dump_entities.csv @@ -3815,7 +3815,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "CR11",thermostat,10,hc1.seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp,6,1,1/2,0,1 "CR11",thermostat,10,hc1.currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp,6,1,1/10,1,1 "CR11",thermostat,10,hc1.haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate,6,1,1,2,1 -"CR11",thermostat,10,hc1.mode,operating mode,enum [manual\|auto], ,false,sensor.thermostat_hc1_operating_mode,sensor.thermostat_hc1_mode,6,1,1,3,1 +"CR11",thermostat,10,hc1.mode,operating mode,enum [off\|manual], ,true,select.thermostat_hc1_operating_mode,select.thermostat_hc1_mode,6,1,1,3,1 "CR11",thermostat,10,hc1.targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp,6,1,1,18,1 "CR11",thermostat,10,hc1.heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1 "RC10",thermostat,65,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 @@ -4287,7 +4287,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp,6,1,1/2,0,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.currtemp,current room temperature,int16 (>=-3199<=3199),C,false,sensor.thermostat_hc1_current_room_temperature,sensor.thermostat_hc1_currtemp,6,1,1/10,1,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.haclimate,mqtt discovery current room temperature,enum [selTemp\|roomTemp] (>=5<=30), ,false,sensor.thermostat_hc1_mqtt_discovery_current_room_temperature,sensor.thermostat_hc1_haclimate,6,1,1,2,1 -"RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.mode,operating mode,enum [manual\|auto], ,false,sensor.thermostat_hc1_operating_mode,sensor.thermostat_hc1_mode,6,1,1,3,1 +"RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.mode,operating mode,enum [off\|manual], ,true,select.thermostat_hc1_operating_mode,select.thermostat_hc1_mode,6,1,1,3,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.targetflowtemp,target flow temperature,uint8 (>=0<=254),C,false,sensor.thermostat_hc1_target_flow_temperature,sensor.thermostat_hc1_targetflowtemp,6,1,1,18,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.heatingtype,heating type,enum [off\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1 "Rego 2000/3000",thermostat,172,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 @@ -4664,6 +4664,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FW100",thermostat,105,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FW100",thermostat,105,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FW100",thermostat,105,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FW100",thermostat,105,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FW100",thermostat,105,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FW100",thermostat,105,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FW100",thermostat,105,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FW100",thermostat,105,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 @@ -4699,6 +4701,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FW200",thermostat,106,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FW200",thermostat,106,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FW200",thermostat,106,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FW200",thermostat,106,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FW200",thermostat,106,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FW200",thermostat,106,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FW200",thermostat,106,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FW200",thermostat,106,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 @@ -4804,6 +4808,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FB10",thermostat,109,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FB10",thermostat,109,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FB10",thermostat,109,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FB10",thermostat,109,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FB10",thermostat,109,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FB10",thermostat,109,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FB10",thermostat,109,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FB10",thermostat,109,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 @@ -4839,6 +4845,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FB100",thermostat,110,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FB100",thermostat,110,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FB100",thermostat,110,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FB100",thermostat,110,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FB100",thermostat,110,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FB100",thermostat,110,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FB100",thermostat,110,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FB100",thermostat,110,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 @@ -4909,6 +4917,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FW500",thermostat,116,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FW500",thermostat,116,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FW500",thermostat,116,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FW500",thermostat,116,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FW500",thermostat,116,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FW500",thermostat,116,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FW500",thermostat,116,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FW500",thermostat,116,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 @@ -5014,6 +5024,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/ "FW120",thermostat,192,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 "FW120",thermostat,192,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 "FW120",thermostat,192,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 +"FW120",thermostat,192,display,display,enum [dhw temperature\|date\|external temperature], ,true,select.thermostat_display,select.thermostat_display,6,0,1,65,1 +"FW120",thermostat,192,language,language,enum [german\|italian\|french\|dutch], ,true,select.thermostat_language,select.thermostat_language,6,0,1,66,1 "FW120",thermostat,192,hybridstrategy,hybrid control strategy,enum [co2 optimized\|cost optimized\|outside temp switched\|co2 cost mix], ,true,select.thermostat_hybrid_control_strategy,select.thermostat_hybridstrategy,6,0,1,54,1 "FW120",thermostat,192,switchovertemp,outside switchover temperature,int8 (>=-20<=20),C,true,number.thermostat_outside_switchover_temperature,number.thermostat_switchovertemp,6,0,1,55,1 "FW120",thermostat,192,energycostratio,energy cost ratio,uint8 (>=0<=20), ,true,number.thermostat_energy_cost_ratio,number.thermostat_energycostratio,6,0,1/10,56,1 diff --git a/docs/dump_telegrams.csv b/docs/dump_telegrams.csv index bbd35d4c3..3e450696c 100644 --- a/docs/dump_telegrams.csv +++ b/docs/dump_telegrams.csv @@ -13,7 +13,7 @@ telegram_type_id,name,is_fetched 0x19,UBAMonitorSlow, 0x1A,UBASetPoints, 0x1C,UBAMaintenanceStatus, -0x1E,HydrTemp, +0x1E,WM10TempMessage, 0x23,JunkersSetMixer,fetched 0x27,UBASettingsWW,fetched 0x28,WeatherComp,fetched @@ -76,7 +76,7 @@ telegram_type_id,name,is_fetched 0x0103,ISM1StatusMessage,fetched 0x0104,ISM2StatusMessage, 0x010C,IPMStatusMessage, -0x011E,IPMTempMessage, +0x011E,JunkersDisp,fetched 0x012E,HPEnergy1, 0x013B,HPEnergy2, 0x0165,JunkersSet, @@ -111,8 +111,8 @@ telegram_type_id,name,is_fetched 0x02A0,RC300Curves, 0x02A1,RC300Curves, 0x02A2,RC300Curves, -0x02A5,RC300Monitor,fetched -0x02A6,RC300Monitor, +0x02A5,EasyMonitor, +0x02A6,CRFMonitor, 0x02A7,RC300Monitor, 0x02A8,CRFMonitor, 0x02A9,RC300Monitor, @@ -135,7 +135,7 @@ telegram_type_id,name,is_fetched 0x02BE,RC300Set, 0x02BF,RC300Set, 0x02C0,RC300Set, -0x02CC,RC300Set2, +0x02CC,HPPressure,fetched 0x02CD,MMPLUSConfigMessage,fetched 0x02CE,RC300Set2, 0x02D0,RC300Set2, diff --git a/interface/package.json b/interface/package.json index b3a599de4..1ad582085 100644 --- a/interface/package.json +++ b/interface/package.json @@ -25,8 +25,8 @@ "@alova/adapter-xhr": "2.2.1", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@mui/icons-material": "^7.3.2", - "@mui/material": "^7.3.2", + "@mui/icons-material": "^7.3.4", + "@mui/material": "^7.3.4", "@table-library/react-table-library": "4.1.15", "alova": "3.3.4", "async-validator": "^4.2.5", @@ -35,33 +35,33 @@ "magic-string": "^0.30.19", "mime-types": "^3.0.1", "preact": "^10.27.2", - "react": "^19.1.1", - "react-dom": "^19.1.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-icons": "^5.5.0", - "react-router": "^7.9.2", + "react-router": "^7.9.3", "react-toastify": "^11.0.5", "typesafe-i18n": "^5.26.2", - "typescript": "^5.9.2" + "typescript": "^5.9.3" }, "devDependencies": { "@babel/core": "^7.28.4", - "@eslint/js": "^9.36.0", + "@eslint/js": "^9.37.0", "@preact/compat": "^18.3.1", "@preact/preset-vite": "^2.10.2", "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^24.5.2", - "@types/react": "^19.1.13", - "@types/react-dom": "^19.1.9", + "@types/node": "^24.7.0", + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", "concurrently": "^9.2.1", - "eslint": "^9.36.0", + "eslint": "^9.37.0", "eslint-config-prettier": "^10.1.8", "prettier": "^3.6.2", - "rollup-plugin-visualizer": "^6.0.3", + "rollup-plugin-visualizer": "^6.0.4", "terser": "^5.44.0", - "typescript-eslint": "^8.44.1", - "vite": "^7.1.7", + "typescript-eslint": "^8.46.0", + "vite": "^7.1.9", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^5.1.4" }, - "packageManager": "pnpm@10.17.1" + "packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 516685851..6932055f8 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -13,19 +13,19 @@ importers: version: 2.2.1(alova@3.3.4) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.13)(react@19.1.1) + version: 11.14.0(@types/react@19.2.0)(react@19.2.0) '@emotion/styled': specifier: ^11.14.1 - version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) '@mui/icons-material': - specifier: ^7.3.2 - version: 7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + specifier: ^7.3.4 + version: 7.3.4(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) '@mui/material': - specifier: ^7.3.2 - version: 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^7.3.4 + version: 7.3.4(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@table-library/react-table-library': specifier: 4.1.15 - version: 4.1.15(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) alova: specifier: 3.3.4 version: 3.3.4 @@ -48,81 +48,81 @@ importers: specifier: ^10.27.2 version: 10.27.2 react: - specifier: ^19.1.1 - version: 19.1.1 + specifier: ^19.2.0 + version: 19.2.0 react-dom: - specifier: ^19.1.1 - version: 19.1.1(react@19.1.1) + specifier: ^19.2.0 + version: 19.2.0(react@19.2.0) react-icons: specifier: ^5.5.0 - version: 5.5.0(react@19.1.1) + version: 5.5.0(react@19.2.0) react-router: - specifier: ^7.9.2 - version: 7.9.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^7.9.3 + version: 7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react-toastify: specifier: ^11.0.5 - version: 11.0.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 11.0.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) typesafe-i18n: specifier: ^5.26.2 - version: 5.26.2(typescript@5.9.2) + version: 5.26.2(typescript@5.9.3) typescript: - specifier: ^5.9.2 - version: 5.9.2 + specifier: ^5.9.3 + version: 5.9.3 devDependencies: '@babel/core': specifier: ^7.28.4 version: 7.28.4 '@eslint/js': - specifier: ^9.36.0 - version: 9.36.0 + specifier: ^9.37.0 + version: 9.37.0 '@preact/compat': specifier: ^18.3.1 version: 18.3.1(preact@10.27.2) '@preact/preset-vite': specifier: ^2.10.2 - version: 2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) + version: 2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)) '@trivago/prettier-plugin-sort-imports': specifier: ^5.2.2 version: 5.2.2(prettier@3.6.2) '@types/node': - specifier: ^24.5.2 - version: 24.5.2 + specifier: ^24.7.0 + version: 24.7.0 '@types/react': - specifier: ^19.1.13 - version: 19.1.13 + specifier: ^19.2.0 + version: 19.2.0 '@types/react-dom': - specifier: ^19.1.9 - version: 19.1.9(@types/react@19.1.13) + specifier: ^19.2.0 + version: 19.2.0(@types/react@19.2.0) concurrently: specifier: ^9.2.1 version: 9.2.1 eslint: - specifier: ^9.36.0 - version: 9.36.0 + specifier: ^9.37.0 + version: 9.37.0 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.36.0) + version: 10.1.8(eslint@9.37.0) prettier: specifier: ^3.6.2 version: 3.6.2 rollup-plugin-visualizer: - specifier: ^6.0.3 - version: 6.0.3(rollup@4.52.2) + specifier: ^6.0.4 + version: 6.0.4(rollup@4.52.4) terser: specifier: ^5.44.0 version: 5.44.0 typescript-eslint: - specifier: ^8.44.1 - version: 8.44.1(eslint@9.36.0)(typescript@5.9.2) + specifier: ^8.46.0 + version: 8.46.0(eslint@9.37.0)(typescript@5.9.3) vite: - specifier: ^7.1.7 - version: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + specifier: ^7.1.9 + version: 7.1.9(@types/node@24.7.0)(terser@5.44.0) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) + version: 0.6.1(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)) packages: @@ -461,28 +461,28 @@ packages: resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.3.1': - resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + '@eslint/config-helpers@0.4.0': + resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + '@eslint/core@0.16.0': + resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.36.0': - resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} + '@eslint/js@9.37.0': + resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + '@eslint/plugin-kit@0.4.0': + resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': @@ -528,27 +528,27 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@mui/core-downloads-tracker@7.3.2': - resolution: {integrity: sha512-AOyfHjyDKVPGJJFtxOlept3EYEdLoar/RvssBTWVAvDJGIE676dLi2oT/Kx+FoVXFoA/JdV7DEMq/BVWV3KHRw==} + '@mui/core-downloads-tracker@7.3.4': + resolution: {integrity: sha512-BIktMapG3r4iXwIhYNpvk97ZfYWTreBBQTWjQKbNbzI64+ULHfYavQEX2w99aSWHS58DvXESWIgbD9adKcUOBw==} - '@mui/icons-material@7.3.2': - resolution: {integrity: sha512-TZWazBjWXBjR6iGcNkbKklnwodcwj0SrChCNHc9BhD9rBgET22J1eFhHsEmvSvru9+opDy3umqAimQjokhfJlQ==} + '@mui/icons-material@7.3.4': + resolution: {integrity: sha512-9n6Xcq7molXWYb680N2Qx+FRW8oT6j/LXF5PZFH3ph9X/Rct0B/BlLAsFI7iL9ySI6LVLuQIVtrLiPT82R7OZw==} engines: {node: '>=14.0.0'} peerDependencies: - '@mui/material': ^7.3.2 + '@mui/material': ^7.3.4 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/material@7.3.2': - resolution: {integrity: sha512-qXvbnawQhqUVfH1LMgMaiytP+ZpGoYhnGl7yYq2x57GYzcFL/iPzSZ3L30tlbwEjSVKNYcbiKO8tANR1tadjUg==} + '@mui/material@7.3.4': + resolution: {integrity: sha512-gEQL9pbJZZHT7lYJBKQCS723v1MGys2IFc94COXbUIyCTWa+qC77a7hUax4Yjd5ggEm35dk4AyYABpKKWC4MLw==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material-pigment-css': ^7.3.2 + '@mui/material-pigment-css': ^7.3.3 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -562,8 +562,8 @@ packages: '@types/react': optional: true - '@mui/private-theming@7.3.2': - resolution: {integrity: sha512-ha7mFoOyZGJr75xeiO9lugS3joRROjc8tG1u4P50dH0KR7bwhHznVMcYg7MouochUy0OxooJm/OOSpJ7gKcMvg==} + '@mui/private-theming@7.3.3': + resolution: {integrity: sha512-OJM+9nj5JIyPUvsZ5ZjaeC9PfktmK+W5YaVLToLR8L0lB/DGmv1gcKE43ssNLSvpoW71Hct0necfade6+kW3zQ==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -572,8 +572,8 @@ packages: '@types/react': optional: true - '@mui/styled-engine@7.3.2': - resolution: {integrity: sha512-PkJzW+mTaek4e0nPYZ6qLnW5RGa0KN+eRTf5FA2nc7cFZTeM+qebmGibaTLrgQBy3UpcpemaqfzToBNkzuxqew==} + '@mui/styled-engine@7.3.3': + resolution: {integrity: sha512-CmFxvRJIBCEaWdilhXMw/5wFJ1+FT9f3xt+m2pPXhHPeVIbBg9MnMvNSJjdALvnQJMPw8jLhrUtXmN7QAZV2fw==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -585,8 +585,8 @@ packages: '@emotion/styled': optional: true - '@mui/system@7.3.2': - resolution: {integrity: sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA==} + '@mui/system@7.3.3': + resolution: {integrity: sha512-Lqq3emZr5IzRLKaHPuMaLBDVaGvxoh6z7HMWd1RPKawBM5uMRaQ4ImsmmgXWtwJdfZux5eugfDhXJUo2mliS8Q==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -601,16 +601,16 @@ packages: '@types/react': optional: true - '@mui/types@7.4.6': - resolution: {integrity: sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==} + '@mui/types@7.4.7': + resolution: {integrity: sha512-8vVje9rdEr1rY8oIkYgP+Su5Kwl6ik7O3jQ0wl78JGSmiZhRHV+vkjooGdKD8pbtZbutXFVTWQYshu2b3sG9zw==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/utils@7.3.2': - resolution: {integrity: sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==} + '@mui/utils@7.3.3': + resolution: {integrity: sha512-kwNAUh7bLZ7mRz9JZ+6qfRnnxbE4Zuc+RzXnhSpRSxjTlSTj7b4JxRLXpG+MVtPVtqks5k/XC8No1Vs3x4Z2gg==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -655,8 +655,8 @@ packages: '@prefresh/babel-plugin@0.5.2': resolution: {integrity: sha512-AOl4HG6dAxWkJ5ndPHBgBa49oo/9bOiJuRDKHLSTyH+Fd9x00shTXpdiTj1W41l6oQIwUOAgJeHMn4QwIDpHkA==} - '@prefresh/core@1.5.7': - resolution: {integrity: sha512-AsyeitiPwG7UkT0mqgKzIDuydmYSKtBlzXEb5ymzskvxewcmVGRjQkcHDy6PCNBT7soAyHpQ0mPgXX4IeyOlUg==} + '@prefresh/core@1.5.8': + resolution: {integrity: sha512-T7HMpakS1iPVCFZvfDLMGyrWAcO3toUN9/RkJUqqoRr/vNhQrZgHjidfhq3awDzAQtw1emDWH8dsOeu0DWqtgA==} peerDependencies: preact: ^10.0.0 || ^11.0.0-0 @@ -673,113 +673,113 @@ packages: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - '@rollup/rollup-android-arm-eabi@4.52.2': - resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} + '@rollup/rollup-android-arm-eabi@4.52.4': + resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.52.2': - resolution: {integrity: sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==} + '@rollup/rollup-android-arm64@4.52.4': + resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.52.2': - resolution: {integrity: sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==} + '@rollup/rollup-darwin-arm64@4.52.4': + resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.52.2': - resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==} + '@rollup/rollup-darwin-x64@4.52.4': + resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.52.2': - resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==} + '@rollup/rollup-freebsd-arm64@4.52.4': + resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.52.2': - resolution: {integrity: sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==} + '@rollup/rollup-freebsd-x64@4.52.4': + resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': - resolution: {integrity: sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': + resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.52.2': - resolution: {integrity: sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==} + '@rollup/rollup-linux-arm-musleabihf@4.52.4': + resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.52.2': - resolution: {integrity: sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==} + '@rollup/rollup-linux-arm64-gnu@4.52.4': + resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.52.2': - resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==} + '@rollup/rollup-linux-arm64-musl@4.52.4': + resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.52.2': - resolution: {integrity: sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==} + '@rollup/rollup-linux-loong64-gnu@4.52.4': + resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.52.2': - resolution: {integrity: sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==} + '@rollup/rollup-linux-ppc64-gnu@4.52.4': + resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.52.2': - resolution: {integrity: sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==} + '@rollup/rollup-linux-riscv64-gnu@4.52.4': + resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.52.2': - resolution: {integrity: sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==} + '@rollup/rollup-linux-riscv64-musl@4.52.4': + resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.52.2': - resolution: {integrity: sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==} + '@rollup/rollup-linux-s390x-gnu@4.52.4': + resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.52.2': - resolution: {integrity: sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==} + '@rollup/rollup-linux-x64-gnu@4.52.4': + resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.52.2': - resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==} + '@rollup/rollup-linux-x64-musl@4.52.4': + resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.52.2': - resolution: {integrity: sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==} + '@rollup/rollup-openharmony-arm64@4.52.4': + resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.52.2': - resolution: {integrity: sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==} + '@rollup/rollup-win32-arm64-msvc@4.52.4': + resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.52.2': - resolution: {integrity: sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==} + '@rollup/rollup-win32-ia32-msvc@4.52.4': + resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.52.2': - resolution: {integrity: sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==} + '@rollup/rollup-win32-x64-gnu@4.52.4': + resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.52.2': - resolution: {integrity: sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==} + '@rollup/rollup-win32-x64-msvc@4.52.4': + resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==} cpu: [x64] os: [win32] @@ -851,8 +851,8 @@ packages: resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/node@24.7.0': + resolution: {integrity: sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -860,18 +860,18 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react-dom@19.1.9': - resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} + '@types/react-dom@19.2.0': + resolution: {integrity: sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg==} peerDependencies: - '@types/react': ^19.0.0 + '@types/react': ^19.2.0 '@types/react-transition-group@4.4.12': resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: '@types/react': '*' - '@types/react@19.1.13': - resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} + '@types/react@19.2.0': + resolution: {integrity: sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -879,63 +879,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.44.1': - resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} + '@typescript-eslint/eslint-plugin@8.46.0': + resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.44.1 + '@typescript-eslint/parser': ^8.46.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.44.1': - resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} + '@typescript-eslint/parser@8.46.0': + resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.44.1': - resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} + '@typescript-eslint/project-service@8.46.0': + resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.44.1': - resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} + '@typescript-eslint/scope-manager@8.46.0': + resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.44.1': - resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} + '@typescript-eslint/tsconfig-utils@8.46.0': + resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.44.1': - resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} + '@typescript-eslint/type-utils@8.46.0': + resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.44.1': - resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} + '@typescript-eslint/types@8.46.0': + resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.44.1': - resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} + '@typescript-eslint/typescript-estree@8.46.0': + resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.44.1': - resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} + '@typescript-eslint/utils@8.46.0': + resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.44.1': - resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} + '@typescript-eslint/visitor-keys@8.46.0': + resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -1014,8 +1014,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.7: - resolution: {integrity: sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==} + baseline-browser-mapping@2.8.12: + resolution: {integrity: sha512-vAPMQdnyKCBtkmQA6FMCBvU9qFIppS3nzyXnEM+Lo2IAhG4Mpjv9cCxMudhgV3YdNNJv6TNqXy97dfRVL2LmaQ==} hasBin: true bin-build@3.0.0: @@ -1054,8 +1054,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.26.2: - resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} + browserslist@4.26.3: + resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1104,8 +1104,8 @@ packages: resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001745: - resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} + caniuse-lite@1.0.30001748: + resolution: {integrity: sha512-5P5UgAr0+aBmNiplks08JLw+AW/XG/SurlgZLgB1dDLfAw7EfRGxIwzPHxdSCGY/BTKDqIVyJL87cCN6s0ZR0w==} caw@2.0.1: resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==} @@ -1324,8 +1324,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.223: - resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} + electron-to-chromium@1.5.231: + resolution: {integrity: sha512-cyl6vqZGkEBnz/PmvFHn/u9G/hbo+FF2CNAOXriG87QOeLsUdifCZ9UbHNscE9wGdrC8XstNMli0CbQnZQ+fkA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1515,8 +1515,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.36.0: - resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} + eslint@9.37.0: + resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2238,8 +2238,8 @@ packages: node-html-parser@6.1.13: resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - node-releases@2.0.21: - resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + node-releases@2.0.23: + resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2489,10 +2489,10 @@ packages: rate-limiter-flexible@5.0.5: resolution: {integrity: sha512-+/dSQfo+3FYwYygUs/V2BBdwGa9nFtakDwKt4l0bnvNB53TNT++QSFewwHX9qXrZJuMe9j+TUaU21lm5ARgqdQ==} - react-dom@19.1.1: - resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: - react: ^19.1.1 + react: ^19.2.0 react-icons@5.5.0: resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} @@ -2502,11 +2502,11 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@19.1.1: - resolution: {integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==} + react-is@19.2.0: + resolution: {integrity: sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==} - react-router@7.9.2: - resolution: {integrity: sha512-i2TPp4dgaqrOqiRGLZmqh2WXmbdFknUyiCRmSKs0hf6fWXkTKg5h56b+9F22NbGRAMxjYfqQnpi63egzD2SuZA==} + react-router@7.9.3: + resolution: {integrity: sha512-4o2iWCFIwhI/eYAIL43+cjORXYn/aRQPgtFRRZb3VzoyQ5Uej0Bmqj7437L97N9NJW4wnicSwLOLS+yCXfAPgg==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -2540,8 +2540,8 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} read-pkg-up@1.0.1: @@ -2592,8 +2592,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup-plugin-visualizer@6.0.3: - resolution: {integrity: sha512-ZU41GwrkDcCpVoffviuM9Clwjy5fcUxlz0oMoTXTYsK+tcIFzbdacnrr2n8TXcHxbGKKXtOdjxM2HUS4HjkwIw==} + rollup-plugin-visualizer@6.0.4: + resolution: {integrity: sha512-q8Q7J/6YofkmaGW1sH/fPRAz37x/+pd7VBuaUU7lwvOS/YikuiiEU9jeb9PH8XHiq50XFrUsBbOxeAMYQ7KZkg==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -2605,8 +2605,8 @@ packages: rollup: optional: true - rollup@4.52.2: - resolution: {integrity: sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==} + rollup@4.52.4: + resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2622,8 +2622,8 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} seek-bzip@1.0.6: resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} @@ -2904,23 +2904,23 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.44.1: - resolution: {integrity: sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==} + typescript-eslint@8.46.0: + resolution: {integrity: sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - undici-types@7.12.0: - resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + undici-types@7.14.0: + resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -2976,8 +2976,8 @@ packages: vite: optional: true - vite@7.1.7: - resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} + vite@7.1.9: + resolution: {integrity: sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3126,7 +3126,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.2 + browserslist: 4.26.3 lru-cache: 5.1.1 semver: 6.3.1 @@ -3245,19 +3245,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1)': + '@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 transitivePeerDependencies: - supports-color @@ -3271,26 +3271,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.0) '@emotion/utils': 1.4.2 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.1)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.0)': dependencies: - react: 19.1.1 + react: 19.2.0 '@emotion/utils@1.4.2': {} @@ -3377,9 +3377,9 @@ snapshots: '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0)': dependencies: - eslint: 9.36.0 + eslint: 9.37.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -3392,9 +3392,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.1': {} + '@eslint/config-helpers@0.4.0': + dependencies: + '@eslint/core': 0.16.0 - '@eslint/core@0.15.2': + '@eslint/core@0.16.0': dependencies: '@types/json-schema': 7.0.15 @@ -3412,13 +3414,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.36.0': {} + '@eslint/js@9.37.0': {} '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.3.5': + '@eslint/plugin-kit@0.4.0': dependencies: - '@eslint/core': 0.15.2 + '@eslint/core': 0.16.0 levn: 0.4.1 '@humanfs/core@0.19.1': {} @@ -3462,47 +3464,47 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@mui/core-downloads-tracker@7.3.2': {} + '@mui/core-downloads-tracker@7.3.4': {} - '@mui/icons-material@7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': + '@mui/icons-material@7.3.4(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 - '@mui/material': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - react: 19.1.1 + '@mui/material': 7.3.4(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 - '@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 - '@mui/core-downloads-tracker': 7.3.2 - '@mui/system': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) - '@mui/types': 7.4.6(@types/react@19.1.13) - '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) + '@mui/core-downloads-tracker': 7.3.4 + '@mui/system': 7.3.3(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) + '@mui/types': 7.4.7(@types/react@19.2.0) + '@mui/utils': 7.3.3(@types/react@19.2.0)(react@19.2.0) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.1.13) + '@types/react-transition-group': 4.4.12(@types/react@19.2.0) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-is: 19.1.1 - react-transition-group: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-is: 19.2.0 + react-transition-group: 4.4.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) - '@types/react': 19.1.13 + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) + '@types/react': 19.2.0 - '@mui/private-theming@7.3.2(@types/react@19.1.13)(react@19.1.1)': + '@mui/private-theming@7.3.3(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 - '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) + '@mui/utils': 7.3.3(@types/react@19.2.0)(react@19.2.0) prop-types: 15.8.1 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 - '@mui/styled-engine@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(react@19.1.1)': + '@mui/styled-engine@7.3.3(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 '@emotion/cache': 11.14.0 @@ -3510,44 +3512,44 @@ snapshots: '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) - '@mui/system@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': + '@mui/system@7.3.3(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 - '@mui/private-theming': 7.3.2(@types/react@19.1.13)(react@19.1.1) - '@mui/styled-engine': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(react@19.1.1) - '@mui/types': 7.4.6(@types/react@19.1.13) - '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) + '@mui/private-theming': 7.3.3(@types/react@19.2.0)(react@19.2.0) + '@mui/styled-engine': 7.3.3(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0))(react@19.2.0) + '@mui/types': 7.4.7(@types/react@19.2.0) + '@mui/utils': 7.3.3(@types/react@19.2.0)(react@19.2.0) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.1.1 + react: 19.2.0 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) - '@types/react': 19.1.13 + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react@19.2.0) + '@types/react': 19.2.0 - '@mui/types@7.4.6(@types/react@19.1.13)': + '@mui/types@7.4.7(@types/react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 - '@mui/utils@7.3.2(@types/react@19.1.13)(react@19.1.1)': + '@mui/utils@7.3.3(@types/react@19.2.0)(react@19.2.0)': dependencies: '@babel/runtime': 7.28.4 - '@mui/types': 7.4.6(@types/react@19.1.13) + '@mui/types': 7.4.7(@types/react@19.2.0) '@types/prop-types': 15.7.15 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.1.1 - react-is: 19.1.1 + react: 19.2.0 + react-is: 19.2.0 optionalDependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 '@noble/hashes@1.8.0': {} @@ -3573,39 +3575,39 @@ snapshots: dependencies: preact: 10.27.2 - '@preact/preset-vite@2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0))': + '@preact/preset-vite@2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4) - '@prefresh/vite': 2.4.10(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) + '@prefresh/vite': 2.4.10(preact@10.27.2)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)) '@rollup/pluginutils': 4.2.1 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.4) debug: 4.4.3 picocolors: 1.1.1 - vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) - vite-prerender-plugin: 0.5.12(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) + vite: 7.1.9(@types/node@24.7.0)(terser@5.44.0) + vite-prerender-plugin: 0.5.12(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)) transitivePeerDependencies: - preact - supports-color '@prefresh/babel-plugin@0.5.2': {} - '@prefresh/core@1.5.7(preact@10.27.2)': + '@prefresh/core@1.5.8(preact@10.27.2)': dependencies: preact: 10.27.2 '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.10(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0))': + '@prefresh/vite@2.4.10(preact@10.27.2)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0))': dependencies: '@babel/core': 7.28.4 '@prefresh/babel-plugin': 0.5.2 - '@prefresh/core': 1.5.7(preact@10.27.2) + '@prefresh/core': 1.5.8(preact@10.27.2) '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 preact: 10.27.2 - vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + vite: 7.1.9(@types/node@24.7.0)(terser@5.44.0) transitivePeerDependencies: - supports-color @@ -3614,82 +3616,82 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/rollup-android-arm-eabi@4.52.2': + '@rollup/rollup-android-arm-eabi@4.52.4': optional: true - '@rollup/rollup-android-arm64@4.52.2': + '@rollup/rollup-android-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-arm64@4.52.2': + '@rollup/rollup-darwin-arm64@4.52.4': optional: true - '@rollup/rollup-darwin-x64@4.52.2': + '@rollup/rollup-darwin-x64@4.52.4': optional: true - '@rollup/rollup-freebsd-arm64@4.52.2': + '@rollup/rollup-freebsd-arm64@4.52.4': optional: true - '@rollup/rollup-freebsd-x64@4.52.2': + '@rollup/rollup-freebsd-x64@4.52.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.52.2': + '@rollup/rollup-linux-arm-gnueabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.52.2': + '@rollup/rollup-linux-arm-musleabihf@4.52.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.52.2': + '@rollup/rollup-linux-arm64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.52.2': + '@rollup/rollup-linux-arm64-musl@4.52.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.52.2': + '@rollup/rollup-linux-loong64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.52.2': + '@rollup/rollup-linux-ppc64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.52.2': + '@rollup/rollup-linux-riscv64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.52.2': + '@rollup/rollup-linux-riscv64-musl@4.52.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.52.2': + '@rollup/rollup-linux-s390x-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.52.2': + '@rollup/rollup-linux-x64-gnu@4.52.4': optional: true - '@rollup/rollup-linux-x64-musl@4.52.2': + '@rollup/rollup-linux-x64-musl@4.52.4': optional: true - '@rollup/rollup-openharmony-arm64@4.52.2': + '@rollup/rollup-openharmony-arm64@4.52.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.52.2': + '@rollup/rollup-win32-arm64-msvc@4.52.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.52.2': + '@rollup/rollup-win32-ia32-msvc@4.52.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.52.2': + '@rollup/rollup-win32-x64-gnu@4.52.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.52.2': + '@rollup/rollup-win32-x64-msvc@4.52.4': optional: true '@sindresorhus/is@0.7.0': {} - '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.2.0)(react@19.2.0) clsx: 1.1.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - react-virtualized-auto-sizer: 1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - react-window: 1.8.11(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react-window: 1.8.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)': dependencies: @@ -3710,7 +3712,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 24.5.2 + '@types/node': 24.7.0 '@types/imagemin-gifsicle@7.0.4': dependencies: @@ -3739,137 +3741,137 @@ snapshots: '@types/imagemin@7.0.1': dependencies: - '@types/node': 24.5.2 + '@types/node': 24.7.0 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 24.5.2 + '@types/node': 24.7.0 '@types/minimatch@6.0.0': dependencies: minimatch: 10.0.3 - '@types/node@24.5.2': + '@types/node@24.7.0': dependencies: - undici-types: 7.12.0 + undici-types: 7.14.0 '@types/parse-json@4.0.2': {} '@types/prop-types@15.7.15': {} - '@types/react-dom@19.1.9(@types/react@19.1.13)': + '@types/react-dom@19.2.0(@types/react@19.2.0)': dependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 - '@types/react-transition-group@4.4.12(@types/react@19.1.13)': + '@types/react-transition-group@4.4.12(@types/react@19.2.0)': dependencies: - '@types/react': 19.1.13 + '@types/react': 19.2.0 - '@types/react@19.1.13': + '@types/react@19.2.0': dependencies: csstype: 3.1.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 24.5.2 + '@types/node': 24.7.0 '@types/svgo@2.6.4': dependencies: - '@types/node': 24.5.2 + '@types/node': 24.7.0 - '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 - eslint: 9.36.0 + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.0 + eslint: 9.37.0 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2)': + '@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.0 debug: 4.4.3 - eslint: 9.36.0 - typescript: 5.9.2 + eslint: 9.37.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': + '@typescript-eslint/project-service@8.46.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) + '@typescript-eslint/types': 8.46.0 debug: 4.4.3 - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.44.1': + '@typescript-eslint/scope-manager@8.46.0': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/visitor-keys': 8.46.0 - '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.46.0(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) debug: 4.4.3 - eslint: 9.36.0 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + eslint: 9.37.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.44.1': {} + '@typescript-eslint/types@8.46.0': {} - '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/project-service': 8.46.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/visitor-keys': 8.46.0 debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.9.2) - typescript: 5.9.2 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': + '@typescript-eslint/utils@8.46.0(eslint@9.37.0)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - eslint: 9.36.0 - typescript: 5.9.2 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) + '@typescript-eslint/scope-manager': 8.46.0 + '@typescript-eslint/types': 8.46.0 + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + eslint: 9.37.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.44.1': + '@typescript-eslint/visitor-keys@8.46.0': dependencies: - '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/types': 8.46.0 eslint-visitor-keys: 4.2.1 acorn-jsx@5.3.2(acorn@8.15.0): @@ -3934,7 +3936,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.8.7: {} + baseline-browser-mapping@2.8.12: {} bin-build@3.0.0: dependencies: @@ -3989,13 +3991,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.26.2: + browserslist@4.26.3: dependencies: - baseline-browser-mapping: 2.8.7 - caniuse-lite: 1.0.30001745 - electron-to-chromium: 1.5.223 - node-releases: 2.0.21 - update-browserslist-db: 1.1.3(browserslist@4.26.2) + baseline-browser-mapping: 2.8.12 + caniuse-lite: 1.0.30001748 + electron-to-chromium: 1.5.231 + node-releases: 2.0.23 + update-browserslist-db: 1.1.3(browserslist@4.26.3) buffer-alloc-unsafe@1.1.0: {} @@ -4051,7 +4053,7 @@ snapshots: camelcase@2.1.1: {} - caniuse-lite@1.0.30001745: {} + caniuse-lite@1.0.30001748: {} caw@2.0.1: dependencies: @@ -4338,7 +4340,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.223: {} + electron-to-chromium@1.5.231: {} emoji-regex@8.0.0: {} @@ -4481,9 +4483,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.36.0): + eslint-config-prettier@10.1.8(eslint@9.37.0): dependencies: - eslint: 9.36.0 + eslint: 9.37.0 eslint-scope@8.4.0: dependencies: @@ -4494,16 +4496,16 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.36.0: + eslint@9.37.0: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.1 - '@eslint/core': 0.15.2 + '@eslint/config-helpers': 0.4.0 + '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.36.0 - '@eslint/plugin-kit': 0.3.5 + '@eslint/js': 9.37.0 + '@eslint/plugin-kit': 0.4.0 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -5261,7 +5263,7 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.21: {} + node-releases@2.0.23: {} normalize-package-data@2.5.0: dependencies: @@ -5483,55 +5485,55 @@ snapshots: rate-limiter-flexible@5.0.5: {} - react-dom@19.1.1(react@19.1.1): + react-dom@19.2.0(react@19.2.0): dependencies: - react: 19.1.1 - scheduler: 0.26.0 + react: 19.2.0 + scheduler: 0.27.0 - react-icons@5.5.0(react@19.1.1): + react-icons@5.5.0(react@19.2.0): dependencies: - react: 19.1.1 + react: 19.2.0 react-is@16.13.1: {} - react-is@19.1.1: {} + react-is@19.2.0: {} - react-router@7.9.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-router@7.9.3(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: cookie: 1.0.2 - react: 19.1.1 + react: 19.2.0 set-cookie-parser: 2.7.1 optionalDependencies: - react-dom: 19.1.1(react@19.1.1) + react-dom: 19.2.0(react@19.2.0) - react-toastify@11.0.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-toastify@11.0.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: clsx: 2.1.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react-transition-group@4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-transition-group@4.4.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@babel/runtime': 7.28.4 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react-virtualized-auto-sizer@1.0.26(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-virtualized-auto-sizer@1.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react-window@1.8.11(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-window@1.8.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: '@babel/runtime': 7.28.4 memoize-one: 5.2.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) - react@19.1.1: {} + react@19.2.0: {} read-pkg-up@1.0.1: dependencies: @@ -5585,41 +5587,41 @@ snapshots: dependencies: glob: 7.2.3 - rollup-plugin-visualizer@6.0.3(rollup@4.52.2): + rollup-plugin-visualizer@6.0.4(rollup@4.52.4): dependencies: open: 8.4.2 picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: - rollup: 4.52.2 + rollup: 4.52.4 - rollup@4.52.2: + rollup@4.52.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.52.2 - '@rollup/rollup-android-arm64': 4.52.2 - '@rollup/rollup-darwin-arm64': 4.52.2 - '@rollup/rollup-darwin-x64': 4.52.2 - '@rollup/rollup-freebsd-arm64': 4.52.2 - '@rollup/rollup-freebsd-x64': 4.52.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.52.2 - '@rollup/rollup-linux-arm-musleabihf': 4.52.2 - '@rollup/rollup-linux-arm64-gnu': 4.52.2 - '@rollup/rollup-linux-arm64-musl': 4.52.2 - '@rollup/rollup-linux-loong64-gnu': 4.52.2 - '@rollup/rollup-linux-ppc64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-gnu': 4.52.2 - '@rollup/rollup-linux-riscv64-musl': 4.52.2 - '@rollup/rollup-linux-s390x-gnu': 4.52.2 - '@rollup/rollup-linux-x64-gnu': 4.52.2 - '@rollup/rollup-linux-x64-musl': 4.52.2 - '@rollup/rollup-openharmony-arm64': 4.52.2 - '@rollup/rollup-win32-arm64-msvc': 4.52.2 - '@rollup/rollup-win32-ia32-msvc': 4.52.2 - '@rollup/rollup-win32-x64-gnu': 4.52.2 - '@rollup/rollup-win32-x64-msvc': 4.52.2 + '@rollup/rollup-android-arm-eabi': 4.52.4 + '@rollup/rollup-android-arm64': 4.52.4 + '@rollup/rollup-darwin-arm64': 4.52.4 + '@rollup/rollup-darwin-x64': 4.52.4 + '@rollup/rollup-freebsd-arm64': 4.52.4 + '@rollup/rollup-freebsd-x64': 4.52.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.4 + '@rollup/rollup-linux-arm-musleabihf': 4.52.4 + '@rollup/rollup-linux-arm64-gnu': 4.52.4 + '@rollup/rollup-linux-arm64-musl': 4.52.4 + '@rollup/rollup-linux-loong64-gnu': 4.52.4 + '@rollup/rollup-linux-ppc64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-gnu': 4.52.4 + '@rollup/rollup-linux-riscv64-musl': 4.52.4 + '@rollup/rollup-linux-s390x-gnu': 4.52.4 + '@rollup/rollup-linux-x64-gnu': 4.52.4 + '@rollup/rollup-linux-x64-musl': 4.52.4 + '@rollup/rollup-openharmony-arm64': 4.52.4 + '@rollup/rollup-win32-arm64-msvc': 4.52.4 + '@rollup/rollup-win32-ia32-msvc': 4.52.4 + '@rollup/rollup-win32-x64-gnu': 4.52.4 + '@rollup/rollup-win32-x64-msvc': 4.52.4 fsevents: 2.3.3 run-parallel@1.2.0: @@ -5634,7 +5636,7 @@ snapshots: safe-buffer@5.2.1: {} - scheduler@0.26.0: {} + scheduler@0.27.0: {} seek-bzip@1.0.6: dependencies: @@ -5853,13 +5855,13 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - ts-api-utils@2.1.0(typescript@5.9.2): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - tsconfck@3.1.6(typescript@5.9.2): + tsconfck@3.1.6(typescript@5.9.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 tslib@2.8.1: {} @@ -5879,35 +5881,35 @@ snapshots: es-errors: 1.3.0 is-typed-array: 1.1.15 - typesafe-i18n@5.26.2(typescript@5.9.2): + typesafe-i18n@5.26.2(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - typescript-eslint@8.44.1(eslint@9.36.0)(typescript@5.9.2): + typescript-eslint@8.46.0(eslint@9.37.0)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2) - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) - eslint: 9.36.0 - typescript: 5.9.2 + '@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.0(eslint@9.37.0)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.0(eslint@9.37.0)(typescript@5.9.3) + eslint: 9.37.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - typescript@5.9.2: {} + typescript@5.9.3: {} unbzip2-stream@1.4.3: dependencies: buffer: 5.7.1 through: 2.3.8 - undici-types@7.12.0: {} + undici-types@7.14.0: {} universalify@2.0.1: {} - update-browserslist-db@1.1.3(browserslist@4.26.2): + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: - browserslist: 4.26.2 + browserslist: 4.26.3 escalade: 3.2.0 picocolors: 1.1.1 @@ -5934,7 +5936,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-imagemin@0.6.1(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): + vite-plugin-imagemin@0.6.1(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -5959,11 +5961,11 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + vite: 7.1.9(@types/node@24.7.0)(terser@5.44.0) transitivePeerDependencies: - supports-color - vite-prerender-plugin@0.5.12(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): + vite-prerender-plugin@0.5.12(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)): dependencies: kolorist: 1.8.0 magic-string: 0.30.19 @@ -5971,29 +5973,29 @@ snapshots: simple-code-frame: 1.3.0 source-map: 0.7.6 stack-trace: 1.0.0-pre2 - vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + vite: 7.1.9(@types/node@24.7.0)(terser@5.44.0) - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.0)(terser@5.44.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.9.2) + tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + vite: 7.1.9(@types/node@24.7.0)(terser@5.44.0) transitivePeerDependencies: - supports-color - typescript - vite@7.1.7(@types/node@24.5.2)(terser@5.44.0): + vite@7.1.9(@types/node@24.7.0)(terser@5.44.0): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.52.2 + rollup: 4.52.4 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.5.2 + '@types/node': 24.7.0 fsevents: 2.3.3 terser: 5.44.0 diff --git a/lib_standalone/ArduinoJson.h b/lib_standalone/ArduinoJson.h index 91d3151e2..5fbf79b27 100644 --- a/lib_standalone/ArduinoJson.h +++ b/lib_standalone/ArduinoJson.h @@ -7,226 +7,220 @@ #ifdef __cplusplus #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_VER < 1910) -# error ArduinoJson requires C++11 or newer. Configure your compiler for C++11 or downgrade ArduinoJson to 6.20. +#error ArduinoJson requires C++11 or newer. Configure your compiler for C++11 or downgrade ArduinoJson to 6.20. #endif #ifndef ARDUINOJSON_ENABLE_STD_STREAM -# ifdef __has_include -# if __has_include() && \ +#ifdef __has_include +#if __has_include() && \ __has_include() && \ !defined(min) && \ !defined(max) -# define ARDUINOJSON_ENABLE_STD_STREAM 1 -# else -# define ARDUINOJSON_ENABLE_STD_STREAM 0 -# endif -# else -# ifdef ARDUINO -# define ARDUINOJSON_ENABLE_STD_STREAM 0 -# else -# define ARDUINOJSON_ENABLE_STD_STREAM 1 -# endif -# endif +#define ARDUINOJSON_ENABLE_STD_STREAM 1 +#else +#define ARDUINOJSON_ENABLE_STD_STREAM 0 +#endif +#else +#ifdef ARDUINO +#define ARDUINOJSON_ENABLE_STD_STREAM 0 +#else +#define ARDUINOJSON_ENABLE_STD_STREAM 1 +#endif +#endif #endif #ifndef ARDUINOJSON_ENABLE_STD_STRING -# ifdef __has_include -# if __has_include() && !defined(min) && !defined(max) -# define ARDUINOJSON_ENABLE_STD_STRING 1 -# else -# define ARDUINOJSON_ENABLE_STD_STRING 0 -# endif -# else -# ifdef ARDUINO -# define ARDUINOJSON_ENABLE_STD_STRING 0 -# else -# define ARDUINOJSON_ENABLE_STD_STRING 1 -# endif -# endif +#ifdef __has_include +#if __has_include() && !defined(min) && !defined(max) +#define ARDUINOJSON_ENABLE_STD_STRING 1 +#else +#define ARDUINOJSON_ENABLE_STD_STRING 0 +#endif +#else +#ifdef ARDUINO +#define ARDUINOJSON_ENABLE_STD_STRING 0 +#else +#define ARDUINOJSON_ENABLE_STD_STRING 1 +#endif +#endif #endif #ifndef ARDUINOJSON_ENABLE_STRING_VIEW -# ifdef __has_include -# if __has_include() && __cplusplus >= 201703L -# define ARDUINOJSON_ENABLE_STRING_VIEW 1 -# else -# define ARDUINOJSON_ENABLE_STRING_VIEW 0 -# endif -# else -# define ARDUINOJSON_ENABLE_STRING_VIEW 0 -# endif +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ARDUINOJSON_ENABLE_STRING_VIEW 1 +#else +#define ARDUINOJSON_ENABLE_STRING_VIEW 0 +#endif +#else +#define ARDUINOJSON_ENABLE_STRING_VIEW 0 +#endif #endif #ifndef ARDUINOJSON_SIZEOF_POINTER -# if defined(__SIZEOF_POINTER__) -# define ARDUINOJSON_SIZEOF_POINTER __SIZEOF_POINTER__ -# elif defined(_WIN64) && _WIN64 -# define ARDUINOJSON_SIZEOF_POINTER 8 // 64 bits -# else -# define ARDUINOJSON_SIZEOF_POINTER 4 // assume 32 bits otherwise -# endif +#if defined(__SIZEOF_POINTER__) +#define ARDUINOJSON_SIZEOF_POINTER __SIZEOF_POINTER__ +#elif defined(_WIN64) && _WIN64 +#define ARDUINOJSON_SIZEOF_POINTER 8 // 64 bits +#else +#define ARDUINOJSON_SIZEOF_POINTER 4 // assume 32 bits otherwise +#endif #endif #ifndef ARDUINOJSON_USE_DOUBLE -# if ARDUINOJSON_SIZEOF_POINTER >= 4 // 32 & 64 bits systems -# define ARDUINOJSON_USE_DOUBLE 1 -# else -# define ARDUINOJSON_USE_DOUBLE 0 -# endif +#if ARDUINOJSON_SIZEOF_POINTER >= 4 // 32 & 64 bits systems +#define ARDUINOJSON_USE_DOUBLE 1 +#else +#define ARDUINOJSON_USE_DOUBLE 0 +#endif #endif #ifndef ARDUINOJSON_USE_LONG_LONG -# if ARDUINOJSON_SIZEOF_POINTER >= 4 // 32 & 64 bits systems -# define ARDUINOJSON_USE_LONG_LONG 1 -# else -# define ARDUINOJSON_USE_LONG_LONG 0 -# endif +#if ARDUINOJSON_SIZEOF_POINTER >= 4 // 32 & 64 bits systems +#define ARDUINOJSON_USE_LONG_LONG 1 +#else +#define ARDUINOJSON_USE_LONG_LONG 0 +#endif #endif #ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT -# define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 +#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 #endif #ifndef ARDUINOJSON_SLOT_ID_SIZE -# if ARDUINOJSON_SIZEOF_POINTER <= 2 -# define ARDUINOJSON_SLOT_ID_SIZE 1 -# elif ARDUINOJSON_SIZEOF_POINTER == 4 -# define ARDUINOJSON_SLOT_ID_SIZE 2 -# else -# define ARDUINOJSON_SLOT_ID_SIZE 4 -# endif +#if ARDUINOJSON_SIZEOF_POINTER <= 2 +#define ARDUINOJSON_SLOT_ID_SIZE 1 +#elif ARDUINOJSON_SIZEOF_POINTER == 4 +#define ARDUINOJSON_SLOT_ID_SIZE 2 +#else +#define ARDUINOJSON_SLOT_ID_SIZE 4 +#endif #endif #ifndef ARDUINOJSON_POOL_CAPACITY -# if ARDUINOJSON_SLOT_ID_SIZE == 1 -# define ARDUINOJSON_POOL_CAPACITY 16 // 96 bytes -# elif ARDUINOJSON_SLOT_ID_SIZE == 2 -# define ARDUINOJSON_POOL_CAPACITY 128 // 1024 bytes -# else -# define ARDUINOJSON_POOL_CAPACITY 256 // 4096 bytes -# endif +#if ARDUINOJSON_SLOT_ID_SIZE == 1 +#define ARDUINOJSON_POOL_CAPACITY 16 // 96 bytes +#elif ARDUINOJSON_SLOT_ID_SIZE == 2 +#define ARDUINOJSON_POOL_CAPACITY 128 // 1024 bytes +#else +#define ARDUINOJSON_POOL_CAPACITY 256 // 4096 bytes +#endif #endif #ifndef ARDUINOJSON_INITIAL_POOL_COUNT -# define ARDUINOJSON_INITIAL_POOL_COUNT 4 +#define ARDUINOJSON_INITIAL_POOL_COUNT 4 #endif #ifndef ARDUINOJSON_AUTO_SHRINK -# if ARDUINOJSON_SIZEOF_POINTER <= 2 -# define ARDUINOJSON_AUTO_SHRINK 0 -# else -# define ARDUINOJSON_AUTO_SHRINK 1 -# endif +#if ARDUINOJSON_SIZEOF_POINTER <= 2 +#define ARDUINOJSON_AUTO_SHRINK 0 +#else +#define ARDUINOJSON_AUTO_SHRINK 1 +#endif #endif #ifndef ARDUINOJSON_STRING_LENGTH_SIZE -# if ARDUINOJSON_SIZEOF_POINTER <= 2 -# define ARDUINOJSON_STRING_LENGTH_SIZE 1 // up to 255 characters -# else -# define ARDUINOJSON_STRING_LENGTH_SIZE 2 // up to 65535 characters -# endif +#if ARDUINOJSON_SIZEOF_POINTER <= 2 +#define ARDUINOJSON_STRING_LENGTH_SIZE 1 // up to 255 characters +#else +#define ARDUINOJSON_STRING_LENGTH_SIZE 2 // up to 65535 characters +#endif #endif #ifdef ARDUINO -# ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING -# define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 -# endif -# ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM -# define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 -# endif -# ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT -# define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1 -# endif -# ifndef ARDUINOJSON_ENABLE_PROGMEM -# define ARDUINOJSON_ENABLE_PROGMEM 1 -# endif -#else // ARDUINO -# ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING -# define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 -# endif -# ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM -# define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0 -# endif -# ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT -# define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0 -# endif -# ifndef ARDUINOJSON_ENABLE_PROGMEM -# ifdef __AVR__ -# define ARDUINOJSON_ENABLE_PROGMEM 1 -# else -# define ARDUINOJSON_ENABLE_PROGMEM 0 -# endif -# endif -#endif // ARDUINO +#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING +#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 +#endif +#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM +#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 +#endif +#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT +#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1 +#endif +#ifndef ARDUINOJSON_ENABLE_PROGMEM +#define ARDUINOJSON_ENABLE_PROGMEM 1 +#endif +#else // ARDUINO +#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING +#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 +#endif +#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM +#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0 +#endif +#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT +#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0 +#endif +#ifndef ARDUINOJSON_ENABLE_PROGMEM +#ifdef __AVR__ +#define ARDUINOJSON_ENABLE_PROGMEM 1 +#else +#define ARDUINOJSON_ENABLE_PROGMEM 0 +#endif +#endif +#endif // ARDUINO #ifndef ARDUINOJSON_DECODE_UNICODE -# define ARDUINOJSON_DECODE_UNICODE 1 +#define ARDUINOJSON_DECODE_UNICODE 1 #endif #ifndef ARDUINOJSON_ENABLE_COMMENTS -# define ARDUINOJSON_ENABLE_COMMENTS 0 +#define ARDUINOJSON_ENABLE_COMMENTS 0 #endif #ifndef ARDUINOJSON_ENABLE_NAN -# define ARDUINOJSON_ENABLE_NAN 0 +#define ARDUINOJSON_ENABLE_NAN 0 #endif #ifndef ARDUINOJSON_ENABLE_INFINITY -# define ARDUINOJSON_ENABLE_INFINITY 0 +#define ARDUINOJSON_ENABLE_INFINITY 0 #endif #ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD -# define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7 +#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7 #endif #ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD -# define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5 +#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5 #endif #ifndef ARDUINOJSON_LITTLE_ENDIAN -# if defined(_MSC_VER) || \ - (defined(__BYTE_ORDER__) && \ - __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ - defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64) -# define ARDUINOJSON_LITTLE_ENDIAN 1 -# else -# define ARDUINOJSON_LITTLE_ENDIAN 0 -# endif +#if defined(_MSC_VER) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN__) || defined(__i386) \ + || defined(__x86_64) +#define ARDUINOJSON_LITTLE_ENDIAN 1 +#else +#define ARDUINOJSON_LITTLE_ENDIAN 0 +#endif #endif #ifndef ARDUINOJSON_ENABLE_ALIGNMENT -# if defined(__AVR) -# define ARDUINOJSON_ENABLE_ALIGNMENT 0 -# else -# define ARDUINOJSON_ENABLE_ALIGNMENT 1 -# endif +#if defined(__AVR) +#define ARDUINOJSON_ENABLE_ALIGNMENT 0 +#else +#define ARDUINOJSON_ENABLE_ALIGNMENT 1 +#endif #endif #ifndef ARDUINOJSON_TAB -# define ARDUINOJSON_TAB " " +#define ARDUINOJSON_TAB " " #endif #ifndef ARDUINOJSON_STRING_BUFFER_SIZE -# define ARDUINOJSON_STRING_BUFFER_SIZE 32 +#define ARDUINOJSON_STRING_BUFFER_SIZE 32 #endif #ifndef ARDUINOJSON_DEBUG -# ifdef __PLATFORMIO_BUILD_DEBUG__ -# define ARDUINOJSON_DEBUG 1 -# else -# define ARDUINOJSON_DEBUG 0 -# endif +#ifdef __PLATFORMIO_BUILD_DEBUG__ +#define ARDUINOJSON_DEBUG 1 +#else +#define ARDUINOJSON_DEBUG 0 +#endif #endif #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_DOUBLE -# define ARDUINOJSON_USE_EXTENSIONS 1 +#define ARDUINOJSON_USE_EXTENSIONS 1 #else -# define ARDUINOJSON_USE_EXTENSIONS 0 +#define ARDUINOJSON_USE_EXTENSIONS 0 #endif #if defined(nullptr) -# error nullptr is defined as a macro. Remove the faulty #define or #undef nullptr +#error nullptr is defined as a macro. Remove the faulty #define or #undef nullptr #endif -#if ARDUINOJSON_ENABLE_ARDUINO_STRING || ARDUINOJSON_ENABLE_ARDUINO_STREAM || \ - ARDUINOJSON_ENABLE_ARDUINO_PRINT || \ - (ARDUINOJSON_ENABLE_PROGMEM && defined(ARDUINO)) +#if ARDUINOJSON_ENABLE_ARDUINO_STRING || ARDUINOJSON_ENABLE_ARDUINO_STREAM || ARDUINOJSON_ENABLE_ARDUINO_PRINT \ + || (ARDUINOJSON_ENABLE_PROGMEM && defined(ARDUINO)) #include #endif #if !ARDUINOJSON_DEBUG -# ifdef __clang__ -# pragma clang system_header -# elif defined __GNUC__ -# pragma GCC system_header -# endif +#ifdef __clang__ +#pragma clang system_header +#elif defined __GNUC__ +#pragma GCC system_header +#endif #endif #ifdef true -# undef true +#undef true #endif #ifdef false -# undef false +#undef false #endif #define ARDUINOJSON_CONCAT_(A, B) A##B #define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_CONCAT_(A, B) -#define ARDUINOJSON_CONCAT3(A, B, C) \ - ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), C) -#define ARDUINOJSON_CONCAT4(A, B, C, D) \ - ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT3(A, B, C), D) -#define ARDUINOJSON_CONCAT5(A, B, C, D, E) \ - ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), E) +#define ARDUINOJSON_CONCAT3(A, B, C) ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), C) +#define ARDUINOJSON_CONCAT4(A, B, C, D) ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT3(A, B, C), D) +#define ARDUINOJSON_CONCAT5(A, B, C, D, E) ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), E) #define ARDUINOJSON_BIN2ALPHA_0000() A #define ARDUINOJSON_BIN2ALPHA_0001() B #define ARDUINOJSON_BIN2ALPHA_0010() C @@ -251,206 +245,209 @@ #define ARDUINOJSON_VERSION_REVISION 2 #define ARDUINOJSON_VERSION_MACRO V742 #ifndef ARDUINOJSON_VERSION_NAMESPACE -# define ARDUINOJSON_VERSION_NAMESPACE \ - ARDUINOJSON_CONCAT5( \ - ARDUINOJSON_VERSION_MACRO, \ - ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_PROGMEM, \ - ARDUINOJSON_USE_LONG_LONG, \ - ARDUINOJSON_USE_DOUBLE, 1), \ - ARDUINOJSON_BIN2ALPHA( \ - ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \ - ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE), \ - ARDUINOJSON_SLOT_ID_SIZE, ARDUINOJSON_STRING_LENGTH_SIZE) +#define ARDUINOJSON_VERSION_NAMESPACE \ + ARDUINOJSON_CONCAT5(ARDUINOJSON_VERSION_MACRO, \ + ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, 1), \ + ARDUINOJSON_BIN2ALPHA(ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE), \ + ARDUINOJSON_SLOT_ID_SIZE, \ + ARDUINOJSON_STRING_LENGTH_SIZE) #endif -#define ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE \ - namespace ArduinoJson { \ - inline namespace ARDUINOJSON_VERSION_NAMESPACE { -#define ARDUINOJSON_END_PUBLIC_NAMESPACE \ - } \ - } -#define ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE \ - namespace ArduinoJson { \ - inline namespace ARDUINOJSON_VERSION_NAMESPACE { \ - namespace detail { -#define ARDUINOJSON_END_PRIVATE_NAMESPACE \ - } \ - } \ - } +#define ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE \ + namespace ArduinoJson { \ + inline namespace ARDUINOJSON_VERSION_NAMESPACE { +#define ARDUINOJSON_END_PUBLIC_NAMESPACE \ + } \ + } +#define ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE \ + namespace ArduinoJson { \ + inline namespace ARDUINOJSON_VERSION_NAMESPACE { \ + namespace detail { +#define ARDUINOJSON_END_PRIVATE_NAMESPACE \ + } \ + } \ + } ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE template struct Converter; ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template -class InvalidConversion; // Error here? See https://arduinojson.org/v7/invalid-conversion/ +class InvalidConversion; // Error here? See https://arduinojson.org/v7/invalid-conversion/ ARDUINOJSON_END_PRIVATE_NAMESPACE #include #include #include ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class Allocator { - public: - virtual void* allocate(size_t size) = 0; - virtual void deallocate(void* ptr) = 0; - virtual void* reallocate(void* ptr, size_t new_size) = 0; - protected: - ~Allocator() = default; + public: + virtual void * allocate(size_t size) = 0; + virtual void deallocate(void * ptr) = 0; + virtual void * reallocate(void * ptr, size_t new_size) = 0; + + protected: + ~Allocator() = default; }; namespace detail { class DefaultAllocator : public Allocator { - public: - void* allocate(size_t size) override { - return malloc(size); - } - void deallocate(void* ptr) override { - free(ptr); - } - void* reallocate(void* ptr, size_t new_size) override { - return realloc(ptr, new_size); - } - static Allocator* instance() { - static DefaultAllocator allocator; - return &allocator; - } - private: - DefaultAllocator() = default; - ~DefaultAllocator() = default; + public: + void * allocate(size_t size) override { + return malloc(size); + } + void deallocate(void * ptr) override { + free(ptr); + } + void * reallocate(void * ptr, size_t new_size) override { + return realloc(ptr, new_size); + } + static Allocator * instance() { + static DefaultAllocator allocator; + return &allocator; + } + + private: + DefaultAllocator() = default; + ~DefaultAllocator() = default; }; -} // namespace detail +} // namespace detail ARDUINOJSON_END_PUBLIC_NAMESPACE #if ARDUINOJSON_DEBUG #include -# define ARDUINOJSON_ASSERT(X) assert(X) +#define ARDUINOJSON_ASSERT(X) assert(X) #else -# define ARDUINOJSON_ASSERT(X) ((void)0) +#define ARDUINOJSON_ASSERT(X) ((void)0) #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template struct uint_; template <> struct uint_<8> { - using type = uint8_t; + using type = uint8_t; }; template <> struct uint_<16> { - using type = uint16_t; + using type = uint16_t; }; template <> struct uint_<32> { - using type = uint32_t; + using type = uint32_t; }; template -using uint_t = typename uint_::type; -using SlotId = uint_t; -using SlotCount = SlotId; +using uint_t = typename uint_::type; +using SlotId = uint_t; +using SlotCount = SlotId; const SlotId NULL_SLOT = SlotId(-1); template class Slot { - public: - Slot() : ptr_(nullptr), id_(NULL_SLOT) {} - Slot(T* p, SlotId id) : ptr_(p), id_(id) { - ARDUINOJSON_ASSERT((p == nullptr) == (id == NULL_SLOT)); - } - explicit operator bool() const { - return ptr_ != nullptr; - } - SlotId id() const { - return id_; - } - T* ptr() const { - return ptr_; - } - T* operator->() const { - ARDUINOJSON_ASSERT(ptr_ != nullptr); - return ptr_; - } - private: - T* ptr_; - SlotId id_; + public: + Slot() + : ptr_(nullptr) + , id_(NULL_SLOT) { + } + Slot(T * p, SlotId id) + : ptr_(p) + , id_(id) { + ARDUINOJSON_ASSERT((p == nullptr) == (id == NULL_SLOT)); + } + explicit operator bool() const { + return ptr_ != nullptr; + } + SlotId id() const { + return id_; + } + T * ptr() const { + return ptr_; + } + T * operator->() const { + ARDUINOJSON_ASSERT(ptr_ != nullptr); + return ptr_; + } + + private: + T * ptr_; + SlotId id_; }; template class MemoryPool { - public: - void create(SlotCount cap, Allocator* allocator) { - ARDUINOJSON_ASSERT(cap > 0); - slots_ = reinterpret_cast(allocator->allocate(slotsToBytes(cap))); - capacity_ = slots_ ? cap : 0; - usage_ = 0; - } - void destroy(Allocator* allocator) { - if (slots_) - allocator->deallocate(slots_); - slots_ = nullptr; - capacity_ = 0; - usage_ = 0; - } - Slot allocSlot() { - if (!slots_) - return {}; - if (usage_ >= capacity_) - return {}; - auto index = usage_++; - return {slots_ + index, SlotId(index)}; - } - T* getSlot(SlotId id) const { - ARDUINOJSON_ASSERT(id < usage_); - return slots_ + id; - } - void clear() { - usage_ = 0; - } - void shrinkToFit(Allocator* allocator) { - auto newSlots = reinterpret_cast( - allocator->reallocate(slots_, slotsToBytes(usage_))); - if (newSlots) { - slots_ = newSlots; - capacity_ = usage_; + public: + void create(SlotCount cap, Allocator * allocator) { + ARDUINOJSON_ASSERT(cap > 0); + slots_ = reinterpret_cast(allocator->allocate(slotsToBytes(cap))); + capacity_ = slots_ ? cap : 0; + usage_ = 0; } - } - SlotCount usage() const { - return usage_; - } - static SlotCount bytesToSlots(size_t n) { - return static_cast(n / sizeof(T)); - } - static size_t slotsToBytes(SlotCount n) { - return n * sizeof(T); - } - private: - SlotCount capacity_; - SlotCount usage_; - T* slots_; + void destroy(Allocator * allocator) { + if (slots_) + allocator->deallocate(slots_); + slots_ = nullptr; + capacity_ = 0; + usage_ = 0; + } + Slot allocSlot() { + if (!slots_) + return {}; + if (usage_ >= capacity_) + return {}; + auto index = usage_++; + return {slots_ + index, SlotId(index)}; + } + T * getSlot(SlotId id) const { + ARDUINOJSON_ASSERT(id < usage_); + return slots_ + id; + } + void clear() { + usage_ = 0; + } + void shrinkToFit(Allocator * allocator) { + auto newSlots = reinterpret_cast(allocator->reallocate(slots_, slotsToBytes(usage_))); + if (newSlots) { + slots_ = newSlots; + capacity_ = usage_; + } + } + SlotCount usage() const { + return usage_; + } + static SlotCount bytesToSlots(size_t n) { + return static_cast(n / sizeof(T)); + } + static size_t slotsToBytes(SlotCount n) { + return n * sizeof(T); + } + + private: + SlotCount capacity_; + SlotCount usage_; + T * slots_; }; template struct conditional { - using type = TrueType; + using type = TrueType; }; template struct conditional { - using type = FalseType; + using type = FalseType; }; template -using conditional_t = - typename conditional::type; +using conditional_t = typename conditional::type; template struct decay { - using type = T; + using type = T; }; template -struct decay : decay {}; +struct decay : decay {}; template -struct decay : decay {}; +struct decay : decay {}; template -struct decay : decay {}; +struct decay : decay {}; template -struct decay : decay {}; +struct decay : decay {}; template using decay_t = typename decay::type; template struct enable_if {}; template struct enable_if { - using type = T; + using type = T; }; template using enable_if_t = typename enable_if::type; @@ -458,23 +455,23 @@ template struct function_traits; template struct function_traits { - using return_type = ReturnType; - using arg1_type = Arg1; + using return_type = ReturnType; + using arg1_type = Arg1; }; template struct function_traits { - using return_type = ReturnType; - using arg1_type = Arg1; - using arg2_type = Arg2; + using return_type = ReturnType; + using arg1_type = Arg1; + using arg2_type = Arg2; }; template struct integral_constant { - static const T value = v; + static const T value = v; }; template using bool_constant = integral_constant; -using true_type = bool_constant; -using false_type = bool_constant; +using true_type = bool_constant; +using false_type = bool_constant; template struct is_array : false_type {}; template @@ -483,35 +480,35 @@ template struct is_array : true_type {}; template struct remove_reference { - using type = T; + using type = T; }; template -struct remove_reference { - using type = T; +struct remove_reference { + using type = T; }; template using remove_reference_t = typename remove_reference::type; template class is_base_of { - protected: // <- to avoid GCC's "all member functions in class are private" - static int probe(const TBase*); - static char probe(...); - public: - static const bool value = - sizeof(probe(reinterpret_cast*>(0))) == - sizeof(int); + protected: // <- to avoid GCC's "all member functions in class are private" + static int probe(const TBase *); + static char probe(...); + + public: + static const bool value = sizeof(probe(reinterpret_cast *>(0))) == sizeof(int); }; template -T&& declval(); +T && declval(); template struct is_class { - protected: // <- to avoid GCC's "all member functions in class are private" - template - static int probe(void (U::*)(void)); - template - static char probe(...); - public: - static const bool value = sizeof(probe(0)) == sizeof(int); + protected: // <- to avoid GCC's "all member functions in class are private" + template + static int probe(void (U::*)(void)); + template + static char probe(...); + + public: + static const bool value = sizeof(probe(0)) == sizeof(int); }; template struct is_const : false_type {}; @@ -519,28 +516,29 @@ template struct is_const : true_type {}; ARDUINOJSON_END_PRIVATE_NAMESPACE #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4244) +#pragma warning(push) +#pragma warning(disable : 4244) #endif #ifdef __ICCARM__ -#pragma diag_suppress=Pa093 +#pragma diag_suppress = Pa093 #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template struct is_convertible { - protected: // <- to avoid GCC's "all member functions in class are private" - static int probe(To); - static char probe(...); - static const From& from_; - public: - static const bool value = sizeof(probe(from_)) == sizeof(int); + protected: // <- to avoid GCC's "all member functions in class are private" + static int probe(To); + static char probe(...); + static const From & from_; + + public: + static const bool value = sizeof(probe(from_)) == sizeof(int); }; ARDUINOJSON_END_PRIVATE_NAMESPACE #ifdef _MSC_VER -# pragma warning(pop) +#pragma warning(pop) #endif #ifdef __ICCARM__ -#pragma diag_default=Pa093 +#pragma diag_default = Pa093 #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template @@ -549,72 +547,56 @@ template struct is_same : true_type {}; template struct remove_cv { - using type = T; + using type = T; }; template struct remove_cv { - using type = T; + using type = T; }; template struct remove_cv { - using type = T; + using type = T; }; template struct remove_cv { - using type = T; + using type = T; }; template using remove_cv_t = typename remove_cv::type; template -struct is_floating_point - : integral_constant>::value || - is_same>::value> {}; +struct is_floating_point : integral_constant>::value || is_same>::value> {}; template -struct is_integral : integral_constant, signed char>::value || - is_same, unsigned char>::value || - is_same, signed short>::value || - is_same, unsigned short>::value || - is_same, signed int>::value || - is_same, unsigned int>::value || - is_same, signed long>::value || - is_same, unsigned long>::value || - is_same, signed long long>::value || - is_same, unsigned long long>::value || - is_same, char>::value || - is_same, bool>::value> {}; +struct is_integral + : integral_constant< + bool, + is_same, signed char>::value || is_same, unsigned char>::value || is_same, signed short>::value + || is_same, unsigned short>::value || is_same, signed int>::value || is_same, unsigned int>::value + || is_same, signed long>::value || is_same, unsigned long>::value || is_same, signed long long>::value + || is_same, unsigned long long>::value || is_same, char>::value || is_same, bool>::value> {}; template struct is_enum { - static const bool value = is_convertible::value && - !is_class::value && !is_integral::value && - !is_floating_point::value; + static const bool value = is_convertible::value && !is_class::value && !is_integral::value && !is_floating_point::value; }; template struct is_pointer : false_type {}; template -struct is_pointer : true_type {}; +struct is_pointer : true_type {}; template -struct is_signed : integral_constant, char>::value || - is_same, signed char>::value || - is_same, signed short>::value || - is_same, signed int>::value || - is_same, signed long>::value || - is_same, signed long long>::value || - is_same, float>::value || - is_same, double>::value> {}; +struct is_signed + : integral_constant, char>::value || is_same, signed char>::value || is_same, signed short>::value + || is_same, signed int>::value || is_same, signed long>::value + || is_same, signed long long>::value || is_same, float>::value || is_same, double>::value> { +}; template struct is_unsigned : integral_constant, unsigned char>::value || - is_same, unsigned short>::value || - is_same, unsigned int>::value || - is_same, unsigned long>::value || - is_same, unsigned long long>::value || - is_same, bool>::value> {}; + is_same, unsigned char>::value || is_same, unsigned short>::value + || is_same, unsigned int>::value || is_same, unsigned long>::value + || is_same, unsigned long long>::value || is_same, bool>::value> {}; template struct type_identity { - using type = T; + using type = T; }; template struct make_unsigned; @@ -644,34 +626,34 @@ template using make_unsigned_t = typename make_unsigned::type; template struct remove_const { - using type = T; + using type = T; }; template struct remove_const { - using type = T; + using type = T; }; template using remove_const_t = typename remove_const::type; template struct make_void { - using type = void; + using type = void; }; template -using void_t = typename make_void::type; +using void_t = typename make_void::type; using nullptr_t = decltype(nullptr); template -T&& forward(remove_reference_t& t) noexcept { - return static_cast(t); +T && forward(remove_reference_t & t) noexcept { + return static_cast(t); } template -remove_reference_t&& move(T&& t) { - return static_cast&&>(t); +remove_reference_t && move(T && t) { + return static_cast &&>(t); } template -void swap_(T& a, T& b) { - T tmp = move(a); - a = move(b); - b = move(tmp); +void swap_(T & a, T & b) { + T tmp = move(a); + a = move(b); + b = move(tmp); } ARDUINOJSON_END_PRIVATE_NAMESPACE #include @@ -679,273 +661,269 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE using PoolCount = SlotId; template class MemoryPoolList { - struct FreeSlot { - SlotId next; - }; - static_assert(sizeof(FreeSlot) <= sizeof(T), "T is too small"); - public: - using Pool = MemoryPool; - MemoryPoolList() = default; - ~MemoryPoolList() { - ARDUINOJSON_ASSERT(count_ == 0); - } - friend void swap(MemoryPoolList& a, MemoryPoolList& b) { - bool aUsedPreallocated = a.pools_ == a.preallocatedPools_; - bool bUsedPreallocated = b.pools_ == b.preallocatedPools_; - if (aUsedPreallocated && bUsedPreallocated) { - for (PoolCount i = 0; i < ARDUINOJSON_INITIAL_POOL_COUNT; i++) - swap_(a.preallocatedPools_[i], b.preallocatedPools_[i]); - } else if (bUsedPreallocated) { - for (PoolCount i = 0; i < b.count_; i++) - a.preallocatedPools_[i] = b.preallocatedPools_[i]; - b.pools_ = a.pools_; - a.pools_ = a.preallocatedPools_; - } else if (aUsedPreallocated) { - for (PoolCount i = 0; i < a.count_; i++) - b.preallocatedPools_[i] = a.preallocatedPools_[i]; - a.pools_ = b.pools_; - b.pools_ = b.preallocatedPools_; - } else { - swap_(a.pools_, b.pools_); + struct FreeSlot { + SlotId next; + }; + static_assert(sizeof(FreeSlot) <= sizeof(T), "T is too small"); + + public: + using Pool = MemoryPool; + MemoryPoolList() = default; + ~MemoryPoolList() { + ARDUINOJSON_ASSERT(count_ == 0); } - swap_(a.count_, b.count_); - swap_(a.capacity_, b.capacity_); - swap_(a.freeList_, b.freeList_); - } - MemoryPoolList& operator=(MemoryPoolList&& src) { - ARDUINOJSON_ASSERT(count_ == 0); - if (src.pools_ == src.preallocatedPools_) { - memcpy(preallocatedPools_, src.preallocatedPools_, - sizeof(preallocatedPools_)); - pools_ = preallocatedPools_; - } else { - pools_ = src.pools_; - src.pools_ = nullptr; + friend void swap(MemoryPoolList & a, MemoryPoolList & b) { + bool aUsedPreallocated = a.pools_ == a.preallocatedPools_; + bool bUsedPreallocated = b.pools_ == b.preallocatedPools_; + if (aUsedPreallocated && bUsedPreallocated) { + for (PoolCount i = 0; i < ARDUINOJSON_INITIAL_POOL_COUNT; i++) + swap_(a.preallocatedPools_[i], b.preallocatedPools_[i]); + } else if (bUsedPreallocated) { + for (PoolCount i = 0; i < b.count_; i++) + a.preallocatedPools_[i] = b.preallocatedPools_[i]; + b.pools_ = a.pools_; + a.pools_ = a.preallocatedPools_; + } else if (aUsedPreallocated) { + for (PoolCount i = 0; i < a.count_; i++) + b.preallocatedPools_[i] = a.preallocatedPools_[i]; + a.pools_ = b.pools_; + b.pools_ = b.preallocatedPools_; + } else { + swap_(a.pools_, b.pools_); + } + swap_(a.count_, b.count_); + swap_(a.capacity_, b.capacity_); + swap_(a.freeList_, b.freeList_); } - count_ = src.count_; - capacity_ = src.capacity_; - src.count_ = 0; - src.capacity_ = 0; - return *this; - } - Slot allocSlot(Allocator* allocator) { - if (freeList_ != NULL_SLOT) { - return allocFromFreeList(); + MemoryPoolList & operator=(MemoryPoolList && src) { + ARDUINOJSON_ASSERT(count_ == 0); + if (src.pools_ == src.preallocatedPools_) { + memcpy(preallocatedPools_, src.preallocatedPools_, sizeof(preallocatedPools_)); + pools_ = preallocatedPools_; + } else { + pools_ = src.pools_; + src.pools_ = nullptr; + } + count_ = src.count_; + capacity_ = src.capacity_; + src.count_ = 0; + src.capacity_ = 0; + return *this; } - if (count_) { - auto slot = allocFromLastPool(); - if (slot) - return slot; + Slot allocSlot(Allocator * allocator) { + if (freeList_ != NULL_SLOT) { + return allocFromFreeList(); + } + if (count_) { + auto slot = allocFromLastPool(); + if (slot) + return slot; + } + auto pool = addPool(allocator); + if (!pool) + return {}; + return allocFromLastPool(); } - auto pool = addPool(allocator); - if (!pool) - return {}; - return allocFromLastPool(); - } - void freeSlot(Slot slot) { - reinterpret_cast(slot.ptr())->next = freeList_; - freeList_ = slot.id(); - } - T* getSlot(SlotId id) const { - if (id == NULL_SLOT) - return nullptr; - auto poolIndex = SlotId(id / ARDUINOJSON_POOL_CAPACITY); - auto indexInPool = SlotId(id % ARDUINOJSON_POOL_CAPACITY); - ARDUINOJSON_ASSERT(poolIndex < count_); - return pools_[poolIndex].getSlot(indexInPool); - } - void clear(Allocator* allocator) { - for (PoolCount i = 0; i < count_; i++) - pools_[i].destroy(allocator); - count_ = 0; - freeList_ = NULL_SLOT; - if (pools_ != preallocatedPools_) { - allocator->deallocate(pools_); - pools_ = preallocatedPools_; - capacity_ = ARDUINOJSON_INITIAL_POOL_COUNT; + void freeSlot(Slot slot) { + reinterpret_cast(slot.ptr())->next = freeList_; + freeList_ = slot.id(); } - } - SlotCount usage() const { - SlotCount total = 0; - for (PoolCount i = 0; i < count_; i++) - total = SlotCount(total + pools_[i].usage()); - return total; - } - size_t size() const { - return Pool::slotsToBytes(usage()); - } - void shrinkToFit(Allocator* allocator) { - if (count_ > 0) - pools_[count_ - 1].shrinkToFit(allocator); - if (pools_ != preallocatedPools_ && count_ != capacity_) { - pools_ = static_cast( - allocator->reallocate(pools_, count_ * sizeof(Pool))); - ARDUINOJSON_ASSERT(pools_ != nullptr); // realloc to smaller can't fail - capacity_ = count_; + T * getSlot(SlotId id) const { + if (id == NULL_SLOT) + return nullptr; + auto poolIndex = SlotId(id / ARDUINOJSON_POOL_CAPACITY); + auto indexInPool = SlotId(id % ARDUINOJSON_POOL_CAPACITY); + ARDUINOJSON_ASSERT(poolIndex < count_); + return pools_[poolIndex].getSlot(indexInPool); } - } - private: - Slot allocFromFreeList() { - ARDUINOJSON_ASSERT(freeList_ != NULL_SLOT); - auto id = freeList_; - auto slot = getSlot(freeList_); - freeList_ = reinterpret_cast(slot)->next; - return {slot, id}; - } - Slot allocFromLastPool() { - ARDUINOJSON_ASSERT(count_ > 0); - auto poolIndex = SlotId(count_ - 1); - auto slot = pools_[poolIndex].allocSlot(); - if (!slot) - return {}; - return {slot.ptr(), - SlotId(poolIndex * ARDUINOJSON_POOL_CAPACITY + slot.id())}; - } - Pool* addPool(Allocator* allocator) { - if (count_ == capacity_ && !increaseCapacity(allocator)) - return nullptr; - auto pool = &pools_[count_++]; - SlotCount poolCapacity = ARDUINOJSON_POOL_CAPACITY; - if (count_ == maxPools) // last pool is smaller because of NULL_SLOT - poolCapacity--; - pool->create(poolCapacity, allocator); - return pool; - } - bool increaseCapacity(Allocator* allocator) { - if (capacity_ == maxPools) - return false; - void* newPools; - auto newCapacity = PoolCount(capacity_ * 2); - if (pools_ == preallocatedPools_) { - newPools = allocator->allocate(newCapacity * sizeof(Pool)); - if (!newPools) - return false; - memcpy(newPools, preallocatedPools_, sizeof(preallocatedPools_)); - } else { - newPools = allocator->reallocate(pools_, newCapacity * sizeof(Pool)); - if (!newPools) - return false; + void clear(Allocator * allocator) { + for (PoolCount i = 0; i < count_; i++) + pools_[i].destroy(allocator); + count_ = 0; + freeList_ = NULL_SLOT; + if (pools_ != preallocatedPools_) { + allocator->deallocate(pools_); + pools_ = preallocatedPools_; + capacity_ = ARDUINOJSON_INITIAL_POOL_COUNT; + } } - pools_ = static_cast(newPools); - capacity_ = newCapacity; - return true; - } - Pool preallocatedPools_[ARDUINOJSON_INITIAL_POOL_COUNT]; - Pool* pools_ = preallocatedPools_; - PoolCount count_ = 0; - PoolCount capacity_ = ARDUINOJSON_INITIAL_POOL_COUNT; - SlotId freeList_ = NULL_SLOT; - public: - static const PoolCount maxPools = - PoolCount(NULL_SLOT / ARDUINOJSON_POOL_CAPACITY + 1); + SlotCount usage() const { + SlotCount total = 0; + for (PoolCount i = 0; i < count_; i++) + total = SlotCount(total + pools_[i].usage()); + return total; + } + size_t size() const { + return Pool::slotsToBytes(usage()); + } + void shrinkToFit(Allocator * allocator) { + if (count_ > 0) + pools_[count_ - 1].shrinkToFit(allocator); + if (pools_ != preallocatedPools_ && count_ != capacity_) { + pools_ = static_cast(allocator->reallocate(pools_, count_ * sizeof(Pool))); + ARDUINOJSON_ASSERT(pools_ != nullptr); // realloc to smaller can't fail + capacity_ = count_; + } + } + + private: + Slot allocFromFreeList() { + ARDUINOJSON_ASSERT(freeList_ != NULL_SLOT); + auto id = freeList_; + auto slot = getSlot(freeList_); + freeList_ = reinterpret_cast(slot)->next; + return {slot, id}; + } + Slot allocFromLastPool() { + ARDUINOJSON_ASSERT(count_ > 0); + auto poolIndex = SlotId(count_ - 1); + auto slot = pools_[poolIndex].allocSlot(); + if (!slot) + return {}; + return {slot.ptr(), SlotId(poolIndex * ARDUINOJSON_POOL_CAPACITY + slot.id())}; + } + Pool * addPool(Allocator * allocator) { + if (count_ == capacity_ && !increaseCapacity(allocator)) + return nullptr; + auto pool = &pools_[count_++]; + SlotCount poolCapacity = ARDUINOJSON_POOL_CAPACITY; + if (count_ == maxPools) // last pool is smaller because of NULL_SLOT + poolCapacity--; + pool->create(poolCapacity, allocator); + return pool; + } + bool increaseCapacity(Allocator * allocator) { + if (capacity_ == maxPools) + return false; + void * newPools; + auto newCapacity = PoolCount(capacity_ * 2); + if (pools_ == preallocatedPools_) { + newPools = allocator->allocate(newCapacity * sizeof(Pool)); + if (!newPools) + return false; + memcpy(newPools, preallocatedPools_, sizeof(preallocatedPools_)); + } else { + newPools = allocator->reallocate(pools_, newCapacity * sizeof(Pool)); + if (!newPools) + return false; + } + pools_ = static_cast(newPools); + capacity_ = newCapacity; + return true; + } + Pool preallocatedPools_[ARDUINOJSON_INITIAL_POOL_COUNT]; + Pool * pools_ = preallocatedPools_; + PoolCount count_ = 0; + PoolCount capacity_ = ARDUINOJSON_INITIAL_POOL_COUNT; + SlotId freeList_ = NULL_SLOT; + + public: + static const PoolCount maxPools = PoolCount(NULL_SLOT / ARDUINOJSON_POOL_CAPACITY + 1); }; ARDUINOJSON_END_PRIVATE_NAMESPACE #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4310) +#pragma warning(push) +#pragma warning(disable : 4310) #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template struct numeric_limits; template struct numeric_limits::value>> { - static constexpr T lowest() { - return 0; - } - static constexpr T highest() { - return T(-1); - } + static constexpr T lowest() { + return 0; + } + static constexpr T highest() { + return T(-1); + } }; template -struct numeric_limits< - T, enable_if_t::value && is_signed::value>> { - static constexpr T lowest() { - return T(T(1) << (sizeof(T) * 8 - 1)); - } - static constexpr T highest() { - return T(~lowest()); - } +struct numeric_limits::value && is_signed::value>> { + static constexpr T lowest() { + return T(T(1) << (sizeof(T) * 8 - 1)); + } + static constexpr T highest() { + return T(~lowest()); + } }; ARDUINOJSON_END_PRIVATE_NAMESPACE #ifdef _MSC_VER -# pragma warning(pop) +#pragma warning(pop) #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE struct StringNode { - using references_type = uint_t; - using length_type = uint_t; - struct StringNode* next; - references_type references; - length_type length; - char data[1]; - static constexpr size_t maxLength = numeric_limits::highest(); - static constexpr size_t sizeForLength(size_t n) { - return n + 1 + offsetof(StringNode, data); - } - static StringNode* create(size_t length, Allocator* allocator) { - if (length > maxLength) - return nullptr; - auto size = sizeForLength(length); - if (size < length) // integer overflow - return nullptr; // (not testable on 64-bit) - auto node = reinterpret_cast(allocator->allocate(size)); - if (node) { - node->length = length_type(length); - node->references = 1; + using references_type = uint_t; + using length_type = uint_t; + struct StringNode * next; + references_type references; + length_type length; + char data[1]; + static constexpr size_t maxLength = numeric_limits::highest(); + static constexpr size_t sizeForLength(size_t n) { + return n + 1 + offsetof(StringNode, data); + } + static StringNode * create(size_t length, Allocator * allocator) { + if (length > maxLength) + return nullptr; + auto size = sizeForLength(length); + if (size < length) // integer overflow + return nullptr; // (not testable on 64-bit) + auto node = reinterpret_cast(allocator->allocate(size)); + if (node) { + node->length = length_type(length); + node->references = 1; + } + return node; + } + static StringNode * resize(StringNode * node, size_t length, Allocator * allocator) { + ARDUINOJSON_ASSERT(node != nullptr); + StringNode * newNode; + if (length <= maxLength) + newNode = reinterpret_cast(allocator->reallocate(node, sizeForLength(length))); + else + newNode = nullptr; + if (newNode) + newNode->length = length_type(length); + else + allocator->deallocate(node); + return newNode; + } + static void destroy(StringNode * node, Allocator * allocator) { + allocator->deallocate(node); } - return node; - } - static StringNode* resize(StringNode* node, size_t length, - Allocator* allocator) { - ARDUINOJSON_ASSERT(node != nullptr); - StringNode* newNode; - if (length <= maxLength) - newNode = reinterpret_cast( - allocator->reallocate(node, sizeForLength(length))); - else - newNode = nullptr; - if (newNode) - newNode->length = length_type(length); - else - allocator->deallocate(node); - return newNode; - } - static void destroy(StringNode* node, Allocator* allocator) { - allocator->deallocate(node); - } }; constexpr size_t sizeofString(size_t n) { - return StringNode::sizeForLength(n); + return StringNode::sizeForLength(n); } ARDUINOJSON_END_PRIVATE_NAMESPACE -#ifdef _MSC_VER // Visual Studio -# define FORCE_INLINE // __forceinline causes C4714 when returning std::string -# ifndef ARDUINOJSON_DEPRECATED -# define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg)) -# endif -#elif defined(__GNUC__) // GCC or Clang -# define FORCE_INLINE __attribute__((always_inline)) -# ifndef ARDUINOJSON_DEPRECATED -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -# define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated(msg))) -# else -# define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated)) -# endif -# endif -#else // Other compilers -# define FORCE_INLINE -# ifndef ARDUINOJSON_DEPRECATED -# define ARDUINOJSON_DEPRECATED(msg) -# endif +#ifdef _MSC_VER // Visual Studio +#define FORCE_INLINE // __forceinline causes C4714 when returning std::string +#ifndef ARDUINOJSON_DEPRECATED +#define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg)) +#endif +#elif defined(__GNUC__) // GCC or Clang +#define FORCE_INLINE __attribute__((always_inline)) +#ifndef ARDUINOJSON_DEPRECATED +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated(msg))) +#else +#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated)) +#endif +#endif +#else // Other compilers +#define FORCE_INLINE +#ifndef ARDUINOJSON_DEPRECATED +#define ARDUINOJSON_DEPRECATED(msg) +#endif #endif #if defined(__has_attribute) -# if __has_attribute(no_sanitize) -# define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check))) -# else -# define ARDUINOJSON_NO_SANITIZE(check) -# endif +#if __has_attribute(no_sanitize) +#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check))) #else -# define ARDUINOJSON_NO_SANITIZE(check) +#define ARDUINOJSON_NO_SANITIZE(check) +#endif +#else +#define ARDUINOJSON_NO_SANITIZE(check) #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template @@ -957,165 +935,155 @@ struct StringAdapter; template struct SizedStringAdapter; template -using StringAdapterFor = - StringAdapter::value, TString, - remove_cv_t>>>; +using StringAdapterFor = StringAdapter::value, TString, remove_cv_t>>>; template using AdaptedString = typename StringAdapterFor::AdaptedString; template -AdaptedString adaptString(TString&& s) { - return StringAdapterFor::adapt(detail::forward(s)); +AdaptedString adaptString(TString && s) { + return StringAdapterFor::adapt(detail::forward(s)); } template ::value, int> = 0> -AdaptedString adaptString(TChar* p) { - return StringAdapter::adapt(p); +AdaptedString adaptString(TChar * p) { + return StringAdapter::adapt(p); } template -AdaptedString adaptString(TChar* p, size_t n) { - return SizedStringAdapter::adapt(p, n); +AdaptedString adaptString(TChar * p, size_t n) { + return SizedStringAdapter::adapt(p, n); } template -struct IsChar - : integral_constant::value && sizeof(T) == 1> {}; +struct IsChar : integral_constant::value && sizeof(T) == 1> {}; class RamString { - public: - static const size_t typeSortKey = 2; + public: + static const size_t typeSortKey = 2; #if ARDUINOJSON_SIZEOF_POINTER <= 2 - static constexpr size_t sizeMask = size_t(-1) >> 1; + static constexpr size_t sizeMask = size_t(-1) >> 1; #else - static constexpr size_t sizeMask = size_t(-1); + static constexpr size_t sizeMask = size_t(-1); #endif - RamString(const char* str, size_t sz, bool isStatic = false) - : str_(str), size_(sz & sizeMask), static_(isStatic) { - ARDUINOJSON_ASSERT(size_ == sz); - } - bool isNull() const { - return !str_; - } - size_t size() const { - return size_; - } - char operator[](size_t i) const { - ARDUINOJSON_ASSERT(str_ != 0); - ARDUINOJSON_ASSERT(i <= size()); - return str_[i]; - } - const char* data() const { - return str_; - } - bool isStatic() const { - return static_; - } - protected: - const char* str_; + RamString(const char * str, size_t sz, bool isStatic = false) + : str_(str) + , size_(sz & sizeMask) + , static_(isStatic) { + ARDUINOJSON_ASSERT(size_ == sz); + } + bool isNull() const { + return !str_; + } + size_t size() const { + return size_; + } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(str_ != 0); + ARDUINOJSON_ASSERT(i <= size()); + return str_[i]; + } + const char * data() const { + return str_; + } + bool isStatic() const { + return static_; + } + + protected: + const char * str_; #if ARDUINOJSON_SIZEOF_POINTER <= 2 - size_t size_ : sizeof(size_t) * 8 - 1; - bool static_ : 1; + size_t size_ : sizeof(size_t) * 8 - 1; + bool static_ : 1; #else - size_t size_; - bool static_; + size_t size_; + bool static_; #endif }; template -struct StringAdapter::value>> { - using AdaptedString = RamString; - static AdaptedString adapt(const TChar* p) { - auto str = reinterpret_cast(p); - return AdaptedString(str, str ? ::strlen(str) : 0); - } +struct StringAdapter::value>> { + using AdaptedString = RamString; + static AdaptedString adapt(const TChar * p) { + auto str = reinterpret_cast(p); + return AdaptedString(str, str ? ::strlen(str) : 0); + } }; template struct StringAdapter::value>> { - using AdaptedString = RamString; - static AdaptedString adapt(const TChar* p) { - auto str = reinterpret_cast(p); - return AdaptedString(str, str ? ::strlen(str) : 0); - } + using AdaptedString = RamString; + static AdaptedString adapt(const TChar * p) { + auto str = reinterpret_cast(p); + return AdaptedString(str, str ? ::strlen(str) : 0); + } }; template struct StringAdapter { - using AdaptedString = RamString; - static AdaptedString adapt(const char (&p)[N]) { - return RamString(p, N - 1, true); - } + using AdaptedString = RamString; + static AdaptedString adapt(const char (&p)[N]) { + return RamString(p, N - 1, true); + } }; template struct StringAdapter::value>> { - using AdaptedString = RamString; - static AdaptedString adapt(const TChar* p) { - ARDUINOJSON_ASSERT(p); - auto str = reinterpret_cast(p); - return AdaptedString(str, ::strlen(str)); - } + using AdaptedString = RamString; + static AdaptedString adapt(const TChar * p) { + ARDUINOJSON_ASSERT(p); + auto str = reinterpret_cast(p); + return AdaptedString(str, ::strlen(str)); + } }; template -struct SizedStringAdapter::value>> { - using AdaptedString = RamString; - static AdaptedString adapt(const TChar* p, size_t n) { - return AdaptedString(reinterpret_cast(p), n); - } +struct SizedStringAdapter::value>> { + using AdaptedString = RamString; + static AdaptedString adapt(const TChar * p, size_t n) { + return AdaptedString(reinterpret_cast(p), n); + } }; namespace string_traits_impl { template struct has_cstr : false_type {}; template -struct has_cstr().c_str()), - const char*>::value>> : true_type {}; +struct has_cstr().c_str()), const char *>::value>> : true_type {}; template struct has_data : false_type {}; template -struct has_data().data()), - const char*>::value>> : true_type {}; +struct has_data().data()), const char *>::value>> : true_type {}; template struct has_length : false_type {}; template -struct has_length< - T, enable_if_t().length())>::value>> - : true_type {}; +struct has_length().length())>::value>> : true_type {}; template struct has_size : false_type {}; template -struct has_size< - T, enable_if_t().size()), size_t>::value>> - : true_type {}; -} // namespace string_traits_impl +struct has_size().size()), size_t>::value>> : true_type {}; +} // namespace string_traits_impl template struct string_traits { - enum { - has_cstr = string_traits_impl::has_cstr::value, - has_length = string_traits_impl::has_length::value, - has_data = string_traits_impl::has_data::value, - has_size = string_traits_impl::has_size::value - }; + enum { + has_cstr = string_traits_impl::has_cstr::value, + has_length = string_traits_impl::has_length::value, + has_data = string_traits_impl::has_data::value, + has_size = string_traits_impl::has_size::value + }; }; template -struct StringAdapter< - T, - enable_if_t<(string_traits::has_cstr || string_traits::has_data) && - (string_traits::has_length || string_traits::has_size)>> { - using AdaptedString = RamString; - static AdaptedString adapt(const T& s) { - return AdaptedString(get_data(s), get_size(s)); - } - private: - template - static enable_if_t::has_size, size_t> get_size(const U& s) { - return s.size(); - } - template - static enable_if_t::has_size, size_t> get_size(const U& s) { - return s.length(); - } - template - static enable_if_t::has_data, const char*> get_data( - const U& s) { - return s.data(); - } - template - static enable_if_t::has_data, const char*> get_data( - const U& s) { - return s.c_str(); - } +struct StringAdapter::has_cstr || string_traits::has_data) && (string_traits::has_length || string_traits::has_size)>> { + using AdaptedString = RamString; + static AdaptedString adapt(const T & s) { + return AdaptedString(get_data(s), get_size(s)); + } + + private: + template + static enable_if_t::has_size, size_t> get_size(const U & s) { + return s.size(); + } + template + static enable_if_t::has_size, size_t> get_size(const U & s) { + return s.length(); + } + template + static enable_if_t::has_data, const char *> get_data(const U & s) { + return s.data(); + } + template + static enable_if_t::has_data, const char *> get_data(const U & s) { + return s.c_str(); + } }; ARDUINOJSON_END_PRIVATE_NAMESPACE #if ARDUINOJSON_ENABLE_PROGMEM @@ -1126,596 +1094,588 @@ class __FlashStringHelper; #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE struct pgm_p { - pgm_p(const void* p) : address(reinterpret_cast(p)) {} - const char* address; + pgm_p(const void * p) + : address(reinterpret_cast(p)) { + } + const char * address; }; ARDUINOJSON_END_PRIVATE_NAMESPACE #ifndef strlen_P inline size_t strlen_P(ArduinoJson::detail::pgm_p s) { - const char* p = s.address; - ARDUINOJSON_ASSERT(p != NULL); - while (pgm_read_byte(p)) - p++; - return size_t(p - s.address); + const char * p = s.address; + ARDUINOJSON_ASSERT(p != NULL); + while (pgm_read_byte(p)) + p++; + return size_t(p - s.address); } #endif #ifndef strncmp_P -inline int strncmp_P(const char* a, ArduinoJson::detail::pgm_p b, size_t n) { - const char* s1 = a; - const char* s2 = b.address; - ARDUINOJSON_ASSERT(s1 != NULL); - ARDUINOJSON_ASSERT(s2 != NULL); - while (n-- > 0) { - char c1 = *s1++; - char c2 = static_cast(pgm_read_byte(s2++)); - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - if (c1 == 0 /* and c2 as well */) - return 0; - } - return 0; +inline int strncmp_P(const char * a, ArduinoJson::detail::pgm_p b, size_t n) { + const char * s1 = a; + const char * s2 = b.address; + ARDUINOJSON_ASSERT(s1 != NULL); + ARDUINOJSON_ASSERT(s2 != NULL); + while (n-- > 0) { + char c1 = *s1++; + char c2 = static_cast(pgm_read_byte(s2++)); + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + if (c1 == 0 /* and c2 as well */) + return 0; + } + return 0; } #endif #ifndef strcmp_P -inline int strcmp_P(const char* a, ArduinoJson::detail::pgm_p b) { - const char* s1 = a; - const char* s2 = b.address; - ARDUINOJSON_ASSERT(s1 != NULL); - ARDUINOJSON_ASSERT(s2 != NULL); - for (;;) { - char c1 = *s1++; - char c2 = static_cast(pgm_read_byte(s2++)); - if (c1 < c2) - return -1; - if (c1 > c2) - return 1; - if (c1 == 0 /* and c2 as well */) - return 0; - } +inline int strcmp_P(const char * a, ArduinoJson::detail::pgm_p b) { + const char * s1 = a; + const char * s2 = b.address; + ARDUINOJSON_ASSERT(s1 != NULL); + ARDUINOJSON_ASSERT(s2 != NULL); + for (;;) { + char c1 = *s1++; + char c2 = static_cast(pgm_read_byte(s2++)); + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + if (c1 == 0 /* and c2 as well */) + return 0; + } } #endif #ifndef memcmp_P -inline int memcmp_P(const void* a, ArduinoJson::detail::pgm_p b, size_t n) { - const uint8_t* p1 = reinterpret_cast(a); - const char* p2 = b.address; - ARDUINOJSON_ASSERT(p1 != NULL); - ARDUINOJSON_ASSERT(p2 != NULL); - while (n-- > 0) { - uint8_t v1 = *p1++; - uint8_t v2 = pgm_read_byte(p2++); - if (v1 != v2) - return v1 - v2; - } - return 0; +inline int memcmp_P(const void * a, ArduinoJson::detail::pgm_p b, size_t n) { + const uint8_t * p1 = reinterpret_cast(a); + const char * p2 = b.address; + ARDUINOJSON_ASSERT(p1 != NULL); + ARDUINOJSON_ASSERT(p2 != NULL); + while (n-- > 0) { + uint8_t v1 = *p1++; + uint8_t v2 = pgm_read_byte(p2++); + if (v1 != v2) + return v1 - v2; + } + return 0; } #endif #ifndef memcpy_P -inline void* memcpy_P(void* dst, ArduinoJson::detail::pgm_p src, size_t n) { - uint8_t* d = reinterpret_cast(dst); - const char* s = src.address; - ARDUINOJSON_ASSERT(d != NULL); - ARDUINOJSON_ASSERT(s != NULL); - while (n-- > 0) { - *d++ = pgm_read_byte(s++); - } - return dst; +inline void * memcpy_P(void * dst, ArduinoJson::detail::pgm_p src, size_t n) { + uint8_t * d = reinterpret_cast(dst); + const char * s = src.address; + ARDUINOJSON_ASSERT(d != NULL); + ARDUINOJSON_ASSERT(s != NULL); + while (n-- > 0) { + *d++ = pgm_read_byte(s++); + } + return dst; } #endif #ifndef pgm_read_dword inline uint32_t pgm_read_dword(ArduinoJson::detail::pgm_p p) { - uint32_t result; - memcpy_P(&result, p.address, 4); - return result; + uint32_t result; + memcpy_P(&result, p.address, 4); + return result; } #endif #ifndef pgm_read_float inline float pgm_read_float(ArduinoJson::detail::pgm_p p) { - float result; - memcpy_P(&result, p.address, sizeof(float)); - return result; + float result; + memcpy_P(&result, p.address, sizeof(float)); + return result; } #endif #ifndef pgm_read_double -# if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_FLOAT__) && \ - __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__ +#if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_FLOAT__) && __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__ inline double pgm_read_double(ArduinoJson::detail::pgm_p p) { - return pgm_read_float(p.address); + return pgm_read_float(p.address); } -# else +#else inline double pgm_read_double(ArduinoJson::detail::pgm_p p) { - double result; - memcpy_P(&result, p.address, sizeof(double)); - return result; + double result; + memcpy_P(&result, p.address, sizeof(double)); + return result; } -# endif +#endif #endif #ifndef pgm_read_ptr -inline void* pgm_read_ptr(ArduinoJson::detail::pgm_p p) { - void* result; - memcpy_P(&result, p.address, sizeof(result)); - return result; +inline void * pgm_read_ptr(ArduinoJson::detail::pgm_p p) { + void * result; + memcpy_P(&result, p.address, sizeof(result)); + return result; } #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class FlashString { - public: - static const size_t typeSortKey = 1; - FlashString(const __FlashStringHelper* str, size_t sz) - : str_(reinterpret_cast(str)), size_(sz) {} - bool isNull() const { - return !str_; - } - char operator[](size_t i) const { - ARDUINOJSON_ASSERT(str_ != 0); - ARDUINOJSON_ASSERT(i <= size_); - return static_cast(pgm_read_byte(str_ + i)); - } - const char* data() const { - return nullptr; - } - size_t size() const { - return size_; - } - friend bool stringEquals(FlashString a, RamString b) { - ARDUINOJSON_ASSERT(a.typeSortKey < b.typeSortKey); - ARDUINOJSON_ASSERT(!a.isNull()); - ARDUINOJSON_ASSERT(!b.isNull()); - if (a.size() != b.size()) - return false; - return ::memcmp_P(b.data(), a.str_, a.size_) == 0; - } - friend int stringCompare(FlashString a, RamString b) { - ARDUINOJSON_ASSERT(a.typeSortKey < b.typeSortKey); - ARDUINOJSON_ASSERT(!a.isNull()); - ARDUINOJSON_ASSERT(!b.isNull()); - size_t minsize = a.size() < b.size() ? a.size() : b.size(); - int res = ::memcmp_P(b.data(), a.str_, minsize); - if (res) - return -res; - if (a.size() < b.size()) - return -1; - if (a.size() > b.size()) - return 1; - return 0; - } - friend void stringGetChars(FlashString s, char* p, size_t n) { - ARDUINOJSON_ASSERT(s.size() <= n); - ::memcpy_P(p, s.str_, n); - } - bool isStatic() const { - return false; - } - private: - const char* str_; - size_t size_; + public: + static const size_t typeSortKey = 1; + FlashString(const __FlashStringHelper * str, size_t sz) + : str_(reinterpret_cast(str)) + , size_(sz) { + } + bool isNull() const { + return !str_; + } + char operator[](size_t i) const { + ARDUINOJSON_ASSERT(str_ != 0); + ARDUINOJSON_ASSERT(i <= size_); + return static_cast(pgm_read_byte(str_ + i)); + } + const char * data() const { + return nullptr; + } + size_t size() const { + return size_; + } + friend bool stringEquals(FlashString a, RamString b) { + ARDUINOJSON_ASSERT(a.typeSortKey < b.typeSortKey); + ARDUINOJSON_ASSERT(!a.isNull()); + ARDUINOJSON_ASSERT(!b.isNull()); + if (a.size() != b.size()) + return false; + return ::memcmp_P(b.data(), a.str_, a.size_) == 0; + } + friend int stringCompare(FlashString a, RamString b) { + ARDUINOJSON_ASSERT(a.typeSortKey < b.typeSortKey); + ARDUINOJSON_ASSERT(!a.isNull()); + ARDUINOJSON_ASSERT(!b.isNull()); + size_t minsize = a.size() < b.size() ? a.size() : b.size(); + int res = ::memcmp_P(b.data(), a.str_, minsize); + if (res) + return -res; + if (a.size() < b.size()) + return -1; + if (a.size() > b.size()) + return 1; + return 0; + } + friend void stringGetChars(FlashString s, char * p, size_t n) { + ARDUINOJSON_ASSERT(s.size() <= n); + ::memcpy_P(p, s.str_, n); + } + bool isStatic() const { + return false; + } + + private: + const char * str_; + size_t size_; }; template <> -struct StringAdapter { - using AdaptedString = FlashString; - static AdaptedString adapt(const __FlashStringHelper* s) { - return AdaptedString(s, s ? strlen_P(reinterpret_cast(s)) : 0); - } +struct StringAdapter { + using AdaptedString = FlashString; + static AdaptedString adapt(const __FlashStringHelper * s) { + return AdaptedString(s, s ? strlen_P(reinterpret_cast(s)) : 0); + } }; template <> -struct SizedStringAdapter { - using AdaptedString = FlashString; - static AdaptedString adapt(const __FlashStringHelper* s, size_t n) { - return AdaptedString(s, n); - } +struct SizedStringAdapter { + using AdaptedString = FlashString; + static AdaptedString adapt(const __FlashStringHelper * s, size_t n) { + return AdaptedString(s, n); + } }; ARDUINOJSON_END_PRIVATE_NAMESPACE #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template -enable_if_t -stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { - ARDUINOJSON_ASSERT(!s1.isNull()); - ARDUINOJSON_ASSERT(!s2.isNull()); - size_t size1 = s1.size(); - size_t size2 = s2.size(); - size_t n = size1 < size2 ? size1 : size2; - for (size_t i = 0; i < n; i++) { - if (s1[i] != s2[i]) - return s1[i] - s2[i]; - } - if (size1 < size2) - return -1; - if (size1 > size2) - return 1; - return 0; +enable_if_t stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { + ARDUINOJSON_ASSERT(!s1.isNull()); + ARDUINOJSON_ASSERT(!s2.isNull()); + size_t size1 = s1.size(); + size_t size2 = s2.size(); + size_t n = size1 < size2 ? size1 : size2; + for (size_t i = 0; i < n; i++) { + if (s1[i] != s2[i]) + return s1[i] - s2[i]; + } + if (size1 < size2) + return -1; + if (size1 > size2) + return 1; + return 0; } template -enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int> -stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { - return -stringCompare(s2, s1); +enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), int> stringCompare(TAdaptedString1 s1, TAdaptedString2 s2) { + return -stringCompare(s2, s1); } template -enable_if_t -stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { - ARDUINOJSON_ASSERT(!s1.isNull()); - ARDUINOJSON_ASSERT(!s2.isNull()); - size_t size1 = s1.size(); - size_t size2 = s2.size(); - if (size1 != size2) - return false; - for (size_t i = 0; i < size1; i++) { - if (s1[i] != s2[i]) - return false; - } - return true; +enable_if_t stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { + ARDUINOJSON_ASSERT(!s1.isNull()); + ARDUINOJSON_ASSERT(!s2.isNull()); + size_t size1 = s1.size(); + size_t size2 = s2.size(); + if (size1 != size2) + return false; + for (size_t i = 0; i < size1; i++) { + if (s1[i] != s2[i]) + return false; + } + return true; } template -enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool> -stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { - return stringEquals(s2, s1); +enable_if_t<(TAdaptedString1::typeSortKey > TAdaptedString2::typeSortKey), bool> stringEquals(TAdaptedString1 s1, TAdaptedString2 s2) { + return stringEquals(s2, s1); } template -static void stringGetChars(TAdaptedString s, char* p, size_t n) { - ARDUINOJSON_ASSERT(s.size() <= n); - for (size_t i = 0; i < n; i++) { - p[i] = s[i]; - } +static void stringGetChars(TAdaptedString s, char * p, size_t n) { + ARDUINOJSON_ASSERT(s.size() <= n); + for (size_t i = 0; i < n; i++) { + p[i] = s[i]; + } } class StringPool { - public: - StringPool() = default; - StringPool(const StringPool&) = delete; - void operator=(StringPool&& src) = delete; - ~StringPool() { - ARDUINOJSON_ASSERT(strings_ == nullptr); - } - friend void swap(StringPool& a, StringPool& b) { - swap_(a.strings_, b.strings_); - } - void clear(Allocator* allocator) { - while (strings_) { - auto node = strings_; - strings_ = node->next; - StringNode::destroy(node, allocator); + public: + StringPool() = default; + StringPool(const StringPool &) = delete; + void operator=(StringPool && src) = delete; + ~StringPool() { + ARDUINOJSON_ASSERT(strings_ == nullptr); } - } - size_t size() const { - size_t total = 0; - for (auto node = strings_; node; node = node->next) - total += sizeofString(node->length); - return total; - } - template - StringNode* add(TAdaptedString str, Allocator* allocator) { - ARDUINOJSON_ASSERT(str.isNull() == false); - auto node = get(str); - if (node) { - node->references++; - return node; + friend void swap(StringPool & a, StringPool & b) { + swap_(a.strings_, b.strings_); } - size_t n = str.size(); - node = StringNode::create(n, allocator); - if (!node) - return nullptr; - stringGetChars(str, node->data, n); - node->data[n] = 0; // force NUL terminator - add(node); - return node; - } - void add(StringNode* node) { - ARDUINOJSON_ASSERT(node != nullptr); - node->next = strings_; - strings_ = node; - } - template - StringNode* get(const TAdaptedString& str) const { - for (auto node = strings_; node; node = node->next) { - if (stringEquals(str, adaptString(node->data, node->length))) + void clear(Allocator * allocator) { + while (strings_) { + auto node = strings_; + strings_ = node->next; + StringNode::destroy(node, allocator); + } + } + size_t size() const { + size_t total = 0; + for (auto node = strings_; node; node = node->next) + total += sizeofString(node->length); + return total; + } + template + StringNode * add(TAdaptedString str, Allocator * allocator) { + ARDUINOJSON_ASSERT(str.isNull() == false); + auto node = get(str); + if (node) { + node->references++; + return node; + } + size_t n = str.size(); + node = StringNode::create(n, allocator); + if (!node) + return nullptr; + stringGetChars(str, node->data, n); + node->data[n] = 0; // force NUL terminator + add(node); return node; } - return nullptr; - } - void dereference(const char* s, Allocator* allocator) { - StringNode* prev = nullptr; - for (auto node = strings_; node; node = node->next) { - if (node->data == s) { - if (--node->references == 0) { - if (prev) - prev->next = node->next; - else - strings_ = node->next; - StringNode::destroy(node, allocator); - } - return; - } - prev = node; + void add(StringNode * node) { + ARDUINOJSON_ASSERT(node != nullptr); + node->next = strings_; + strings_ = node; } - } - private: - StringNode* strings_ = nullptr; + template + StringNode * get(const TAdaptedString & str) const { + for (auto node = strings_; node; node = node->next) { + if (stringEquals(str, adaptString(node->data, node->length))) + return node; + } + return nullptr; + } + void dereference(const char * s, Allocator * allocator) { + StringNode * prev = nullptr; + for (auto node = strings_; node; node = node->next) { + if (node->data == s) { + if (--node->references == 0) { + if (prev) + prev->next = node->next; + else + strings_ = node->next; + StringNode::destroy(node, allocator); + } + return; + } + prev = node; + } + } + + private: + StringNode * strings_ = nullptr; }; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE template class SerializedValue { - public: - explicit SerializedValue(T str) : str_(str) {} - operator T() const { - return str_; - } - const char* data() const { - return str_.c_str(); - } - size_t size() const { - return str_.length(); - } - private: - T str_; + public: + explicit SerializedValue(T str) + : str_(str) { + } + operator T() const { + return str_; + } + const char * data() const { + return str_.c_str(); + } + size_t size() const { + return str_.length(); + } + + private: + T str_; }; template -class SerializedValue { - public: - explicit SerializedValue(TChar* p, size_t n) : data_(p), size_(n) {} - operator TChar*() const { - return data_; - } - TChar* data() const { - return data_; - } - size_t size() const { - return size_; - } - private: - TChar* data_; - size_t size_; +class SerializedValue { + public: + explicit SerializedValue(TChar * p, size_t n) + : data_(p) + , size_(n) { + } + operator TChar *() const { + return data_; + } + TChar * data() const { + return data_; + } + size_t size() const { + return size_; + } + + private: + TChar * data_; + size_t size_; }; -using RawString = SerializedValue; +using RawString = SerializedValue; template inline SerializedValue serialized(T str) { - return SerializedValue(str); + return SerializedValue(str); } template -inline SerializedValue serialized(TChar* p) { - return SerializedValue(p, detail::adaptString(p).size()); +inline SerializedValue serialized(TChar * p) { + return SerializedValue(p, detail::adaptString(p).size()); } template -inline SerializedValue serialized(TChar* p, size_t n) { - return SerializedValue(p, n); +inline SerializedValue serialized(TChar * p, size_t n) { + return SerializedValue(p, n); } ARDUINOJSON_END_PUBLIC_NAMESPACE #if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" #elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE #ifndef isnan template bool isnan(T x) { - return x != x; + return x != x; } #endif #ifndef isinf template bool isinf(T x) { - return x != 0.0 && x * 2 == x; + return x != 0.0 && x * 2 == x; } #endif template struct alias_cast_t { - union { - F raw; - T data; - }; + union { + F raw; + T data; + }; }; template T alias_cast(F raw_data) { - alias_cast_t ac; - ac.raw = raw_data; - return ac.data; + alias_cast_t ac; + ac.raw = raw_data; + return ac.data; } ARDUINOJSON_END_PRIVATE_NAMESPACE #if ARDUINOJSON_ENABLE_PROGMEM #endif ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE #if ARDUINOJSON_ENABLE_PROGMEM -# ifndef ARDUINOJSON_DEFINE_PROGMEM_ARRAY -# define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, ...) \ - static type const name[] PROGMEM = __VA_ARGS__; -# endif +#ifndef ARDUINOJSON_DEFINE_PROGMEM_ARRAY +#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, ...) static type const name[] PROGMEM = __VA_ARGS__; +#endif template -inline const T* pgm_read(const T* const* p) { - return reinterpret_cast(pgm_read_ptr(p)); +inline const T * pgm_read(const T * const * p) { + return reinterpret_cast(pgm_read_ptr(p)); } -inline uint32_t pgm_read(const uint32_t* p) { - return pgm_read_dword(p); +inline uint32_t pgm_read(const uint32_t * p) { + return pgm_read_dword(p); } -inline double pgm_read(const double* p) { - return pgm_read_double(p); +inline double pgm_read(const double * p) { + return pgm_read_double(p); } -inline float pgm_read(const float* p) { - return pgm_read_float(p); +inline float pgm_read(const float * p) { + return pgm_read_float(p); } #else -# ifndef ARDUINOJSON_DEFINE_PROGMEM_ARRAY -# define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, ...) \ - static type const name[] = __VA_ARGS__; -# endif +#ifndef ARDUINOJSON_DEFINE_PROGMEM_ARRAY +#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, ...) static type const name[] = __VA_ARGS__; +#endif template -inline T pgm_read(const T* p) { - return *p; +inline T pgm_read(const T * p) { + return *p; } #endif template class pgm_ptr { - public: - explicit pgm_ptr(const T* ptr) : ptr_(ptr) {} - T operator[](intptr_t index) const { - return pgm_read(ptr_ + index); - } - private: - const T* ptr_; + public: + explicit pgm_ptr(const T * ptr) + : ptr_(ptr) { + } + T operator[](intptr_t index) const { + return pgm_read(ptr_ + index); + } + + private: + const T * ptr_; }; template struct FloatTraits {}; template struct FloatTraits { - using mantissa_type = uint64_t; - static const short mantissa_bits = 52; - static const mantissa_type mantissa_max = - (mantissa_type(1) << mantissa_bits) - 1; - using exponent_type = int16_t; - static const exponent_type exponent_max = 308; - static pgm_ptr positiveBinaryPowersOfTen() { - ARDUINOJSON_DEFINE_PROGMEM_ARRAY( // - uint64_t, factors, - { - 0x4024000000000000, // 1e1 - 0x4059000000000000, // 1e2 - 0x40C3880000000000, // 1e4 - 0x4197D78400000000, // 1e8 - 0x4341C37937E08000, // 1e16 - 0x4693B8B5B5056E17, // 1e32 - 0x4D384F03E93FF9F5, // 1e64 - 0x5A827748F9301D32, // 1e128 - 0x75154FDD7F73BF3C, // 1e256 - }); - return pgm_ptr(reinterpret_cast(factors)); - } - static pgm_ptr negativeBinaryPowersOfTen() { - ARDUINOJSON_DEFINE_PROGMEM_ARRAY( // - uint64_t, factors, - { - 0x3FB999999999999A, // 1e-1 - 0x3F847AE147AE147B, // 1e-2 - 0x3F1A36E2EB1C432D, // 1e-4 - 0x3E45798EE2308C3A, // 1e-8 - 0x3C9CD2B297D889BC, // 1e-16 - 0x3949F623D5A8A733, // 1e-32 - 0x32A50FFD44F4A73D, // 1e-64 - 0x255BBA08CF8C979D, // 1e-128 - 0x0AC8062864AC6F43 // 1e-256 - }); - return pgm_ptr(reinterpret_cast(factors)); - } - static T nan() { - return forge(0x7ff8000000000000); - } - static T inf() { - return forge(0x7ff0000000000000); - } - static T highest() { - return forge(0x7FEFFFFFFFFFFFFF); - } - template // int64_t - static T highest_for( - enable_if_t::value && is_signed::value && - sizeof(TOut) == 8, - signed>* = 0) { - return forge(0x43DFFFFFFFFFFFFF); // 9.2233720368547748e+18 - } - template // uint64_t - static T highest_for( - enable_if_t::value && is_unsigned::value && - sizeof(TOut) == 8, - unsigned>* = 0) { - return forge(0x43EFFFFFFFFFFFFF); // 1.8446744073709549568e+19 - } - static T lowest() { - return forge(0xFFEFFFFFFFFFFFFF); - } - static T forge(uint64_t bits) { - return alias_cast(bits); - } + using mantissa_type = uint64_t; + static const short mantissa_bits = 52; + static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1; + using exponent_type = int16_t; + static const exponent_type exponent_max = 308; + static pgm_ptr positiveBinaryPowersOfTen() { + ARDUINOJSON_DEFINE_PROGMEM_ARRAY( // + uint64_t, + factors, + { + 0x4024000000000000, // 1e1 + 0x4059000000000000, // 1e2 + 0x40C3880000000000, // 1e4 + 0x4197D78400000000, // 1e8 + 0x4341C37937E08000, // 1e16 + 0x4693B8B5B5056E17, // 1e32 + 0x4D384F03E93FF9F5, // 1e64 + 0x5A827748F9301D32, // 1e128 + 0x75154FDD7F73BF3C, // 1e256 + }); + return pgm_ptr(reinterpret_cast(factors)); + } + static pgm_ptr negativeBinaryPowersOfTen() { + ARDUINOJSON_DEFINE_PROGMEM_ARRAY( // + uint64_t, + factors, + { + 0x3FB999999999999A, // 1e-1 + 0x3F847AE147AE147B, // 1e-2 + 0x3F1A36E2EB1C432D, // 1e-4 + 0x3E45798EE2308C3A, // 1e-8 + 0x3C9CD2B297D889BC, // 1e-16 + 0x3949F623D5A8A733, // 1e-32 + 0x32A50FFD44F4A73D, // 1e-64 + 0x255BBA08CF8C979D, // 1e-128 + 0x0AC8062864AC6F43 // 1e-256 + }); + return pgm_ptr(reinterpret_cast(factors)); + } + static T nan() { + return forge(0x7ff8000000000000); + } + static T inf() { + return forge(0x7ff0000000000000); + } + static T highest() { + return forge(0x7FEFFFFFFFFFFFFF); + } + template // int64_t + static T highest_for(enable_if_t::value && is_signed::value && sizeof(TOut) == 8, signed> * = 0) { + return forge(0x43DFFFFFFFFFFFFF); // 9.2233720368547748e+18 + } + template // uint64_t + static T highest_for(enable_if_t::value && is_unsigned::value && sizeof(TOut) == 8, unsigned> * = 0) { + return forge(0x43EFFFFFFFFFFFFF); // 1.8446744073709549568e+19 + } + static T lowest() { + return forge(0xFFEFFFFFFFFFFFFF); + } + static T forge(uint64_t bits) { + return alias_cast(bits); + } }; template struct FloatTraits { - using mantissa_type = uint32_t; - static const short mantissa_bits = 23; - static const mantissa_type mantissa_max = - (mantissa_type(1) << mantissa_bits) - 1; - using exponent_type = int8_t; - static const exponent_type exponent_max = 38; - static pgm_ptr positiveBinaryPowersOfTen() { - ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors, - { - 0x41200000, // 1e1f - 0x42c80000, // 1e2f - 0x461c4000, // 1e4f - 0x4cbebc20, // 1e8f - 0x5a0e1bca, // 1e16f - 0x749dc5ae // 1e32f - }); - return pgm_ptr(reinterpret_cast(factors)); - } - static pgm_ptr negativeBinaryPowersOfTen() { - ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors, - { - 0x3dcccccd, // 1e-1f - 0x3c23d70a, // 1e-2f - 0x38d1b717, // 1e-4f - 0x322bcc77, // 1e-8f - 0x24e69595, // 1e-16f - 0x0a4fb11f // 1e-32f - }); - return pgm_ptr(reinterpret_cast(factors)); - } - static T forge(uint32_t bits) { - return alias_cast(bits); - } - static T nan() { - return forge(0x7fc00000); - } - static T inf() { - return forge(0x7f800000); - } - static T highest() { - return forge(0x7f7fffff); - } - template // int32_t - static T highest_for( - enable_if_t::value && is_signed::value && - sizeof(TOut) == 4, - signed>* = 0) { - return forge(0x4EFFFFFF); // 2.14748352E9 - } - template // uint32_t - static T highest_for( - enable_if_t::value && is_unsigned::value && - sizeof(TOut) == 4, - unsigned>* = 0) { - return forge(0x4F7FFFFF); // 4.29496704E9 - } - template // int64_t - static T highest_for( - enable_if_t::value && is_signed::value && - sizeof(TOut) == 8, - signed>* = 0) { - return forge(0x5EFFFFFF); // 9.22337148709896192E18 - } - template // uint64_t - static T highest_for( - enable_if_t::value && is_unsigned::value && - sizeof(TOut) == 8, - unsigned>* = 0) { - return forge(0x5F7FFFFF); // 1.844674297419792384E19 - } - static T lowest() { - return forge(0xFf7fffff); - } + using mantissa_type = uint32_t; + static const short mantissa_bits = 23; + static const mantissa_type mantissa_max = (mantissa_type(1) << mantissa_bits) - 1; + using exponent_type = int8_t; + static const exponent_type exponent_max = 38; + static pgm_ptr positiveBinaryPowersOfTen() { + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, + factors, + { + 0x41200000, // 1e1f + 0x42c80000, // 1e2f + 0x461c4000, // 1e4f + 0x4cbebc20, // 1e8f + 0x5a0e1bca, // 1e16f + 0x749dc5ae // 1e32f + }); + return pgm_ptr(reinterpret_cast(factors)); + } + static pgm_ptr negativeBinaryPowersOfTen() { + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, + factors, + { + 0x3dcccccd, // 1e-1f + 0x3c23d70a, // 1e-2f + 0x38d1b717, // 1e-4f + 0x322bcc77, // 1e-8f + 0x24e69595, // 1e-16f + 0x0a4fb11f // 1e-32f + }); + return pgm_ptr(reinterpret_cast(factors)); + } + static T forge(uint32_t bits) { + return alias_cast(bits); + } + static T nan() { + return forge(0x7fc00000); + } + static T inf() { + return forge(0x7f800000); + } + static T highest() { + return forge(0x7f7fffff); + } + template // int32_t + static T highest_for(enable_if_t::value && is_signed::value && sizeof(TOut) == 4, signed> * = 0) { + return forge(0x4EFFFFFF); // 2.14748352E9 + } + template // uint32_t + static T highest_for(enable_if_t::value && is_unsigned::value && sizeof(TOut) == 4, unsigned> * = 0) { + return forge(0x4F7FFFFF); // 4.29496704E9 + } + template // int64_t + static T highest_for(enable_if_t::value && is_signed::value && sizeof(TOut) == 8, signed> * = 0) { + return forge(0x5EFFFFFF); // 9.22337148709896192E18 + } + template // uint64_t + static T highest_for(enable_if_t::value && is_unsigned::value && sizeof(TOut) == 8, unsigned> * = 0) { + return forge(0x5F7FFFFF); // 1.844674297419792384E19 + } + static T lowest() { + return forge(0xFf7fffff); + } }; template inline TFloat make_float(TFloat m, TExponent e) { - using traits = FloatTraits; - auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen() - : traits::negativeBinaryPowersOfTen(); - if (e <= 0) - e = TExponent(-e); - for (uint8_t index = 0; e != 0; index++) { - if (e & 1) - m *= powersOfTen[index]; - e >>= 1; - } - return m; + using traits = FloatTraits; + auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen() : traits::negativeBinaryPowersOfTen(); + if (e <= 0) + e = TExponent(-e); + for (uint8_t index = 0; e != 0; index++) { + if (e & 1) + m *= powersOfTen[index]; + e >>= 1; + } + return m; } ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE @@ -1727,992 +1687,953 @@ using JsonFloat = float; ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template -enable_if_t::value && is_unsigned::value && - is_integral::value && sizeof(TOut) <= sizeof(TIn), - bool> -canConvertNumber(TIn value) { - return value <= TIn(numeric_limits::highest()); +enable_if_t::value && is_unsigned::value && is_integral::value && sizeof(TOut) <= sizeof(TIn), bool> canConvertNumber(TIn value) { + return value <= TIn(numeric_limits::highest()); } template -enable_if_t::value && is_unsigned::value && - is_integral::value && sizeof(TIn) < sizeof(TOut), - bool> +enable_if_t::value && is_unsigned::value && is_integral::value && sizeof(TIn) < sizeof(TOut), bool> canConvertNumber(TIn) { + return true; +} +template +enable_if_t::value && is_floating_point::value, bool> canConvertNumber(TIn) { + return true; +} +template +enable_if_t::value && is_signed::value && is_integral::value && is_signed::value && sizeof(TOut) < sizeof(TIn), bool> +canConvertNumber(TIn value) { + return value >= TIn(numeric_limits::lowest()) && value <= TIn(numeric_limits::highest()); +} +template +enable_if_t::value && is_signed::value && is_integral::value && is_signed::value && sizeof(TIn) <= sizeof(TOut), bool> canConvertNumber(TIn) { - return true; + return true; } template -enable_if_t::value && is_floating_point::value, bool> -canConvertNumber(TIn) { - return true; -} -template -enable_if_t::value && is_signed::value && - is_integral::value && is_signed::value && - sizeof(TOut) < sizeof(TIn), - bool> +enable_if_t::value && is_signed::value && is_integral::value && is_unsigned::value && sizeof(TOut) >= sizeof(TIn), bool> canConvertNumber(TIn value) { - return value >= TIn(numeric_limits::lowest()) && - value <= TIn(numeric_limits::highest()); + if (value < 0) + return false; + return TOut(value) <= numeric_limits::highest(); } template -enable_if_t::value && is_signed::value && - is_integral::value && is_signed::value && - sizeof(TIn) <= sizeof(TOut), - bool> -canConvertNumber(TIn) { - return true; -} -template -enable_if_t::value && is_signed::value && - is_integral::value && is_unsigned::value && - sizeof(TOut) >= sizeof(TIn), - bool> +enable_if_t::value && is_signed::value && is_integral::value && is_unsigned::value && sizeof(TOut) < sizeof(TIn), bool> canConvertNumber(TIn value) { - if (value < 0) - return false; - return TOut(value) <= numeric_limits::highest(); + if (value < 0) + return false; + return value <= TIn(numeric_limits::highest()); } template -enable_if_t::value && is_signed::value && - is_integral::value && is_unsigned::value && - sizeof(TOut) < sizeof(TIn), - bool> -canConvertNumber(TIn value) { - if (value < 0) - return false; - return value <= TIn(numeric_limits::highest()); +enable_if_t::value && is_integral::value && sizeof(TOut) < sizeof(TIn), bool> canConvertNumber(TIn value) { + return value >= numeric_limits::lowest() && value <= numeric_limits::highest(); } template -enable_if_t::value && is_integral::value && - sizeof(TOut) < sizeof(TIn), - bool> -canConvertNumber(TIn value) { - return value >= numeric_limits::lowest() && - value <= numeric_limits::highest(); +enable_if_t::value && is_integral::value && sizeof(TOut) >= sizeof(TIn), bool> canConvertNumber(TIn value) { + return value >= numeric_limits::lowest() && value <= FloatTraits::template highest_for(); } template -enable_if_t::value && is_integral::value && - sizeof(TOut) >= sizeof(TIn), - bool> -canConvertNumber(TIn value) { - return value >= numeric_limits::lowest() && - value <= FloatTraits::template highest_for(); -} -template -enable_if_t::value && is_floating_point::value, - bool> -canConvertNumber(TIn) { - return true; +enable_if_t::value && is_floating_point::value, bool> canConvertNumber(TIn) { + return true; } template TOut convertNumber(TIn value) { - return canConvertNumber(value) ? TOut(value) : 0; + return canConvertNumber(value) ? TOut(value) : 0; } ARDUINOJSON_END_PRIVATE_NAMESPACE #if defined(__clang__) -# pragma clang diagnostic pop +#pragma clang diagnostic pop #elif defined(__GNUC__) -# pragma GCC diagnostic pop +#pragma GCC diagnostic pop #endif #if ARDUINOJSON_ENABLE_STD_STREAM #include #endif ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonString { - friend struct detail::StringAdapter; - public: - JsonString() : str_(nullptr, 0, true) {} - JsonString(const char* data, bool isStatic = false) - : str_(data, data ? ::strlen(data) : 0, isStatic) {} - template ::value && - !detail::is_same::value, - int> = 0> - JsonString(const char* data, TSize sz, bool isStatic = false) - : str_(data, size_t(sz), isStatic) {} - const char* c_str() const { - return str_.data(); - } - bool isNull() const { - return str_.isNull(); - } - bool isStatic() const { - return str_.isStatic(); - } - size_t size() const { - return str_.size(); - } - explicit operator bool() const { - return str_.data() != 0; - } - friend bool operator==(JsonString lhs, JsonString rhs) { - if (lhs.size() != rhs.size()) - return false; - if (lhs.c_str() == rhs.c_str()) - return true; - if (!lhs.c_str()) - return false; - if (!rhs.c_str()) - return false; - return memcmp(lhs.c_str(), rhs.c_str(), lhs.size()) == 0; - } - friend bool operator!=(JsonString lhs, JsonString rhs) { - return !(lhs == rhs); - } + friend struct detail::StringAdapter; + + public: + JsonString() + : str_(nullptr, 0, true) { + } + JsonString(const char * data, bool isStatic = false) + : str_(data, data ? ::strlen(data) : 0, isStatic) { + } + template ::value && !detail::is_same::value, int> = 0> + JsonString(const char * data, TSize sz, bool isStatic = false) + : str_(data, size_t(sz), isStatic) { + } + const char * c_str() const { + return str_.data(); + } + bool isNull() const { + return str_.isNull(); + } + bool isStatic() const { + return str_.isStatic(); + } + size_t size() const { + return str_.size(); + } + explicit operator bool() const { + return str_.data() != 0; + } + friend bool operator==(JsonString lhs, JsonString rhs) { + if (lhs.size() != rhs.size()) + return false; + if (lhs.c_str() == rhs.c_str()) + return true; + if (!lhs.c_str()) + return false; + if (!rhs.c_str()) + return false; + return memcmp(lhs.c_str(), rhs.c_str(), lhs.size()) == 0; + } + friend bool operator!=(JsonString lhs, JsonString rhs) { + return !(lhs == rhs); + } #if ARDUINOJSON_ENABLE_STD_STREAM - friend std::ostream& operator<<(std::ostream& lhs, const JsonString& rhs) { - lhs.write(rhs.c_str(), static_cast(rhs.size())); - return lhs; - } + friend std::ostream & operator<<(std::ostream & lhs, const JsonString & rhs) { + lhs.write(rhs.c_str(), static_cast(rhs.size())); + return lhs; + } #endif - private: - detail::RamString str_; + private: + detail::RamString str_; }; namespace detail { template <> struct StringAdapter { - using AdaptedString = RamString; - static const AdaptedString& adapt(const JsonString& s) { - return s.str_; - } + using AdaptedString = RamString; + static const AdaptedString & adapt(const JsonString & s) { + return s.str_; + } }; -} // namespace detail +} // namespace detail ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class VariantData; class ResourceManager; class CollectionIterator { - friend class CollectionData; - public: - CollectionIterator() : slot_(nullptr), currentId_(NULL_SLOT) {} - void next(const ResourceManager* resources); - bool done() const { - return slot_ == nullptr; - } - bool operator==(const CollectionIterator& other) const { - return slot_ == other.slot_; - } - bool operator!=(const CollectionIterator& other) const { - return slot_ != other.slot_; - } - VariantData* operator->() { - ARDUINOJSON_ASSERT(slot_ != nullptr); - return data(); - } - VariantData& operator*() { - ARDUINOJSON_ASSERT(slot_ != nullptr); - return *data(); - } - const VariantData& operator*() const { - ARDUINOJSON_ASSERT(slot_ != nullptr); - return *data(); - } - VariantData* data() { - return reinterpret_cast(slot_); - } - const VariantData* data() const { - return reinterpret_cast(slot_); - } - private: - CollectionIterator(VariantData* slot, SlotId slotId); - VariantData* slot_; - SlotId currentId_, nextId_; + friend class CollectionData; + + public: + CollectionIterator() + : slot_(nullptr) + , currentId_(NULL_SLOT) { + } + void next(const ResourceManager * resources); + bool done() const { + return slot_ == nullptr; + } + bool operator==(const CollectionIterator & other) const { + return slot_ == other.slot_; + } + bool operator!=(const CollectionIterator & other) const { + return slot_ != other.slot_; + } + VariantData * operator->() { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return data(); + } + VariantData & operator*() { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return *data(); + } + const VariantData & operator*() const { + ARDUINOJSON_ASSERT(slot_ != nullptr); + return *data(); + } + VariantData * data() { + return reinterpret_cast(slot_); + } + const VariantData * data() const { + return reinterpret_cast(slot_); + } + + private: + CollectionIterator(VariantData * slot, SlotId slotId); + VariantData * slot_; + SlotId currentId_, nextId_; }; class CollectionData { - SlotId head_ = NULL_SLOT; - SlotId tail_ = NULL_SLOT; - public: - static void* operator new(size_t, void* p) noexcept { - return p; - } - static void operator delete(void*, void*) noexcept {} - using iterator = CollectionIterator; - iterator createIterator(const ResourceManager* resources) const; - size_t size(const ResourceManager*) const; - size_t nesting(const ResourceManager*) const; - void clear(ResourceManager* resources); - static void clear(CollectionData* collection, ResourceManager* resources) { - if (!collection) - return; - collection->clear(resources); - } - SlotId head() const { - return head_; - } - protected: - void appendOne(Slot slot, const ResourceManager* resources); - void appendPair(Slot key, Slot value, - const ResourceManager* resources); - void removeOne(iterator it, ResourceManager* resources); - void removePair(iterator it, ResourceManager* resources); - private: - Slot getPreviousSlot(VariantData*, const ResourceManager*) const; + SlotId head_ = NULL_SLOT; + SlotId tail_ = NULL_SLOT; + + public: + static void * operator new(size_t, void * p) noexcept { + return p; + } + static void operator delete(void *, void *) noexcept { + } + using iterator = CollectionIterator; + iterator createIterator(const ResourceManager * resources) const; + size_t size(const ResourceManager *) const; + size_t nesting(const ResourceManager *) const; + void clear(ResourceManager * resources); + static void clear(CollectionData * collection, ResourceManager * resources) { + if (!collection) + return; + collection->clear(resources); + } + SlotId head() const { + return head_; + } + + protected: + void appendOne(Slot slot, const ResourceManager * resources); + void appendPair(Slot key, Slot value, const ResourceManager * resources); + void removeOne(iterator it, ResourceManager * resources); + void removePair(iterator it, ResourceManager * resources); + + private: + Slot getPreviousSlot(VariantData *, const ResourceManager *) const; }; -inline const VariantData* collectionToVariant( - const CollectionData* collection) { - const void* data = collection; // prevent warning cast-align - return reinterpret_cast(data); +inline const VariantData * collectionToVariant(const CollectionData * collection) { + const void * data = collection; // prevent warning cast-align + return reinterpret_cast(data); } -inline VariantData* collectionToVariant(CollectionData* collection) { - void* data = collection; // prevent warning cast-align - return reinterpret_cast(data); +inline VariantData * collectionToVariant(CollectionData * collection) { + void * data = collection; // prevent warning cast-align + return reinterpret_cast(data); } class ArrayData : public CollectionData { - public: - VariantData* addElement(ResourceManager* resources); - static VariantData* addElement(ArrayData* array, ResourceManager* resources) { - if (!array) - return nullptr; - return array->addElement(resources); - } - template - bool addValue(const T& value, ResourceManager* resources); - template - static bool addValue(ArrayData* array, const T& value, - ResourceManager* resources) { - if (!array) - return false; - return array->addValue(value, resources); - } - VariantData* getOrAddElement(size_t index, ResourceManager* resources); - VariantData* getElement(size_t index, const ResourceManager* resources) const; - static VariantData* getElement(const ArrayData* array, size_t index, - const ResourceManager* resources) { - if (!array) - return nullptr; - return array->getElement(index, resources); - } - void removeElement(size_t index, ResourceManager* resources); - static void removeElement(ArrayData* array, size_t index, - ResourceManager* resources) { - if (!array) - return; - array->removeElement(index, resources); - } - void remove(iterator it, ResourceManager* resources) { - CollectionData::removeOne(it, resources); - } - static void remove(ArrayData* array, iterator it, - ResourceManager* resources) { - if (array) - return array->remove(it, resources); - } - private: - iterator at(size_t index, const ResourceManager* resources) const; + public: + VariantData * addElement(ResourceManager * resources); + static VariantData * addElement(ArrayData * array, ResourceManager * resources) { + if (!array) + return nullptr; + return array->addElement(resources); + } + template + bool addValue(const T & value, ResourceManager * resources); + template + static bool addValue(ArrayData * array, const T & value, ResourceManager * resources) { + if (!array) + return false; + return array->addValue(value, resources); + } + VariantData * getOrAddElement(size_t index, ResourceManager * resources); + VariantData * getElement(size_t index, const ResourceManager * resources) const; + static VariantData * getElement(const ArrayData * array, size_t index, const ResourceManager * resources) { + if (!array) + return nullptr; + return array->getElement(index, resources); + } + void removeElement(size_t index, ResourceManager * resources); + static void removeElement(ArrayData * array, size_t index, ResourceManager * resources) { + if (!array) + return; + array->removeElement(index, resources); + } + void remove(iterator it, ResourceManager * resources) { + CollectionData::removeOne(it, resources); + } + static void remove(ArrayData * array, iterator it, ResourceManager * resources) { + if (array) + return array->remove(it, resources); + } + + private: + iterator at(size_t index, const ResourceManager * resources) const; }; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE #if ARDUINOJSON_USE_LONG_LONG using JsonInteger = int64_t; -using JsonUInt = uint64_t; +using JsonUInt = uint64_t; #else using JsonInteger = long; -using JsonUInt = unsigned long; +using JsonUInt = unsigned long; #endif ARDUINOJSON_END_PUBLIC_NAMESPACE -#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \ - static_assert(sizeof(T) <= sizeof(ArduinoJson::JsonInteger), \ - "To use 64-bit integers with ArduinoJson, you must set " \ - "ARDUINOJSON_USE_LONG_LONG to 1. See " \ - "https://arduinojson.org/v7/api/config/use_long_long/"); +#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \ + static_assert(sizeof(T) <= sizeof(ArduinoJson::JsonInteger), \ + "To use 64-bit integers with ArduinoJson, you must set " \ + "ARDUINOJSON_USE_LONG_LONG to 1. See " \ + "https://arduinojson.org/v7/api/config/use_long_long/"); ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class ObjectData : public CollectionData { - public: - template - VariantData* addMember(TAdaptedString key, ResourceManager* resources); - VariantData* addPair(VariantData** value, ResourceManager* resources); - template - VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources); - template - VariantData* getMember(TAdaptedString key, - const ResourceManager* resources) const; - template - static VariantData* getMember(const ObjectData* object, TAdaptedString key, - const ResourceManager* resources) { - if (!object) - return nullptr; - return object->getMember(key, resources); - } - template - void removeMember(TAdaptedString key, ResourceManager* resources); - template - static void removeMember(ObjectData* obj, TAdaptedString key, - ResourceManager* resources) { - if (!obj) - return; - obj->removeMember(key, resources); - } - void remove(iterator it, ResourceManager* resources) { - CollectionData::removePair(it, resources); - } - static void remove(ObjectData* obj, ObjectData::iterator it, - ResourceManager* resources) { - if (!obj) - return; - obj->remove(it, resources); - } - size_t size(const ResourceManager* resources) const { - return CollectionData::size(resources) / 2; - } - static size_t size(const ObjectData* obj, const ResourceManager* resources) { - if (!obj) - return 0; - return obj->size(resources); - } - private: - template - iterator findKey(TAdaptedString key, const ResourceManager* resources) const; + public: + template + VariantData * addMember(TAdaptedString key, ResourceManager * resources); + VariantData * addPair(VariantData ** value, ResourceManager * resources); + template + VariantData * getOrAddMember(TAdaptedString key, ResourceManager * resources); + template + VariantData * getMember(TAdaptedString key, const ResourceManager * resources) const; + template + static VariantData * getMember(const ObjectData * object, TAdaptedString key, const ResourceManager * resources) { + if (!object) + return nullptr; + return object->getMember(key, resources); + } + template + void removeMember(TAdaptedString key, ResourceManager * resources); + template + static void removeMember(ObjectData * obj, TAdaptedString key, ResourceManager * resources) { + if (!obj) + return; + obj->removeMember(key, resources); + } + void remove(iterator it, ResourceManager * resources) { + CollectionData::removePair(it, resources); + } + static void remove(ObjectData * obj, ObjectData::iterator it, ResourceManager * resources) { + if (!obj) + return; + obj->remove(it, resources); + } + size_t size(const ResourceManager * resources) const { + return CollectionData::size(resources) / 2; + } + static size_t size(const ObjectData * obj, const ResourceManager * resources) { + if (!obj) + return 0; + return obj->size(resources); + } + + private: + template + iterator findKey(TAdaptedString key, const ResourceManager * resources) const; }; enum class VariantTypeBits : uint8_t { - OwnedStringBit = 0x01, // 0000 0001 - NumberBit = 0x08, // 0000 1000 + OwnedStringBit = 0x01, // 0000 0001 + NumberBit = 0x08, // 0000 1000 #if ARDUINOJSON_USE_EXTENSIONS - ExtensionBit = 0x10, // 0001 0000 + ExtensionBit = 0x10, // 0001 0000 #endif - CollectionMask = 0x60, + CollectionMask = 0x60, }; enum class VariantType : uint8_t { - Null = 0, // 0000 0000 - TinyString = 0x02, // 0000 0010 - RawString = 0x03, // 0000 0011 - LinkedString = 0x04, // 0000 0100 - OwnedString = 0x05, // 0000 0101 - Boolean = 0x06, // 0000 0110 - Uint32 = 0x0A, // 0000 1010 - Int32 = 0x0C, // 0000 1100 - Float = 0x0E, // 0000 1110 + Null = 0, // 0000 0000 + TinyString = 0x02, // 0000 0010 + RawString = 0x03, // 0000 0011 + LinkedString = 0x04, // 0000 0100 + OwnedString = 0x05, // 0000 0101 + Boolean = 0x06, // 0000 0110 + Uint32 = 0x0A, // 0000 1010 + Int32 = 0x0C, // 0000 1100 + Float = 0x0E, // 0000 1110 #if ARDUINOJSON_USE_LONG_LONG - Uint64 = 0x1A, // 0001 1010 - Int64 = 0x1C, // 0001 1100 + Uint64 = 0x1A, // 0001 1010 + Int64 = 0x1C, // 0001 1100 #endif #if ARDUINOJSON_USE_DOUBLE - Double = 0x1E, // 0001 1110 + Double = 0x1E, // 0001 1110 #endif - Object = 0x20, - Array = 0x40, + Object = 0x20, + Array = 0x40, }; inline bool operator&(VariantType type, VariantTypeBits bit) { - return (uint8_t(type) & uint8_t(bit)) != 0; + return (uint8_t(type) & uint8_t(bit)) != 0; } const size_t tinyStringMaxLength = 3; union VariantContent { - VariantContent() {} - float asFloat; - bool asBoolean; - uint32_t asUint32; - int32_t asInt32; + VariantContent() { + } + float asFloat; + bool asBoolean; + uint32_t asUint32; + int32_t asInt32; #if ARDUINOJSON_USE_EXTENSIONS - SlotId asSlotId; + SlotId asSlotId; #endif - ArrayData asArray; - ObjectData asObject; - CollectionData asCollection; - const char* asLinkedString; - struct StringNode* asOwnedString; - char asTinyString[tinyStringMaxLength + 1]; + ArrayData asArray; + ObjectData asObject; + CollectionData asCollection; + const char * asLinkedString; + struct StringNode * asOwnedString; + char asTinyString[tinyStringMaxLength + 1]; }; #if ARDUINOJSON_USE_EXTENSIONS union VariantExtension { -# if ARDUINOJSON_USE_LONG_LONG - uint64_t asUint64; - int64_t asInt64; -# endif -# if ARDUINOJSON_USE_DOUBLE - double asDouble; -# endif +#if ARDUINOJSON_USE_LONG_LONG + uint64_t asUint64; + int64_t asInt64; +#endif +#if ARDUINOJSON_USE_DOUBLE + double asDouble; +#endif }; #endif template -T parseNumber(const char* s); +T parseNumber(const char * s); template -static bool isTinyString(const T& s, size_t n) { - if (n > tinyStringMaxLength) - return false; - bool containsNul = false; - for (uint8_t i = 0; i < uint8_t(n); i++) - containsNul |= !s[i]; - return !containsNul; +static bool isTinyString(const T & s, size_t n) { + if (n > tinyStringMaxLength) + return false; + bool containsNul = false; + for (uint8_t i = 0; i < uint8_t(n); i++) + containsNul |= !s[i]; + return !containsNul; } class VariantData { - VariantContent content_; // must be first to allow cast from array to variant - VariantType type_; - SlotId next_; - public: - static void* operator new(size_t, void* p) noexcept { - return p; - } - static void operator delete(void*, void*) noexcept {} - VariantData() : type_(VariantType::Null), next_(NULL_SLOT) {} - SlotId next() const { - return next_; - } - void setNext(SlotId slot) { - next_ = slot; - } - template - typename TVisitor::result_type accept( - TVisitor& visit, const ResourceManager* resources) const { -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); -#else - (void)resources; // silence warning -#endif - switch (type_) { - case VariantType::Float: - return visit.visit(content_.asFloat); -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return visit.visit(extension->asDouble); -#endif - case VariantType::Array: - return visit.visit(content_.asArray); - case VariantType::Object: - return visit.visit(content_.asObject); - case VariantType::TinyString: - return visit.visit(JsonString(content_.asTinyString)); - case VariantType::LinkedString: - return visit.visit(JsonString(content_.asLinkedString, true)); - case VariantType::OwnedString: - return visit.visit(JsonString(content_.asOwnedString->data, - content_.asOwnedString->length)); - case VariantType::RawString: - return visit.visit(RawString(content_.asOwnedString->data, - content_.asOwnedString->length)); - case VariantType::Int32: - return visit.visit(static_cast(content_.asInt32)); - case VariantType::Uint32: - return visit.visit(static_cast(content_.asUint32)); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Int64: - return visit.visit(extension->asInt64); - case VariantType::Uint64: - return visit.visit(extension->asUint64); -#endif - case VariantType::Boolean: - return visit.visit(content_.asBoolean != 0); - default: - return visit.visit(nullptr); + VariantContent content_; // must be first to allow cast from array to variant + VariantType type_; + SlotId next_; + + public: + static void * operator new(size_t, void * p) noexcept { + return p; } - } - template - static typename TVisitor::result_type accept(const VariantData* var, - const ResourceManager* resources, - TVisitor& visit) { - if (var != 0) - return var->accept(visit, resources); - else - return visit.visit(nullptr); - } - VariantData* addElement(ResourceManager* resources) { - auto array = isNull() ? &toArray() : asArray(); - return detail::ArrayData::addElement(array, resources); - } - static VariantData* addElement(VariantData* var, ResourceManager* resources) { - if (!var) - return nullptr; - return var->addElement(resources); - } - template - bool addValue(const T& value, ResourceManager* resources) { - auto array = isNull() ? &toArray() : asArray(); - return detail::ArrayData::addValue(array, value, resources); - } - template - static bool addValue(VariantData* var, const T& value, - ResourceManager* resources) { - if (!var) - return false; - return var->addValue(value, resources); - } - bool asBoolean(const ResourceManager* resources) const { + static void operator delete(void *, void *) noexcept { + } + VariantData() + : type_(VariantType::Null) + , next_(NULL_SLOT) { + } + SlotId next() const { + return next_; + } + void setNext(SlotId slot) { + next_ = slot; + } + template + typename TVisitor::result_type accept(TVisitor & visit, const ResourceManager * resources) const { #if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); + auto extension = getExtension(resources); #else - (void)resources; // silence warning + (void)resources; // silence warning #endif - switch (type_) { - case VariantType::Boolean: - return content_.asBoolean; - case VariantType::Uint32: - case VariantType::Int32: - return content_.asUint32 != 0; - case VariantType::Float: - return content_.asFloat != 0; + switch (type_) { + case VariantType::Float: + return visit.visit(content_.asFloat); #if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return extension->asDouble != 0; + case VariantType::Double: + return visit.visit(extension->asDouble); #endif - case VariantType::Null: - return false; + case VariantType::Array: + return visit.visit(content_.asArray); + case VariantType::Object: + return visit.visit(content_.asObject); + case VariantType::TinyString: + return visit.visit(JsonString(content_.asTinyString)); + case VariantType::LinkedString: + return visit.visit(JsonString(content_.asLinkedString, true)); + case VariantType::OwnedString: + return visit.visit(JsonString(content_.asOwnedString->data, content_.asOwnedString->length)); + case VariantType::RawString: + return visit.visit(RawString(content_.asOwnedString->data, content_.asOwnedString->length)); + case VariantType::Int32: + return visit.visit(static_cast(content_.asInt32)); + case VariantType::Uint32: + return visit.visit(static_cast(content_.asUint32)); #if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - case VariantType::Int64: - return extension->asUint64 != 0; + case VariantType::Int64: + return visit.visit(extension->asInt64); + case VariantType::Uint64: + return visit.visit(extension->asUint64); #endif - default: + case VariantType::Boolean: + return visit.visit(content_.asBoolean != 0); + default: + return visit.visit(nullptr); + } + } + template + static typename TVisitor::result_type accept(const VariantData * var, const ResourceManager * resources, TVisitor & visit) { + if (var != 0) + return var->accept(visit, resources); + else + return visit.visit(nullptr); + } + VariantData * addElement(ResourceManager * resources) { + auto array = isNull() ? &toArray() : asArray(); + return detail::ArrayData::addElement(array, resources); + } + static VariantData * addElement(VariantData * var, ResourceManager * resources) { + if (!var) + return nullptr; + return var->addElement(resources); + } + template + bool addValue(const T & value, ResourceManager * resources) { + auto array = isNull() ? &toArray() : asArray(); + return detail::ArrayData::addValue(array, value, resources); + } + template + static bool addValue(VariantData * var, const T & value, ResourceManager * resources) { + if (!var) + return false; + return var->addValue(value, resources); + } + bool asBoolean(const ResourceManager * resources) const { +#if ARDUINOJSON_USE_EXTENSIONS + auto extension = getExtension(resources); +#else + (void)resources; // silence warning +#endif + switch (type_) { + case VariantType::Boolean: + return content_.asBoolean; + case VariantType::Uint32: + case VariantType::Int32: + return content_.asUint32 != 0; + case VariantType::Float: + return content_.asFloat != 0; +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return extension->asDouble != 0; +#endif + case VariantType::Null: + return false; +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + case VariantType::Int64: + return extension->asUint64 != 0; +#endif + default: + return true; + } + } + ArrayData * asArray() { + return isArray() ? &content_.asArray : 0; + } + const ArrayData * asArray() const { + return const_cast(this)->asArray(); + } + CollectionData * asCollection() { + return isCollection() ? &content_.asCollection : 0; + } + const CollectionData * asCollection() const { + return const_cast(this)->asCollection(); + } + template + T asFloat(const ResourceManager * resources) const { + static_assert(is_floating_point::value, "T must be a floating point"); +#if ARDUINOJSON_USE_EXTENSIONS + auto extension = getExtension(resources); +#else + (void)resources; // silence warning +#endif + const char * str = nullptr; + switch (type_) { + case VariantType::Boolean: + return static_cast(content_.asBoolean); + case VariantType::Uint32: + return static_cast(content_.asUint32); + case VariantType::Int32: + return static_cast(content_.asInt32); +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return static_cast(extension->asUint64); + case VariantType::Int64: + return static_cast(extension->asInt64); +#endif + case VariantType::TinyString: + str = content_.asTinyString; + break; + case VariantType::LinkedString: + str = content_.asLinkedString; + break; + case VariantType::OwnedString: + str = content_.asOwnedString->data; + break; + case VariantType::Float: + return static_cast(content_.asFloat); +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return static_cast(extension->asDouble); +#endif + default: + return 0.0; + } + ARDUINOJSON_ASSERT(str != nullptr); + return parseNumber(str); + } + template + T asIntegral(const ResourceManager * resources) const { + static_assert(is_integral::value, "T must be an integral type"); +#if ARDUINOJSON_USE_EXTENSIONS + auto extension = getExtension(resources); +#else + (void)resources; // silence warning +#endif + const char * str = nullptr; + switch (type_) { + case VariantType::Boolean: + return content_.asBoolean; + case VariantType::Uint32: + return convertNumber(content_.asUint32); + case VariantType::Int32: + return convertNumber(content_.asInt32); +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return convertNumber(extension->asUint64); + case VariantType::Int64: + return convertNumber(extension->asInt64); +#endif + case VariantType::TinyString: + str = content_.asTinyString; + break; + case VariantType::LinkedString: + str = content_.asLinkedString; + break; + case VariantType::OwnedString: + str = content_.asOwnedString->data; + break; + case VariantType::Float: + return convertNumber(content_.asFloat); +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return convertNumber(extension->asDouble); +#endif + default: + return 0; + } + ARDUINOJSON_ASSERT(str != nullptr); + return parseNumber(str); + } + ObjectData * asObject() { + return isObject() ? &content_.asObject : 0; + } + const ObjectData * asObject() const { + return const_cast(this)->asObject(); + } + JsonString asRawString() const { + switch (type_) { + case VariantType::RawString: + return JsonString(content_.asOwnedString->data, content_.asOwnedString->length); + default: + return JsonString(); + } + } + JsonString asString() const { + switch (type_) { + case VariantType::TinyString: + return JsonString(content_.asTinyString); + case VariantType::LinkedString: + return JsonString(content_.asLinkedString, true); + case VariantType::OwnedString: + return JsonString(content_.asOwnedString->data, content_.asOwnedString->length); + default: + return JsonString(); + } + } +#if ARDUINOJSON_USE_EXTENSIONS + const VariantExtension * getExtension(const ResourceManager * resources) const; +#endif + VariantData * getElement(size_t index, const ResourceManager * resources) const { + return ArrayData::getElement(asArray(), index, resources); + } + static VariantData * getElement(const VariantData * var, size_t index, const ResourceManager * resources) { + return var != 0 ? var->getElement(index, resources) : 0; + } + template + VariantData * getMember(TAdaptedString key, const ResourceManager * resources) const { + return ObjectData::getMember(asObject(), key, resources); + } + template + static VariantData * getMember(const VariantData * var, TAdaptedString key, const ResourceManager * resources) { + if (!var) + return 0; + return var->getMember(key, resources); + } + VariantData * getOrAddElement(size_t index, ResourceManager * resources) { + auto array = isNull() ? &toArray() : asArray(); + if (!array) + return nullptr; + return array->getOrAddElement(index, resources); + } + template + VariantData * getOrAddMember(TAdaptedString key, ResourceManager * resources) { + if (key.isNull()) + return nullptr; + auto obj = isNull() ? &toObject() : asObject(); + if (!obj) + return nullptr; + return obj->getOrAddMember(key, resources); + } + bool isArray() const { + return type_ == VariantType::Array; + } + bool isBoolean() const { + return type_ == VariantType::Boolean; + } + bool isCollection() const { + return type_ & VariantTypeBits::CollectionMask; + } + bool isFloat() const { + return type_ & VariantTypeBits::NumberBit; + } + template + bool isInteger(const ResourceManager * resources) const { +#if ARDUINOJSON_USE_LONG_LONG + auto extension = getExtension(resources); +#else + (void)resources; // silence warning +#endif + switch (type_) { + case VariantType::Uint32: + return canConvertNumber(content_.asUint32); + case VariantType::Int32: + return canConvertNumber(content_.asInt32); +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return canConvertNumber(extension->asUint64); + case VariantType::Int64: + return canConvertNumber(extension->asInt64); +#endif + default: + return false; + } + } + bool isNull() const { + return type_ == VariantType::Null; + } + static bool isNull(const VariantData * var) { + if (!var) + return true; + return var->isNull(); + } + bool isObject() const { + return type_ == VariantType::Object; + } + bool isString() const { + return type_ == VariantType::LinkedString || type_ == VariantType::OwnedString || type_ == VariantType::TinyString; + } + size_t nesting(const ResourceManager * resources) const { + auto collection = asCollection(); + if (collection) + return collection->nesting(resources); + else + return 0; + } + static size_t nesting(const VariantData * var, const ResourceManager * resources) { + if (!var) + return 0; + return var->nesting(resources); + } + void removeElement(size_t index, ResourceManager * resources) { + ArrayData::removeElement(asArray(), index, resources); + } + static void removeElement(VariantData * var, size_t index, ResourceManager * resources) { + if (!var) + return; + var->removeElement(index, resources); + } + template + void removeMember(TAdaptedString key, ResourceManager * resources) { + ObjectData::removeMember(asObject(), key, resources); + } + template + static void removeMember(VariantData * var, TAdaptedString key, ResourceManager * resources) { + if (!var) + return; + var->removeMember(key, resources); + } + void reset() { + type_ = VariantType::Null; + } + void setBoolean(bool value) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + type_ = VariantType::Boolean; + content_.asBoolean = value; + } + template + enable_if_t setFloat(T value, ResourceManager *) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + type_ = VariantType::Float; + content_.asFloat = value; return true; } - } - ArrayData* asArray() { - return isArray() ? &content_.asArray : 0; - } - const ArrayData* asArray() const { - return const_cast(this)->asArray(); - } - CollectionData* asCollection() { - return isCollection() ? &content_.asCollection : 0; - } - const CollectionData* asCollection() const { - return const_cast(this)->asCollection(); - } - template - T asFloat(const ResourceManager* resources) const { - static_assert(is_floating_point::value, "T must be a floating point"); -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); -#else - (void)resources; // silence warning -#endif - const char* str = nullptr; - switch (type_) { - case VariantType::Boolean: - return static_cast(content_.asBoolean); - case VariantType::Uint32: - return static_cast(content_.asUint32); - case VariantType::Int32: - return static_cast(content_.asInt32); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return static_cast(extension->asUint64); - case VariantType::Int64: - return static_cast(extension->asInt64); -#endif - case VariantType::TinyString: - str = content_.asTinyString; - break; - case VariantType::LinkedString: - str = content_.asLinkedString; - break; - case VariantType::OwnedString: - str = content_.asOwnedString->data; - break; - case VariantType::Float: - return static_cast(content_.asFloat); -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return static_cast(extension->asDouble); -#endif - default: - return 0.0; + template + enable_if_t setFloat(T value, ResourceManager *); + template + enable_if_t::value, bool> setInteger(T value, ResourceManager * resources); + template + enable_if_t::value, bool> setInteger(T value, ResourceManager * resources); + void setRawString(StringNode * s) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + ARDUINOJSON_ASSERT(s); + type_ = VariantType::RawString; + content_.asOwnedString = s; } - ARDUINOJSON_ASSERT(str != nullptr); - return parseNumber(str); - } - template - T asIntegral(const ResourceManager* resources) const { - static_assert(is_integral::value, "T must be an integral type"); -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); -#else - (void)resources; // silence warning -#endif - const char* str = nullptr; - switch (type_) { - case VariantType::Boolean: - return content_.asBoolean; - case VariantType::Uint32: - return convertNumber(content_.asUint32); - case VariantType::Int32: - return convertNumber(content_.asInt32); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return convertNumber(extension->asUint64); - case VariantType::Int64: - return convertNumber(extension->asInt64); -#endif - case VariantType::TinyString: - str = content_.asTinyString; - break; - case VariantType::LinkedString: - str = content_.asLinkedString; - break; - case VariantType::OwnedString: - str = content_.asOwnedString->data; - break; - case VariantType::Float: - return convertNumber(content_.asFloat); -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return convertNumber(extension->asDouble); -#endif - default: + template + void setRawString(SerializedValue value, ResourceManager * resources); + template + static void setRawString(VariantData * var, SerializedValue value, ResourceManager * resources) { + if (!var) + return; + var->clear(resources); + var->setRawString(value, resources); + } + template + bool setString(TAdaptedString value, ResourceManager * resources); + template + static void setString(VariantData * var, TAdaptedString value, ResourceManager * resources) { + if (!var) + return; + var->clear(resources); + var->setString(value, resources); + } + void setLinkedString(const char * s) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + ARDUINOJSON_ASSERT(s); + type_ = VariantType::LinkedString; + content_.asLinkedString = s; + } + template + void setTinyString(const TAdaptedString & s) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + ARDUINOJSON_ASSERT(s.size() <= tinyStringMaxLength); + type_ = VariantType::TinyString; + auto n = uint8_t(s.size()); + for (uint8_t i = 0; i < n; i++) { + char c = s[i]; + ARDUINOJSON_ASSERT(c != 0); // no NUL in tiny string + content_.asTinyString[i] = c; + } + content_.asTinyString[n] = 0; + } + void setOwnedString(StringNode * s) { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + ARDUINOJSON_ASSERT(s); + type_ = VariantType::OwnedString; + content_.asOwnedString = s; + } + size_t size(const ResourceManager * resources) const { + if (isObject()) + return content_.asObject.size(resources); + if (isArray()) + return content_.asArray.size(resources); return 0; } - ARDUINOJSON_ASSERT(str != nullptr); - return parseNumber(str); - } - ObjectData* asObject() { - return isObject() ? &content_.asObject : 0; - } - const ObjectData* asObject() const { - return const_cast(this)->asObject(); - } - JsonString asRawString() const { - switch (type_) { - case VariantType::RawString: - return JsonString(content_.asOwnedString->data, - content_.asOwnedString->length); - default: - return JsonString(); + static size_t size(const VariantData * var, const ResourceManager * resources) { + return var != 0 ? var->size(resources) : 0; } - } - JsonString asString() const { - switch (type_) { - case VariantType::TinyString: - return JsonString(content_.asTinyString); - case VariantType::LinkedString: - return JsonString(content_.asLinkedString, true); - case VariantType::OwnedString: - return JsonString(content_.asOwnedString->data, - content_.asOwnedString->length); - default: - return JsonString(); + ArrayData & toArray() { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + type_ = VariantType::Array; + new (&content_.asArray) ArrayData(); + return content_.asArray; } - } -#if ARDUINOJSON_USE_EXTENSIONS - const VariantExtension* getExtension(const ResourceManager* resources) const; -#endif - VariantData* getElement(size_t index, - const ResourceManager* resources) const { - return ArrayData::getElement(asArray(), index, resources); - } - static VariantData* getElement(const VariantData* var, size_t index, - const ResourceManager* resources) { - return var != 0 ? var->getElement(index, resources) : 0; - } - template - VariantData* getMember(TAdaptedString key, - const ResourceManager* resources) const { - return ObjectData::getMember(asObject(), key, resources); - } - template - static VariantData* getMember(const VariantData* var, TAdaptedString key, - const ResourceManager* resources) { - if (!var) - return 0; - return var->getMember(key, resources); - } - VariantData* getOrAddElement(size_t index, ResourceManager* resources) { - auto array = isNull() ? &toArray() : asArray(); - if (!array) - return nullptr; - return array->getOrAddElement(index, resources); - } - template - VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources) { - if (key.isNull()) - return nullptr; - auto obj = isNull() ? &toObject() : asObject(); - if (!obj) - return nullptr; - return obj->getOrAddMember(key, resources); - } - bool isArray() const { - return type_ == VariantType::Array; - } - bool isBoolean() const { - return type_ == VariantType::Boolean; - } - bool isCollection() const { - return type_ & VariantTypeBits::CollectionMask; - } - bool isFloat() const { - return type_ & VariantTypeBits::NumberBit; - } - template - bool isInteger(const ResourceManager* resources) const { -#if ARDUINOJSON_USE_LONG_LONG - auto extension = getExtension(resources); -#else - (void)resources; // silence warning -#endif - switch (type_) { - case VariantType::Uint32: - return canConvertNumber(content_.asUint32); - case VariantType::Int32: - return canConvertNumber(content_.asInt32); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return canConvertNumber(extension->asUint64); - case VariantType::Int64: - return canConvertNumber(extension->asInt64); -#endif - default: - return false; + static ArrayData * toArray(VariantData * var, ResourceManager * resources) { + if (!var) + return 0; + var->clear(resources); + return &var->toArray(); } - } - bool isNull() const { - return type_ == VariantType::Null; - } - static bool isNull(const VariantData* var) { - if (!var) - return true; - return var->isNull(); - } - bool isObject() const { - return type_ == VariantType::Object; - } - bool isString() const { - return type_ == VariantType::LinkedString || - type_ == VariantType::OwnedString || - type_ == VariantType::TinyString; - } - size_t nesting(const ResourceManager* resources) const { - auto collection = asCollection(); - if (collection) - return collection->nesting(resources); - else - return 0; - } - static size_t nesting(const VariantData* var, - const ResourceManager* resources) { - if (!var) - return 0; - return var->nesting(resources); - } - void removeElement(size_t index, ResourceManager* resources) { - ArrayData::removeElement(asArray(), index, resources); - } - static void removeElement(VariantData* var, size_t index, - ResourceManager* resources) { - if (!var) - return; - var->removeElement(index, resources); - } - template - void removeMember(TAdaptedString key, ResourceManager* resources) { - ObjectData::removeMember(asObject(), key, resources); - } - template - static void removeMember(VariantData* var, TAdaptedString key, - ResourceManager* resources) { - if (!var) - return; - var->removeMember(key, resources); - } - void reset() { // TODO: remove - type_ = VariantType::Null; - } - void setBoolean(bool value) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - type_ = VariantType::Boolean; - content_.asBoolean = value; - } - template - enable_if_t setFloat(T value, ResourceManager*) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - type_ = VariantType::Float; - content_.asFloat = value; - return true; - } - template - enable_if_t setFloat(T value, ResourceManager*); - template - enable_if_t::value, bool> setInteger(T value, - ResourceManager* resources); - template - enable_if_t::value, bool> setInteger( - T value, ResourceManager* resources); - void setRawString(StringNode* s) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - ARDUINOJSON_ASSERT(s); - type_ = VariantType::RawString; - content_.asOwnedString = s; - } - template - void setRawString(SerializedValue value, ResourceManager* resources); - template - static void setRawString(VariantData* var, SerializedValue value, - ResourceManager* resources) { - if (!var) - return; - var->clear(resources); - var->setRawString(value, resources); - } - template - bool setString(TAdaptedString value, ResourceManager* resources); - template - static void setString(VariantData* var, TAdaptedString value, - ResourceManager* resources) { - if (!var) - return; - var->clear(resources); - var->setString(value, resources); - } - void setLinkedString(const char* s) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - ARDUINOJSON_ASSERT(s); - type_ = VariantType::LinkedString; - content_.asLinkedString = s; - } - template - void setTinyString(const TAdaptedString& s) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - ARDUINOJSON_ASSERT(s.size() <= tinyStringMaxLength); - type_ = VariantType::TinyString; - auto n = uint8_t(s.size()); - for (uint8_t i = 0; i < n; i++) { - char c = s[i]; - ARDUINOJSON_ASSERT(c != 0); // no NUL in tiny string - content_.asTinyString[i] = c; + ObjectData & toObject() { + ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first + type_ = VariantType::Object; + new (&content_.asObject) ObjectData(); + return content_.asObject; + } + static ObjectData * toObject(VariantData * var, ResourceManager * resources) { + if (!var) + return 0; + var->clear(resources); + return &var->toObject(); + } + VariantType type() const { + return type_; + } + void clear(ResourceManager * resources); + static void clear(VariantData * var, ResourceManager * resources) { + if (!var) + return; + var->clear(resources); } - content_.asTinyString[n] = 0; - } - void setOwnedString(StringNode* s) { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - ARDUINOJSON_ASSERT(s); - type_ = VariantType::OwnedString; - content_.asOwnedString = s; - } - size_t size(const ResourceManager* resources) const { - if (isObject()) - return content_.asObject.size(resources); - if (isArray()) - return content_.asArray.size(resources); - return 0; - } - static size_t size(const VariantData* var, const ResourceManager* resources) { - return var != 0 ? var->size(resources) : 0; - } - ArrayData& toArray() { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - type_ = VariantType::Array; - new (&content_.asArray) ArrayData(); - return content_.asArray; - } - static ArrayData* toArray(VariantData* var, ResourceManager* resources) { - if (!var) - return 0; - var->clear(resources); - return &var->toArray(); - } - ObjectData& toObject() { - ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first - type_ = VariantType::Object; - new (&content_.asObject) ObjectData(); - return content_.asObject; - } - static ObjectData* toObject(VariantData* var, ResourceManager* resources) { - if (!var) - return 0; - var->clear(resources); - return &var->toObject(); - } - VariantType type() const { - return type_; - } - void clear(ResourceManager* resources); - static void clear(VariantData* var, ResourceManager* resources) { - if (!var) - return; - var->clear(resources); - } }; class VariantData; class VariantWithId; class ResourceManager { - union SlotData { - VariantData variant; + union SlotData { + VariantData variant; #if ARDUINOJSON_USE_EXTENSIONS - VariantExtension extension; + VariantExtension extension; #endif - }; - public: - constexpr static size_t slotSize = sizeof(SlotData); - ResourceManager(Allocator* allocator = DefaultAllocator::instance()) - : allocator_(allocator), overflowed_(false) {} - ~ResourceManager() { - stringPool_.clear(allocator_); - variantPools_.clear(allocator_); - } - ResourceManager(const ResourceManager&) = delete; - ResourceManager& operator=(const ResourceManager& src) = delete; - friend void swap(ResourceManager& a, ResourceManager& b) { - swap(a.stringPool_, b.stringPool_); - swap(a.variantPools_, b.variantPools_); - swap_(a.allocator_, b.allocator_); - swap_(a.overflowed_, b.overflowed_); - } - Allocator* allocator() const { - return allocator_; - } - size_t size() const { - return variantPools_.size() + stringPool_.size(); - } - bool overflowed() const { - return overflowed_; - } - Slot allocVariant(); - void freeVariant(Slot slot); - VariantData* getVariant(SlotId id) const; + }; + + public: + constexpr static size_t slotSize = sizeof(SlotData); + ResourceManager(Allocator * allocator = DefaultAllocator::instance()) + : allocator_(allocator) + , overflowed_(false) { + } + ~ResourceManager() { + stringPool_.clear(allocator_); + variantPools_.clear(allocator_); + } + ResourceManager(const ResourceManager &) = delete; + ResourceManager & operator=(const ResourceManager & src) = delete; + friend void swap(ResourceManager & a, ResourceManager & b) { + swap(a.stringPool_, b.stringPool_); + swap(a.variantPools_, b.variantPools_); + swap_(a.allocator_, b.allocator_); + swap_(a.overflowed_, b.overflowed_); + } + Allocator * allocator() const { + return allocator_; + } + size_t size() const { + return variantPools_.size() + stringPool_.size(); + } + bool overflowed() const { + return overflowed_; + } + Slot allocVariant(); + void freeVariant(Slot slot); + VariantData * getVariant(SlotId id) const; #if ARDUINOJSON_USE_EXTENSIONS - Slot allocExtension(); - void freeExtension(SlotId slot); - VariantExtension* getExtension(SlotId id) const; + Slot allocExtension(); + void freeExtension(SlotId slot); + VariantExtension * getExtension(SlotId id) const; #endif - template - StringNode* saveString(TAdaptedString str) { - if (str.isNull()) - return 0; - auto node = stringPool_.add(str, allocator_); - if (!node) - overflowed_ = true; - return node; - } - void saveString(StringNode* node) { - stringPool_.add(node); - } - template - StringNode* getString(const TAdaptedString& str) const { - return stringPool_.get(str); - } - StringNode* createString(size_t length) { - auto node = StringNode::create(length, allocator_); - if (!node) - overflowed_ = true; - return node; - } - StringNode* resizeString(StringNode* node, size_t length) { - node = StringNode::resize(node, length, allocator_); - if (!node) - overflowed_ = true; - return node; - } - void destroyString(StringNode* node) { - StringNode::destroy(node, allocator_); - } - void dereferenceString(const char* s) { - stringPool_.dereference(s, allocator_); - } - void clear() { - variantPools_.clear(allocator_); - overflowed_ = false; - stringPool_.clear(allocator_); - } - void shrinkToFit() { - variantPools_.shrinkToFit(allocator_); - } - private: - Allocator* allocator_; - bool overflowed_; - StringPool stringPool_; - MemoryPoolList variantPools_; + template + StringNode * saveString(TAdaptedString str) { + if (str.isNull()) + return 0; + auto node = stringPool_.add(str, allocator_); + if (!node) + overflowed_ = true; + return node; + } + void saveString(StringNode * node) { + stringPool_.add(node); + } + template + StringNode * getString(const TAdaptedString & str) const { + return stringPool_.get(str); + } + StringNode * createString(size_t length) { + auto node = StringNode::create(length, allocator_); + if (!node) + overflowed_ = true; + return node; + } + StringNode * resizeString(StringNode * node, size_t length) { + node = StringNode::resize(node, length, allocator_); + if (!node) + overflowed_ = true; + return node; + } + void destroyString(StringNode * node) { + StringNode::destroy(node, allocator_); + } + void dereferenceString(const char * s) { + stringPool_.dereference(s, allocator_); + } + void clear() { + variantPools_.clear(allocator_); + overflowed_ = false; + stringPool_.clear(allocator_); + } + void shrinkToFit() { + variantPools_.shrinkToFit(allocator_); + } + + private: + Allocator * allocator_; + bool overflowed_; + StringPool stringPool_; + MemoryPoolList variantPools_; }; template struct IsString : false_type {}; template -struct IsString::AdaptedString>> - : true_type {}; +struct IsString::AdaptedString>> : true_type {}; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonArray; @@ -2724,122 +2645,104 @@ template struct VariantTo {}; template <> struct VariantTo { - using type = JsonArray; + using type = JsonArray; }; template <> struct VariantTo { - using type = JsonObject; + using type = JsonObject; }; template <> struct VariantTo { - using type = JsonVariant; + using type = JsonVariant; }; class VariantAttorney { - public: - template - static auto getResourceManager(TClient& client) - -> decltype(client.getResourceManager()) { - return client.getResourceManager(); - } - template - static auto getData(TClient& client) -> decltype(client.getData()) { - return client.getData(); - } - template - static VariantData* getOrCreateData(TClient& client) { - return client.getOrCreateData(); - } + public: + template + static auto getResourceManager(TClient & client) -> decltype(client.getResourceManager()) { + return client.getResourceManager(); + } + template + static auto getData(TClient & client) -> decltype(client.getData()) { + return client.getData(); + } + template + static VariantData * getOrCreateData(TClient & client) { + return client.getOrCreateData(); + } }; enum CompareResult { - COMPARE_RESULT_DIFFER = 0, - COMPARE_RESULT_EQUAL = 1, - COMPARE_RESULT_GREATER = 2, - COMPARE_RESULT_LESS = 4, - COMPARE_RESULT_GREATER_OR_EQUAL = 3, - COMPARE_RESULT_LESS_OR_EQUAL = 5 + COMPARE_RESULT_DIFFER = 0, + COMPARE_RESULT_EQUAL = 1, + COMPARE_RESULT_GREATER = 2, + COMPARE_RESULT_LESS = 4, + COMPARE_RESULT_GREATER_OR_EQUAL = 3, + COMPARE_RESULT_LESS_OR_EQUAL = 5 }; template -CompareResult arithmeticCompare(const T& lhs, const T& rhs) { - if (lhs < rhs) - return COMPARE_RESULT_LESS; - else if (lhs > rhs) - return COMPARE_RESULT_GREATER; - else - return COMPARE_RESULT_EQUAL; +CompareResult arithmeticCompare(const T & lhs, const T & rhs) { + if (lhs < rhs) + return COMPARE_RESULT_LESS; + else if (lhs > rhs) + return COMPARE_RESULT_GREATER; + else + return COMPARE_RESULT_EQUAL; +} +template +CompareResult arithmeticCompare(const T1 & lhs, const T2 & rhs, enable_if_t::value && is_integral::value && sizeof(T1) < sizeof(T2)> * = 0) { + return arithmeticCompare(static_cast(lhs), rhs); +} +template +CompareResult arithmeticCompare(const T1 & lhs, const T2 & rhs, enable_if_t::value && is_integral::value && sizeof(T2) < sizeof(T1)> * = 0) { + return arithmeticCompare(lhs, static_cast(rhs)); +} +template +CompareResult +arithmeticCompare(const T1 & lhs, + const T2 & rhs, + enable_if_t::value && is_integral::value && is_signed::value == is_signed::value && sizeof(T2) == sizeof(T1)> * = 0) { + return arithmeticCompare(lhs, static_cast(rhs)); } template CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value && is_integral::value && - sizeof(T1) < sizeof(T2)>* = 0) { - return arithmeticCompare(static_cast(lhs), rhs); + const T1 & lhs, + const T2 & rhs, + enable_if_t::value && is_integral::value && is_unsigned::value && is_signed::value && sizeof(T2) == sizeof(T1)> * = 0) { + if (rhs < 0) + return COMPARE_RESULT_GREATER; + return arithmeticCompare(lhs, static_cast(rhs)); } template CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value && is_integral::value && - sizeof(T2) < sizeof(T1)>* = 0) { - return arithmeticCompare(lhs, static_cast(rhs)); + const T1 & lhs, + const T2 & rhs, + enable_if_t::value && is_integral::value && is_signed::value && is_unsigned::value && sizeof(T2) == sizeof(T1)> * = 0) { + if (lhs < 0) + return COMPARE_RESULT_LESS; + return arithmeticCompare(static_cast(lhs), rhs); } template -CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value && is_integral::value && - is_signed::value == is_signed::value && - sizeof(T2) == sizeof(T1)>* = 0) { - return arithmeticCompare(lhs, static_cast(rhs)); -} -template -CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value && is_integral::value && - is_unsigned::value && is_signed::value && - sizeof(T2) == sizeof(T1)>* = 0) { - if (rhs < 0) - return COMPARE_RESULT_GREATER; - return arithmeticCompare(lhs, static_cast(rhs)); -} -template -CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value && is_integral::value && - is_signed::value && is_unsigned::value && - sizeof(T2) == sizeof(T1)>* = 0) { - if (lhs < 0) - return COMPARE_RESULT_LESS; - return arithmeticCompare(static_cast(lhs), rhs); -} -template -CompareResult arithmeticCompare( - const T1& lhs, const T2& rhs, - enable_if_t::value || is_floating_point::value>* = - 0) { - return arithmeticCompare(static_cast(lhs), - static_cast(rhs)); +CompareResult arithmeticCompare(const T1 & lhs, const T2 & rhs, enable_if_t::value || is_floating_point::value> * = 0) { + return arithmeticCompare(static_cast(lhs), static_cast(rhs)); } template -CompareResult arithmeticCompareNegateLeft( - JsonUInt, const T2&, enable_if_t::value>* = 0) { - return COMPARE_RESULT_LESS; +CompareResult arithmeticCompareNegateLeft(JsonUInt, const T2 &, enable_if_t::value> * = 0) { + return COMPARE_RESULT_LESS; } template -CompareResult arithmeticCompareNegateLeft( - JsonUInt lhs, const T2& rhs, enable_if_t::value>* = 0) { - if (rhs > 0) - return COMPARE_RESULT_LESS; - return arithmeticCompare(-rhs, static_cast(lhs)); +CompareResult arithmeticCompareNegateLeft(JsonUInt lhs, const T2 & rhs, enable_if_t::value> * = 0) { + if (rhs > 0) + return COMPARE_RESULT_LESS; + return arithmeticCompare(-rhs, static_cast(lhs)); } template -CompareResult arithmeticCompareNegateRight( - const T1&, JsonUInt, enable_if_t::value>* = 0) { - return COMPARE_RESULT_GREATER; -} -template -CompareResult arithmeticCompareNegateRight( - const T1& lhs, JsonUInt rhs, enable_if_t::value>* = 0) { - if (lhs > 0) +CompareResult arithmeticCompareNegateRight(const T1 &, JsonUInt, enable_if_t::value> * = 0) { return COMPARE_RESULT_GREATER; - return arithmeticCompare(static_cast(rhs), -lhs); +} +template +CompareResult arithmeticCompareNegateRight(const T1 & lhs, JsonUInt rhs, enable_if_t::value> * = 0) { + if (lhs > 0) + return COMPARE_RESULT_GREATER; + return arithmeticCompare(static_cast(rhs), -lhs); } struct VariantTag {}; template @@ -2851,254 +2754,225 @@ ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template CompareResult compare(JsonVariantConst lhs, - const T& rhs); // VariantCompare.cpp + const T & rhs); // VariantCompare.cpp struct VariantOperatorTag {}; template struct VariantOperators : VariantOperatorTag { - template ::value && !is_array::value, int> = 0> - friend T operator|(const TVariant& variant, const T& defaultValue) { - if (variant.template is()) - return variant.template as(); - else - return defaultValue; - } - friend const char* operator|(const TVariant& variant, - const char* defaultValue) { - if (variant.template is()) - return variant.template as(); - else - return defaultValue; - } - template - friend enable_if_t::value, JsonVariantConst> operator|( - const TVariant& variant, const T& defaultValue) { - if (variant) - return variant; - else - return defaultValue; - } - template - friend bool operator==(T* lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_EQUAL; - } - template - friend bool operator==(const T& lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_EQUAL; - } - template - friend bool operator==(const TVariant& lhs, T* rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; - } - template ::value, int> = 0> - friend bool operator==(const TVariant& lhs, const T& rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; - } - template - friend bool operator!=(T* lhs, const TVariant& rhs) { - return compare(rhs, lhs) != COMPARE_RESULT_EQUAL; - } - template - friend bool operator!=(const T& lhs, const TVariant& rhs) { - return compare(rhs, lhs) != COMPARE_RESULT_EQUAL; - } - template - friend bool operator!=(const TVariant& lhs, T* rhs) { - return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; - } - template ::value, int> = 0> - friend bool operator!=(TVariant lhs, const T& rhs) { - return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; - } - template - friend bool operator<(T* lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_GREATER; - } - template - friend bool operator<(const T& lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_GREATER; - } - template - friend bool operator<(const TVariant& lhs, T* rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_LESS; - } - template ::value, int> = 0> - friend bool operator<(TVariant lhs, const T& rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_LESS; - } - template - friend bool operator<=(T* lhs, const TVariant& rhs) { - return (compare(rhs, lhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; - } - template - friend bool operator<=(const T& lhs, const TVariant& rhs) { - return (compare(rhs, lhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; - } - template - friend bool operator<=(const TVariant& lhs, T* rhs) { - return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; - } - template ::value, int> = 0> - friend bool operator<=(TVariant lhs, const T& rhs) { - return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; - } - template - friend bool operator>(T* lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_LESS; - } - template - friend bool operator>(const T& lhs, const TVariant& rhs) { - return compare(rhs, lhs) == COMPARE_RESULT_LESS; - } - template - friend bool operator>(const TVariant& lhs, T* rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_GREATER; - } - template ::value, int> = 0> - friend bool operator>(TVariant lhs, const T& rhs) { - return compare(lhs, rhs) == COMPARE_RESULT_GREATER; - } - template - friend bool operator>=(T* lhs, const TVariant& rhs) { - return (compare(rhs, lhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; - } - template - friend bool operator>=(const T& lhs, const TVariant& rhs) { - return (compare(rhs, lhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; - } - template - friend bool operator>=(const TVariant& lhs, T* rhs) { - return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; - } - template ::value, int> = 0> - friend bool operator>=(const TVariant& lhs, const T& rhs) { - return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; - } + template ::value && !is_array::value, int> = 0> + friend T operator|(const TVariant & variant, const T & defaultValue) { + if (variant.template is()) + return variant.template as(); + else + return defaultValue; + } + friend const char * operator|(const TVariant & variant, const char * defaultValue) { + if (variant.template is()) + return variant.template as(); + else + return defaultValue; + } + template + friend enable_if_t::value, JsonVariantConst> operator|(const TVariant & variant, const T & defaultValue) { + if (variant) + return variant; + else + return defaultValue; + } + template + friend bool operator==(T * lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_EQUAL; + } + template + friend bool operator==(const T & lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_EQUAL; + } + template + friend bool operator==(const TVariant & lhs, T * rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; + } + template ::value, int> = 0> + friend bool operator==(const TVariant & lhs, const T & rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_EQUAL; + } + template + friend bool operator!=(T * lhs, const TVariant & rhs) { + return compare(rhs, lhs) != COMPARE_RESULT_EQUAL; + } + template + friend bool operator!=(const T & lhs, const TVariant & rhs) { + return compare(rhs, lhs) != COMPARE_RESULT_EQUAL; + } + template + friend bool operator!=(const TVariant & lhs, T * rhs) { + return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; + } + template ::value, int> = 0> + friend bool operator!=(TVariant lhs, const T & rhs) { + return compare(lhs, rhs) != COMPARE_RESULT_EQUAL; + } + template + friend bool operator<(T * lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_GREATER; + } + template + friend bool operator<(const T & lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_GREATER; + } + template + friend bool operator<(const TVariant & lhs, T * rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_LESS; + } + template ::value, int> = 0> + friend bool operator<(TVariant lhs, const T & rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_LESS; + } + template + friend bool operator<=(T * lhs, const TVariant & rhs) { + return (compare(rhs, lhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; + } + template + friend bool operator<=(const T & lhs, const TVariant & rhs) { + return (compare(rhs, lhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; + } + template + friend bool operator<=(const TVariant & lhs, T * rhs) { + return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; + } + template ::value, int> = 0> + friend bool operator<=(TVariant lhs, const T & rhs) { + return (compare(lhs, rhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; + } + template + friend bool operator>(T * lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_LESS; + } + template + friend bool operator>(const T & lhs, const TVariant & rhs) { + return compare(rhs, lhs) == COMPARE_RESULT_LESS; + } + template + friend bool operator>(const TVariant & lhs, T * rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_GREATER; + } + template ::value, int> = 0> + friend bool operator>(TVariant lhs, const T & rhs) { + return compare(lhs, rhs) == COMPARE_RESULT_GREATER; + } + template + friend bool operator>=(T * lhs, const TVariant & rhs) { + return (compare(rhs, lhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; + } + template + friend bool operator>=(const T & lhs, const TVariant & rhs) { + return (compare(rhs, lhs) & COMPARE_RESULT_LESS_OR_EQUAL) != 0; + } + template + friend bool operator>=(const TVariant & lhs, T * rhs) { + return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; + } + template ::value, int> = 0> + friend bool operator>=(const TVariant & lhs, const T & rhs) { + return (compare(lhs, rhs) & COMPARE_RESULT_GREATER_OR_EQUAL) != 0; + } }; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonArray; class JsonObject; -class JsonVariantConst : public detail::VariantTag, - public detail::VariantOperators { - friend class detail::VariantAttorney; - template - using ConversionSupported = - detail::is_same::fromJson)>::arg1_type, - JsonVariantConst>; - public: - JsonVariantConst() : data_(nullptr), resources_(nullptr) {} - explicit JsonVariantConst(const detail::VariantData* data, - const detail::ResourceManager* resources) - : data_(data), resources_(resources) {} - bool isNull() const { - return detail::VariantData::isNull(data_); - } - bool isUnbound() const { - return !data_; - } - size_t nesting() const { - return detail::VariantData::nesting(data_, resources_); - } - size_t size() const { - return detail::VariantData::size(data_, resources_); - } - template ::value, int> = 0> - T as() const { - return Converter::fromJson(*this); - } - template ::value, int> = 0> - detail::InvalidConversion as() const; - template ::value, int> = 0> - bool is() const { - return Converter::checkJson(*this); - } - template ::value, int> = 0> - bool is() const { - return false; - } - template - operator T() const { - return as(); - } - template ::value, int> = 0> - JsonVariantConst operator[](T index) const { - return JsonVariantConst( - detail::VariantData::getElement(data_, size_t(index), resources_), - resources_); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TString& key) const { - return JsonVariantConst(detail::VariantData::getMember( - data_, detail::adaptString(key), resources_), - resources_); - } - template ::value && - !detail::is_const::value, - int> = 0> - JsonVariantConst operator[](TChar* key) const { - return JsonVariantConst(detail::VariantData::getMember( - data_, detail::adaptString(key), resources_), - resources_); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TVariant& key) const { - if (key.template is()) - return operator[](key.template as()); - else - return operator[](key.template as()); - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use var[key].is() instead") - bool containsKey(const TString& key) const { - return detail::VariantData::getMember(getData(), detail::adaptString(key), - resources_) != 0; - } - template ::value && - !detail::is_const::value, - int> = 0> - ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") - bool containsKey(TChar* key) const { - return detail::VariantData::getMember(getData(), detail::adaptString(key), - resources_) != 0; - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use var[key].is() instead") - bool containsKey(const TVariant& key) const { - return containsKey(key.template as()); - } - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - protected: - const detail::VariantData* getData() const { - return data_; - } - const detail::ResourceManager* getResourceManager() const { - return resources_; - } - private: - const detail::VariantData* data_; - const detail::ResourceManager* resources_; +class JsonVariantConst : public detail::VariantTag, public detail::VariantOperators { + friend class detail::VariantAttorney; + template + using ConversionSupported = detail::is_same::fromJson)>::arg1_type, JsonVariantConst>; + + public: + JsonVariantConst() + : data_(nullptr) + , resources_(nullptr) { + } + explicit JsonVariantConst(const detail::VariantData * data, const detail::ResourceManager * resources) + : data_(data) + , resources_(resources) { + } + bool isNull() const { + return detail::VariantData::isNull(data_); + } + bool isUnbound() const { + return !data_; + } + size_t nesting() const { + return detail::VariantData::nesting(data_, resources_); + } + size_t size() const { + return detail::VariantData::size(data_, resources_); + } + template ::value, int> = 0> + T as() const { + return Converter::fromJson(*this); + } + template ::value, int> = 0> + detail::InvalidConversion as() const; + template ::value, int> = 0> + bool is() const { + return Converter::checkJson(*this); + } + template ::value, int> = 0> + bool is() const { + return false; + } + template + operator T() const { + return as(); + } + template ::value, int> = 0> + JsonVariantConst operator[](T index) const { + return JsonVariantConst(detail::VariantData::getElement(data_, size_t(index), resources_), resources_); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TString & key) const { + return JsonVariantConst(detail::VariantData::getMember(data_, detail::adaptString(key), resources_), resources_); + } + template ::value && !detail::is_const::value, int> = 0> + JsonVariantConst operator[](TChar * key) const { + return JsonVariantConst(detail::VariantData::getMember(data_, detail::adaptString(key), resources_), resources_); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TVariant & key) const { + if (key.template is()) + return operator[](key.template as()); + else + return operator[](key.template as()); + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use var[key].is() instead") + bool containsKey(const TString & key) const { + return detail::VariantData::getMember(getData(), detail::adaptString(key), resources_) != 0; + } + template ::value && !detail::is_const::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") + bool containsKey(TChar * key) const { + return detail::VariantData::getMember(getData(), detail::adaptString(key), resources_) != 0; + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use var[key].is() instead") + bool containsKey(const TVariant & key) const { + return containsKey(key.template as()); + } + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + protected: + const detail::VariantData * getData() const { + return data_; + } + const detail::ResourceManager * getResourceManager() const { + return resources_; + } + + private: + const detail::VariantData * data_; + const detail::ResourceManager * resources_; }; class JsonVariant; ARDUINOJSON_END_PUBLIC_NAMESPACE @@ -3109,2060 +2983,2026 @@ template class MemberProxy; template class VariantRefBase : public VariantTag { - friend class VariantAttorney; - public: - void clear() const { - VariantData::clear(getOrCreateData(), getResourceManager()); - } - bool isNull() const { - return VariantData::isNull(getData()); - } - bool isUnbound() const { - return !getData(); - } - template - T as() const; - template ::value, int> = 0> - operator T() const { - return as(); - } - template ::value, int> = 0> - JsonArray to() const; - template ::value, int> = 0> - JsonObject to() const; - template ::value, int> = 0> - JsonVariant to() const; - template - FORCE_INLINE bool is() const; - template - bool set(const T& value) const { - using TypeForConverter = conditional_t::value, T, - remove_cv_t>>; - return doSet>(value); - } - template ::value, int> = 0> - bool set(T* value) const { - return doSet>(value); - } - size_t size() const { - return VariantData::size(getData(), getResourceManager()); - } - size_t nesting() const { - return VariantData::nesting(getData(), getResourceManager()); - } - template ::value, int> = 0> - T add() const { - return add().template to(); - } - template ::value, int> = 0> - T add() const; - template - bool add(const T& value) const { - return detail::VariantData::addValue(getOrCreateData(), value, - getResourceManager()); - } - template ::value, int> = 0> - bool add(T* value) const { - return detail::VariantData::addValue(getOrCreateData(), value, - getResourceManager()); - } - void remove(size_t index) const { - VariantData::removeElement(getData(), index, getResourceManager()); - } - template ::value, int> = 0> - void remove(TChar* key) const { - VariantData::removeMember(getData(), adaptString(key), - getResourceManager()); - } - template ::value, int> = 0> - void remove(const TString& key) const { - VariantData::removeMember(getData(), adaptString(key), - getResourceManager()); - } - template ::value, int> = 0> - void remove(const TVariant& key) const { - if (key.template is()) - remove(key.template as()); - else - remove(key.template as()); - } - ElementProxy operator[](size_t index) const; - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TString& key) const; - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") - bool containsKey(TChar* key) const; - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TVariant& key) const; - template ::value, int> = 0> - FORCE_INLINE MemberProxy> operator[]( - const TString& key) const; - template < - typename TChar, - enable_if_t::value && !is_const::value, int> = 0> - FORCE_INLINE MemberProxy> operator[]( - TChar* key) const; - template ::value, int> = 0> - JsonVariantConst operator[](const TVariant& key) const { - if (key.template is()) - return operator[](key.template as()); - else - return operator[](key.template as()); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonVariant add() const; - ARDUINOJSON_DEPRECATED("use add() instead") - JsonArray createNestedArray() const; - template - ARDUINOJSON_DEPRECATED("use var[key].to() instead") - JsonArray createNestedArray(TChar* key) const; - template - ARDUINOJSON_DEPRECATED("use var[key].to() instead") - JsonArray createNestedArray(const TString& key) const; - ARDUINOJSON_DEPRECATED("use add() instead") - JsonObject createNestedObject() const; - template - ARDUINOJSON_DEPRECATED("use var[key].to() instead") - JsonObject createNestedObject(TChar* key) const; - template - ARDUINOJSON_DEPRECATED("use var[key].to() instead") - JsonObject createNestedObject(const TString& key) const; - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - ARDUINOJSON_DEPRECATED("performs a deep copy") - void shallowCopy(JsonVariantConst src) const { - set(src); - } - private: - TDerived& derived() { - return static_cast(*this); - } - const TDerived& derived() const { - return static_cast(*this); - } - ResourceManager* getResourceManager() const { - return VariantAttorney::getResourceManager(derived()); - } - VariantData* getData() const { - return VariantAttorney::getData(derived()); - } - VariantData* getOrCreateData() const { - return VariantAttorney::getOrCreateData(derived()); - } - FORCE_INLINE ArduinoJson::JsonVariant getVariant() const; - FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const { - return ArduinoJson::JsonVariantConst(getData(), getResourceManager()); - } - template - FORCE_INLINE enable_if_t::value, T> getVariant() - const { - return getVariantConst(); - } - template - FORCE_INLINE enable_if_t::value, T> getVariant() - const { - return getVariant(); - } - template - bool doSet(const T& value) const { - return doSet( - value, is_same::return_type, - bool>{}); - } - template - bool doSet(const T& value, false_type) const; - template - bool doSet(const T& value, true_type) const; - ArduinoJson::JsonVariant getOrCreateVariant() const; + friend class VariantAttorney; + + public: + void clear() const { + VariantData::clear(getOrCreateData(), getResourceManager()); + } + bool isNull() const { + return VariantData::isNull(getData()); + } + bool isUnbound() const { + return !getData(); + } + template + T as() const; + template ::value, int> = 0> + operator T() const { + return as(); + } + template ::value, int> = 0> + JsonArray to() const; + template ::value, int> = 0> + JsonObject to() const; + template ::value, int> = 0> + JsonVariant to() const; + template + FORCE_INLINE bool is() const; + template + bool set(const T & value) const { + using TypeForConverter = conditional_t::value, T, remove_cv_t>>; + return doSet>(value); + } + template ::value, int> = 0> + bool set(T * value) const { + return doSet>(value); + } + size_t size() const { + return VariantData::size(getData(), getResourceManager()); + } + size_t nesting() const { + return VariantData::nesting(getData(), getResourceManager()); + } + template ::value, int> = 0> + T add() const { + return add().template to(); + } + template ::value, int> = 0> + T add() const; + template + bool add(const T & value) const { + return detail::VariantData::addValue(getOrCreateData(), value, getResourceManager()); + } + template ::value, int> = 0> + bool add(T * value) const { + return detail::VariantData::addValue(getOrCreateData(), value, getResourceManager()); + } + void remove(size_t index) const { + VariantData::removeElement(getData(), index, getResourceManager()); + } + template ::value, int> = 0> + void remove(TChar * key) const { + VariantData::removeMember(getData(), adaptString(key), getResourceManager()); + } + template ::value, int> = 0> + void remove(const TString & key) const { + VariantData::removeMember(getData(), adaptString(key), getResourceManager()); + } + template ::value, int> = 0> + void remove(const TVariant & key) const { + if (key.template is()) + remove(key.template as()); + else + remove(key.template as()); + } + ElementProxy operator[](size_t index) const; + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TString & key) const; + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") + bool containsKey(TChar * key) const; + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TVariant & key) const; + template ::value, int> = 0> + FORCE_INLINE MemberProxy> operator[](const TString & key) const; + template ::value && !is_const::value, int> = 0> + FORCE_INLINE MemberProxy> operator[](TChar * key) const; + template ::value, int> = 0> + JsonVariantConst operator[](const TVariant & key) const { + if (key.template is()) + return operator[](key.template as()); + else + return operator[](key.template as()); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonVariant add() const; + ARDUINOJSON_DEPRECATED("use add() instead") + JsonArray createNestedArray() const; + template + ARDUINOJSON_DEPRECATED("use var[key].to() instead") + JsonArray createNestedArray(TChar * key) const; + template + ARDUINOJSON_DEPRECATED("use var[key].to() instead") + JsonArray createNestedArray(const TString & key) const; + ARDUINOJSON_DEPRECATED("use add() instead") + JsonObject createNestedObject() const; + template + ARDUINOJSON_DEPRECATED("use var[key].to() instead") + JsonObject createNestedObject(TChar * key) const; + template + ARDUINOJSON_DEPRECATED("use var[key].to() instead") + JsonObject createNestedObject(const TString & key) const; + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + ARDUINOJSON_DEPRECATED("performs a deep copy") + void shallowCopy(JsonVariantConst src) const { + set(src); + } + + private: + TDerived & derived() { + return static_cast(*this); + } + const TDerived & derived() const { + return static_cast(*this); + } + ResourceManager * getResourceManager() const { + return VariantAttorney::getResourceManager(derived()); + } + VariantData * getData() const { + return VariantAttorney::getData(derived()); + } + VariantData * getOrCreateData() const { + return VariantAttorney::getOrCreateData(derived()); + } + FORCE_INLINE ArduinoJson::JsonVariant getVariant() const; + FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const { + return ArduinoJson::JsonVariantConst(getData(), getResourceManager()); + } + template + FORCE_INLINE enable_if_t::value, T> getVariant() const { + return getVariantConst(); + } + template + FORCE_INLINE enable_if_t::value, T> getVariant() const { + return getVariant(); + } + template + bool doSet(const T & value) const { + return doSet(value, is_same::return_type, bool>{}); + } + template + bool doSet(const T & value, false_type) const; + template + bool doSet(const T & value, true_type) const; + ArduinoJson::JsonVariant getOrCreateVariant() const; }; template -class ElementProxy : public VariantRefBase>, - public VariantOperators> { - friend class VariantAttorney; - friend class VariantRefBase>; - template - friend class MemberProxy; - template - friend class ElementProxy; - public: - ElementProxy(TUpstream upstream, size_t index) - : upstream_(upstream), index_(index) {} - ElementProxy& operator=(const ElementProxy& src) { - this->set(src); - return *this; - } - template - ElementProxy& operator=(const T& src) { - this->set(src); - return *this; - } - template - ElementProxy& operator=(T* src) { - this->set(src); - return *this; - } - private: - ElementProxy(const ElementProxy& src) // Error here? See https://arduinojson.org/v7/proxy-non-copyable/ - : upstream_(src.upstream_), index_(src.index_) {} - ResourceManager* getResourceManager() const { - return VariantAttorney::getResourceManager(upstream_); - } - FORCE_INLINE VariantData* getData() const { - return VariantData::getElement( - VariantAttorney::getData(upstream_), index_, - VariantAttorney::getResourceManager(upstream_)); - } - VariantData* getOrCreateData() const { - auto data = VariantAttorney::getOrCreateData(upstream_); - if (!data) - return nullptr; - return data->getOrAddElement( - index_, VariantAttorney::getResourceManager(upstream_)); - } - TUpstream upstream_; - size_t index_; +class ElementProxy : public VariantRefBase>, public VariantOperators> { + friend class VariantAttorney; + friend class VariantRefBase>; + template + friend class MemberProxy; + template + friend class ElementProxy; + + public: + ElementProxy(TUpstream upstream, size_t index) + : upstream_(upstream) + , index_(index) { + } + ElementProxy & operator=(const ElementProxy & src) { + this->set(src); + return *this; + } + template + ElementProxy & operator=(const T & src) { + this->set(src); + return *this; + } + template + ElementProxy & operator=(T * src) { + this->set(src); + return *this; + } + + private: + ElementProxy(const ElementProxy & src) // Error here? See https://arduinojson.org/v7/proxy-non-copyable/ + : upstream_(src.upstream_) + , index_(src.index_) { + } + ResourceManager * getResourceManager() const { + return VariantAttorney::getResourceManager(upstream_); + } + FORCE_INLINE VariantData * getData() const { + return VariantData::getElement(VariantAttorney::getData(upstream_), index_, VariantAttorney::getResourceManager(upstream_)); + } + VariantData * getOrCreateData() const { + auto data = VariantAttorney::getOrCreateData(upstream_); + if (!data) + return nullptr; + return data->getOrAddElement(index_, VariantAttorney::getResourceManager(upstream_)); + } + TUpstream upstream_; + size_t index_; }; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE -class JsonVariant : public detail::VariantRefBase, - public detail::VariantOperators { - friend class detail::VariantAttorney; - public: - JsonVariant() : data_(0), resources_(0) {} - JsonVariant(detail::VariantData* data, detail::ResourceManager* resources) - : data_(data), resources_(resources) {} - private: - detail::ResourceManager* getResourceManager() const { - return resources_; - } - detail::VariantData* getData() const { - return data_; - } - detail::VariantData* getOrCreateData() const { - return data_; - } - detail::VariantData* data_; - detail::ResourceManager* resources_; +class JsonVariant : public detail::VariantRefBase, public detail::VariantOperators { + friend class detail::VariantAttorney; + + public: + JsonVariant() + : data_(0) + , resources_(0) { + } + JsonVariant(detail::VariantData * data, detail::ResourceManager * resources) + : data_(data) + , resources_(resources) { + } + + private: + detail::ResourceManager * getResourceManager() const { + return resources_; + } + detail::VariantData * getData() const { + return data_; + } + detail::VariantData * getOrCreateData() const { + return data_; + } + detail::VariantData * data_; + detail::ResourceManager * resources_; }; namespace detail { bool copyVariant(JsonVariant dst, JsonVariantConst src); } template <> struct Converter : private detail::VariantAttorney { - static void toJson(JsonVariantConst src, JsonVariant dst) { - copyVariant(dst, src); - } - static JsonVariant fromJson(JsonVariant src) { - return src; - } - static bool checkJson(JsonVariant src) { - auto data = getData(src); - return !!data; - } + static void toJson(JsonVariantConst src, JsonVariant dst) { + copyVariant(dst, src); + } + static JsonVariant fromJson(JsonVariant src) { + return src; + } + static bool checkJson(JsonVariant src) { + auto data = getData(src); + return !!data; + } }; template <> struct Converter : private detail::VariantAttorney { - static void toJson(JsonVariantConst src, JsonVariant dst) { - copyVariant(dst, src); - } - static JsonVariantConst fromJson(JsonVariantConst src) { - return JsonVariantConst(getData(src), getResourceManager(src)); - } - static bool checkJson(JsonVariantConst src) { - auto data = getData(src); - return !!data; - } + static void toJson(JsonVariantConst src, JsonVariant dst) { + copyVariant(dst, src); + } + static JsonVariantConst fromJson(JsonVariantConst src) { + return JsonVariantConst(getData(src), getResourceManager(src)); + } + static bool checkJson(JsonVariantConst src) { + auto data = getData(src); + return !!data; + } }; template class Ptr { - public: - Ptr(T value) : value_(value) {} - T* operator->() { - return &value_; - } - T& operator*() { - return value_; - } - private: - T value_; + public: + Ptr(T value) + : value_(value) { + } + T * operator->() { + return &value_; + } + T & operator*() { + return value_; + } + + private: + T value_; }; class JsonArrayIterator { - friend class JsonArray; - public: - JsonArrayIterator() {} - explicit JsonArrayIterator(detail::ArrayData::iterator iterator, - detail::ResourceManager* resources) - : iterator_(iterator), resources_(resources) {} - JsonVariant operator*() { - return JsonVariant(iterator_.data(), resources_); - } - Ptr operator->() { - return operator*(); - } - bool operator==(const JsonArrayIterator& other) const { - return iterator_ == other.iterator_; - } - bool operator!=(const JsonArrayIterator& other) const { - return iterator_ != other.iterator_; - } - JsonArrayIterator& operator++() { - iterator_.next(resources_); - return *this; - } - private: - detail::ArrayData::iterator iterator_; - detail::ResourceManager* resources_; + friend class JsonArray; + + public: + JsonArrayIterator() { + } + explicit JsonArrayIterator(detail::ArrayData::iterator iterator, detail::ResourceManager * resources) + : iterator_(iterator) + , resources_(resources) { + } + JsonVariant operator*() { + return JsonVariant(iterator_.data(), resources_); + } + Ptr operator->() { + return operator*(); + } + bool operator==(const JsonArrayIterator & other) const { + return iterator_ == other.iterator_; + } + bool operator!=(const JsonArrayIterator & other) const { + return iterator_ != other.iterator_; + } + JsonArrayIterator & operator++() { + iterator_.next(resources_); + return *this; + } + + private: + detail::ArrayData::iterator iterator_; + detail::ResourceManager * resources_; }; class JsonArrayConstIterator { - friend class JsonArray; - public: - JsonArrayConstIterator() {} - explicit JsonArrayConstIterator(detail::ArrayData::iterator iterator, - const detail::ResourceManager* resources) - : iterator_(iterator), resources_(resources) {} - JsonVariantConst operator*() const { - return JsonVariantConst(iterator_.data(), resources_); - } - Ptr operator->() { - return operator*(); - } - bool operator==(const JsonArrayConstIterator& other) const { - return iterator_ == other.iterator_; - } - bool operator!=(const JsonArrayConstIterator& other) const { - return iterator_ != other.iterator_; - } - JsonArrayConstIterator& operator++() { - iterator_.next(resources_); - return *this; - } - private: - detail::ArrayData::iterator iterator_; - const detail::ResourceManager* resources_; + friend class JsonArray; + + public: + JsonArrayConstIterator() { + } + explicit JsonArrayConstIterator(detail::ArrayData::iterator iterator, const detail::ResourceManager * resources) + : iterator_(iterator) + , resources_(resources) { + } + JsonVariantConst operator*() const { + return JsonVariantConst(iterator_.data(), resources_); + } + Ptr operator->() { + return operator*(); + } + bool operator==(const JsonArrayConstIterator & other) const { + return iterator_ == other.iterator_; + } + bool operator!=(const JsonArrayConstIterator & other) const { + return iterator_ != other.iterator_; + } + JsonArrayConstIterator & operator++() { + iterator_.next(resources_); + return *this; + } + + private: + detail::ArrayData::iterator iterator_; + const detail::ResourceManager * resources_; }; class JsonObject; class JsonArrayConst : public detail::VariantOperators { - friend class JsonArray; - friend class detail::VariantAttorney; - public: - using iterator = JsonArrayConstIterator; - iterator begin() const { - if (!data_) - return iterator(); - return iterator(data_->createIterator(resources_), resources_); - } - iterator end() const { - return iterator(); - } - JsonArrayConst() : data_(0), resources_(0) {} - JsonArrayConst(const detail::ArrayData* data, - const detail::ResourceManager* resources) - : data_(data), resources_(resources) {} - template ::value, int> = 0> - JsonVariantConst operator[](T index) const { - return JsonVariantConst( - detail::ArrayData::getElement(data_, size_t(index), resources_), - resources_); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TVariant& variant) const { - if (variant.template is()) - return operator[](variant.template as()); - else - return JsonVariantConst(); - } - operator JsonVariantConst() const { - return JsonVariantConst(getData(), resources_); - } - bool isNull() const { - return data_ == 0; - } - operator bool() const { - return data_ != 0; - } - size_t nesting() const { - return detail::VariantData::nesting(getData(), resources_); - } - size_t size() const { - return data_ ? data_->size(resources_) : 0; - } - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - private: - const detail::VariantData* getData() const { - return collectionToVariant(data_); - } - const detail::ArrayData* data_; - const detail::ResourceManager* resources_; + friend class JsonArray; + friend class detail::VariantAttorney; + + public: + using iterator = JsonArrayConstIterator; + iterator begin() const { + if (!data_) + return iterator(); + return iterator(data_->createIterator(resources_), resources_); + } + iterator end() const { + return iterator(); + } + JsonArrayConst() + : data_(0) + , resources_(0) { + } + JsonArrayConst(const detail::ArrayData * data, const detail::ResourceManager * resources) + : data_(data) + , resources_(resources) { + } + template ::value, int> = 0> + JsonVariantConst operator[](T index) const { + return JsonVariantConst(detail::ArrayData::getElement(data_, size_t(index), resources_), resources_); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TVariant & variant) const { + if (variant.template is()) + return operator[](variant.template as()); + else + return JsonVariantConst(); + } + operator JsonVariantConst() const { + return JsonVariantConst(getData(), resources_); + } + bool isNull() const { + return data_ == 0; + } + operator bool() const { + return data_ != 0; + } + size_t nesting() const { + return detail::VariantData::nesting(getData(), resources_); + } + size_t size() const { + return data_ ? data_->size(resources_) : 0; + } + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + private: + const detail::VariantData * getData() const { + return collectionToVariant(data_); + } + const detail::ArrayData * data_; + const detail::ResourceManager * resources_; }; inline bool operator==(JsonArrayConst lhs, JsonArrayConst rhs) { - if (!lhs && !rhs) - return true; - if (!lhs || !rhs) - return false; - auto a = lhs.begin(); - auto b = rhs.begin(); - for (;;) { - if (a == b) // same pointer or both null - return true; - if (a == lhs.end() || b == rhs.end()) - return false; - if (*a != *b) - return false; - ++a; - ++b; - } + if (!lhs && !rhs) + return true; + if (!lhs || !rhs) + return false; + auto a = lhs.begin(); + auto b = rhs.begin(); + for (;;) { + if (a == b) // same pointer or both null + return true; + if (a == lhs.end() || b == rhs.end()) + return false; + if (*a != *b) + return false; + ++a; + ++b; + } } class JsonObject; class JsonArray : public detail::VariantOperators { - friend class detail::VariantAttorney; - public: - using iterator = JsonArrayIterator; - JsonArray() : data_(0), resources_(0) {} - JsonArray(detail::ArrayData* data, detail::ResourceManager* resources) - : data_(data), resources_(resources) {} - operator JsonVariant() { - void* data = data_; // prevent warning cast-align - return JsonVariant(reinterpret_cast(data), - resources_); - } - operator JsonArrayConst() const { - return JsonArrayConst(data_, resources_); - } - template ::value, int> = 0> - T add() const { - return add().to(); - } - template ::value, int> = 0> - JsonVariant add() const { - return JsonVariant(detail::ArrayData::addElement(data_, resources_), - resources_); - } - template - bool add(const T& value) const { - return detail::ArrayData::addValue(data_, value, resources_); - } - template ::value, int> = 0> - bool add(T* value) const { - return detail::ArrayData::addValue(data_, value, resources_); - } - iterator begin() const { - if (!data_) - return iterator(); - return iterator(data_->createIterator(resources_), resources_); - } - iterator end() const { - return iterator(); - } - bool set(JsonArrayConst src) const { - if (!data_) - return false; - clear(); - for (auto element : src) { - if (!add(element)) - return false; + friend class detail::VariantAttorney; + + public: + using iterator = JsonArrayIterator; + JsonArray() + : data_(0) + , resources_(0) { } - return true; - } - void remove(iterator it) const { - detail::ArrayData::remove(data_, it.iterator_, resources_); - } - void remove(size_t index) const { - detail::ArrayData::removeElement(data_, index, resources_); - } - template ::value, int> = 0> - void remove(const TVariant& variant) const { - if (variant.template is()) - remove(variant.template as()); - } - void clear() const { - detail::ArrayData::clear(data_, resources_); - } - template ::value, int> = 0> - detail::ElementProxy operator[](T index) const { - return {*this, size_t(index)}; - } - template ::value, int> = 0> - detail::ElementProxy operator[](const TVariant& variant) const { - if (variant.template is()) - return {*this, variant.template as()}; - else - return {*this, size_t(-1)}; - } - operator JsonVariantConst() const { - return JsonVariantConst(collectionToVariant(data_), resources_); - } - bool isNull() const { - return data_ == 0; - } - operator bool() const { - return data_ != 0; - } - size_t nesting() const { - return detail::VariantData::nesting(collectionToVariant(data_), resources_); - } - size_t size() const { - return data_ ? data_->size(resources_) : 0; - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonVariant add() const { - return add(); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonArray createNestedArray() const { - return add(); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonObject createNestedObject() const; - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - private: - detail::ResourceManager* getResourceManager() const { - return resources_; - } - detail::VariantData* getData() const { - return collectionToVariant(data_); - } - detail::VariantData* getOrCreateData() const { - return collectionToVariant(data_); - } - detail::ArrayData* data_; - detail::ResourceManager* resources_; + JsonArray(detail::ArrayData * data, detail::ResourceManager * resources) + : data_(data) + , resources_(resources) { + } + operator JsonVariant() { + void * data = data_; // prevent warning cast-align + return JsonVariant(reinterpret_cast(data), resources_); + } + operator JsonArrayConst() const { + return JsonArrayConst(data_, resources_); + } + template ::value, int> = 0> + T add() const { + return add().to(); + } + template ::value, int> = 0> + JsonVariant add() const { + return JsonVariant(detail::ArrayData::addElement(data_, resources_), resources_); + } + template + bool add(const T & value) const { + return detail::ArrayData::addValue(data_, value, resources_); + } + template ::value, int> = 0> + bool add(T * value) const { + return detail::ArrayData::addValue(data_, value, resources_); + } + iterator begin() const { + if (!data_) + return iterator(); + return iterator(data_->createIterator(resources_), resources_); + } + iterator end() const { + return iterator(); + } + bool set(JsonArrayConst src) const { + if (!data_) + return false; + clear(); + for (auto element : src) { + if (!add(element)) + return false; + } + return true; + } + void remove(iterator it) const { + detail::ArrayData::remove(data_, it.iterator_, resources_); + } + void remove(size_t index) const { + detail::ArrayData::removeElement(data_, index, resources_); + } + template ::value, int> = 0> + void remove(const TVariant & variant) const { + if (variant.template is()) + remove(variant.template as()); + } + void clear() const { + detail::ArrayData::clear(data_, resources_); + } + template ::value, int> = 0> + detail::ElementProxy operator[](T index) const { + return {*this, size_t(index)}; + } + template ::value, int> = 0> + detail::ElementProxy operator[](const TVariant & variant) const { + if (variant.template is()) + return {*this, variant.template as()}; + else + return {*this, size_t(-1)}; + } + operator JsonVariantConst() const { + return JsonVariantConst(collectionToVariant(data_), resources_); + } + bool isNull() const { + return data_ == 0; + } + operator bool() const { + return data_ != 0; + } + size_t nesting() const { + return detail::VariantData::nesting(collectionToVariant(data_), resources_); + } + size_t size() const { + return data_ ? data_->size(resources_) : 0; + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonVariant add() const { + return add(); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonArray createNestedArray() const { + return add(); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonObject createNestedObject() const; + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + private: + detail::ResourceManager * getResourceManager() const { + return resources_; + } + detail::VariantData * getData() const { + return collectionToVariant(data_); + } + detail::VariantData * getOrCreateData() const { + return collectionToVariant(data_); + } + detail::ArrayData * data_; + detail::ResourceManager * resources_; }; class JsonPair { - public: - JsonPair(detail::ObjectData::iterator iterator, - detail::ResourceManager* resources) { - if (!iterator.done()) { - key_ = iterator->asString(); - iterator.next(resources); - value_ = JsonVariant(iterator.data(), resources); + public: + JsonPair(detail::ObjectData::iterator iterator, detail::ResourceManager * resources) { + if (!iterator.done()) { + key_ = iterator->asString(); + iterator.next(resources); + value_ = JsonVariant(iterator.data(), resources); + } } - } - JsonString key() const { - return key_; - } - JsonVariant value() { - return value_; - } - private: - JsonString key_; - JsonVariant value_; + JsonString key() const { + return key_; + } + JsonVariant value() { + return value_; + } + + private: + JsonString key_; + JsonVariant value_; }; class JsonPairConst { - public: - JsonPairConst(detail::ObjectData::iterator iterator, - const detail::ResourceManager* resources) { - if (!iterator.done()) { - key_ = iterator->asString(); - iterator.next(resources); - value_ = JsonVariantConst(iterator.data(), resources); + public: + JsonPairConst(detail::ObjectData::iterator iterator, const detail::ResourceManager * resources) { + if (!iterator.done()) { + key_ = iterator->asString(); + iterator.next(resources); + value_ = JsonVariantConst(iterator.data(), resources); + } } - } - JsonString key() const { - return key_; - } - JsonVariantConst value() const { - return value_; - } - private: - JsonString key_; - JsonVariantConst value_; + JsonString key() const { + return key_; + } + JsonVariantConst value() const { + return value_; + } + + private: + JsonString key_; + JsonVariantConst value_; }; class JsonObjectIterator { - friend class JsonObject; - public: - JsonObjectIterator() {} - explicit JsonObjectIterator(detail::ObjectData::iterator iterator, - detail::ResourceManager* resources) - : iterator_(iterator), resources_(resources) {} - JsonPair operator*() const { - return JsonPair(iterator_, resources_); - } - Ptr operator->() { - return operator*(); - } - bool operator==(const JsonObjectIterator& other) const { - return iterator_ == other.iterator_; - } - bool operator!=(const JsonObjectIterator& other) const { - return iterator_ != other.iterator_; - } - JsonObjectIterator& operator++() { - iterator_.next(resources_); // key - iterator_.next(resources_); // value - return *this; - } - private: - detail::ObjectData::iterator iterator_; - detail::ResourceManager* resources_; + friend class JsonObject; + + public: + JsonObjectIterator() { + } + explicit JsonObjectIterator(detail::ObjectData::iterator iterator, detail::ResourceManager * resources) + : iterator_(iterator) + , resources_(resources) { + } + JsonPair operator*() const { + return JsonPair(iterator_, resources_); + } + Ptr operator->() { + return operator*(); + } + bool operator==(const JsonObjectIterator & other) const { + return iterator_ == other.iterator_; + } + bool operator!=(const JsonObjectIterator & other) const { + return iterator_ != other.iterator_; + } + JsonObjectIterator & operator++() { + iterator_.next(resources_); // key + iterator_.next(resources_); // value + return *this; + } + + private: + detail::ObjectData::iterator iterator_; + detail::ResourceManager * resources_; }; class JsonObjectConstIterator { - friend class JsonObject; - public: - JsonObjectConstIterator() {} - explicit JsonObjectConstIterator(detail::ObjectData::iterator iterator, - const detail::ResourceManager* resources) - : iterator_(iterator), resources_(resources) {} - JsonPairConst operator*() const { - return JsonPairConst(iterator_, resources_); - } - Ptr operator->() { - return operator*(); - } - bool operator==(const JsonObjectConstIterator& other) const { - return iterator_ == other.iterator_; - } - bool operator!=(const JsonObjectConstIterator& other) const { - return iterator_ != other.iterator_; - } - JsonObjectConstIterator& operator++() { - iterator_.next(resources_); // key - iterator_.next(resources_); // value - return *this; - } - private: - detail::ObjectData::iterator iterator_; - const detail::ResourceManager* resources_; + friend class JsonObject; + + public: + JsonObjectConstIterator() { + } + explicit JsonObjectConstIterator(detail::ObjectData::iterator iterator, const detail::ResourceManager * resources) + : iterator_(iterator) + , resources_(resources) { + } + JsonPairConst operator*() const { + return JsonPairConst(iterator_, resources_); + } + Ptr operator->() { + return operator*(); + } + bool operator==(const JsonObjectConstIterator & other) const { + return iterator_ == other.iterator_; + } + bool operator!=(const JsonObjectConstIterator & other) const { + return iterator_ != other.iterator_; + } + JsonObjectConstIterator & operator++() { + iterator_.next(resources_); // key + iterator_.next(resources_); // value + return *this; + } + + private: + detail::ObjectData::iterator iterator_; + const detail::ResourceManager * resources_; }; class JsonObjectConst : public detail::VariantOperators { - friend class JsonObject; - friend class detail::VariantAttorney; - public: - using iterator = JsonObjectConstIterator; - JsonObjectConst() : data_(0), resources_(0) {} - JsonObjectConst(const detail::ObjectData* data, - const detail::ResourceManager* resources) - : data_(data), resources_(resources) {} - operator JsonVariantConst() const { - return JsonVariantConst(getData(), resources_); - } - bool isNull() const { - return data_ == 0; - } - operator bool() const { - return data_ != 0; - } - size_t nesting() const { - return detail::VariantData::nesting(getData(), resources_); - } - size_t size() const { - return data_ ? data_->size(resources_) : 0; - } - iterator begin() const { - if (!data_) - return iterator(); - return iterator(data_->createIterator(resources_), resources_); - } - iterator end() const { - return iterator(); - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TString& key) const { - return detail::ObjectData::getMember(data_, detail::adaptString(key), - resources_) != 0; - } - template - ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") - bool containsKey(TChar* key) const { - return detail::ObjectData::getMember(data_, detail::adaptString(key), - resources_) != 0; - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TVariant& key) const { - return containsKey(key.template as()); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TString& key) const { - return JsonVariantConst(detail::ObjectData::getMember( - data_, detail::adaptString(key), resources_), - resources_); - } - template ::value && - !detail::is_const::value, - int> = 0> - JsonVariantConst operator[](TChar* key) const { - return JsonVariantConst(detail::ObjectData::getMember( - data_, detail::adaptString(key), resources_), - resources_); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TVariant& key) const { - if (key.template is()) - return operator[](key.template as()); - else - return JsonVariantConst(); - } - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - private: - const detail::VariantData* getData() const { - return collectionToVariant(data_); - } - const detail::ObjectData* data_; - const detail::ResourceManager* resources_; + friend class JsonObject; + friend class detail::VariantAttorney; + + public: + using iterator = JsonObjectConstIterator; + JsonObjectConst() + : data_(0) + , resources_(0) { + } + JsonObjectConst(const detail::ObjectData * data, const detail::ResourceManager * resources) + : data_(data) + , resources_(resources) { + } + operator JsonVariantConst() const { + return JsonVariantConst(getData(), resources_); + } + bool isNull() const { + return data_ == 0; + } + operator bool() const { + return data_ != 0; + } + size_t nesting() const { + return detail::VariantData::nesting(getData(), resources_); + } + size_t size() const { + return data_ ? data_->size(resources_) : 0; + } + iterator begin() const { + if (!data_) + return iterator(); + return iterator(data_->createIterator(resources_), resources_); + } + iterator end() const { + return iterator(); + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TString & key) const { + return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; + } + template + ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") + bool containsKey(TChar * key) const { + return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TVariant & key) const { + return containsKey(key.template as()); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TString & key) const { + return JsonVariantConst(detail::ObjectData::getMember(data_, detail::adaptString(key), resources_), resources_); + } + template ::value && !detail::is_const::value, int> = 0> + JsonVariantConst operator[](TChar * key) const { + return JsonVariantConst(detail::ObjectData::getMember(data_, detail::adaptString(key), resources_), resources_); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TVariant & key) const { + if (key.template is()) + return operator[](key.template as()); + else + return JsonVariantConst(); + } + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + private: + const detail::VariantData * getData() const { + return collectionToVariant(data_); + } + const detail::ObjectData * data_; + const detail::ResourceManager * resources_; }; inline bool operator==(JsonObjectConst lhs, JsonObjectConst rhs) { - if (!lhs && !rhs) // both are null - return true; - if (!lhs || !rhs) // only one is null - return false; - size_t count = 0; - for (auto kvp : lhs) { - auto rhsValue = rhs[kvp.key()]; - if (rhsValue.isUnbound()) - return false; - if (kvp.value() != rhsValue) - return false; - count++; - } - return count == rhs.size(); + if (!lhs && !rhs) // both are null + return true; + if (!lhs || !rhs) // only one is null + return false; + size_t count = 0; + for (auto kvp : lhs) { + auto rhsValue = rhs[kvp.key()]; + if (rhsValue.isUnbound()) + return false; + if (kvp.value() != rhsValue) + return false; + count++; + } + return count == rhs.size(); } ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template -class MemberProxy - : public VariantRefBase>, - public VariantOperators> { - friend class VariantAttorney; - friend class VariantRefBase>; - template - friend class MemberProxy; - template - friend class ElementProxy; - public: - MemberProxy(TUpstream upstream, AdaptedString key) - : upstream_(upstream), key_(key) {} - MemberProxy& operator=(const MemberProxy& src) { - this->set(src); - return *this; - } - template - MemberProxy& operator=(const T& src) { - this->set(src); - return *this; - } - template ::value, int> = 0> - MemberProxy& operator=(T* src) { - this->set(src); - return *this; - } - private: - MemberProxy(const MemberProxy& src) // Error here? See https://arduinojson.org/v7/proxy-non-copyable/ - : upstream_(src.upstream_), key_(src.key_) {} - ResourceManager* getResourceManager() const { - return VariantAttorney::getResourceManager(upstream_); - } - VariantData* getData() const { - return VariantData::getMember( - VariantAttorney::getData(upstream_), key_, - VariantAttorney::getResourceManager(upstream_)); - } - VariantData* getOrCreateData() const { - auto data = VariantAttorney::getOrCreateData(upstream_); - if (!data) - return nullptr; - return data->getOrAddMember(key_, - VariantAttorney::getResourceManager(upstream_)); - } - private: - TUpstream upstream_; - AdaptedString key_; +class MemberProxy : public VariantRefBase>, public VariantOperators> { + friend class VariantAttorney; + friend class VariantRefBase>; + template + friend class MemberProxy; + template + friend class ElementProxy; + + public: + MemberProxy(TUpstream upstream, AdaptedString key) + : upstream_(upstream) + , key_(key) { + } + MemberProxy & operator=(const MemberProxy & src) { + this->set(src); + return *this; + } + template + MemberProxy & operator=(const T & src) { + this->set(src); + return *this; + } + template ::value, int> = 0> + MemberProxy & operator=(T * src) { + this->set(src); + return *this; + } + + private: + MemberProxy(const MemberProxy & src) // Error here? See https://arduinojson.org/v7/proxy-non-copyable/ + : upstream_(src.upstream_) + , key_(src.key_) { + } + ResourceManager * getResourceManager() const { + return VariantAttorney::getResourceManager(upstream_); + } + VariantData * getData() const { + return VariantData::getMember(VariantAttorney::getData(upstream_), key_, VariantAttorney::getResourceManager(upstream_)); + } + VariantData * getOrCreateData() const { + auto data = VariantAttorney::getOrCreateData(upstream_); + if (!data) + return nullptr; + return data->getOrAddMember(key_, VariantAttorney::getResourceManager(upstream_)); + } + + private: + TUpstream upstream_; + AdaptedString key_; }; ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE class JsonArray; class JsonObject : public detail::VariantOperators { - friend class detail::VariantAttorney; - public: - using iterator = JsonObjectIterator; - JsonObject() : data_(0), resources_(0) {} - JsonObject(detail::ObjectData* data, detail::ResourceManager* resource) - : data_(data), resources_(resource) {} - operator JsonVariant() const { - void* data = data_; // prevent warning cast-align - return JsonVariant(reinterpret_cast(data), - resources_); - } - operator JsonObjectConst() const { - return JsonObjectConst(data_, resources_); - } - operator JsonVariantConst() const { - return JsonVariantConst(collectionToVariant(data_), resources_); - } - bool isNull() const { - return data_ == 0; - } - operator bool() const { - return data_ != 0; - } - size_t nesting() const { - return detail::VariantData::nesting(collectionToVariant(data_), resources_); - } - size_t size() const { - return data_ ? data_->size(resources_) : 0; - } - iterator begin() const { - if (!data_) - return iterator(); - return iterator(data_->createIterator(resources_), resources_); - } - iterator end() const { - return iterator(); - } - void clear() const { - detail::ObjectData::clear(data_, resources_); - } - bool set(JsonObjectConst src) { - if (!data_ || !src.data_) - return false; - clear(); - for (auto kvp : src) { - if (!operator[](kvp.key()).set(kvp.value())) - return false; + friend class detail::VariantAttorney; + + public: + using iterator = JsonObjectIterator; + JsonObject() + : data_(0) + , resources_(0) { } - return true; - } - template ::value, int> = 0> - detail::MemberProxy> operator[]( - const TString& key) const { - return {*this, detail::adaptString(key)}; - } - template ::value && - !detail::is_const::value, - int> = 0> - detail::MemberProxy> operator[]( - TChar* key) const { - return {*this, detail::adaptString(key)}; - } - template ::value, int> = 0> - detail::MemberProxy> operator[]( - const TVariant& key) const { - return {*this, detail::adaptString(key.template as())}; - } - FORCE_INLINE void remove(iterator it) const { - detail::ObjectData::remove(data_, it.iterator_, resources_); - } - template ::value, int> = 0> - void remove(const TString& key) const { - detail::ObjectData::removeMember(data_, detail::adaptString(key), - resources_); - } - template ::value, int> = 0> - void remove(const TVariant& key) const { - if (key.template is()) - remove(key.template as()); - } - template - FORCE_INLINE void remove(TChar* key) const { - detail::ObjectData::removeMember(data_, detail::adaptString(key), - resources_); - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TString& key) const { - return detail::ObjectData::getMember(data_, detail::adaptString(key), - resources_) != 0; - } - template ::value && - !detail::is_const::value, - int> = 0> - ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") - bool containsKey(TChar* key) const { - return detail::ObjectData::getMember(data_, detail::adaptString(key), - resources_) != 0; - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use obj[key].is() instead") - bool containsKey(const TVariant& key) const { - return containsKey(key.template as()); - } - template - ARDUINOJSON_DEPRECATED("use obj[key].to() instead") - JsonArray createNestedArray(TChar* key) const { - return operator[](key).template to(); - } - template - ARDUINOJSON_DEPRECATED("use obj[key].to() instead") - JsonArray createNestedArray(const TString& key) const { - return operator[](key).template to(); - } - template - ARDUINOJSON_DEPRECATED("use obj[key].to() instead") - JsonObject createNestedObject(TChar* key) { - return operator[](key).template to(); - } - template - ARDUINOJSON_DEPRECATED("use obj[key].to() instead") - JsonObject createNestedObject(const TString& key) { - return operator[](key).template to(); - } - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - private: - detail::ResourceManager* getResourceManager() const { - return resources_; - } - detail::VariantData* getData() const { - return detail::collectionToVariant(data_); - } - detail::VariantData* getOrCreateData() const { - return detail::collectionToVariant(data_); - } - detail::ObjectData* data_; - detail::ResourceManager* resources_; + JsonObject(detail::ObjectData * data, detail::ResourceManager * resource) + : data_(data) + , resources_(resource) { + } + operator JsonVariant() const { + void * data = data_; // prevent warning cast-align + return JsonVariant(reinterpret_cast(data), resources_); + } + operator JsonObjectConst() const { + return JsonObjectConst(data_, resources_); + } + operator JsonVariantConst() const { + return JsonVariantConst(collectionToVariant(data_), resources_); + } + bool isNull() const { + return data_ == 0; + } + operator bool() const { + return data_ != 0; + } + size_t nesting() const { + return detail::VariantData::nesting(collectionToVariant(data_), resources_); + } + size_t size() const { + return data_ ? data_->size(resources_) : 0; + } + iterator begin() const { + if (!data_) + return iterator(); + return iterator(data_->createIterator(resources_), resources_); + } + iterator end() const { + return iterator(); + } + void clear() const { + detail::ObjectData::clear(data_, resources_); + } + bool set(JsonObjectConst src) { + if (!data_ || !src.data_) + return false; + clear(); + for (auto kvp : src) { + if (!operator[](kvp.key()).set(kvp.value())) + return false; + } + return true; + } + template ::value, int> = 0> + detail::MemberProxy> operator[](const TString & key) const { + return {*this, detail::adaptString(key)}; + } + template ::value && !detail::is_const::value, int> = 0> + detail::MemberProxy> operator[](TChar * key) const { + return {*this, detail::adaptString(key)}; + } + template ::value, int> = 0> + detail::MemberProxy> operator[](const TVariant & key) const { + return {*this, detail::adaptString(key.template as())}; + } + FORCE_INLINE void remove(iterator it) const { + detail::ObjectData::remove(data_, it.iterator_, resources_); + } + template ::value, int> = 0> + void remove(const TString & key) const { + detail::ObjectData::removeMember(data_, detail::adaptString(key), resources_); + } + template ::value, int> = 0> + void remove(const TVariant & key) const { + if (key.template is()) + remove(key.template as()); + } + template + FORCE_INLINE void remove(TChar * key) const { + detail::ObjectData::removeMember(data_, detail::adaptString(key), resources_); + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TString & key) const { + return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; + } + template ::value && !detail::is_const::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[\"key\"].is() instead") + bool containsKey(TChar * key) const { + return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use obj[key].is() instead") + bool containsKey(const TVariant & key) const { + return containsKey(key.template as()); + } + template + ARDUINOJSON_DEPRECATED("use obj[key].to() instead") + JsonArray createNestedArray(TChar * key) const { + return operator[](key).template to(); + } + template + ARDUINOJSON_DEPRECATED("use obj[key].to() instead") + JsonArray createNestedArray(const TString & key) const { + return operator[](key).template to(); + } + template + ARDUINOJSON_DEPRECATED("use obj[key].to() instead") + JsonObject createNestedObject(TChar * key) { + return operator[](key).template to(); + } + template + ARDUINOJSON_DEPRECATED("use obj[key].to() instead") + JsonObject createNestedObject(const TString & key) { + return operator[](key).template to(); + } + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + private: + detail::ResourceManager * getResourceManager() const { + return resources_; + } + detail::VariantData * getData() const { + return detail::collectionToVariant(data_); + } + detail::VariantData * getOrCreateData() const { + return detail::collectionToVariant(data_); + } + detail::ObjectData * data_; + detail::ResourceManager * resources_; }; -class JsonDocument : public detail::VariantOperators { - friend class detail::VariantAttorney; - public: - explicit JsonDocument(Allocator* alloc = detail::DefaultAllocator::instance()) - : resources_(alloc) {} - JsonDocument(const JsonDocument& src) : JsonDocument(src.allocator()) { - set(src); - } - JsonDocument(JsonDocument&& src) - : JsonDocument(detail::DefaultAllocator::instance()) { - swap(*this, src); - } - template ::value || - detail::is_same::value || - detail::is_same::value || - detail::is_same::value || - detail::is_same::value, - int> = 0> - JsonDocument(const T& src, - Allocator* alloc = detail::DefaultAllocator::instance()) - : JsonDocument(alloc) { - set(src); - } - JsonDocument& operator=(JsonDocument src) { - swap(*this, src); - return *this; - } - template - JsonDocument& operator=(const T& src) { - set(src); - return *this; - } - Allocator* allocator() const { - return resources_.allocator(); - } - void shrinkToFit() { - resources_.shrinkToFit(); - } - template - T as() { - return getVariant().template as(); - } - template - T as() const { - return getVariant().template as(); - } - void clear() { - resources_.clear(); - data_.reset(); - } - template - bool is() { - return getVariant().template is(); - } - template - bool is() const { - return getVariant().template is(); - } - bool isNull() const { - return getVariant().isNull(); - } - bool overflowed() const { - return resources_.overflowed(); - } - size_t nesting() const { - return data_.nesting(&resources_); - } - size_t size() const { - return data_.size(&resources_); - } - bool set(const JsonDocument& src) { - return to().set(src.as()); - } - template < - typename T, - detail::enable_if_t::value, int> = 0> - bool set(const T& src) { - return to().set(src); - } - template ::value, int> = 0> - bool set(TChar* src) { - return to().set(src); - } - template - typename detail::VariantTo::type to() { - clear(); - return getVariant().template to(); - } - template - ARDUINOJSON_DEPRECATED("use doc[\"key\"].is() instead") - bool containsKey(TChar* key) const { - return data_.getMember(detail::adaptString(key), &resources_) != 0; - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use doc[key].is() instead") - bool containsKey(const TString& key) const { - return data_.getMember(detail::adaptString(key), &resources_) != 0; - } - template ::value, int> = 0> - ARDUINOJSON_DEPRECATED("use doc[key].is() instead") - bool containsKey(const TVariant& key) const { - return containsKey(key.template as()); - } - template ::value, int> = 0> - detail::MemberProxy> operator[]( - const TString& key) { - return {*this, detail::adaptString(key)}; - } - template ::value && - !detail::is_const::value, - int> = 0> - detail::MemberProxy> operator[]( - TChar* key) { - return {*this, detail::adaptString(key)}; - } - template ::value, int> = 0> - JsonVariantConst operator[](const TString& key) const { - return JsonVariantConst( - data_.getMember(detail::adaptString(key), &resources_), &resources_); - } - template ::value && - !detail::is_const::value, - int> = 0> - JsonVariantConst operator[](TChar* key) const { - return JsonVariantConst( - data_.getMember(detail::adaptString(key), &resources_), &resources_); - } - template ::value, int> = 0> - detail::ElementProxy operator[](T index) { - return {*this, size_t(index)}; - } - JsonVariantConst operator[](size_t index) const { - return JsonVariantConst(data_.getElement(index, &resources_), &resources_); - } - template ::value, int> = 0> - JsonVariantConst operator[](const TVariant& key) const { - if (key.template is()) - return operator[](key.template as()); - if (key.template is()) - return operator[](key.template as()); - return {}; - } - template ::value, int> = 0> - T add() { - return add().to(); - } - template ::value, int> = 0> - JsonVariant add() { - return JsonVariant(data_.addElement(&resources_), &resources_); - } - template - bool add(const TValue& value) { - return data_.addValue(value, &resources_); - } - template ::value, int> = 0> - bool add(TChar* value) { - return data_.addValue(value, &resources_); - } - template ::value, int> = 0> - void remove(T index) { - detail::VariantData::removeElement(getData(), size_t(index), - getResourceManager()); - } - template ::value && - !detail::is_const::value, - int> = 0> - void remove(TChar* key) { - detail::VariantData::removeMember(getData(), detail::adaptString(key), - getResourceManager()); - } - template ::value, int> = 0> - void remove(const TString& key) { - detail::VariantData::removeMember(getData(), detail::adaptString(key), - getResourceManager()); - } - template ::value, int> = 0> - void remove(const TVariant& key) { - if (key.template is()) - remove(key.template as()); - if (key.template is()) - remove(key.template as()); - } - operator JsonVariant() { - return getVariant(); - } - operator JsonVariantConst() const { - return getVariant(); - } - friend void swap(JsonDocument& a, JsonDocument& b) { - swap(a.resources_, b.resources_); - swap_(a.data_, b.data_); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonVariant add() { - return add(); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonArray createNestedArray() { - return add(); - } - template - ARDUINOJSON_DEPRECATED("use doc[key].to() instead") - JsonArray createNestedArray(TChar* key) { - return operator[](key).template to(); - } - template - ARDUINOJSON_DEPRECATED("use doc[key].to() instead") - JsonArray createNestedArray(const TString& key) { - return operator[](key).template to(); - } - ARDUINOJSON_DEPRECATED("use add() instead") - JsonObject createNestedObject() { - return add(); - } - template - ARDUINOJSON_DEPRECATED("use doc[key].to() instead") - JsonObject createNestedObject(TChar* key) { - return operator[](key).template to(); - } - template - ARDUINOJSON_DEPRECATED("use doc[key].to() instead") - JsonObject createNestedObject(const TString& key) { - return operator[](key).template to(); - } - ARDUINOJSON_DEPRECATED("always returns zero") - size_t memoryUsage() const { - return 0; - } - private: - JsonVariant getVariant() { - return JsonVariant(&data_, &resources_); - } - JsonVariantConst getVariant() const { - return JsonVariantConst(&data_, &resources_); - } - detail::ResourceManager* getResourceManager() { - return &resources_; - } - detail::VariantData* getData() { - return &data_; - } - const detail::VariantData* getData() const { - return &data_; - } - detail::VariantData* getOrCreateData() { - return &data_; - } - detail::ResourceManager resources_; - detail::VariantData data_; +class JsonDocument : public detail::VariantOperators { + friend class detail::VariantAttorney; + + public: + explicit JsonDocument(Allocator * alloc = detail::DefaultAllocator::instance()) + : resources_(alloc) { + } + JsonDocument(const JsonDocument & src) + : JsonDocument(src.allocator()) { + set(src); + } + JsonDocument(JsonDocument && src) + : JsonDocument(detail::DefaultAllocator::instance()) { + swap(*this, src); + } + template ::value || detail::is_same::value || detail::is_same::value + || detail::is_same::value || detail::is_same::value, + int> = 0> + JsonDocument(const T & src, Allocator * alloc = detail::DefaultAllocator::instance()) + : JsonDocument(alloc) { + set(src); + } + JsonDocument & operator=(JsonDocument src) { + swap(*this, src); + return *this; + } + template + JsonDocument & operator=(const T & src) { + set(src); + return *this; + } + Allocator * allocator() const { + return resources_.allocator(); + } + void shrinkToFit() { + resources_.shrinkToFit(); + } + template + T as() { + return getVariant().template as(); + } + template + T as() const { + return getVariant().template as(); + } + void clear() { + resources_.clear(); + data_.reset(); + } + template + bool is() { + return getVariant().template is(); + } + template + bool is() const { + return getVariant().template is(); + } + bool isNull() const { + return getVariant().isNull(); + } + bool overflowed() const { + return resources_.overflowed(); + } + size_t nesting() const { + return data_.nesting(&resources_); + } + size_t size() const { + return data_.size(&resources_); + } + bool set(const JsonDocument & src) { + return to().set(src.as()); + } + template ::value, int> = 0> + bool set(const T & src) { + return to().set(src); + } + template ::value, int> = 0> + bool set(TChar * src) { + return to().set(src); + } + template + typename detail::VariantTo::type to() { + clear(); + return getVariant().template to(); + } + template + ARDUINOJSON_DEPRECATED("use doc[\"key\"].is() instead") + bool containsKey(TChar * key) const { + return data_.getMember(detail::adaptString(key), &resources_) != 0; + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use doc[key].is() instead") + bool containsKey(const TString & key) const { + return data_.getMember(detail::adaptString(key), &resources_) != 0; + } + template ::value, int> = 0> + ARDUINOJSON_DEPRECATED("use doc[key].is() instead") + bool containsKey(const TVariant & key) const { + return containsKey(key.template as()); + } + template ::value, int> = 0> + detail::MemberProxy> operator[](const TString & key) { + return {*this, detail::adaptString(key)}; + } + template ::value && !detail::is_const::value, int> = 0> + detail::MemberProxy> operator[](TChar * key) { + return {*this, detail::adaptString(key)}; + } + template ::value, int> = 0> + JsonVariantConst operator[](const TString & key) const { + return JsonVariantConst(data_.getMember(detail::adaptString(key), &resources_), &resources_); + } + template ::value && !detail::is_const::value, int> = 0> + JsonVariantConst operator[](TChar * key) const { + return JsonVariantConst(data_.getMember(detail::adaptString(key), &resources_), &resources_); + } + template ::value, int> = 0> + detail::ElementProxy operator[](T index) { + return {*this, size_t(index)}; + } + JsonVariantConst operator[](size_t index) const { + return JsonVariantConst(data_.getElement(index, &resources_), &resources_); + } + template ::value, int> = 0> + JsonVariantConst operator[](const TVariant & key) const { + if (key.template is()) + return operator[](key.template as()); + if (key.template is()) + return operator[](key.template as()); + return {}; + } + template ::value, int> = 0> + T add() { + return add().to(); + } + template ::value, int> = 0> + JsonVariant add() { + return JsonVariant(data_.addElement(&resources_), &resources_); + } + template + bool add(const TValue & value) { + return data_.addValue(value, &resources_); + } + template ::value, int> = 0> + bool add(TChar * value) { + return data_.addValue(value, &resources_); + } + template ::value, int> = 0> + void remove(T index) { + detail::VariantData::removeElement(getData(), size_t(index), getResourceManager()); + } + template ::value && !detail::is_const::value, int> = 0> + void remove(TChar * key) { + detail::VariantData::removeMember(getData(), detail::adaptString(key), getResourceManager()); + } + template ::value, int> = 0> + void remove(const TString & key) { + detail::VariantData::removeMember(getData(), detail::adaptString(key), getResourceManager()); + } + template ::value, int> = 0> + void remove(const TVariant & key) { + if (key.template is()) + remove(key.template as()); + if (key.template is()) + remove(key.template as()); + } + operator JsonVariant() { + return getVariant(); + } + operator JsonVariantConst() const { + return getVariant(); + } + friend void swap(JsonDocument & a, JsonDocument & b) { + swap(a.resources_, b.resources_); + swap_(a.data_, b.data_); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonVariant add() { + return add(); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonArray createNestedArray() { + return add(); + } + template + ARDUINOJSON_DEPRECATED("use doc[key].to() instead") + JsonArray createNestedArray(TChar * key) { + return operator[](key).template to(); + } + template + ARDUINOJSON_DEPRECATED("use doc[key].to() instead") + JsonArray createNestedArray(const TString & key) { + return operator[](key).template to(); + } + ARDUINOJSON_DEPRECATED("use add() instead") + JsonObject createNestedObject() { + return add(); + } + template + ARDUINOJSON_DEPRECATED("use doc[key].to() instead") + JsonObject createNestedObject(TChar * key) { + return operator[](key).template to(); + } + template + ARDUINOJSON_DEPRECATED("use doc[key].to() instead") + JsonObject createNestedObject(const TString & key) { + return operator[](key).template to(); + } + ARDUINOJSON_DEPRECATED("always returns zero") + size_t memoryUsage() const { + return 0; + } + + private: + JsonVariant getVariant() { + return JsonVariant(&data_, &resources_); + } + JsonVariantConst getVariant() const { + return JsonVariantConst(&data_, &resources_); + } + detail::ResourceManager * getResourceManager() { + return &resources_; + } + detail::VariantData * getData() { + return &data_; + } + const detail::VariantData * getData() const { + return &data_; + } + detail::VariantData * getOrCreateData() { + return &data_; + } + detail::ResourceManager resources_; + detail::VariantData data_; }; -inline void convertToJson(const JsonDocument& src, JsonVariant dst) { - dst.set(src.as()); +inline void convertToJson(const JsonDocument & src, JsonVariant dst) { + dst.set(src.as()); } ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template struct VariantDataVisitor { - using result_type = TResult; - template - TResult visit(const T&) { - return TResult(); - } + using result_type = TResult; + template + TResult visit(const T &) { + return TResult(); + } }; template struct JsonVariantVisitor { - using result_type = TResult; - template - TResult visit(const T&) { - return TResult(); - } + using result_type = TResult; + template + TResult visit(const T &) { + return TResult(); + } }; template class VisitorAdapter { - public: - using result_type = typename TVisitor::result_type; - VisitorAdapter(TVisitor& visitor, const ResourceManager* resources) - : visitor_(&visitor), resources_(resources) {} - result_type visit(const ArrayData& value) { - return visitor_->visit(JsonArrayConst(&value, resources_)); - } - result_type visit(const ObjectData& value) { - return visitor_->visit(JsonObjectConst(&value, resources_)); - } - template - result_type visit(const T& value) { - return visitor_->visit(value); - } - private: - TVisitor* visitor_; - const ResourceManager* resources_; + public: + using result_type = typename TVisitor::result_type; + VisitorAdapter(TVisitor & visitor, const ResourceManager * resources) + : visitor_(&visitor) + , resources_(resources) { + } + result_type visit(const ArrayData & value) { + return visitor_->visit(JsonArrayConst(&value, resources_)); + } + result_type visit(const ObjectData & value) { + return visitor_->visit(JsonObjectConst(&value, resources_)); + } + template + result_type visit(const T & value) { + return visitor_->visit(value); + } + + private: + TVisitor * visitor_; + const ResourceManager * resources_; }; template -typename TVisitor::result_type accept(JsonVariantConst variant, - TVisitor& visit) { - auto data = VariantAttorney::getData(variant); - if (!data) - return visit.visit(nullptr); - auto resources = VariantAttorney::getResourceManager(variant); - VisitorAdapter adapter(visit, resources); - return data->accept(adapter, resources); +typename TVisitor::result_type accept(JsonVariantConst variant, TVisitor & visit) { + auto data = VariantAttorney::getData(variant); + if (!data) + return visit.visit(nullptr); + auto resources = VariantAttorney::getResourceManager(variant); + VisitorAdapter adapter(visit, resources); + return data->accept(adapter, resources); } struct ComparerBase : JsonVariantVisitor {}; template struct Comparer; template struct Comparer::value>> : ComparerBase { - T rhs; // TODO: store adapted string? - explicit Comparer(T value) : rhs(value) {} - CompareResult visit(JsonString lhs) { - int i = stringCompare(adaptString(rhs), adaptString(lhs)); - if (i < 0) - return COMPARE_RESULT_GREATER; - else if (i > 0) - return COMPARE_RESULT_LESS; - else - return COMPARE_RESULT_EQUAL; - } - CompareResult visit(nullptr_t) { - if (adaptString(rhs).isNull()) - return COMPARE_RESULT_EQUAL; - else - return COMPARE_RESULT_DIFFER; - } - using ComparerBase::visit; + T rhs; + explicit Comparer(T value) + : rhs(value) { + } + CompareResult visit(JsonString lhs) { + int i = stringCompare(adaptString(rhs), adaptString(lhs)); + if (i < 0) + return COMPARE_RESULT_GREATER; + else if (i > 0) + return COMPARE_RESULT_LESS; + else + return COMPARE_RESULT_EQUAL; + } + CompareResult visit(nullptr_t) { + if (adaptString(rhs).isNull()) + return COMPARE_RESULT_EQUAL; + else + return COMPARE_RESULT_DIFFER; + } + using ComparerBase::visit; }; template -struct Comparer< - T, enable_if_t::value || is_floating_point::value>> - : ComparerBase { - T rhs; - explicit Comparer(T value) : rhs(value) {} - template - enable_if_t::value || is_integral::value, - CompareResult> - visit(const U& lhs) { - return arithmeticCompare(lhs, rhs); - } - template - enable_if_t::value && !is_integral::value, - CompareResult> - visit(const U& lhs) { - return ComparerBase::visit(lhs); - } +struct Comparer::value || is_floating_point::value>> : ComparerBase { + T rhs; + explicit Comparer(T value) + : rhs(value) { + } + template + enable_if_t::value || is_integral::value, CompareResult> visit(const U & lhs) { + return arithmeticCompare(lhs, rhs); + } + template + enable_if_t::value && !is_integral::value, CompareResult> visit(const U & lhs) { + return ComparerBase::visit(lhs); + } }; struct NullComparer : ComparerBase { - CompareResult visit(nullptr_t) { - return COMPARE_RESULT_EQUAL; - } - using ComparerBase::visit; + CompareResult visit(nullptr_t) { + return COMPARE_RESULT_EQUAL; + } + using ComparerBase::visit; }; template <> struct Comparer : NullComparer { - explicit Comparer(nullptr_t) : NullComparer() {} + explicit Comparer(nullptr_t) + : NullComparer() { + } }; struct ArrayComparer : ComparerBase { - JsonArrayConst rhs_; - explicit ArrayComparer(JsonArrayConst rhs) : rhs_(rhs) {} - CompareResult visit(JsonArrayConst lhs) { - if (rhs_ == lhs) - return COMPARE_RESULT_EQUAL; - else - return COMPARE_RESULT_DIFFER; - } - using ComparerBase::visit; + JsonArrayConst rhs_; + explicit ArrayComparer(JsonArrayConst rhs) + : rhs_(rhs) { + } + CompareResult visit(JsonArrayConst lhs) { + if (rhs_ == lhs) + return COMPARE_RESULT_EQUAL; + else + return COMPARE_RESULT_DIFFER; + } + using ComparerBase::visit; }; struct ObjectComparer : ComparerBase { - JsonObjectConst rhs_; - explicit ObjectComparer(JsonObjectConst rhs) : rhs_(rhs) {} - CompareResult visit(JsonObjectConst lhs) { - if (lhs == rhs_) - return COMPARE_RESULT_EQUAL; - else - return COMPARE_RESULT_DIFFER; - } - using ComparerBase::visit; + JsonObjectConst rhs_; + explicit ObjectComparer(JsonObjectConst rhs) + : rhs_(rhs) { + } + CompareResult visit(JsonObjectConst lhs) { + if (lhs == rhs_) + return COMPARE_RESULT_EQUAL; + else + return COMPARE_RESULT_DIFFER; + } + using ComparerBase::visit; }; struct RawComparer : ComparerBase { - RawString rhs_; - explicit RawComparer(RawString rhs) : rhs_(rhs) {} - CompareResult visit(RawString lhs) { - size_t size = rhs_.size() < lhs.size() ? rhs_.size() : lhs.size(); - int n = memcmp(lhs.data(), rhs_.data(), size); - if (n < 0) - return COMPARE_RESULT_LESS; - else if (n > 0) - return COMPARE_RESULT_GREATER; - else - return COMPARE_RESULT_EQUAL; - } - using ComparerBase::visit; + RawString rhs_; + explicit RawComparer(RawString rhs) + : rhs_(rhs) { + } + CompareResult visit(RawString lhs) { + size_t size = rhs_.size() < lhs.size() ? rhs_.size() : lhs.size(); + int n = memcmp(lhs.data(), rhs_.data(), size); + if (n < 0) + return COMPARE_RESULT_LESS; + else if (n > 0) + return COMPARE_RESULT_GREATER; + else + return COMPARE_RESULT_EQUAL; + } + using ComparerBase::visit; }; struct VariantComparer : ComparerBase { - JsonVariantConst rhs; - explicit VariantComparer(JsonVariantConst value) : rhs(value) {} - CompareResult visit(JsonArrayConst lhs) { - ArrayComparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(JsonObjectConst lhs) { - ObjectComparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(JsonFloat lhs) { - Comparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(JsonString lhs) { - Comparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(RawString value) { - RawComparer comparer(value); - return reverseResult(comparer); - } - CompareResult visit(JsonInteger lhs) { - Comparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(JsonUInt lhs) { - Comparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(bool lhs) { - Comparer comparer(lhs); - return reverseResult(comparer); - } - CompareResult visit(nullptr_t) { - NullComparer comparer; - return reverseResult(comparer); - } - private: - template - CompareResult reverseResult(TComparer& comparer) { - CompareResult reversedResult = accept(rhs, comparer); - switch (reversedResult) { - case COMPARE_RESULT_GREATER: - return COMPARE_RESULT_LESS; - case COMPARE_RESULT_LESS: - return COMPARE_RESULT_GREATER; - default: - return reversedResult; + JsonVariantConst rhs; + explicit VariantComparer(JsonVariantConst value) + : rhs(value) { + } + CompareResult visit(JsonArrayConst lhs) { + ArrayComparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(JsonObjectConst lhs) { + ObjectComparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(JsonFloat lhs) { + Comparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(JsonString lhs) { + Comparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(RawString value) { + RawComparer comparer(value); + return reverseResult(comparer); + } + CompareResult visit(JsonInteger lhs) { + Comparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(JsonUInt lhs) { + Comparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(bool lhs) { + Comparer comparer(lhs); + return reverseResult(comparer); + } + CompareResult visit(nullptr_t) { + NullComparer comparer; + return reverseResult(comparer); + } + + private: + template + CompareResult reverseResult(TComparer & comparer) { + CompareResult reversedResult = accept(rhs, comparer); + switch (reversedResult) { + case COMPARE_RESULT_GREATER: + return COMPARE_RESULT_LESS; + case COMPARE_RESULT_LESS: + return COMPARE_RESULT_GREATER; + default: + return reversedResult; + } } - } }; template -struct Comparer< - T, enable_if_t::value>> - : VariantComparer { - explicit Comparer(const T& value) - : VariantComparer(static_cast(value)) {} +struct Comparer::value>> : VariantComparer { + explicit Comparer(const T & value) + : VariantComparer(static_cast(value)) { + } }; template -CompareResult compare(ArduinoJson::JsonVariantConst lhs, const T& rhs) { - Comparer comparer(rhs); - return accept(lhs, comparer); +CompareResult compare(ArduinoJson::JsonVariantConst lhs, const T & rhs) { + Comparer comparer(rhs); + return accept(lhs, comparer); } -inline ArrayData::iterator ArrayData::at( - size_t index, const ResourceManager* resources) const { - auto it = createIterator(resources); - while (!it.done() && index) { - it.next(resources); - --index; - } - return it; +inline ArrayData::iterator ArrayData::at(size_t index, const ResourceManager * resources) const { + auto it = createIterator(resources); + while (!it.done() && index) { + it.next(resources); + --index; + } + return it; } -inline VariantData* ArrayData::addElement(ResourceManager* resources) { - auto slot = resources->allocVariant(); - if (!slot) - return nullptr; - CollectionData::appendOne(slot, resources); - return slot.ptr(); +inline VariantData * ArrayData::addElement(ResourceManager * resources) { + auto slot = resources->allocVariant(); + if (!slot) + return nullptr; + CollectionData::appendOne(slot, resources); + return slot.ptr(); } -inline VariantData* ArrayData::getOrAddElement(size_t index, - ResourceManager* resources) { - auto it = createIterator(resources); - while (!it.done() && index > 0) { - it.next(resources); - index--; - } - if (it.done()) - index++; - VariantData* element = it.data(); - while (index > 0) { - element = addElement(resources); - if (!element) - return nullptr; - index--; - } - return element; +inline VariantData * ArrayData::getOrAddElement(size_t index, ResourceManager * resources) { + auto it = createIterator(resources); + while (!it.done() && index > 0) { + it.next(resources); + index--; + } + if (it.done()) + index++; + VariantData * element = it.data(); + while (index > 0) { + element = addElement(resources); + if (!element) + return nullptr; + index--; + } + return element; } -inline VariantData* ArrayData::getElement( - size_t index, const ResourceManager* resources) const { - return at(index, resources).data(); +inline VariantData * ArrayData::getElement(size_t index, const ResourceManager * resources) const { + return at(index, resources).data(); } -inline void ArrayData::removeElement(size_t index, ResourceManager* resources) { - remove(at(index, resources), resources); +inline void ArrayData::removeElement(size_t index, ResourceManager * resources) { + remove(at(index, resources), resources); } template -inline bool ArrayData::addValue(const T& value, ResourceManager* resources) { - ARDUINOJSON_ASSERT(resources != nullptr); - auto slot = resources->allocVariant(); - if (!slot) - return false; - JsonVariant variant(slot.ptr(), resources); - if (!variant.set(value)) { - resources->freeVariant(slot); - return false; - } - CollectionData::appendOne(slot, resources); - return true; +inline bool ArrayData::addValue(const T & value, ResourceManager * resources) { + ARDUINOJSON_ASSERT(resources != nullptr); + auto slot = resources->allocVariant(); + if (!slot) + return false; + JsonVariant variant(slot.ptr(), resources); + if (!variant.set(value)) { + resources->freeVariant(slot); + return false; + } + CollectionData::appendOne(slot, resources); + return true; } constexpr size_t sizeofArray(size_t n) { - return n * ResourceManager::slotSize; + return n * ResourceManager::slotSize; } ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE template ::value, int> = 0> -inline bool copyArray(const T& src, JsonVariant dst) { - return dst.set(src); +inline bool copyArray(const T & src, JsonVariant dst) { + return dst.set(src); } -template ::value, int> = 0> -inline bool copyArray(T (&src)[N], const TDestination& dst) { - return copyArray(src, N, dst); +template ::value, int> = 0> +inline bool copyArray(T (&src)[N], const TDestination & dst) { + return copyArray(src, N, dst); } -template ::value, int> = 0> -inline bool copyArray(const T* src, size_t len, const TDestination& dst) { - bool ok = true; - for (size_t i = 0; i < len; i++) { - ok &= copyArray(src[i], dst.template add()); - } - return ok; +template ::value, int> = 0> +inline bool copyArray(const T * src, size_t len, const TDestination & dst) { + bool ok = true; + for (size_t i = 0; i < len; i++) { + ok &= copyArray(src[i], dst.template add()); + } + return ok; } template -inline bool copyArray(const char* src, size_t, const TDestination& dst) { - return dst.set(src); +inline bool copyArray(const char * src, size_t, const TDestination & dst) { + return dst.set(src); } template -inline bool copyArray(const T& src, JsonDocument& dst) { - return copyArray(src, dst.to()); +inline bool copyArray(const T & src, JsonDocument & dst) { + return copyArray(src, dst.to()); } template -inline bool copyArray(const T* src, size_t len, JsonDocument& dst) { - return copyArray(src, len, dst.to()); +inline bool copyArray(const T * src, size_t len, JsonDocument & dst) { + return copyArray(src, len, dst.to()); } template ::value, int> = 0> -inline size_t copyArray(JsonVariantConst src, T& dst) { - dst = src.as(); - return 1; +inline size_t copyArray(JsonVariantConst src, T & dst) { + dst = src.as(); + return 1; } template inline size_t copyArray(JsonArrayConst src, T (&dst)[N]) { - return copyArray(src, dst, N); + return copyArray(src, dst, N); } template -inline size_t copyArray(JsonArrayConst src, T* dst, size_t len) { - size_t i = 0; - for (JsonArrayConst::iterator it = src.begin(); it != src.end() && i < len; - ++it) - copyArray(*it, dst[i++]); - return i; +inline size_t copyArray(JsonArrayConst src, T * dst, size_t len) { + size_t i = 0; + for (JsonArrayConst::iterator it = src.begin(); it != src.end() && i < len; ++it) + copyArray(*it, dst[i++]); + return i; } template inline size_t copyArray(JsonVariantConst src, char (&dst)[N]) { - JsonString s = src; - size_t len = N - 1; - if (len > s.size()) - len = s.size(); - memcpy(dst, s.c_str(), len); - dst[len] = 0; - return 1; + JsonString s = src; + size_t len = N - 1; + if (len > s.size()) + len = s.size(); + memcpy(dst, s.c_str(), len); + dst[len] = 0; + return 1; } -template < - typename TSource, typename T, - detail::enable_if_t::value && - detail::is_base_of::value, - int> = 0> -inline size_t copyArray(const TSource& src, T& dst) { - return copyArray(src.template as(), dst); +template ::value && detail::is_base_of::value, int> = 0> +inline size_t copyArray(const TSource & src, T & dst) { + return copyArray(src.template as(), dst); } ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE #if ARDUINOJSON_ENABLE_ALIGNMENT inline bool isAligned(size_t value) { - const size_t mask = sizeof(void*) - 1; - size_t addr = value; - return (addr & mask) == 0; + const size_t mask = sizeof(void *) - 1; + size_t addr = value; + return (addr & mask) == 0; } inline size_t addPadding(size_t bytes) { - const size_t mask = sizeof(void*) - 1; - return (bytes + mask) & ~mask; + const size_t mask = sizeof(void *) - 1; + return (bytes + mask) & ~mask; } template struct AddPadding { - static const size_t mask = sizeof(void*) - 1; - static const size_t value = (bytes + mask) & ~mask; + static const size_t mask = sizeof(void *) - 1; + static const size_t value = (bytes + mask) & ~mask; }; #else inline bool isAligned(size_t) { - return true; + return true; } inline size_t addPadding(size_t bytes) { - return bytes; + return bytes; } template struct AddPadding { - static const size_t value = bytes; + static const size_t value = bytes; }; #endif template -inline bool isAligned(T* ptr) { - return isAligned(reinterpret_cast(ptr)); +inline bool isAligned(T * ptr) { + return isAligned(reinterpret_cast(ptr)); } template -inline T* addPadding(T* p) { - size_t address = addPadding(reinterpret_cast(p)); - return reinterpret_cast(address); +inline T * addPadding(T * p) { + size_t address = addPadding(reinterpret_cast(p)); + return reinterpret_cast(address); } -inline CollectionIterator::CollectionIterator(VariantData* slot, SlotId slotId) - : slot_(slot), currentId_(slotId) { - nextId_ = slot_ ? slot_->next() : NULL_SLOT; +inline CollectionIterator::CollectionIterator(VariantData * slot, SlotId slotId) + : slot_(slot) + , currentId_(slotId) { + nextId_ = slot_ ? slot_->next() : NULL_SLOT; } -inline void CollectionIterator::next(const ResourceManager* resources) { - ARDUINOJSON_ASSERT(currentId_ != NULL_SLOT); - slot_ = resources->getVariant(nextId_); - currentId_ = nextId_; - if (slot_) - nextId_ = slot_->next(); +inline void CollectionIterator::next(const ResourceManager * resources) { + ARDUINOJSON_ASSERT(currentId_ != NULL_SLOT); + slot_ = resources->getVariant(nextId_); + currentId_ = nextId_; + if (slot_) + nextId_ = slot_->next(); } -inline CollectionData::iterator CollectionData::createIterator( - const ResourceManager* resources) const { - return iterator(resources->getVariant(head_), head_); +inline CollectionData::iterator CollectionData::createIterator(const ResourceManager * resources) const { + return iterator(resources->getVariant(head_), head_); } -inline void CollectionData::appendOne(Slot slot, - const ResourceManager* resources) { - if (tail_ != NULL_SLOT) { - auto tail = resources->getVariant(tail_); - tail->setNext(slot.id()); - tail_ = slot.id(); - } else { - head_ = slot.id(); - tail_ = slot.id(); - } +inline void CollectionData::appendOne(Slot slot, const ResourceManager * resources) { + if (tail_ != NULL_SLOT) { + auto tail = resources->getVariant(tail_); + tail->setNext(slot.id()); + tail_ = slot.id(); + } else { + head_ = slot.id(); + tail_ = slot.id(); + } } -inline void CollectionData::appendPair(Slot key, - Slot value, - const ResourceManager* resources) { - key->setNext(value.id()); - if (tail_ != NULL_SLOT) { - auto tail = resources->getVariant(tail_); - tail->setNext(key.id()); - tail_ = value.id(); - } else { - head_ = key.id(); - tail_ = value.id(); - } +inline void CollectionData::appendPair(Slot key, Slot value, const ResourceManager * resources) { + key->setNext(value.id()); + if (tail_ != NULL_SLOT) { + auto tail = resources->getVariant(tail_); + tail->setNext(key.id()); + tail_ = value.id(); + } else { + head_ = key.id(); + tail_ = value.id(); + } } -inline void CollectionData::clear(ResourceManager* resources) { - auto next = head_; - while (next != NULL_SLOT) { - auto currId = next; - auto slot = resources->getVariant(next); - next = slot->next(); - resources->freeVariant({slot, currId}); - } - head_ = NULL_SLOT; - tail_ = NULL_SLOT; +inline void CollectionData::clear(ResourceManager * resources) { + auto next = head_; + while (next != NULL_SLOT) { + auto currId = next; + auto slot = resources->getVariant(next); + next = slot->next(); + resources->freeVariant({slot, currId}); + } + head_ = NULL_SLOT; + tail_ = NULL_SLOT; } -inline Slot CollectionData::getPreviousSlot( - VariantData* target, const ResourceManager* resources) const { - auto prev = Slot(); - auto currentId = head_; - while (currentId != NULL_SLOT) { - auto currentSlot = resources->getVariant(currentId); - if (currentSlot == target) - break; - prev = Slot(currentSlot, currentId); - currentId = currentSlot->next(); - } - return prev; +inline Slot CollectionData::getPreviousSlot(VariantData * target, const ResourceManager * resources) const { + auto prev = Slot(); + auto currentId = head_; + while (currentId != NULL_SLOT) { + auto currentSlot = resources->getVariant(currentId); + if (currentSlot == target) + break; + prev = Slot(currentSlot, currentId); + currentId = currentSlot->next(); + } + return prev; } -inline void CollectionData::removeOne(iterator it, ResourceManager* resources) { - if (it.done()) - return; - auto curr = it.slot_; - auto prev = getPreviousSlot(curr, resources); - auto next = curr->next(); - if (prev) - prev->setNext(next); - else - head_ = next; - if (next == NULL_SLOT) - tail_ = prev.id(); - resources->freeVariant({it.slot_, it.currentId_}); +inline void CollectionData::removeOne(iterator it, ResourceManager * resources) { + if (it.done()) + return; + auto curr = it.slot_; + auto prev = getPreviousSlot(curr, resources); + auto next = curr->next(); + if (prev) + prev->setNext(next); + else + head_ = next; + if (next == NULL_SLOT) + tail_ = prev.id(); + resources->freeVariant({it.slot_, it.currentId_}); } -inline void CollectionData::removePair(ObjectData::iterator it, - ResourceManager* resources) { - if (it.done()) - return; - auto keySlot = it.slot_; - auto valueId = it.nextId_; - auto valueSlot = resources->getVariant(valueId); - keySlot->setNext(valueSlot->next()); - resources->freeVariant({valueSlot, valueId}); - removeOne(it, resources); +inline void CollectionData::removePair(ObjectData::iterator it, ResourceManager * resources) { + if (it.done()) + return; + auto keySlot = it.slot_; + auto valueId = it.nextId_; + auto valueSlot = resources->getVariant(valueId); + keySlot->setNext(valueSlot->next()); + resources->freeVariant({valueSlot, valueId}); + removeOne(it, resources); } -inline size_t CollectionData::nesting(const ResourceManager* resources) const { - size_t maxChildNesting = 0; - for (auto it = createIterator(resources); !it.done(); it.next(resources)) { - size_t childNesting = it->nesting(resources); - if (childNesting > maxChildNesting) - maxChildNesting = childNesting; - } - return maxChildNesting + 1; +inline size_t CollectionData::nesting(const ResourceManager * resources) const { + size_t maxChildNesting = 0; + for (auto it = createIterator(resources); !it.done(); it.next(resources)) { + size_t childNesting = it->nesting(resources); + if (childNesting > maxChildNesting) + maxChildNesting = childNesting; + } + return maxChildNesting + 1; } -inline size_t CollectionData::size(const ResourceManager* resources) const { - size_t count = 0; - for (auto it = createIterator(resources); !it.done(); it.next(resources)) - count++; - return count; +inline size_t CollectionData::size(const ResourceManager * resources) const { + size_t count = 0; + for (auto it = createIterator(resources); !it.done(); it.next(resources)) + count++; + return count; } inline Slot ResourceManager::allocVariant() { - auto p = variantPools_.allocSlot(allocator_); - if (!p) { - overflowed_ = true; - return {}; - } - return {new (&p->variant) VariantData, p.id()}; + auto p = variantPools_.allocSlot(allocator_); + if (!p) { + overflowed_ = true; + return {}; + } + return {new (&p->variant) VariantData, p.id()}; } inline void ResourceManager::freeVariant(Slot variant) { - variant->clear(this); - variantPools_.freeSlot({alias_cast(variant.ptr()), variant.id()}); + variant->clear(this); + variantPools_.freeSlot({alias_cast(variant.ptr()), variant.id()}); } -inline VariantData* ResourceManager::getVariant(SlotId id) const { - return reinterpret_cast(variantPools_.getSlot(id)); +inline VariantData * ResourceManager::getVariant(SlotId id) const { + return reinterpret_cast(variantPools_.getSlot(id)); } #if ARDUINOJSON_USE_EXTENSIONS inline Slot ResourceManager::allocExtension() { - auto p = variantPools_.allocSlot(allocator_); - if (!p) { - overflowed_ = true; - return {}; - } - return {&p->extension, p.id()}; + auto p = variantPools_.allocSlot(allocator_); + if (!p) { + overflowed_ = true; + return {}; + } + return {&p->extension, p.id()}; } inline void ResourceManager::freeExtension(SlotId id) { - auto p = getExtension(id); - variantPools_.freeSlot({reinterpret_cast(p), id}); + auto p = getExtension(id); + variantPools_.freeSlot({reinterpret_cast(p), id}); } -inline VariantExtension* ResourceManager::getExtension(SlotId id) const { - return &variantPools_.getSlot(id)->extension; +inline VariantExtension * ResourceManager::getExtension(SlotId id) const { + return &variantPools_.getSlot(id)->extension; } #endif template -inline VariantData* ObjectData::getMember( - TAdaptedString key, const ResourceManager* resources) const { - auto it = findKey(key, resources); - if (it.done()) - return nullptr; - it.next(resources); - return it.data(); +inline VariantData * ObjectData::getMember(TAdaptedString key, const ResourceManager * resources) const { + auto it = findKey(key, resources); + if (it.done()) + return nullptr; + it.next(resources); + return it.data(); } template -VariantData* ObjectData::getOrAddMember(TAdaptedString key, - ResourceManager* resources) { - auto data = getMember(key, resources); - if (data) - return data; - return addMember(key, resources); +VariantData * ObjectData::getOrAddMember(TAdaptedString key, ResourceManager * resources) { + auto data = getMember(key, resources); + if (data) + return data; + return addMember(key, resources); } template -inline ObjectData::iterator ObjectData::findKey( - TAdaptedString key, const ResourceManager* resources) const { - if (key.isNull()) +inline ObjectData::iterator ObjectData::findKey(TAdaptedString key, const ResourceManager * resources) const { + if (key.isNull()) + return iterator(); + bool isKey = true; + for (auto it = createIterator(resources); !it.done(); it.next(resources)) { + if (isKey && stringEquals(key, adaptString(it->asString()))) + return it; + isKey = !isKey; + } return iterator(); - bool isKey = true; - for (auto it = createIterator(resources); !it.done(); it.next(resources)) { - if (isKey && stringEquals(key, adaptString(it->asString()))) - return it; - isKey = !isKey; - } - return iterator(); } template -inline void ObjectData::removeMember(TAdaptedString key, - ResourceManager* resources) { - remove(findKey(key, resources), resources); +inline void ObjectData::removeMember(TAdaptedString key, ResourceManager * resources) { + remove(findKey(key, resources), resources); } template -inline VariantData* ObjectData::addMember(TAdaptedString key, - ResourceManager* resources) { - auto keySlot = resources->allocVariant(); - if (!keySlot) - return nullptr; - auto valueSlot = resources->allocVariant(); - if (!valueSlot) - return nullptr; - if (!keySlot->setString(key, resources)) - return nullptr; - CollectionData::appendPair(keySlot, valueSlot, resources); - return valueSlot.ptr(); +inline VariantData * ObjectData::addMember(TAdaptedString key, ResourceManager * resources) { + auto keySlot = resources->allocVariant(); + if (!keySlot) + return nullptr; + auto valueSlot = resources->allocVariant(); + if (!valueSlot) + return nullptr; + if (!keySlot->setString(key, resources)) + return nullptr; + CollectionData::appendPair(keySlot, valueSlot, resources); + return valueSlot.ptr(); } -inline VariantData* ObjectData::addPair(VariantData** value, - ResourceManager* resources) { - auto keySlot = resources->allocVariant(); - if (!keySlot) - return nullptr; - auto valueSlot = resources->allocVariant(); - if (!valueSlot) - return nullptr; - *value = valueSlot.ptr(); - CollectionData::appendPair(keySlot, valueSlot, resources); - return keySlot.ptr(); +inline VariantData * ObjectData::addPair(VariantData ** value, ResourceManager * resources) { + auto keySlot = resources->allocVariant(); + if (!keySlot) + return nullptr; + auto valueSlot = resources->allocVariant(); + if (!valueSlot) + return nullptr; + *value = valueSlot.ptr(); + CollectionData::appendPair(keySlot, valueSlot, resources); + return keySlot.ptr(); } constexpr size_t sizeofObject(size_t n) { - return 2 * n * ResourceManager::slotSize; + return 2 * n * ResourceManager::slotSize; } class EscapeSequence { - public: - static char escapeChar(char c) { - const char* p = escapeTable(true); - while (p[0] && p[1] != c) { - p += 2; + public: + static char escapeChar(char c) { + const char * p = escapeTable(true); + while (p[0] && p[1] != c) { + p += 2; + } + return p[0]; } - return p[0]; - } - static char unescapeChar(char c) { - const char* p = escapeTable(false); - for (;;) { - if (p[0] == '\0') - return 0; - if (p[0] == c) - return p[1]; - p += 2; + static char unescapeChar(char c) { + const char * p = escapeTable(false); + for (;;) { + if (p[0] == '\0') + return 0; + if (p[0] == c) + return p[1]; + p += 2; + } + } + + private: + static const char * escapeTable(bool isSerializing) { + return &"//''\"\"\\\\b\bf\fn\nr\rt\t"[isSerializing ? 4 : 0]; } - } - private: - static const char* escapeTable(bool isSerializing) { - return &"//''\"\"\\\\b\bf\fn\nr\rt\t"[isSerializing ? 4 : 0]; - } }; struct FloatParts { - uint32_t integral; - uint32_t decimal; - int16_t exponent; - int8_t decimalPlaces; + uint32_t integral; + uint32_t decimal; + int16_t exponent; + int8_t decimalPlaces; }; template -inline int16_t normalize(TFloat& value) { - using traits = FloatTraits; - int16_t powersOf10 = 0; - int8_t index = sizeof(TFloat) == 8 ? 8 : 5; - int bit = 1 << index; - if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) { - for (; index >= 0; index--) { - if (value >= traits::positiveBinaryPowersOfTen()[index]) { - value *= traits::negativeBinaryPowersOfTen()[index]; - powersOf10 = int16_t(powersOf10 + bit); - } - bit >>= 1; +inline int16_t normalize(TFloat & value) { + using traits = FloatTraits; + int16_t powersOf10 = 0; + int8_t index = sizeof(TFloat) == 8 ? 8 : 5; + int bit = 1 << index; + if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) { + for (; index >= 0; index--) { + if (value >= traits::positiveBinaryPowersOfTen()[index]) { + value *= traits::negativeBinaryPowersOfTen()[index]; + powersOf10 = int16_t(powersOf10 + bit); + } + bit >>= 1; + } } - } - if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) { - for (; index >= 0; index--) { - if (value < traits::negativeBinaryPowersOfTen()[index] * 10) { - value *= traits::positiveBinaryPowersOfTen()[index]; - powersOf10 = int16_t(powersOf10 - bit); - } - bit >>= 1; + if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) { + for (; index >= 0; index--) { + if (value < traits::negativeBinaryPowersOfTen()[index] * 10) { + value *= traits::positiveBinaryPowersOfTen()[index]; + powersOf10 = int16_t(powersOf10 - bit); + } + bit >>= 1; + } } - } - return powersOf10; + return powersOf10; } constexpr uint32_t pow10(int exponent) { - return (exponent == 0) ? 1 : 10 * pow10(exponent - 1); + return (exponent == 0) ? 1 : 10 * pow10(exponent - 1); } inline FloatParts decomposeFloat(JsonFloat value, int8_t decimalPlaces) { - uint32_t maxDecimalPart = pow10(decimalPlaces); - int16_t exponent = normalize(value); - uint32_t integral = uint32_t(value); - for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) { - maxDecimalPart /= 10; - decimalPlaces--; - } - JsonFloat remainder = - (value - JsonFloat(integral)) * JsonFloat(maxDecimalPart); - uint32_t decimal = uint32_t(remainder); - remainder = remainder - JsonFloat(decimal); - decimal += uint32_t(remainder * 2); - if (decimal >= maxDecimalPart) { - decimal = 0; - integral++; - if (exponent && integral >= 10) { - exponent++; - integral = 1; + uint32_t maxDecimalPart = pow10(decimalPlaces); + int16_t exponent = normalize(value); + uint32_t integral = uint32_t(value); + for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) { + maxDecimalPart /= 10; + decimalPlaces--; } - } - while (decimal % 10 == 0 && decimalPlaces > 0) { - decimal /= 10; - decimalPlaces--; - } - return {integral, decimal, exponent, decimalPlaces}; + JsonFloat remainder = (value - JsonFloat(integral)) * JsonFloat(maxDecimalPart); + uint32_t decimal = uint32_t(remainder); + remainder = remainder - JsonFloat(decimal); + decimal += uint32_t(remainder * 2); + if (decimal >= maxDecimalPart) { + decimal = 0; + integral++; + if (exponent && integral >= 10) { + exponent++; + integral = 1; + } + } + while (decimal % 10 == 0 && decimalPlaces > 0) { + decimal /= 10; + decimalPlaces--; + } + return {integral, decimal, exponent, decimalPlaces}; } template class CountingDecorator { - public: - explicit CountingDecorator(TWriter& writer) : writer_(writer), count_(0) {} - void write(uint8_t c) { - count_ += writer_.write(c); - } - void write(const uint8_t* s, size_t n) { - count_ += writer_.write(s, n); - } - size_t count() const { - return count_; - } - private: - TWriter writer_; - size_t count_; + public: + explicit CountingDecorator(TWriter & writer) + : writer_(writer) + , count_(0) { + } + void write(uint8_t c) { + count_ += writer_.write(c); + } + void write(const uint8_t * s, size_t n) { + count_ += writer_.write(s, n); + } + size_t count() const { + return count_; + } + + private: + TWriter writer_; + size_t count_; }; template class TextFormatter { - public: - explicit TextFormatter(TWriter writer) : writer_(writer) {} - TextFormatter& operator=(const TextFormatter&) = delete; - size_t bytesWritten() const { - return writer_.count(); - } - void writeBoolean(bool value) { - if (value) - writeRaw("true"); - else - writeRaw("false"); - } - void writeString(const char* value) { - ARDUINOJSON_ASSERT(value != NULL); - writeRaw('\"'); - while (*value) - writeChar(*value++); - writeRaw('\"'); - } - void writeString(const char* value, size_t n) { - ARDUINOJSON_ASSERT(value != NULL); - writeRaw('\"'); - while (n--) - writeChar(*value++); - writeRaw('\"'); - } - void writeChar(char c) { - char specialChar = EscapeSequence::escapeChar(c); - if (specialChar) { - writeRaw('\\'); - writeRaw(specialChar); - } else if (c) { - writeRaw(c); - } else { - writeRaw("\\u0000"); + public: + explicit TextFormatter(TWriter writer) + : writer_(writer) { } - } - template - void writeFloat(T value) { - writeFloat(JsonFloat(value), sizeof(T) >= 8 ? 9 : 6); - } - void writeFloat(JsonFloat value, int8_t decimalPlaces) { - if (isnan(value)) - return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null"); + TextFormatter & operator=(const TextFormatter &) = delete; + size_t bytesWritten() const { + return writer_.count(); + } + void writeBoolean(bool value) { + if (value) + writeRaw("true"); + else + writeRaw("false"); + } + void writeString(const char * value) { + ARDUINOJSON_ASSERT(value != NULL); + writeRaw('\"'); + while (*value) + writeChar(*value++); + writeRaw('\"'); + } + void writeString(const char * value, size_t n) { + ARDUINOJSON_ASSERT(value != NULL); + writeRaw('\"'); + while (n--) + writeChar(*value++); + writeRaw('\"'); + } + void writeChar(char c) { + char specialChar = EscapeSequence::escapeChar(c); + if (specialChar) { + writeRaw('\\'); + writeRaw(specialChar); + } else if (c) { + writeRaw(c); + } else { + writeRaw("\\u0000"); + } + } + template + void writeFloat(T value) { + writeFloat(JsonFloat(value), sizeof(T) >= 8 ? 9 : 6); + } + void writeFloat(JsonFloat value, int8_t decimalPlaces) { + if (isnan(value)) + return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null"); #if ARDUINOJSON_ENABLE_INFINITY - if (value < 0.0) { - writeRaw('-'); - value = -value; - } - if (isinf(value)) - return writeRaw("Infinity"); + if (value < 0.0) { + writeRaw('-'); + value = -value; + } + if (isinf(value)) + return writeRaw("Infinity"); #else - if (isinf(value)) - return writeRaw("null"); - if (value < 0.0) { - writeRaw('-'); - value = -value; - } + if (isinf(value)) + return writeRaw("null"); + if (value < 0.0) { + writeRaw('-'); + value = -value; + } #endif - auto parts = decomposeFloat(value, decimalPlaces); - writeInteger(parts.integral); - if (parts.decimalPlaces) - writeDecimals(parts.decimal, parts.decimalPlaces); - if (parts.exponent) { - writeRaw('e'); - writeInteger(parts.exponent); + auto parts = decomposeFloat(value, decimalPlaces); + writeInteger(parts.integral); + if (parts.decimalPlaces) + writeDecimals(parts.decimal, parts.decimalPlaces); + if (parts.exponent) { + writeRaw('e'); + writeInteger(parts.exponent); + } } - } - template - enable_if_t::value> writeInteger(T value) { - using unsigned_type = make_unsigned_t; - unsigned_type unsigned_value; - if (value < 0) { - writeRaw('-'); - unsigned_value = unsigned_type(unsigned_type(~value) + 1); - } else { - unsigned_value = unsigned_type(value); + template + enable_if_t::value> writeInteger(T value) { + using unsigned_type = make_unsigned_t; + unsigned_type unsigned_value; + if (value < 0) { + writeRaw('-'); + unsigned_value = unsigned_type(unsigned_type(~value) + 1); + } else { + unsigned_value = unsigned_type(value); + } + writeInteger(unsigned_value); } - writeInteger(unsigned_value); - } - template - enable_if_t::value> writeInteger(T value) { - char buffer[22]; - char* end = buffer + sizeof(buffer); - char* begin = end; - do { - *--begin = char(value % 10 + '0'); - value = T(value / 10); - } while (value); - writeRaw(begin, end); - } - void writeDecimals(uint32_t value, int8_t width) { - char buffer[16]; - char* end = buffer + sizeof(buffer); - char* begin = end; - while (width--) { - *--begin = char(value % 10 + '0'); - value /= 10; + template + enable_if_t::value> writeInteger(T value) { + char buffer[22]; + char * end = buffer + sizeof(buffer); + char * begin = end; + do { + *--begin = char(value % 10 + '0'); + value = T(value / 10); + } while (value); + writeRaw(begin, end); } - *--begin = '.'; - writeRaw(begin, end); - } - void writeRaw(const char* s) { - writer_.write(reinterpret_cast(s), strlen(s)); - } - void writeRaw(const char* s, size_t n) { - writer_.write(reinterpret_cast(s), n); - } - void writeRaw(const char* begin, const char* end) { - writer_.write(reinterpret_cast(begin), - static_cast(end - begin)); - } - template - void writeRaw(const char (&s)[N]) { - writer_.write(reinterpret_cast(s), N - 1); - } - void writeRaw(char c) { - writer_.write(static_cast(c)); - } - protected: - CountingDecorator writer_; + void writeDecimals(uint32_t value, int8_t width) { + char buffer[16]; + char * end = buffer + sizeof(buffer); + char * begin = end; + while (width--) { + *--begin = char(value % 10 + '0'); + value /= 10; + } + *--begin = '.'; + writeRaw(begin, end); + } + void writeRaw(const char * s) { + writer_.write(reinterpret_cast(s), strlen(s)); + } + void writeRaw(const char * s, size_t n) { + writer_.write(reinterpret_cast(s), n); + } + void writeRaw(const char * begin, const char * end) { + writer_.write(reinterpret_cast(begin), static_cast(end - begin)); + } + template + void writeRaw(const char (&s)[N]) { + writer_.write(reinterpret_cast(s), N - 1); + } + void writeRaw(char c) { + writer_.write(static_cast(c)); + } + + protected: + CountingDecorator writer_; }; class DummyWriter { - public: - size_t write(uint8_t) { - return 1; - } - size_t write(const uint8_t*, size_t n) { - return n; - } + public: + size_t write(uint8_t) { + return 1; + } + size_t write(const uint8_t *, size_t n) { + return n; + } }; template