@@ -547,49 +547,53 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap
547
547
bKnownTablesCreated = true ;
548
548
}
549
549
550
- pKnownTables->insert (std::make_pair ( this , pKnownTables->size ()) );
550
+ pKnownTables->insert ({ this , pKnownTables->size ()} );
551
551
552
- bool bIsArray = true ;
553
- unsigned int iArrayPos = 1 ; // lua arrays are 1 based
554
- vector<CLuaArgument*>::const_iterator iter = m_Arguments.begin ();
552
+ bool bIsArray = true ;
553
+ std::vector<std::pair<std:: uint32_t , CLuaArgument*>> vecSortedArguments ; // lua arrays are not necessarily sorted
554
+ std:: vector<CLuaArgument*>::const_iterator iter = m_Arguments.begin ();
555
555
for (; iter != m_Arguments.end (); iter += 2 )
556
556
{
557
557
CLuaArgument* pArgument = *iter;
558
558
if (pArgument->GetType () == LUA_TNUMBER)
559
559
{
560
- double num = pArgument->GetNumber ();
561
- unsigned int iNum = static_cast <unsigned int >(num);
562
- if (num == iNum)
563
- {
564
- if (iArrayPos != iNum) // check if the value matches its index in the table
565
- {
566
- bIsArray = false ;
567
- break ;
568
- }
569
- }
570
- else
571
- {
572
- bIsArray = false ;
573
- break ;
574
- }
560
+ double const num = pArgument->GetNumber ();
561
+ auto const iNum = static_cast <std::uint32_t >(num);
562
+
563
+ vecSortedArguments.push_back ({iNum, *(iter + 1 )});
575
564
}
576
565
else
577
566
{
578
567
bIsArray = false ;
579
568
break ;
580
569
}
581
- iArrayPos++;
582
570
}
583
571
584
- if (bIsArray)
572
+ if (bIsArray && !vecSortedArguments. empty ()) // the table could possibly be an array
585
573
{
586
- json_object* my_array = json_object_new_array ();
587
- vector<CLuaArgument*>::const_iterator iter = m_Arguments.begin ();
588
- for (; iter != m_Arguments.end (); iter++)
574
+ // sort the table based on the keys (already handled correctly by std::pair)
575
+ std::sort (vecSortedArguments.begin (), vecSortedArguments.end ());
576
+
577
+ // only the first and last element are checked, everything else is correct by default because the vector was sorted
578
+ // the last key should match the size of vecSortedArguments to ensure there are no gaps in this array-like table
579
+ auto const iFirstKey = vecSortedArguments.front ().first ;
580
+ auto const iLastKey = vecSortedArguments.back ().first ;
581
+
582
+ auto const iFirstArrayPos = 1U ; // lua arrays are 1 based
583
+ auto const iLastArrayPos = static_cast <std::uint32_t >(vecSortedArguments.size ());
584
+
585
+ if (iFirstKey != iFirstArrayPos || iLastKey != iLastArrayPos)
589
586
{
590
- iter++; // skip the key values
591
- CLuaArgument* pArgument = *iter;
592
- json_object* object = pArgument->WriteToJSONObject (bSerialize, pKnownTables);
587
+ bIsArray = false ;
588
+ }
589
+ }
590
+
591
+ if (bIsArray) // the table is definitely an array
592
+ {
593
+ json_object* my_array = json_object_new_array ();
594
+ for (auto const & [iKey, pArgument] : vecSortedArguments)
595
+ {
596
+ json_object* object = pArgument->WriteToJSONObject (bSerialize, pKnownTables);
593
597
if (object)
594
598
{
595
599
json_object_array_add (my_array, object);
0 commit comments