@@ -547,49 +547,53 @@ json_object* CLuaArguments::WriteTableToJSONObject(bool bSerialize, CFastHashMap
547547 bKnownTablesCreated = true ;
548548 }
549549
550- pKnownTables->insert (std::make_pair ( this , pKnownTables->size ()) );
550+ pKnownTables->insert ({ this , pKnownTables->size ()} );
551551
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 ();
555555 for (; iter != m_Arguments.end (); iter += 2 )
556556 {
557557 CLuaArgument* pArgument = *iter;
558558 if (pArgument->GetType () == LUA_TNUMBER)
559559 {
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 )});
575564 }
576565 else
577566 {
578567 bIsArray = false ;
579568 break ;
580569 }
581- iArrayPos++;
582570 }
583571
584- if (bIsArray)
572+ if (bIsArray && !vecSortedArguments. empty ()) // the table could possibly be an array
585573 {
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)
589586 {
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);
593597 if (object)
594598 {
595599 json_object_array_add (my_array, object);
0 commit comments