1 /* 2 Copyright (c) by Valery Goryachev (Wal) 3 */ 4 5 6 #ifndef WAL_SYS_API_H 7 #define WAL_SYS_API_H 8 9 #ifdef _WIN32 10 # if !defined( NOMINMAX ) 11 # define NOMINMAX 12 # endif 13 # include <windows.h> 14 #else 15 # include <sys/types.h> 16 # include <sys/stat.h> 17 # include <fcntl.h> 18 # include <unistd.h> 19 # include <pthread.h> 20 # include <string.h> 21 # include <stdlib.h> 22 #endif 23 24 #include <errno.h> 25 26 #include "System/Types.h" 27 28 namespace wal 29 { 30 typedef wchar_t unicode_t; 31 32 typedef int64_t seek_t; 33 34 #ifdef _WIN32 35 //typedef unsigned short sys_char_t; 36 typedef wchar_t sys_char_t; 37 sys_strlen(const sys_char_t * s)38 inline int sys_strlen( const sys_char_t* s ) { return int( wcslen( s ) ); } 39 40 typedef HANDLE file_t; 41 42 # define FILE_NULL INVALID_HANDLE_VALUE 43 valid_file(file_t fd)44 inline bool valid_file( file_t fd ) { return fd != FILE_NULL; } 45 46 # define DIR_SPLITTER '\\' 47 48 #else 49 typedef char sys_char_t; sys_strlen(const sys_char_t * s)50 inline int sys_strlen( const sys_char_t* s ) { return strlen( s ); } 51 52 typedef int file_t; 53 54 enum {FILE_NULL = -1 }; 55 valid_file(file_t fd)56 inline bool valid_file( file_t fd ) { return fd >= 0; } 57 58 # define DIR_SPLITTER '/' 59 60 typedef pthread_t thread_t; 61 typedef pthread_mutex_t mutex_t; 62 typedef pthread_cond_t cond_t; 63 64 65 #endif 66 67 /////////////////////////////////////////// charset defs 68 struct charset_struct 69 { 70 int id; 71 const char* name; 72 const char* comment; 73 74 char tabChar; 75 76 unicode_t* ( *cs_to_unicode )( unicode_t* buf, const char* s, int size, int* badCount ); 77 char* ( *unicode_to_cs )( char* s, const unicode_t* buf, int usize, int* badCount ); 78 int ( *symbol_count )( const char* s, int size ); 79 int ( *string_buffer_len )( const unicode_t* s, int ulen ); 80 IsTabcharset_struct81 bool IsTab( char* s, char* endLine ) { return ( s && s < endLine && *s == tabChar ); } 82 char* ( *GetNext )( char* s, char* endLine ); 83 char* ( *_GetPrev )( char* s, char* beginLine ); 84 unicode_t ( *GetChar )( char* s, char* endLine ); 85 int ( *SetChar )( char* buf, unicode_t ch ); //return count of chars in buffer (buf is 8 chars minimun) 86 char* GetPrev( char* s, char* beginLine ); 87 88 charset_struct( int _id, const char* _name, const char* _comment ); 89 }; 90 GetPrev(char * s,char * beginLine)91 inline char* charset_struct::GetPrev( char* s, char* beginLine ) 92 { 93 if ( _GetPrev ) { return _GetPrev( s, beginLine ); } 94 95 if ( s <= beginLine ) { return 0; } 96 97 char* p = 0; 98 char* t = beginLine; 99 100 while ( t ) 101 { 102 p = t; 103 t = GetNext( t, s ); 104 } 105 106 return p; 107 } 108 109 110 enum CHARSET_ID 111 { 112 CS_LATIN1 = 0, 113 CS_ISO8859_1 = 0, 114 CS_UTF8 = 1, 115 CS_CP437, 116 CS_CP737, 117 CS_CP775, 118 CS_CP850, 119 CS_CP852, 120 CS_CP855, 121 CS_CP857, 122 CS_CP860, 123 CS_CP861, 124 CS_CP862, 125 CS_CP863, 126 CS_CP864, 127 CS_CP865, 128 CS_CP866, 129 CS_CP869, 130 CS_CP874, 131 CS_EBCDIC_037, 132 CS_EBCDIC_1025, 133 CS_EBCDIC_1026, 134 CS_EBCDIC_500, 135 CS_EBCDIC_875, 136 137 CS_ISO8859_2, 138 CS_ISO8859_3, 139 CS_ISO8859_4, 140 CS_ISO8859_5, 141 CS_ISO8859_6, 142 CS_ISO8859_7, 143 CS_ISO8859_8, 144 CS_ISO8859_9, 145 CS_ISO8859_10, 146 CS_ISO8859_11, 147 CS_ISO8859_13, 148 CS_ISO8859_14, 149 CS_ISO8859_15, 150 CS_ISO8859_16, 151 CS_KOI8R, 152 CS_KOI8U, 153 CS_MAC_CYRILLIC, 154 CS_MAC_GREEK, 155 CS_MAC_ICELAND, 156 CS_MAC_LATIN2, 157 CS_MAC_ROMAN, 158 CS_MAC_TURKISH, 159 CS_WIN1250, 160 CS_WIN1251, 161 CS_WIN1252, 162 CS_WIN1253, 163 CS_WIN1254, 164 CS_WIN1255, 165 CS_WIN1256, 166 CS_WIN1257, 167 CS_WIN1258 168 //CS_end 169 }; 170 171 172 #ifndef _WIN32 173 extern int sys_charset_id; 174 #endif 175 176 extern charset_struct charsetLatin1; 177 //extern charset_struct charsetUtf8; 178 179 class CharsetTable 180 { 181 //public: 182 enum { TABLESIZE = 128 }; 183 charset_struct* table[TABLESIZE]; 184 public: 185 CharsetTable(); //{ for (int i = 0; i<TABLESIZE; i++) table[i]=&charsetLatin1; } 186 void Add( charset_struct* ); Get(int id)187 charset_struct* Get( int id ) { return id >= 0 && id < TABLESIZE && table[id] ? table[id] : &charsetLatin1; } 188 charset_struct* operator [] ( int id ) { return Get( id ); } 189 const char* NameById( int id ); 190 int IdByName( const char* s ); 191 int GetList( charset_struct**, int size ); 192 }; 193 194 extern CharsetTable charset_table; 195 196 /*inline charset_struct* get_charset(int id){ 197 charset_struct *p = charset_table; 198 while (p->id != id && p->id>=0) p++; 199 return p->id >=0 ? p : 0; 200 }*/ 201 202 /* 203 const char *CharsetNameByID(int id); 204 int CharsetIdByName(const char *s); 205 */ 206 207 ////////////////////////////////////////// 208 209 enum OPEN_FILE_FLAG 210 { 211 FOPEN_READ = 1, 212 FOPEN_WRITE = 2, 213 FOPEN_RW = 3, 214 215 FOPEN_CREATE = 4, //open if exist and create if not exist 216 FOPEN_SYNC = 8, 217 FOPEN_TRUNC = 16 //truncate if exist 218 }; 219 220 enum SEEK_FILE_MODE 221 { 222 #ifdef _WIN32 223 FSEEK_BEGIN = FILE_BEGIN, 224 FSEEK_POS = FILE_CURRENT, 225 FSEEK_END = FILE_END 226 #else 227 FSEEK_BEGIN = SEEK_SET, 228 FSEEK_POS = SEEK_CUR, 229 FSEEK_END = SEEK_END 230 #endif 231 }; 232 233 #ifdef _WIN32 SysErrorIsFileNotFound(int e)234 inline bool SysErrorIsFileNotFound( int e ) { return e == ERROR_FILE_NOT_FOUND; } 235 #else SysErrorIsFileNotFound(int e)236 inline bool SysErrorIsFileNotFound( int e ) { return e == ENOENT; } 237 #endif 238 239 240 #ifdef _WIN32 241 242 //return count of characters (length of buffer for conversion to unicode) 243 extern int sys_symbol_count( const sys_char_t* s, int len = -1 ); 244 245 //return count of sys_chars for saving s 246 extern int sys_string_buffer_len( const unicode_t* s, int ulen = -1 ); //not including \0 247 248 // return point of appended \0 249 extern unicode_t* sys_to_unicode( 250 unicode_t* buf, 251 const sys_char_t* s, int len = -1, 252 int* badCount = 0 ); 253 254 // return point of appended \0 255 extern sys_char_t* unicode_to_sys( 256 sys_char_t* s, 257 const unicode_t* buf, int ulen = -1, 258 int* badCount = 0 ); 259 260 #else 261 //return count of characters (length of buffer for conversion to unicode) 262 extern int ( *fp_sys_symbol_count )( const sys_char_t* s, int len ); 263 264 //return count of sys_chars for saving s 265 extern int ( *fp_sys_string_buffer_len )( const unicode_t* s, int ulen ); //not including \0 266 267 // return point of appended \0 268 extern unicode_t* ( *fp_sys_to_unicode )( 269 unicode_t* buf, 270 const sys_char_t* s, int len, 271 int* badCount ); 272 273 // return point of appended \0 274 extern sys_char_t* ( *fp_unicode_to_sys )( 275 sys_char_t* s, 276 const unicode_t* buf, int len, 277 int* badCount ); 278 279 inline int sys_symbol_count( const sys_char_t* s, int len = -1 ) { return fp_sys_symbol_count( s, len ); } ; 280 inline int sys_string_buffer_len( const unicode_t* s, int ulen = -1 ) { return fp_sys_string_buffer_len( s, ulen ); } 281 inline unicode_t* sys_to_unicode( 282 unicode_t* buf, 283 const sys_char_t* s, int len = -1, 284 int* badCount = 0 ) { return fp_sys_to_unicode( buf, s, len, badCount ); } 285 286 inline sys_char_t* unicode_to_sys( 287 sys_char_t* s, 288 const unicode_t* buf, int ulen = -1, 289 int* badCount = 0 ) { return fp_unicode_to_sys( s, buf, ulen, badCount ); } 290 #endif 291 292 unicode_t* latin1_to_unicode ( unicode_t* buf, const char* s, int size = -1, int* badCount = 0 ); 293 char* unicode_to_latin1 ( char* s, const unicode_t* buf, int usize = -1, int* badCount = 0 ); 294 int latin1_symbol_count ( const char* s, int size = -1 ); 295 int latin1_string_buffer_len( const unicode_t* buf, int ulen = -1 ); 296 297 unicode_t* utf8_to_unicode ( unicode_t* buf, const char* s, int size = -1, int* badCount = 0 ); 298 char* unicode_to_utf8 ( char* s, const unicode_t* buf, int usize = -1, int* badCount = 0 ); 299 int utf8_symbol_count ( const char* s, int size = -1 ); 300 int utf8_string_buffer_len ( const unicode_t* buf, int ulen = -1 ); 301 302 get_sys_error()303 inline int get_sys_error() 304 { 305 #ifdef _WIN32 306 return GetLastError(); 307 #else 308 return errno; 309 #endif 310 } 311 set_sys_error(int e)312 inline void set_sys_error( int e ) 313 { 314 #ifdef _WIN32 315 SetLastError( e ); 316 #else 317 errno = e; 318 #endif 319 } 320 321 sys_char_t* sys_error_str( int err, sys_char_t* buf, int size ); 322 323 int unicode_strlen( const unicode_t* s ); 324 unicode_t* unicode_strchr( const unicode_t* s, unicode_t c ); 325 unicode_t* unicode_strrchr(const unicode_t* s, unicode_t c ); 326 unicode_t* unicode_strcpy( unicode_t* d, const unicode_t* s ); 327 // copy unlit end of string, or when n chars copid, whichever comes first. 328 // d is always 0-ended 329 unicode_t* unicode_strncpy0( unicode_t* d, const unicode_t* s, int n ); 330 void unicode_strcat( unicode_t* d, const unicode_t* s ); 331 unicode_t* unicode_strdup( const unicode_t* s ); 332 333 //for internal use 334 class SysStringStruct 335 { 336 #define SSS_BUF_SIZE 1024 337 #define SSS_UNICODE_BUF_SIZE 1024 338 339 sys_char_t buffer[SSS_BUF_SIZE]; 340 sys_char_t* p; 341 set_oom()342 void set_oom() 343 { 344 #ifdef _WIN32 345 set_sys_error( ERROR_OUTOFMEMORY ); 346 #else 347 set_sys_error( ENOMEM ); 348 #endif 349 } 350 351 void set_unicode( const unicode_t* s, int len = -1 ) 352 { 353 int sys_len = sys_string_buffer_len( s, len ); 354 355 if ( sys_len < SSS_BUF_SIZE ) { p = buffer; } 356 else { p = ( sys_char_t* ) malloc( sizeof( sys_char_t ) * ( sys_len + 1 ) ); } 357 358 if ( p ) 359 { 360 unicode_to_sys( p, s, len ); 361 /* 362 printf("len=%i\n", len); 363 char *t =p; 364 for (;*t;t++) 365 printf("!'%c'\n", char(*t)); 366 */ 367 368 } 369 else { set_oom(); } 370 } 371 #undef SSS_BUF_SIZE 372 373 374 void set_utf8( const char* s, int len = -1 ) 375 { 376 unicode_t unicode_buffer[SSS_UNICODE_BUF_SIZE]; 377 int unicode_len = utf8_symbol_count( s, len ); 378 unicode_t* uPtr = ( unicode_len < SSS_UNICODE_BUF_SIZE ) ? unicode_buffer : ( unicode_t* )malloc( sizeof( unicode_t ) * ( unicode_len + 1 ) ); 379 380 if ( uPtr ) 381 { 382 utf8_to_unicode( uPtr, s, len ); 383 /* 384 unicode_t *t =uPtr; 385 for (;*t;t++) 386 printf("'%c'\n", char(*t)); 387 */ 388 389 set_unicode( uPtr, unicode_len ); 390 391 if ( uPtr != unicode_buffer ) { free( uPtr ); } 392 } 393 else { set_oom(); } 394 } 395 396 public: SysStringStruct(const char * s)397 SysStringStruct( const char* s ): p( 0 ) { set_utf8( s );} get()398 const sys_char_t* get() { return p; } ~SysStringStruct()399 ~SysStringStruct() { if ( p && p != buffer ) { free( p ); } } 400 }; 401 402 403 file_t file_open( const sys_char_t* filename, int open_flag = FOPEN_READ ); 404 file_t file_open_utf8( const char* filename, int open_flag = FOPEN_READ ); 405 file_read(file_t fid,void * buf,int size)406 inline int file_read( file_t fid, void* buf, int size ) 407 { 408 #ifdef _WIN32 409 DWORD retsize; 410 return ReadFile( fid, buf, size, &retsize, 0 ) ? retsize : -1; 411 #else 412 return read( fid, buf, size ); 413 #endif 414 } 415 file_write(file_t fid,void * buf,int size)416 inline int file_write( file_t fid, void* buf, int size ) 417 { 418 #ifdef _WIN32 419 DWORD retsize; 420 return WriteFile( fid, buf, size, &retsize, 0 ) ? retsize : -1; 421 #else 422 return write( fid, buf, size ); 423 #endif 424 } 425 426 inline seek_t file_seek( file_t fid, seek_t distance, SEEK_FILE_MODE method = FSEEK_BEGIN ) 427 { 428 #ifdef _WIN32 429 LARGE_INTEGER li; 430 li.QuadPart = distance; 431 li.LowPart = SetFilePointer ( fid, li.LowPart, &li.HighPart, method ); 432 433 if ( li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ) 434 { 435 return -1; 436 } 437 438 return li.QuadPart; 439 #else 440 return lseek( fid, distance, method ); 441 #endif 442 } 443 file_close(file_t fid)444 inline int file_close( file_t fid ) 445 { 446 #ifdef _WIN32 447 return CloseHandle( fid ) ? 0 : -1; 448 #else 449 return close( fid ); 450 #endif 451 } 452 453 #ifdef _WIN32 454 455 struct _thread_info; 456 typedef _thread_info* thread_t; 457 458 typedef CRITICAL_SECTION mutex_t; 459 460 struct cond_t 461 { 462 HANDLE ev[2]; //??volatile 463 }; 464 465 int thread_create( thread_t* th, void* ( *f )( void* ), void* arg, bool detached = false ); 466 int thread_join( thread_t th, void** val ); 467 thread_t thread_self(); thread_equal(thread_t a,thread_t b)468 inline bool thread_equal( thread_t a, thread_t b ) { return a == b; } 469 mutex_create(mutex_t * m)470 inline int mutex_create( mutex_t* m ) { InitializeCriticalSection( m ); return 0; } mutex_delete(mutex_t * m)471 inline int mutex_delete( mutex_t* m ) { DeleteCriticalSection( m ); return 0; } mutex_lock(mutex_t * m)472 inline int mutex_lock( mutex_t* m ) { EnterCriticalSection( m ); return 0; } mutex_trylock(mutex_t * m)473 inline int mutex_trylock( mutex_t* m ) { return TryEnterCriticalSection( m ) ? 0 : EBUSY ; } mutex_unlock(mutex_t * m)474 inline int mutex_unlock( mutex_t* m ) { LeaveCriticalSection( m ); return 0; } 475 476 int cond_create( cond_t* c ); 477 int cond_delete( cond_t* c ); 478 int cond_wait( cond_t* c, mutex_t* m ); 479 int cond_signal( cond_t* c ); 480 int cond_broadcast( cond_t* c ); 481 482 483 //... 484 #else 485 inline int thread_create( thread_t* th, void* ( *f )( void* ), void* arg, bool detached = false ) 486 { 487 int r = pthread_create( th, 0, f, arg ); 488 489 if ( !r && detached ) { r = pthread_detach( *th ); } 490 491 return r; 492 } 493 thread_join(thread_t th,void ** val)494 inline int thread_join( thread_t th, void** val ) { return pthread_join( th, val ); } mutex_create(mutex_t * m)495 inline int mutex_create( mutex_t* m ) { return pthread_mutex_init( m, 0 ); } mutex_delete(mutex_t * m)496 inline int mutex_delete( mutex_t* m ) { return pthread_mutex_destroy( m ); } mutex_lock(mutex_t * m)497 inline int mutex_lock( mutex_t* m ) { return pthread_mutex_lock( m ); } mutex_trylock(mutex_t * m)498 inline int mutex_trylock( mutex_t* m ) { return pthread_mutex_trylock( m ); } mutex_unlock(mutex_t * m)499 inline int mutex_unlock( mutex_t* m ) { return pthread_mutex_unlock( m ); } cond_create(cond_t * c)500 inline int cond_create( cond_t* c ) { return pthread_cond_init( c, 0 ); } cond_delete(cond_t * c)501 inline int cond_delete( cond_t* c ) { return pthread_cond_destroy( c ); } cond_wait(cond_t * c,mutex_t * m)502 inline int cond_wait( cond_t* c, mutex_t* m ) { return pthread_cond_wait( c, m ); } cond_signal(cond_t * c)503 inline int cond_signal( cond_t* c ) { return pthread_cond_signal( c );} cond_broadcast(cond_t * c)504 inline int cond_broadcast( cond_t* c ) { return pthread_cond_broadcast( c );}; thread_self()505 inline thread_t thread_self() { return pthread_self(); } thread_equal(thread_t a,thread_t b)506 inline bool thread_equal( thread_t a, thread_t b ) { return pthread_equal( a, b ) != 0; } 507 508 #endif 509 510 511 #ifdef _DEBUG 512 void dbg_printf( const char* format, ... ); 513 #else dbg_printf(const char * format,...)514 inline void dbg_printf( const char* format, ... ) { } 515 #endif 516 517 const char* sys_locale_lang(); 518 const char* sys_locale_ter(); 519 const char* sys_locale_lang_ter(); 520 521 }; //namespace wal 522 523 using namespace wal; 524 525 #endif 526