Skip to content

Instantly share code, notes, and snippets.

@TimOliver
Last active August 29, 2015 14:10
Show Gist options
  • Save TimOliver/ebe343188d8fe064f8a1 to your computer and use it in GitHub Desktop.
Save TimOliver/ebe343188d8fe064f8a1 to your computer and use it in GitHub Desktop.
This is the method used to sort the filenames of pages inside an archive for iComics v1.1.
- (NSComparisonResult)sortedArchiveEntryIndex:(NSString *)firstName againstIndex:(NSString *)secondName
{
//if first name is empty, assume ascending
if ([firstName length] == 0)
return NSOrderedAscending;
if ([secondName length] == 0)
return NSOrderedDescending;
//convert the names to raw bytes so they can be manually compared on a numerical basis
const char *firstString = [[firstName uppercaseString] cStringUsingEncoding:NSASCIIStringEncoding];
const char *secondString = [[secondName uppercaseString] cStringUsingEncoding:NSASCIIStringEncoding];
if (!firstString)
return NSOrderedAscending;
if (!secondString)
return NSOrderedDescending;
//loop through each character in the first name byte array
NSInteger i = 0;
for (i = 0; i < strlen(firstString); i++)
{
//if there are no more characters in the second string, assume
if (i >= strlen(secondString))
return NSOrderedDescending;
char j = firstString[i];
char k = secondString[i];
//if first character is '_' (eg it's a notice), send it to the back
if (i == 0 && j == '_') { return NSOrderedDescending; }
if (i == 0 && k == '_') { return NSOrderedAscending; }
//if they're both numbers, collect the lot and compare both
if (isdigit(j) && isdigit(k)) {
NSInteger firstNumber=0, secondNumber=0, index = i;
char p, q;
do {
p = firstString[index];
q = secondString[index];
if (isdigit(p))
firstNumber = (firstNumber * 10) + (p - '0');
if (isdigit(q))
secondNumber = (secondNumber * 10) + (q - '0');
index++;
} while (isdigit(p) || isdigit(q));
if (firstNumber < secondNumber)
return NSOrderedAscending;
else if (firstNumber > secondNumber)
return NSOrderedDescending;
//if the numbers turned out to be equal, skip what we just did, and continue
i = index-2; // (-2 -> Undoes both loops)
continue;
}
if (j == k)
continue;
//give priority to filenames with preceeding periods
if (j == '.' && k != '.')
return NSOrderedAscending;
if (j != '.' && k == '.')
return NSOrderedDescending;
//byte-compare the two letters
if (j > k) {
//if there are no more slashes in the firstString (and more in the second string), assume firstString is in its final
//path component and give priority
if (strchr(firstString+i, '/') == NULL && strchr(secondString+i, '/') != NULL)
return NSOrderedAscending;
return NSOrderedDescending;
}
else
{
if (strchr(secondString+i, '/') == NULL && strchr(firstString+i, '/') != NULL)
return NSOrderedDescending;
return NSOrderedAscending;
}
}
if (i < strlen(secondString))
return NSOrderedAscending;
return NSOrderedSame;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment