blob: 1c8d3261d63ceb45ab6c990aede910c7903a5228 [file] [log] [blame]
#undef BIG_ENDIAN
#undef LITTLE_ENDIAN
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#ifdef __APPLE_CC__
#define UInt32 macUIn32
#include <CoreFoundation/CoreFoundation.h>
#undef UInt32
#endif
#ifdef ENV_HAVE_WCHAR__H
#include <wchar.h>
#endif
#ifdef ENV_HAVE_LOCALE
#include <locale.h>
#endif
#include <windows.h>
#define NEED_NAME_WINDOWS_TO_UNIX
// #include "myPrivate.h"
#include "Common/StringConvert.h"
#include "Common/StdOutStream.h"
#undef NDEBUG
#include <assert.h>
#include "Common/StringConvert.cpp"
#include "Common/StdOutStream.cpp"
#include "Common/IntToString.cpp"
#include "Windows/Synchronization.cpp"
#include "Windows/FileFind.cpp"
#include "Windows/Time.cpp"
#include "../C/Threads.c"
#include "../../C/Ppmd.h"
using namespace NWindows;
#if defined(ENV_HAVE_WCHAR__H) && defined(ENV_HAVE_MBSTOWCS) && defined(ENV_HAVE_WCSTOMBS)
void test_mbs(void) {
wchar_t wstr1[256] = {
L'e',
0xE8, // latin small letter e with grave
0xE9, // latin small letter e with acute
L'a',
0xE0, // latin small letter a with grave
0x20AC, // euro sign
L'b',
0 };
wchar_t wstr2[256];
char astr[256];
global_use_utf16_conversion = 1;
size_t len1 = wcslen(wstr1);
printf("wstr1 - %d - '%ls'\n",(int)len1,wstr1);
size_t len0 = wcstombs(astr,wstr1,sizeof(astr));
printf("astr - %d - '%s'\n",(int)len0,astr);
size_t len2 = mbstowcs(wstr2,astr,sizeof(wstr2)/sizeof(*wstr2));
printf("wstr - %d - '%ls'\n",(int)len2,wstr2);
if (wcscmp(wstr1,wstr2) != 0) {
printf("ERROR during conversions wcs -> mbs -> wcs\n");
exit(EXIT_FAILURE);
}
char *ptr = astr;
size_t len = 0;
while (*ptr) {
ptr = CharNextA(ptr);
len += 1;
}
if ((len != len1) && (len != 12)) { // 12 = when locale is UTF8 instead of ISO8859-15
printf("ERROR CharNextA : len=%d, len1=%d\n",(int)len,(int)len1);
exit(EXIT_FAILURE);
}
UString ustr(wstr1);
assert(ustr.Length() == (int)len1);
AString ansistr(astr);
assert(ansistr.Length() == (int)len0);
ansistr = UnicodeStringToMultiByte(ustr);
assert(ansistr.Length() == (int)len0);
assert(strcmp(ansistr,astr) == 0);
assert(wcscmp(ustr,wstr1) == 0);
UString ustr2 = MultiByteToUnicodeString(astr);
assert(ustr2.Length() == (int)len1);
assert(wcscmp(ustr2,wstr1) == 0);
}
#endif
static void test_astring(int num) {
AString strResult;
strResult = "first part : ";
char number[256];
sprintf(number,"%d",num);
strResult += AString(number);
strResult += " : last part";
printf("strResult -%s-\n",(const char *)strResult);
}
extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base);
static struct {
const char *path;
const char *dir;
const char *base;
}
tabSplit[]=
{
{ "",".","." },
{ "/","/","/" },
{ ".",".","." },
{ "//","/","/" },
{ "///","/","/" },
{ "dir",".","dir" },
{ "/dir","/","dir" },
{ "/dir/","/","dir" },
{ "/dir/base","/dir","base" },
{ "/dir//base","/dir","base" },
{ "/dir///base","/dir","base" },
{ "//dir/base","//dir","base" },
{ "///dir/base","///dir","base" },
{ "/dir/base/","/dir","base" },
{ 0,0,0 }
};
static void test_split_astring() {
int ind = 0;
while (tabSplit[ind].path) {
AString path(tabSplit[ind].path);
AString dir;
AString base;
my_windows_split_path(path,dir,base);
if ((dir != tabSplit[ind].dir) || (base != tabSplit[ind].base)) {
printf("ERROR : '%s' '%s' '%s'\n",(const char *)path,(const char *)dir,(const char *)base);
}
ind++;
}
printf("test_split_astring : done\n");
}
// Number of 100 nanosecond units from 1/1/1601 to 1/1/1970
#define EPOCH_BIAS 116444736000000000LL
static LARGE_INTEGER UnixTimeToUL(time_t tps_unx)
{
LARGE_INTEGER ul;
ul.QuadPart = tps_unx * 10000000LL + EPOCH_BIAS;
return ul;
}
static LARGE_INTEGER FileTimeToUL(FILETIME fileTime)
{
LARGE_INTEGER lFileTime;
lFileTime.QuadPart = fileTime.dwHighDateTime;
lFileTime.QuadPart = (lFileTime.QuadPart << 32) | fileTime.dwLowDateTime;
return lFileTime;
}
static void display(const char *txt,SYSTEMTIME systime)
{
FILETIME fileTime;
BOOL ret = SystemTimeToFileTime(&systime,&fileTime);
assert(ret == TRUE);
LARGE_INTEGER ulFileTime = FileTimeToUL(fileTime);
const char * day="";
switch (systime.wDayOfWeek)
{
case 0:day = "Sunday";break;
case 1:day = "Monday";break;
case 2:day = "Tuesday";break;
case 3:day = "Wednesday";break;
case 4:day = "Thursday";break;
case 5:day = "Friday";break;
case 6:day = "Saturday";break;
}
g_StdOut<< txt << day << " "
<< (int)systime.wYear << "/" << (int)systime.wMonth << "/" << (int)systime.wDay << " "
<< (int)systime.wHour << ":" << (int)systime.wMinute << ":" << (int)systime.wSecond << ":"
<< (int)systime.wMilliseconds
<< " (" << (UInt64)ulFileTime.QuadPart << ")\n";
}
static void test_time()
{
time_t tps_unx = time(0);
printf("Test Time (1):\n");
printf("===========\n");
SYSTEMTIME systimeGM;
GetSystemTime(&systimeGM);
LARGE_INTEGER ul = UnixTimeToUL(tps_unx);
g_StdOut<<" unix time = " << (UInt64)tps_unx << " (" << (UInt64)ul.QuadPart << ")\n";
g_StdOut<<" gmtime : " << asctime(gmtime(&tps_unx))<<"\n";
g_StdOut<<" localtime : " << asctime(localtime(&tps_unx))<<"\n";
display(" GetSystemTime : ", systimeGM);
}
static void test_time2()
{
UInt32 dosTime = 0x30d0094C;
FILETIME utcFileTime;
FILETIME localFileTime;
FILETIME localFileTime2;
UInt32 dosTime2 = 0;
printf("Test Time (2):\n");
printf("===========\n");
NTime::DosTimeToFileTime(dosTime, localFileTime);
NTime::FileTimeToDosTime(localFileTime, dosTime2);
assert(dosTime == dosTime2);
printf("Test Time (3):\n");
printf("===========\n");
/* DosTime To utcFileTime */
if (NTime::DosTimeToFileTime(dosTime, localFileTime)) /* DosDateTimeToFileTime */
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
printf(" - 0x%x => 0x%x 0x%x => 0x%x 0x%x\n",(unsigned)dosTime,
(unsigned)localFileTime.dwHighDateTime,(unsigned)localFileTime.dwLowDateTime,
(unsigned)utcFileTime.dwHighDateTime,(unsigned)utcFileTime.dwLowDateTime);
/* utcFileTime to DosTime */
FileTimeToLocalFileTime(&utcFileTime, &localFileTime2);
NTime::FileTimeToDosTime(localFileTime2, dosTime2); /* FileTimeToDosDateTime */
printf(" - 0x%x <= 0x%x 0x%x <= 0x%x 0x%x\n",(unsigned)dosTime2,
(unsigned)localFileTime2.dwHighDateTime,(unsigned)localFileTime2.dwLowDateTime,
(unsigned)utcFileTime.dwHighDateTime,(unsigned)utcFileTime.dwLowDateTime);
assert(dosTime == dosTime2);
assert(localFileTime.dwHighDateTime == localFileTime2.dwHighDateTime);
assert(localFileTime.dwLowDateTime == localFileTime2.dwLowDateTime);
}
static void test_semaphore()
{
g_StdOut << "\nTEST SEMAPHORE :\n";
NWindows::NSynchronization::CSynchro sync;
NWindows::NSynchronization::CSemaphoreWFMO sema;
bool bres;
DWORD waitResult;
int i;
sync.Create();
sema.Create(&sync,2,10);
g_StdOut << " - Release(1)\n";
for(i = 0 ;i < 8;i++)
{
// g_StdOut << " - Release(1) : "<< i << "\n";
bres = sema.Release(1);
assert(bres == S_OK);
}
// g_StdOut << " - Release(1) : done\n";
bres = sema.Release(1);
assert(bres == S_FALSE);
g_StdOut << " - WaitForMultipleObjects(INFINITE)\n";
HANDLE events[1] = { sema };
for(i=0;i<10;i++)
{
waitResult = ::WaitForMultipleObjects(1, events, FALSE, INFINITE);
assert(waitResult == WAIT_OBJECT_0);
}
g_StdOut << " Done\n";
}
/****************************************************************************************/
static int threads_count = 0;
static THREAD_FUNC_RET_TYPE thread_fct(void * /* param */ ) {
threads_count++;
return 0;
}
#define MAX_THREADS 100000
int test_thread(void) {
::CThread thread;
Thread_Construct(&thread);
threads_count = 0;
printf("test_thread : %d threads\n",MAX_THREADS);
for(int i=0;i<MAX_THREADS;i++) {
Thread_Create(&thread, thread_fct, 0);
Thread_Wait(&thread);
Thread_Close(&thread);
}
assert(threads_count == MAX_THREADS);
return 0;
}
void dumpStr(const char *title,const char *txt)
{
size_t i,len = strlen(txt);
printf("%s - %d :",title,(int)len);
for(i = 0 ; i<len;i++) {
printf(" 0x%02x",(unsigned)(txt[i] & 255));
}
printf("\n");
}
void dumpWStr(const char *title,const wchar_t *txt)
{
size_t i,len = wcslen(txt);
printf("%s - %d :",title,(int)len);
for(i = 0 ; i<len;i++) {
printf(" 0x%02x",(unsigned)(txt[i]));
}
printf("\n");
}
#ifdef __APPLE_CC__
void testMaxOSX_stringConvert()
{
/*
0xE8, // latin small letter e with grave
0xE9, // latin small letter e with acute
L'a',
0xE0, // latin small letter a with grave
0x20AC, // euro sign
*/
struct
{
char astr [256];
wchar_t ustr [256];
}
tab [] =
{
{
// 'a' , 'e with acute' , 'e with grave' , 'a with grave' , 'u with grave' , 'b' , '.' , 't' , 'x' , 't'
{ 0x61, 0x65, 0xcc, 0x81 , 0x65, 0xcc, 0x80, 0x61, 0xcc, 0x80, 0x75, 0xcc, 0x80, 0x62, 0x2e, 0x74, 0x78, 0x74, 0 },
{ 0x61, 0xe9, 0xe8, 0xe0, 0xf9, 0x62, 0x2e, 0x74, 0x78, 0x74, 0 }
},
{
// 'a' , 'euro sign' , 'b' , '.' , 't' , 'x' , 't' , '\n'
{ 0x61, 0xe2, 0x82, 0xac, 0x62, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0 },
{ 0x61, 0x20AC, 0x62, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0 }
},
{
{ 0 },
{ 0 }
}
};
int i;
printf("testMaxOSX_stringConvert : \n");
i = 0;
while (tab[i].astr[0])
{
printf(" %s\n",tab[i].astr);
UString ustr = GetUnicodeString(tab[i].astr);
// dumpWStr("1",&ustr[0]);
assert(MyStringCompare(&ustr[0],tab[i].ustr) == 0);
assert(ustr.Length() == wcslen(tab[i].ustr) );
AString astr = GetAnsiString(ustr);
assert(MyStringCompare(&astr[0],tab[i].astr) == 0);
assert(astr.Length() == strlen(tab[i].astr) );
i++;
}
}
void testMacOSX()
{
// char texte1[]= { 0xc3 , 0xa9 , 0xc3, 0xa0, 0};
wchar_t wpath1[4096] = {
0xE9, // latin small letter e with acute
0xE0,
0xc7,
0x25cc,
0x327,
0xe4,
0xe2,
0xc2,
0xc3,
0x2e,
0x74,
0x78,
0x74,
/*
L'e',
0xE8, // latin small letter e with grave
0xE9, // latin small letter e with acute
L'a',
0xE0, // latin small letter a with grave
0x20AC, // euro sign
L'b',
*/
0 };
char utf8[4096];
wchar_t wpath2[4096];
// dumpStr("UTF8 standart",texte1);
dumpWStr("UCS32 standard",wpath1);
// Translate into FS pathname
{
const wchar_t * wcs = wpath1;
UniChar unipath[4096];
long n = wcslen(wcs);
for(long i = 0 ; i<= n ;i++) {
unipath[i] = wcs[i];
}
CFStringRef cfpath = CFStringCreateWithCharacters(NULL,unipath,n);
CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath);
CFRelease(cfpath);
CFStringNormalize(cfpath2,kCFStringNormalizationFormD);
CFStringGetCString(cfpath2,(char *)utf8,4096,kCFStringEncodingUTF8);
CFRelease(cfpath2);
}
dumpStr("UTF8 MacOSX",utf8);
// Translate from FS pathname
{
const char * path = utf8;
long n = strlen(path);
CFStringRef cfpath = CFStringCreateWithCString(NULL,path,kCFStringEncodingUTF8);
if (cfpath)
{
CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath);
CFRelease(cfpath);
CFStringNormalize(cfpath2,kCFStringNormalizationFormC);
n = CFStringGetLength(cfpath2);
for(long i = 0 ; i<= n ;i++) {
wpath2[i] = CFStringGetCharacterAtIndex(cfpath2,i);
}
wpath2[n] = 0;
CFRelease(cfpath2);
}
else
{
wpath2[0] = 0;
}
}
dumpWStr("UCS32 standard (2)",wpath2);
/*
{
CFStringRef cfpath;
cfpath = CFStringCreateWithCString(kCFAllocatorDefault, texte1, kCFStringEncodingUTF8);
// TODO str = null ?
CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpaht);
CFRealease(cfpath);
}
*/
}
#endif // __APPLE_CC__
static const TCHAR *kMainDll = TEXT("7z.dll");
static CSysString ConvertUInt32ToString(UInt32 value)
{
TCHAR buffer[32];
ConvertUInt32ToString(value, buffer);
return buffer;
}
void test_csystring(void)
{
{
const CSysString baseFolder = TEXT("bin/");
const CSysString b2 = baseFolder + kMainDll;
assert(MyStringCompare(&b2[0],TEXT("bin/7z.dll")) == 0);
}
{
LPCTSTR dirPath=TEXT("/tmp/");
LPCTSTR prefix=TEXT("foo");
CSysString resultPath;
UINT number = 12345;
UInt32 count = 6789;
/*
TCHAR * buf = resultPath.GetBuffer(MAX_PATH);
::swprintf(buf,MAX_PATH,L"%ls%ls#%d@%d.tmp",dirPath,prefix,(unsigned)number,count);
buf[MAX_PATH-1]=0;
resultPath.ReleaseBuffer();
*/
resultPath = dirPath;
resultPath += prefix;
resultPath += TEXT('#');
resultPath += ConvertUInt32ToString(number);
resultPath += TEXT('@');
resultPath += ConvertUInt32ToString(count);
resultPath += TEXT(".tmp");
// printf("##%ls##\n",&resultPath[0]);
assert(MyStringCompare(&resultPath[0],TEXT("/tmp/foo#12345@6789.tmp")) == 0);
}
}
static void test_AString()
{
AString a;
a = "abc";
assert(MyStringCompare(&a[0],"abc") == 0);
assert(a.Length() == 3);
a = GetAnsiString(L"abc");
assert(MyStringCompare(&a[0],"abc") == 0);
assert(a.Length() == 3);
}
const TCHAR kAnyStringWildcard = '*';
static void test_UString2(const UString &phyPrefix)
{
UString tmp = phyPrefix + wchar_t(kAnyStringWildcard);
printf("Enum(%ls-%ls-%lc)\n",&tmp[0],&phyPrefix[0],wchar_t(kAnyStringWildcard));
}
static void test_UString()
{
UString us = L"7za433_tar";
test_UString2(L"7za433_tar");
UString u1(us);
test_UString2(u1);
u1 = L"";
test_UString2(u1);
u1 = us;
test_UString2(u1);
UString u2 = us;
test_UString2(u2);
u2 = L"";
test_UString2(u2);
u2 = u1;
test_UString2(u2);
u1 = L"abc";
assert(MyStringCompare(&u1[0],L"abc") == 0);
assert(u1.Length() == 3);
u1 = GetUnicodeString("abc");
assert(MyStringCompare(&u1[0],L"abc") == 0);
assert(u1.Length() == 3);
}
/****************************************************************************************/
int main() {
// return test_thread();
#ifdef ENV_HAVE_LOCALE
setlocale(LC_ALL,"");
#endif
#if defined(BIG_ENDIAN)
printf("BIG_ENDIAN : %d\n",(int)BIG_ENDIAN);
#endif
#if defined(LITTLE_ENDIAN)
printf("LITTLE_ENDIAN : %d\n",(int)LITTLE_ENDIAN);
#endif
printf("sizeof(Byte) : %d\n",(int)sizeof(Byte));
printf("sizeof(UInt16) : %d\n",(int)sizeof(UInt16));
printf("sizeof(UInt32) : %d\n",(int)sizeof(UInt32));
printf("sizeof(UINT32) : %d\n",(int)sizeof(UINT32));
printf("sizeof(UInt64) : %d\n",(int)sizeof(UInt64));
printf("sizeof(UINT64) : %d\n",(int)sizeof(UINT64));
printf("sizeof(void *) : %d\n",(int)sizeof(void *));
printf("sizeof(size_t) : %d\n",(int)sizeof(size_t));
printf("sizeof(ptrdiff_t) : %d\n",(int)sizeof(ptrdiff_t));
printf("sizeof(off_t) : %d\n",(int)sizeof(off_t));
printf("sizeof(wchar_t) : %d\n",(int)sizeof(wchar_t));
#ifdef __APPLE_CC__
printf("sizeof(UniChar) : %d\n",(int)sizeof(UniChar));
#endif
printf("sizeof(CPpmd_See) : %d\n",(int)sizeof(CPpmd_See));
printf("sizeof(CPpmd_State) : %d\n",(int)sizeof(CPpmd_State));
// size tests
assert(sizeof(Byte)==1);
assert(sizeof(UInt16)==2);
assert(sizeof(UInt32)==4);
assert(sizeof(UINT32)==4);
assert(sizeof(UInt64)==8);
assert(sizeof(UINT64)==8);
// alignement tests
assert(sizeof(CPpmd_See)==4);
assert(sizeof(CPpmd_State)==6);
union {
Byte b[2];
UInt16 s;
} u;
u.s = 0x1234;
if ((u.b[0] == 0x12) && (u.b[1] == 0x34)) {
printf("CPU : big endian\n");
} else if ((u.b[0] == 0x34) && (u.b[1] == 0x12)) {
printf("CPU : little endian\n");
} else {
printf("CPU : unknown endianess\n");
}
#if defined(ENV_HAVE_WCHAR__H) && defined(ENV_HAVE_MBSTOWCS) && defined(ENV_HAVE_WCSTOMBS)
test_mbs();
#endif
test_astring(12345);
test_split_astring();
test_csystring();
test_AString();
test_UString();
test_time();
test_time2();
test_semaphore();
#ifdef __APPLE_CC__
testMacOSX();
testMaxOSX_stringConvert();
#endif
{
LANGID langID;
WORD primLang;
WORD subLang;
langID = GetUserDefaultLangID();
printf("langID=0x%x\n",langID);
primLang = (WORD)(PRIMARYLANGID(langID));
subLang = (WORD)(SUBLANGID(langID));
printf("primLang=%d subLang=%d\n",(unsigned)primLang,(unsigned)subLang);
}
printf("\n### All Done ###\n\n");
return 0;
}