UINT __cdecl MyFunction(LPVOID pParam)
{
Thread_t *pThread = (Thread_t *)pParam;
pThread->lPos = 0;
bool bReturn = MySyntaxHighlightFile(pThread->sInputName, pThread->sOutputName, &pThread->lPos);
return 1;
}
// Copy the input file to the output file inserting RTF markup to syntax color the XML.
bool MySyntaxHighlightFile(const wchar_t *sInputFileName, const wchar_t *sOutputFileName, long *lPos)
{
FILE *fpIn;
_wfopen_s(&fpIn, sInputFileName, L"rb");
if (!fpIn)
return false;
FILE *fpOut;
_wfopen_s(&fpOut, sOutputFileName, L"wb");
if (!fpIn)
return false;
char sTag[1000];
iTagIndex = 0;
sTag[0] = 0;
long long i64FileLength = _filelengthi64(_fileno(fpIn));
long long i64Step = (long long) ((i64FileLength / 60.0) + 0.5);
long long i64CurPos = 0;
bool bInTag = false;
bool bInAttributes = false;
bool bAttrValue = false;
char sBOM[3];
fread(sBOM, 1, 3, fpIn); // Swallow the byte-order-mark.
fputs("{\\rtf1{{\\colortbl ;"
"\\red0\\greeen0\\blue0;" // Regular text - black = 1
"\\red255\\green0\\blue0;" // ObjectTag color = 2
"\\red0\\green128\\blue255;" // Tag color = 3
"\\red0\\green0\\blue255;" // Quote color = 4
"\\red30\\green150\\blue30;" // Attribute name color = 5
"\\red0\\green0\\blue255;" // Angle color = 6
"\\red192\\green192\\blue192;" // Comment color = 7
"\\red0\\green128\\blue255;}" // PI color = 8
, fpOut);
unsigned iChar;
while ((iChar = fgetc(fpIn)) != EOF)
{
i64CurPos++;
switch (iChar)
{
case '\r':
break; // Don't need carriage returns.
case '\n':
fwrite("\\par ", 1, 5, fpOut);
break;
case '{':
case '}':
case '\\':
fputc('\\', fpOut);
fputc(iChar, fpOut);
break;
case '<':
{
fputs("\\cf6 ", fpOut);
fputc(iChar, fpOut);
int iNextChar = fgetc(fpIn);
i64CurPos++;
switch (iNextChar)
{
case '!':
fputs("\\cf7 ", fpOut);
fputc(iNextChar, fpOut);
break;
case '?':
fputs("\\cf8 ", fpOut);
fputc(iNextChar, fpOut);
break;
case '/':
fputc(iNextChar, fpOut);
bInTag = true;
iTagIndex = 0;
break;
default:
bInTag = true;
iTagIndex = 0;
sTag[iTagIndex++] = iNextChar;
sTag[iTagIndex] = 0;
}
}
continue;
case '>':
if (bInTag)
{
OutputTag(sTag, fpOut);
bInTag = false;
}
bInAttributes = false;
fputs("\\cf6 ", fpOut);
fputc(iChar, fpOut);
fputs("\\cf1 ", fpOut);
break;
case ' ':
if (bInTag)
{
OutputTag(sTag, fpOut);
bInTag = false;
bInAttributes = true;
}
fputc(iChar, fpOut);
break;
case '"':
if (bInAttributes)
{
if (bAttrValue)
fputs("\\cf4 \"\\cf5 ", fpOut); // Closing quote for attribute value.
else
fputs("\\cf4 \"\\cf1 ", fpOut); // Opening quote for attribute value.
bAttrValue = !bAttrValue;
}
break;
default:
if (bInTag)
{
sTag[iTagIndex++] = iChar;
sTag[iTagIndex] = 0;
}
else if (iChar <= 0x7F)
fputc(iChar, fpOut);
else
{
// Now we have to convert this UTF8 extended character to Unicode.
unsigned char sUtf8[11];
int iIndex = 0;
sUtf8[iIndex++] = iChar;
// Read in all the bytes of this unicode character.
while ((iChar = fgetc(fpIn)) != EOF)
{
if ((iChar < 0x80) || (iChar > 0xBF) || (iIndex > 9))
break;
sUtf8[iIndex++] = iChar;
i64CurPos++;
}
i64CurPos--;
ungetc(iChar, fpIn);
sUtf8[iIndex] = 0;
wchar_t *sUnicode = ATW::UTF82Wide((char *)sUtf8);
fprintf(fpOut, "\\u%d ?", *sUnicode); // Extended character.
}
}
if ((i64CurPos % i64Step) == 0)
(*lPos)++;
}
fputs("}", fpOut);
fclose(fpIn);
fclose(fpOut);
return true;
}
mProgressBar.StepIt();
mProgressBar.UpdateWindow();
if ((i64CurPos % i64Step) == 0)
{
(*lPos)++;
Sleep(100);
}