40#include "../base/Variant.h"
41#include "../base/PComplexData.h"
42#include "../base/PList.h"
43#include "../objects/PCustomObject.h"
44#include "../devices/PKeyboard.h"
45#include "../apps/Globals.h"
77#elif defined(PEBL_LINUX)
80#include <bits/types.h>
82#elif defined (PEBL_EMSCRIPTEN)
87#elif defined (PEBL_OSX)
106#if defined(PEBL_LINUX) or defined(PEBL_OSX) or defined(PEBL_EMSCRIPTEN)
108#elif defined(PEBL_WIN32)
115#define PI 3.141592653589793238462643383279502884197169399375
124static PEBL_Keycode PEBL_GetKeyFromName(
const char* name) {
125 static std::map<std::string, PEBL_Keycode> nameToKeycode;
128 if (nameToKeycode.empty()) {
254 std::map<std::string, PEBL_Keycode>::const_iterator it = nameToKeycode.find(name);
255 if (it != nameToKeycode.end()) {
264 return std::string(1, (
char)code);
267 return std::string(1, (
char)code);
368 (void)PEBL_GetKeyFromName(
"a");
377 std::string newtext(text);
378 std::transform(newtext.begin(), newtext.end(), newtext.begin(), ::toupper);
386 std::string newtext(text);
387 std::transform(newtext.begin(), newtext.end(), newtext.begin(), ::tolower);
399 char separator =
'/';
401 char separator =
'\\';
404 unsigned long int lastsep = 0;
405 unsigned long int i = file.size();
410 if(file[i] == separator)
413 return file.substr(0,lastsep+1);
428 char separator =
'/';
430 char separator =
'\\';
433 unsigned long int lastsep = 0;
434 unsigned long int i = file.size();
439 if(file[i] == separator)
442 return file.substr(lastsep+1,-1);
506 if(line[i] == separator
517 tokensize = i-begin+(separator==0);
521 token = (
char*)malloc((tokensize+1) *
sizeof(char));
522 strncpy(token, &line[begin], tokensize);
523 token[tokensize]=
'\0';
531 if(line[i] ==
'\0'|| line[i] == 10 || line[i] == 13)
535 if(separator==0 and line[begin]==
'\0')
552 return strtold(mystring,0);
554 return (
pDouble)strtod(mystring,0);
562 return (
pDouble)rand() / RAND_MAX;
575 return sqrt(-2 * log(x1)) * cos(2 *
PI * x2);
585 return logl(val) / logl(2);
596 return (
pInt) floor(val+.5);
607 return (
pDouble)roundl(val*off)/off;
620 int sign = val < 0 ? -1: 1;
621 return sign * Round(sign * val);
632#ifndef PEBL_VALIDATOR
633 PEBL_Keycode code = PEBL_GetKeyFromName(letters.c_str());
640#ifndef PEBL_VALIDATOR
650 if( letters ==
" " ||
651 letters ==
"<space>")
653 if( letters ==
"<return>")
655 if(letters ==
"<esc>"|| letters ==
"<escape>")
660 if(letters==
"<anykey>")
662 if(letters ==
"<back>" || letters ==
"<backspace>" )
730 std::cerr <<
"Unknown keycode!!!\n";
829#ifndef PEBL_VALIDATOR
830 std::string ltrs = PEBL_GetKeyName(code);
848 else if (modeline ==
"640x480") mode =
PVM_640_480;
849 else if (modeline ==
"800x600") mode =
PVM_800_600;
850 else if (modeline ==
"960x720") mode =
PVM_960_720;
863 if(depthline ==
"2") depth =
PVD_2;
864 else if (depthline ==
"15") depth =
PVD_15;
865 else if (depthline ==
"16") depth =
PVD_16;
866 else if (depthline ==
"24") depth =
PVD_24;
867 else if (depthline ==
"32") depth =
PVD_32;
889 dirp = opendir(path.c_str());
913 struct stat stFileInfo;
915 int out = stat(path.c_str(),&stFileInfo);
932 struct dirent *entry;
936 dirp = opendir(path.c_str());
942 while((entry = readdir(dirp)))
961 codes =
"Read permission is denied for the directory named by dirname.(EACCES)";
965 codes =
"The process has too many files open (EMFILE).";
968 codes =
"The entire system, or perhaps the file system which contains the directory, cannot support any additional open files at the moment. (ENFILE)";
971 codes =
"Not enough memory available. (ENOMEM)";
998 if(FileExists(path) && IsDirectory(path))
1003#if defined(PEBL_UNIX) || defined(PEBL_EMSCRIPTEN)
1005 if (mkdir(path.c_str(), 0777) == -1)
1010#elif defined(PEBL_WIN32)
1011 if (mkdir(path.c_str()) == -1)
1024 if(FileExists(path))
1026 if( remove( path.c_str() ) != 0 )
1039 char path[ MAX_PATH ];
1040 if (SHGetFolderPathA(
NULL, CSIDL_PROFILE,
NULL, 0, path ) != S_OK)
1044#elif defined(PEBL_LINUX) or defined(PEBL_OSX)
1046 struct passwd *p=getpwuid(getuid());
1047 std::string path = p->pw_dir;
1049#elif defined( PEBL_EMSCRIPTEN)
1052 std::string path =
"~/";
1061#if defined(PEBL_WIN32) or defined(PEBL_OSX)
1066 path=getcwd(path,size);
1069#elif defined(PEBL_UNIX)
1071 char* path = get_current_dir_name();
1073#elif defined (PEBL_EMSCRIPTEN)
1075 char buffer[PATH_MAX];
1076 char* path = getcwd(buffer,
sizeof(buffer));
1090 if(::SetCurrentDirectory(path.c_str()) == FALSE)
1094 int result = chdir(path.c_str());
1111#if defined(PEBL_WIN32)
1112 HINSTANCE hInst = ShellExecute(0,
1120 if ((INT_PTR)hInst == SE_ERR_NOASSOC ||
1121 (INT_PTR)hInst == SE_ERR_ASSOCINCOMPLETE ||
1122 (INT_PTR)hInst == SE_ERR_ACCESSDENIED)
1124 SHELLEXECUTEINFO exeInfo = {0};
1125 exeInfo.cbSize =
sizeof(SHELLEXECUTEINFO);
1126 exeInfo.lpVerb =
"openas";
1127 exeInfo.lpFile = file.c_str();
1128 exeInfo.fMask = SEE_MASK_INVOKEIDLIST;
1129 exeInfo.nShow = SW_SHOWDEFAULT;
1132 if (ShellExecuteEx(&exeInfo) == FALSE);
1138 x = ((INT_PTR)hInst > 32);
1140#elif defined(PEBL_LINUX)
1143 std::string call2 =
"xdg-open " + file;
1144 int ret = system(call2.c_str());
1149#elif defined(PEBL_OSX)
1150 std::string call2 =
"open " + file;
1151 int ret = system(call2.c_str());
1164#if defined( PEBL_UNIX )
1166 std::string tmp = call +
" " + args;
1168 const char* call2 = tmp.c_str();
1169 int x = system(call2);
1171#elif defined (PEBL_WIN32)
1172 std::string tmp =
"cmd.exe /c " + call +
" " + args;
1175 STARTUPINFO info={
sizeof(info)};
1176 PROCESS_INFORMATION processInfo;
1177 char* callstring =
const_cast<char *
>(tmp.c_str());
1180 ABOVE_NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,
1184 ::WaitForSingleObject(processInfo.hProcess, INFINITE);
1185 CloseHandle(processInfo.hProcess);
1186 CloseHandle(processInfo.hThread);
1189 std::cerr << GetLastError() << std::endl;
1192#elif defined (PEBL_EMSCRIPTEN)
1193 std::cerr <<
"Cannot perform system call in web mode\n";
1206PROCESS_INFORMATION PEBLUtility::SystemCallAndReturn(std::string call, std::string args)
1209 std::string tmp =
"cmd.exe /c " + call +
" " + args;
1211 STARTUPINFO info={
sizeof(info)};
1212 PROCESS_INFORMATION processInfo;
1215 ZeroMemory( &info,
sizeof(info) );
1216 info.cb =
sizeof(info);
1217 ZeroMemory( &processInfo,
sizeof(processInfo) );
1219 char* callstring =
const_cast<char *
>(tmp.c_str());
1222 ABOVE_NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,
1226 ::WaitForSingleObject(processInfo.hProcess, 10);
1230 std::cerr << GetLastError() << std::endl;
1243#define SWP(x,y) (x^=y, y^=x, x^=y)
1249 for(--q; p < q; ++p, --q)
SWP(*p, *q);
1265 const unsigned char * bytes = (
const unsigned char *)(str.c_str());
1272 (0x20 <= bytes[0] && bytes[0] <= 0x7E)
1280 (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
1281 (0x80 <= bytes[1] && bytes[1] <= 0xBF)
1290 (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
1291 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
1294 ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
1296 bytes[0] == 0xEF) &&
1297 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
1298 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
1302 (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
1303 (0x80 <= bytes[2] && bytes[2] <= 0xBF)
1312 (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
1313 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
1314 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
1317 (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
1318 (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
1319 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
1320 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
1324 (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
1325 (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
1326 (0x80 <= bytes[3] && bytes[3] <= 0xBF)
1349 switch( (*q & 0xF0) >> 4 ) {
1351 SWP(*(q-0), *(q-3));
1352 SWP(*(q-1), *(q-2));
1356 SWP(*(q-0), *(q-2));
1361 SWP(*(q-0), *(q-1));
1369 std::string q = std::string(p);
1370 std::reverse(q.begin(),q.end());
1378 std::wstring q(p.length(), L
' ');
1380 std::copy(p.begin(), p.end(), q.begin());
1383 std::reverse(q.begin(),q.end());
1386 std::wstring::iterator i;
1388 for(i = q.begin();i<=q.end();i++)
1394 std::string ns(q.begin(), q.end());
1395 cout << ns << std::endl;
1438 struct stat statbuf;
1439 if(fstat(fd, &statbuf) < 0) exit(-1);
1440 return statbuf.st_size;
1446 if(FileExists(filename))
1451 std::ifstream file(filename.c_str(), std::ios::binary | std::ios::ate);
1452 if (!file.is_open())
1458 std::streamsize file_size = file.tellg();
1459 file.seekg(0, std::ios::beg);
1461 char* file_buffer =
new char[file_size];
1462 if (!file.read(file_buffer, file_size))
1464 delete[] file_buffer;
1471 md5->update((
unsigned char*)file_buffer,(
unsigned int)file_size);
1473 std::string hex =
md5->hexdigest();
1475 delete[] file_buffer;
1481 unsigned long int file_size;
1486 file_descript = open(filename.c_str(), O_RDONLY);
1487 if(file_descript < 0)
1501 md5->update((
unsigned char*)file_buffer,(
unsigned int)file_size);
1504 std::string hex =
md5->hexdigest();
1546 std::string label = text.substr((*t)->start,(*t)->end - (*t)->start);
1552 }
else if(label[0]==
'f' || label[0] ==
'N')
1562 if(label.find(
'.') == std::string::npos &&
1563 label.find(
'e') == std::string::npos &&
1564 label.find(
'E') == std::string::npos &&
1565 numVal == floor(numVal))
1586 Variant out =
Variant(text.substr((*t)->start,(*t)->end-(*t)->start));
1596 std::string name =
"JSON Object";
1605 remaining = (*t)->size * 2;
1611 while(remaining > 0)
1616 std::string objname = text.substr((*t)->start,(*t)->end-(*t)->start);
1632 t,(*t)->
start,(*t)->end);
1655 remaining = (*t)->size ;
1666 while(remaining > 0)
1674 t, (*t)->
start,(*t)->end);
1703 t= (
jsmntok_t*) malloc(
sizeof(*t)*(size_t)10000);
1710 r =
jsmn_parse(&p, text.c_str(), text.length(),*tt,10000);
1713 printf(
"Failed to parse JSON: %d\n", r);
1720 printf(
"Object expected\n");
1738 const unsigned char *bytes = (
const unsigned char *)text.c_str();
1741 if ((bytes[0] == 0xD6 && bytes[1] >= 0x90) ||
1742 (bytes[0] == 0xD7 && bytes[1] <= 0xBF)) {
1747 if (bytes[0] >= 0xD8 && bytes[0] <= 0xDB) {
1752 if (bytes[0] == 0xE0 && bytes[1] == 0xA4) {
1757 if (bytes[0] == 0xE0 && bytes[1] == 0xB8) {
1762 if (bytes[0] == 0xE0 && bytes[1] == 0xA6) {
1767 if (bytes[0] == 0xE1 && (bytes[1] == 0x82 || bytes[1] == 0x83)) {
1772 if (bytes[0] == 0xE3 && (bytes[1] == 0x81 || bytes[1] == 0x82)) {
1777 if (bytes[0] == 0xE3 && bytes[1] == 0x83) {
1782 if (bytes[0] >= 0xEA && bytes[0] <= 0xED) {
1788 if (bytes[0] >= 0xE4 && bytes[0] <= 0xE9) {
1793 if (bytes[0] < 0x80) bytes += 1;
1794 else if ((bytes[0] & 0xE0) == 0xC0) bytes += 2;
1795 else if ((bytes[0] & 0xF0) == 0xE0) bytes += 3;
1796 else if ((bytes[0] & 0xF8) == 0xF0) bytes += 4;
1805 return (script ==
"Hebr" || script ==
"Arab");
1812 std::string upperCode = code;
1813 std::transform(upperCode.begin(), upperCode.end(), upperCode.begin(), ::toupper);
1816 std::string defaultSans =
"DejaVuSans.ttf";
1817 std::string defaultMono =
"DejaVuSansMono.ttf";
1818 std::string defaultSerif =
"DejaVuSerif.ttf";
1821 std::string cjkSans =
"NotoSansCJK-Regular.ttc";
1822 std::string cjkMono =
"NotoSansMono-Regular.ttf";
1823 std::string cjkSerif =
"NotoSerif-Regular.ttf";
1826 if (upperCode.length() == 2) {
1828 if (upperCode ==
"AR") {
1830 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1832 else if (upperCode ==
"HE" || upperCode ==
"IW") {
1834 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1836 else if (upperCode ==
"TH") {
1838 return (fontType == 0) ?
"NotoSansThai-Regular.ttf" :
1839 (fontType == 1) ? cjkMono : cjkSerif;
1841 else if (upperCode ==
"HI" || upperCode ==
"MR" || upperCode ==
"NE") {
1843 return (fontType == 0) ?
"NotoSansDevanagari-Regular.ttf" :
1844 (fontType == 1) ? cjkMono : cjkSerif;
1846 else if (upperCode ==
"BN") {
1848 return (fontType == 0) ?
"NotoSansBengali-Regular.ttf" :
1849 (fontType == 1) ? cjkMono : cjkSerif;
1851 else if (upperCode ==
"KA") {
1853 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1855 else if (upperCode ==
"ZH" || upperCode ==
"CN" || upperCode ==
"TW") {
1857 return (fontType == 0) ? cjkSans : (fontType == 1) ? cjkMono : cjkSerif;
1859 else if (upperCode ==
"JA" || upperCode ==
"JP") {
1861 return (fontType == 0) ? cjkSans : (fontType == 1) ? cjkMono : cjkSerif;
1863 else if (upperCode ==
"KO" || upperCode ==
"KR" || upperCode ==
"KP") {
1865 return (fontType == 0) ? cjkSans : (fontType == 1) ? cjkMono : cjkSerif;
1869 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1872 else if (upperCode.length() == 4) {
1874 if (upperCode ==
"ARAB") {
1876 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1878 else if (upperCode ==
"HEBR") {
1880 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1882 else if (upperCode ==
"THAI") {
1884 return (fontType == 0) ?
"NotoSansThai-Regular.ttf" :
1885 (fontType == 1) ? cjkMono : cjkSerif;
1887 else if (upperCode ==
"DEVA") {
1889 return (fontType == 0) ?
"NotoSansDevanagari-Regular.ttf" :
1890 (fontType == 1) ? cjkMono : cjkSerif;
1892 else if (upperCode ==
"BENG") {
1894 return (fontType == 0) ?
"NotoSansBengali-Regular.ttf" :
1895 (fontType == 1) ? cjkMono : cjkSerif;
1897 else if (upperCode ==
"GEOR") {
1899 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1901 else if (upperCode ==
"HIRA" || upperCode ==
"KANA" || upperCode ==
"HANI") {
1903 return (fontType == 0) ? cjkSans : (fontType == 1) ? cjkMono : cjkSerif;
1905 else if (upperCode ==
"HANG") {
1907 return (fontType == 0) ? cjkSans : (fontType == 1) ? cjkMono : cjkSerif;
1911 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1916 return (fontType == 0) ? defaultSans : (fontType == 1) ? defaultMono : defaultSerif;
1925 if(propertyChain.empty())
1932 std::string::size_type dotPos = propertyChain.find(
".");
1934 if(dotPos == std::string::npos)
1941 propertyChain +
"] of non-object");
1949 std::string firstProp = propertyChain.substr(0, dotPos);
1950 std::string remainingChain = propertyChain.substr(dotPos + 1);
1956 firstProp +
"] of non-object in chain [" + propertyChain +
"]");
1971 if(propertyChain.empty())
1978 std::string::size_type dotPos = propertyChain.find(
".");
1980 if(dotPos == std::string::npos)
1987 propertyChain +
"] on non-object");
1995 std::string firstProp = propertyChain.substr(0, dotPos);
1996 std::string remainingChain = propertyChain.substr(dotPos + 1);
2002 firstProp +
"] of non-object in chain [" + propertyChain +
"]");
unsigned long get_size_by_fd(int fd)
@ PEBL_KEYCODE_UNDERSCORE
@ PEBL_KEYCODE_KP_MULTIPLY
@ PEBL_KEYCODE_RIGHTBRACKET
@ PEBL_KEYCODE_RIGHTPAREN
@ PEBL_KEYCODE_SCROLLLOCK
@ PEBL_KEYCODE_LEFTBRACKET
@ PEBL_KEYCODE_PRINTSCREEN
Variant GetProperty(std::string prop) const
void SetProperty(std::string, Variant v)
This class simply represent an abstract text-based object.
virtual bool SetProperty(std::string, Variant v)
void PushBack(const Variant &v)
PComplexData * GetComplexData() const
JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, jsmntok_t *tokens, const unsigned int num_tokens)
JSMN_API void jsmn_init(jsmn_parser *parser)
std::string md5(const std::string str)
void * mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
Variant SystemCall(std::string path, std::string args)
pDouble StringToPDouble(const char *mystring)
Variant ResolvePropertyChain(Variant obj, const std::string &propertyChain)
Variant LaunchFile(std::string file)
Variant GetHomeDirectory()
PEBL_Keycode TranslateString(const std::string &letters)
PEBLVideoDepth GetVideoDepth(std::string depthline)
const std::string GetBaseFileName(const std::string &file)
bool is_utf8(const std::string str)
pDouble Log2(pDouble val)
void SetPropertyChain(Variant obj, const std::string &propertyChain, Variant value)
const std::string StripFile(const std::string &file)
std::string TranslateKeycode(const PEBL_Keycode key, int modkeys)
void InitializeKeycodeLookups()
std::string ToUpper(const std::string &text)
Variant SetWorkingDirectory(std::string path)
void strrev_utf8(char *p)
std::string DetectScript(const std::string &text)
Variant DeleteMyFile(std::string path)
Variant ParseJSON(const std::string &text)
std::string MD5String(const std::string &text)
Variant ExtractJSONObject(const std::string &text, int remaining, jsmntok_t **t, int start, int end)
bool IsRTLScript(const std::string &script)
std::string MD5File(const std::string &filename)
Variant FileExists(std::string path)
void CopyToClipboard(const std::string &text)
std::string ShiftSwitch(int modkeys, std::string lower, std::string upper)
Variant Tokenize(const char *line, char separator)
Variant GetDirectoryListing(std::string path)
std::string GetFontForLanguageOrScript(const std::string &code, int fontType)
Variant GetWorkingDirectory()
pInt Truncate(pDouble val)
Variant MakeDirectory(std::string path)
std::string ToLower(const std::string &text)
Variant IsDirectory(std::string path)
PEBLVideoMode GetVideoMode(std::string modeline)
void SignalFatalError(const std::string &message)