Moved common, config and mapcache to C++ (#3200)
Dropped BETA_THREAD_TEST and everything around it Dropped mt19937 Replaced msinttypes with cinttypes Removed IRC link and updated README name
This commit is contained in:
381
src/common/utils.cpp
Normal file
381
src/common/utils.cpp
Normal file
@@ -0,0 +1,381 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "cbasetypes.hpp"
|
||||
#include "showmsg.hpp"
|
||||
#include "socket.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h> // floor()
|
||||
|
||||
#ifdef WIN32
|
||||
#include "winapi.hpp"
|
||||
#ifndef F_OK
|
||||
#define F_OK 0x0
|
||||
#endif /* F_OK */
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
|
||||
/// Dumps given buffer into file pointed to by a handle.
|
||||
void WriteDump(FILE* fp, const void* buffer, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
char hex[48+1], ascii[16+1];
|
||||
|
||||
fprintf(fp, "--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
|
||||
ascii[16] = 0;
|
||||
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
char c = RBUFB(buffer,i);
|
||||
|
||||
ascii[i%16] = ISCNTRL(c) ? '.' : c;
|
||||
sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
|
||||
|
||||
if( (i%16) == 15 )
|
||||
{
|
||||
fprintf(fp, "%03X %s %s\n", (unsigned int)(i/16), hex, ascii);
|
||||
}
|
||||
}
|
||||
|
||||
if( (i%16) != 0 )
|
||||
{
|
||||
ascii[i%16] = 0;
|
||||
fprintf(fp, "%03X %-48s %-16s\n", (unsigned int)(i/16), hex, ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Dumps given buffer on the console.
|
||||
void ShowDump(const void* buffer, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
char hex[48+1], ascii[16+1];
|
||||
|
||||
ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
|
||||
ascii[16] = 0;
|
||||
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
char c = RBUFB(buffer,i);
|
||||
|
||||
ascii[i%16] = ISCNTRL(c) ? '.' : c;
|
||||
sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i));
|
||||
|
||||
if( (i%16) == 15 )
|
||||
{
|
||||
ShowDebug("%03X %s %s\n", i/16, hex, ascii);
|
||||
}
|
||||
}
|
||||
|
||||
if( (i%16) != 0 )
|
||||
{
|
||||
ascii[i%16] = 0;
|
||||
ShowDebug("%03X %-48s %-16s\n", i/16, hex, ascii);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
static char* checkpath(char *path, const char *srcpath)
|
||||
{ // just make sure the char*path is not const
|
||||
char *p=path;
|
||||
if(NULL!=path && NULL!=srcpath)
|
||||
while(*srcpath) {
|
||||
if (*srcpath=='/') {
|
||||
*p++ = '\\';
|
||||
srcpath++;
|
||||
}
|
||||
else
|
||||
*p++ = *srcpath++;
|
||||
}
|
||||
*p = *srcpath; //EOS
|
||||
return path;
|
||||
}
|
||||
|
||||
void findfile(const char *p, const char *pat, void (func)(const char*))
|
||||
{
|
||||
WIN32_FIND_DATAA FindFileData;
|
||||
HANDLE hFind;
|
||||
char tmppath[MAX_PATH+1];
|
||||
|
||||
const char *path = (p ==NULL)? "." : p;
|
||||
const char *pattern = (pat==NULL)? "" : pat;
|
||||
|
||||
checkpath(tmppath,path);
|
||||
if( PATHSEP != tmppath[strlen(tmppath)-1])
|
||||
strcat(tmppath, "\\*");
|
||||
else
|
||||
strcat(tmppath, "*");
|
||||
|
||||
hFind = FindFirstFileA(tmppath, &FindFileData);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (strcmp(FindFileData.cFileName, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(FindFileData.cFileName, "..") == 0)
|
||||
continue;
|
||||
|
||||
sprintf(tmppath,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
|
||||
|
||||
if (FindFileData.cFileName && strstr(FindFileData.cFileName, pattern)) {
|
||||
func( tmppath );
|
||||
}
|
||||
|
||||
|
||||
if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
||||
{
|
||||
findfile(tmppath, pat, func);
|
||||
}
|
||||
}while (FindNextFileA(hFind, &FindFileData) != 0);
|
||||
FindClose(hFind);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the path is a directory or file
|
||||
* @param filepath: Location of file
|
||||
* @return 0 = Error
|
||||
* 1 = Directory
|
||||
* 2 = File
|
||||
* 3 = File but doesn't exist
|
||||
*/
|
||||
int check_filepath(const char* filepath)
|
||||
{
|
||||
DWORD Attribute;
|
||||
|
||||
if (Attribute = GetFileAttributes(filepath)) {
|
||||
if ((Attribute&INVALID_FILE_ATTRIBUTES) && GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||
SetLastError(0);
|
||||
return 3;
|
||||
} else if (Attribute&FILE_ATTRIBUTE_DIRECTORY)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define MAX_DIR_PATH 2048
|
||||
|
||||
/**
|
||||
* Check if the path is a directory or file
|
||||
* @param filepath: Location of file
|
||||
* @return 0 = Error
|
||||
* 1 = Directory
|
||||
* 2 = File
|
||||
* 3 = Neither a file or directory
|
||||
*/
|
||||
int check_filepath(const char* filepath)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (stat(filepath, &s) == 0) {
|
||||
if (s.st_mode&S_IFDIR)
|
||||
return 1;
|
||||
else if (s.st_mode&S_IFREG)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* checkpath(char *path, const char*srcpath)
|
||||
{ // just make sure the char*path is not const
|
||||
char *p=path;
|
||||
if(NULL!=path && NULL!=srcpath)
|
||||
while(*srcpath) {
|
||||
if (*srcpath=='\\') {
|
||||
*p++ = '/';
|
||||
srcpath++;
|
||||
}
|
||||
else
|
||||
*p++ = *srcpath++;
|
||||
}
|
||||
*p = *srcpath; //EOS
|
||||
return path;
|
||||
}
|
||||
|
||||
void findfile(const char *p, const char *pat, void (func)(const char*))
|
||||
{
|
||||
DIR* dir; // pointer to the scanned directory.
|
||||
struct dirent* entry; // pointer to one directory entry.
|
||||
struct stat dir_stat; // used by stat().
|
||||
char tmppath[MAX_DIR_PATH+1];
|
||||
char path[MAX_DIR_PATH+1]= ".";
|
||||
const char *pattern = (pat==NULL)? "" : pat;
|
||||
if(p!=NULL) strcpy(path,p);
|
||||
|
||||
// open the directory for reading
|
||||
dir = opendir( checkpath(path, path) );
|
||||
if (!dir) {
|
||||
ShowError("Cannot read directory '%s'\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// scan the directory, traversing each sub-directory
|
||||
// matching the pattern for each file name.
|
||||
while ((entry = readdir(dir))) {
|
||||
// skip the "." and ".." entries.
|
||||
if (strcmp(entry->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name);
|
||||
|
||||
// check if the pattern matchs.
|
||||
if (entry->d_name && strstr(entry->d_name, pattern)) {
|
||||
func( tmppath );
|
||||
}
|
||||
// check if it is a directory.
|
||||
if (stat(tmppath, &dir_stat) == -1) {
|
||||
ShowError("stat error %s\n': ", tmppath);
|
||||
continue;
|
||||
}
|
||||
// is this a directory?
|
||||
if (S_ISDIR(dir_stat.st_mode)) {
|
||||
// decent recursivly
|
||||
findfile(tmppath, pat, func);
|
||||
}
|
||||
}//end while
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool exists(const char* filename)
|
||||
{
|
||||
return !access(filename, F_OK);
|
||||
}
|
||||
|
||||
uint8 GetByte(uint32 val, int idx)
|
||||
{
|
||||
switch( idx )
|
||||
{
|
||||
case 0: return (uint8)( (val & 0x000000FF) );
|
||||
case 1: return (uint8)( (val & 0x0000FF00) >> 0x08 );
|
||||
case 2: return (uint8)( (val & 0x00FF0000) >> 0x10 );
|
||||
case 3: return (uint8)( (val & 0xFF000000) >> 0x18 );
|
||||
default:
|
||||
#if defined(DEBUG)
|
||||
ShowDebug("GetByte: invalid index (idx=%d)\n", idx);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 GetWord(uint32 val, int idx)
|
||||
{
|
||||
switch( idx )
|
||||
{
|
||||
case 0: return (uint16)( (val & 0x0000FFFF) );
|
||||
case 1: return (uint16)( (val & 0xFFFF0000) >> 0x10 );
|
||||
default:
|
||||
#if defined(DEBUG)
|
||||
ShowDebug("GetWord: invalid index (idx=%d)\n", idx);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
uint16 MakeWord(uint8 byte0, uint8 byte1)
|
||||
{
|
||||
return byte0 | (byte1 << 0x08);
|
||||
}
|
||||
|
||||
uint32 MakeDWord(uint16 word0, uint16 word1)
|
||||
{
|
||||
return
|
||||
( (uint32)(word0 ) )|
|
||||
( (uint32)(word1 << 0x10) );
|
||||
}
|
||||
|
||||
/*************************************
|
||||
* Big-endian compatibility functions *
|
||||
*************************************/
|
||||
|
||||
// Converts an int16 from current machine order to little-endian
|
||||
int16 MakeShortLE(int16 val)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
buf[0] = (unsigned char)( (val & 0x00FF) );
|
||||
buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
|
||||
return *((int16*)buf);
|
||||
}
|
||||
|
||||
// Converts an int32 from current machine order to little-endian
|
||||
int32 MakeLongLE(int32 val)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
buf[0] = (unsigned char)( (val & 0x000000FF) );
|
||||
buf[1] = (unsigned char)( (val & 0x0000FF00) >> 0x08 );
|
||||
buf[2] = (unsigned char)( (val & 0x00FF0000) >> 0x10 );
|
||||
buf[3] = (unsigned char)( (val & 0xFF000000) >> 0x18 );
|
||||
return *((int32*)buf);
|
||||
}
|
||||
|
||||
// Reads an uint16 in little-endian from the buffer
|
||||
uint16 GetUShort(const unsigned char* buf)
|
||||
{
|
||||
return ( ((uint16)(buf[0])) )
|
||||
|( ((uint16)(buf[1])) << 0x08 );
|
||||
}
|
||||
|
||||
// Reads an uint32 in little-endian from the buffer
|
||||
uint32 GetULong(const unsigned char* buf)
|
||||
{
|
||||
return ( ((uint32)(buf[0])) )
|
||||
|( ((uint32)(buf[1])) << 0x08 )
|
||||
|( ((uint32)(buf[2])) << 0x10 )
|
||||
|( ((uint32)(buf[3])) << 0x18 );
|
||||
}
|
||||
|
||||
// Reads an int32 in little-endian from the buffer
|
||||
int32 GetLong(const unsigned char* buf)
|
||||
{
|
||||
return (int32)GetULong(buf);
|
||||
}
|
||||
|
||||
// Reads a float (32 bits) from the buffer
|
||||
float GetFloat(const unsigned char* buf)
|
||||
{
|
||||
uint32 val = GetULong(buf);
|
||||
return *((float*)(void*)&val);
|
||||
}
|
||||
|
||||
/// calculates the value of A / B, in percent (rounded down)
|
||||
unsigned int get_percentage(const unsigned int A, const unsigned int B)
|
||||
{
|
||||
double result;
|
||||
|
||||
if( B == 0 )
|
||||
{
|
||||
ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B);
|
||||
return ~0U;
|
||||
}
|
||||
|
||||
result = 100 * ((double)A / (double)B);
|
||||
|
||||
if( result > UINT_MAX )
|
||||
{
|
||||
ShowError("get_percentage(): result percentage too high! (A=%u,B=%u,result=%g)\n", A, B, result);
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
return (unsigned int)floor(result);
|
||||
}
|
||||
Reference in New Issue
Block a user