Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Sorting string8 values (Read 2876 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Sorting string8 values

What's the easiest/best way to compare two string8 values and return whether <string1> is alphabetically before or after <string2>?

I'm experimenting with the diskwriter source, and have little C++ experience, so simple examples and explanations would be greatly appreciated.  Pictures if you have them 

Edit: added tag brackets to string1 and string2, to try to distinguish between the string8 object, and two variables.
I'm on a horse.

Sorting string8 values

Reply #1
The best way to sort a list that has strings as keys, is to use the uSortString* family of functions from utf8api. The general idea would be to build an array of a struct with two members: one for the HANDLE returned by uSortStringCreate and one for the item's original index. Then define a comparison function that compares two of those structs by comparing their HANDLE members using uSortStringCompare. Use that to sort the array of structs. Proceed to apply the permutation to the original list - that's what the index members in the struct are for, they tell you where an item should go. Last but not least, free all those HANDLEs using uSortStringFree.

Well, that's the general idea. There is some extra stuff needed to make it work; you can see that in the SDK in the sort_by_format and sort_by_format_get_order methods of the metadb_handle_list class.

Hm, I guess that's more than you were asking for.  You can also compare UTF-8 strings using stricmp_utf8 which does a case-insensitive comparison, but it uses lexicographic order (character value and character-by-character comparison) instead of the collating order used by uSortStringCompare (which depends on locale settings and is done by Windows). To sort umlauts, accented and other non-ASCII characters correctly, you'll have to use uSortStringCompare.

Sorting string8 values

Reply #2
 

Thank you for your comprehensive reply. I guess I'm more out of my depth than I thought.

I did discover the uSortStringCompare function, but I couldn't get it to work with my string8 values.

I have also tried stricmp_utf8 with no success (well, I can crash foobar).

I think I should perhaps go back to what I know...

Out of interest, here is the code as it stands:

Code: [Select]
case IDC_PRESET_SORT:
{
 bool bOrdered = false;
 unsigned n,m = cfg_presetlist.get_count();
 preset_info * pre_now;

 string8 pre_now_desc;
 string8 pre_nex_desc;

 // if there is more than one preset
 if(m > 1) {

   // loop until all presets have been ordered
   while (bOrdered == false) {
     bOrdered = true;

     // loop through presets
     for(n=0;n<m-1;n++) {

       // get current preset object (pre_now), and its description (pre_now_desc)
       pre_now = new preset_info(cfg_presetlist.get_item(n));
       pre_now->get_description(pre_now_desc);
       // get next preset's description (pre_nex_desc)
       cfg_presetlist.get_item(n+1)->get_description(pre_nex_desc);  
       
       console::info(pre_now_desc);
       console::info(pre_nex_desc);

       // check order
       if(stricmp_utf8(pre_nex_desc, pre_now_desc)) {

         // remove preset from collection...
         cfg_presetlist.delete_item(n);
         // ... and (re)add at the end
         cfg_presetlist.add_item(pre_now);

         // as collection items have shifted up one, shift the counter up too
         n--;
         // still not ordered...
         bOrdered = false;

       } // end if
     } // next
   } // end while

   // redraw list
   update_preset_list(wnd, false);

 } // end if
}
break;
I'm on a horse.