33#include <libFreeWRL.h>
57#include "main/ProdCon.h"
58#if !defined(IPHONE) && !defined(_ANDROID)
59#include "input/InputFunctions.h"
60#include "plugin/pluginUtils.h"
61#include "plugin/PluginSocket.h"
65#if defined (INCLUDE_STL_FILES)
66#include "input/convertSTL.h"
70#define UNUSED(v) ((void) v)
73void append_openned_file(s_list_t *list,
const char *filename,
int fd,
char *text);
75int inputFileType = IS_TYPE_UNKNOWN;
76int inputFileVersion[3] = {0,0,0};
79int fw_mkdir(
const char* path){
83 return mkdir(path,0755);
90char* concat_path(
const char *a,
const char *b)
99 tmp = MALLOC(
char *, 2+lb);
100 sprintf(tmp,
"/%s", b);
106 tmp = MALLOC(
char *, la+2);
107 sprintf(tmp,
"%s/", a);
115 if (a[la-1] ==
'/') {
116 tmp = MALLOC(
char *, la + lb + 1);
117 sprintf(tmp,
"%s%s", a, b);
119 tmp = MALLOC(
char *, la + lb + 2);
120 sprintf(tmp,
"%s/%s", a, b);
129char* remove_filename_from_path(
const char *path)
134 slash = strrchr(path,
'/');
137printf (
"remove_filename_from_path going to copy %d\n", ((
int)slash-(
int)path)+1);
138 rv = strndup(path, ((
int)slash-(
int)path)+1);
140 slash = strrchr(rv,
'/');
142printf (
"remove_filename_from_path, returning :%s:\n",rv);
144 rv = STRNDUP(path, (
size_t)slash - (
size_t)path + 1);
150char *strBackslash2fore(
char *str)
154 for( jj=0;jj<(int)strlen(str);jj++)
155 if(str[jj] ==
'\\' ) str[jj] =
'/';
160char *get_current_dir()
163 cwd = MALLOC(
char *, PATH_MAX);
164 retvar = getcwd(cwd, PATH_MAX);
165 if (NULL != retvar) {
168 cwd = strBackslash2fore(cwd);
172 printf(
"Unable to establish current working directory in %s,%d errno=%d",__FILE__,__LINE__,errno) ;
193bool do_file_exists(
const char *filename)
196 if (stat(filename, &ss) == 0) {
205bool do_file_readable(
const char *filename)
207 if (access(filename, R_OK) == 0) {
217bool do_dir_exists(
const char *dir)
225 if (stat(dir, &ss) == 0) {
226 if (access(dir,X_OK) == 0) {
229 WARN_MSG(
"directory '%s' exists but is not accessible\n", dir);
239void of_dump(openned_file_t *of)
241 static char first_ten[11];
243 int len = of->fileDataSize;
245 memcpy(first_ten, of->fileData, len);
247 printf(
"{%s, %d, %d, %s%s}\n", of->fileFileName, of->fileDescriptor, of->fileDataSize, (of->fileData ? first_ten :
"(null)"), (of->fileData ?
"..." :
""));
255static openned_file_t* create_openned_file(
const char *filename,
int fd,
int dataSize,
char *data,
int imageHeight,
int imageWidth,
bool imageAlpha)
259 char *fileData = NULL;
260 if (dataSize > 0 && data)
262 fileData = MALLOC (
char *, dataSize+1);
263 if (NULL != fileData)
265 memcpy (fileData, data, dataSize);
266 fileData[dataSize] =
'\0';
271 of = XALLOC(openned_file_t);
272 of->fileFileName = filename;
273 of->fileDescriptor = fd;
275 of->fileDataSize = dataSize;
276 of->imageHeight = imageHeight;
277 of->imageWidth = imageWidth;
278 of->imageAlpha = imageAlpha;
289#if defined(FW_USE_MMAP)
290static void* load_file_mmap(
const char *filename)
296 if (stat(filename, &ss) < 0) {
297 PERROR_MSG(
"load_file_mmap: could not stat: %s\n", filename);
300 fd = open(filename, O_RDONLY | O_NONBLOCK);
302 PERROR_MSG(
"load_file_mmap: could not open: %s\n", filename);
306 ERROR_MSG(
"load_file_mmap: file is empty %s\n", filename);
310 text = mmap(NULL, ss.st_size, PROT_READ, MAP_SHARED, fd, 0);
311 if ((text == MAP_FAILED) || (!text)) {
312 PERROR_MSG(
"load_file_mmap: could not mmap: %s\n", filename);
316 return create_openned_file(filename, fd, text,0,0,FALSE);
324 int load_file_blob(
const char *filename,
char **blob,
int *len){
327 char *text, *current;
330 size_t blocksz, readsz;
332 ssize_t blocksz, readsz;
335 if (stat(filename, &ss) < 0) {
336 PERROR_MSG(
"load_file_read: could not stat: %s\n", filename);
340 fd = open(filename, O_RDONLY | O_BINARY);
342 fd = open(filename, O_RDONLY | O_NONBLOCK);
345 PERROR_MSG(
"load_file_read: could not open: %s\n", filename);
349 ERROR_MSG(
"load_file_read: file is empty %s\n", filename);
354 text = current = MALLOC(
char *, ss.st_size +1);
356 ERROR_MSG(
"load_file_read: cannot allocate memory to read file %s\n", filename);
361 if (ss.st_size > SSIZE_MAX) {
365 blocksz = ss.st_size;
368 left2read = ss.st_size;
371 while (left2read > 0) {
372 readsz = read(fd, current, blocksz);
376 left2read -= blocksz;
377 blocksz = min(blocksz,left2read);
385 PERROR_MSG(
"load_file_read: error reading file %s\n", filename);
394 text[ss.st_size] =
'\0';
407static openned_file_t* load_file_read(
const char *filename)
411 openned_file_t *retval = NULL;
412 if( load_file_blob(filename, &blob, &len))
414 retval = create_openned_file(filename, 0, len, blob,0,0,FALSE);
419OLDCODEstatic openned_file_t* load_file_read_old(
const char *filename)
421OLDCODE
struct stat ss;
423OLDCODE
unsigned char *text, *current;
424OLDCODE
int left2read;
425OLDCODE#ifdef _MSC_VER
426OLDCODE
size_t blocksz, readsz;
428OLDCODE ssize_t blocksz, readsz;
431OLDCODE
if (stat(filename, &ss) < 0) {
432OLDCODE PERROR_MSG(
"load_file_read: could not stat: %s\n", filename);
435OLDCODE#ifdef _MSC_VER
436OLDCODE fd = open(filename, O_RDONLY | O_BINARY);
438OLDCODE fd = open(filename, O_RDONLY | O_NONBLOCK);
441OLDCODE PERROR_MSG(
"load_file_read: could not open: %s\n", filename);
444OLDCODE
if (!ss.st_size) {
445OLDCODE ERROR_MSG(
"load_file_read: file is empty %s\n", filename);
450OLDCODE text = current = MALLOC(
unsigned char *, ss.st_size +1);
452OLDCODE ERROR_MSG(
"load_file_read: cannot allocate memory to read file %s\n", filename);
457OLDCODE
if (ss.st_size > SSIZE_MAX) {
459OLDCODE blocksz = SSIZE_MAX;
461OLDCODE blocksz = ss.st_size+1;
464OLDCODE left2read = ss.st_size;
467OLDCODE
while (left2read > 0) {
468OLDCODE readsz = read(fd, current, blocksz);
469OLDCODE
if (readsz > 0) {
471OLDCODE current += blocksz;
472OLDCODE left2read -= blocksz;
475OLDCODE
if (readsz == 0) {
480OLDCODE PERROR_MSG(
"load_file_read: error reading file %s\n", filename);
489OLDCODE text[ss.st_size] =
'\0';
492OLDCODE
return create_openned_file(filename, fd, ss.st_size+1, text,0,0,FALSE);
499char *fwg_frontEndWantsFileName() {
return NULL;}
500void fwg_frontEndReturningData(
char* fileData,
int length,
int width,
int height,
bool hasAlpha) {}
506openned_file_t* load_file(
const char *filename)
509 if (NULL == filename) {
519 DEBUG_RES(
"loading file: %s pthread %p\n", filename,pthread_self());
523#if defined(FW_USE_MMAP)
524#if !defined(_MSC_VER)
526 of = load_file_mmap(filename);
529 of = load_file_win32_mmap(filename);
533 of = load_file_read(filename);
535 DEBUG_RES(
"%s loading status: %s\n", filename, BOOL_STR((of!=NULL)));
544int determineFileType(
const char *buffer,
const int len)
548 int foundStart = FALSE;
550 for (count = 0; count < 3; count ++) inputFileVersion[count] = 0;
553 if (strncmp((
const char*)buffer,
"<?xml version",12) == 0){
562 while (!foundStart) {
563 while ((*rv !=
'<') && (*rv !=
'\0')) rv++;
566 if (*rv !=
'!') foundStart = TRUE;
567 }
else if (*rv ==
'\0') foundStart = TRUE;
569 if (strncmp((
const char*)rv,
"X3D",3) == 0) {
571 inputFileVersion[0] = 3;
572 return IS_TYPE_XML_X3D;
575#if defined (INCLUDE_NON_WEB3D_FORMATS)
576 if (strncmp((
const char*)rv,
"COLLADA",7) == 0) {
577 return IS_TYPE_COLLADA;
579 if (strncmp((
const char*)rv,
"kml",3) == 0) {
586 if (strncmp((
const char*)buffer,
"#VRML V2.0 utf8",15) == 0) {
587 inputFileVersion[0] = 2;
591 if (strncmp ((
const char*)buffer,
"#X3D",4) == 0) {
592 inputFileVersion[0] = 3;
595 if (strncmp ((
const char*)buffer,
"#X3D V3.0 utf8",14) == 0) {
596 inputFileVersion[1] = 0;
599 if (strncmp ((
const char*)buffer,
"#X3D V3.1 utf8",14) == 0) {
600 inputFileVersion[1] = 1;
603 if (strncmp ((
const char*)buffer,
"#X3D V3.2 utf8",14) == 0) {
604 inputFileVersion[1] = 2;
607 if (strncmp ((
const char*)buffer,
"#X3D V3.3 utf8",14) == 0) {
608 inputFileVersion[1] = 3;
611 if (strncmp ((
const char*)buffer,
"#X3D V4.0 utf8",14) == 0) {
612 inputFileVersion[0] = 4;
613 inputFileVersion[1] = 0;
620 if (strncmp((
const char*)buffer,
"#VRML V1.0 asc",10) == 0) {
621 return IS_TYPE_VRML1;
628 while(rv && *rv !=
'\0'){
629 if(*rv ==
'<')
return IS_TYPE_XML_X3D;
630 if (*rv ==
'{')
return IS_TYPE_VRML;
634 #if defined (INCLUDE_STL_FILES)
635 return stlDTFT((
const unsigned char*)buffer,len);
638 return IS_TYPE_UNKNOWN;
647#if !defined( _MSC_VER) && !defined(_ANDROID) && !defined(ANDROIDNDK) && !defined(IOS)
648int freewrlSystem (
const char *sysline)
654#define MAXEXECPARAMS 10
655#define EXECBUFSIZE 2000
656 char *paramline[MAXEXECPARAMS];
657 char buf[EXECBUFSIZE];
668 memset(paramline, 0,
sizeof(paramline));
671 haveXmessage = !strncmp(sysline, FREEWRL_MESSAGE_WRAPPER, strlen(FREEWRL_MESSAGE_WRAPPER));
676 if (strlen(sysline)>=EXECBUFSIZE)
return FALSE;
677 strcpy (buf,sysline);
684 paramline[0] = FREEWRL_MESSAGE_WRAPPER;
685 paramline[1] = strchr(internbuf,
' ');
689 while (internbuf != NULL) {
691 paramline[count] = internbuf;
692 internbuf = strchr(internbuf,
' ');
693 if (internbuf != NULL) {
699 if (count >= MAXEXECPARAMS)
return -1;
712 waitForChild = FALSE;
715 if (strncmp(paramline[count],
"&",strlen(paramline[count])) == 0) {
717 paramline[count] =
'\0';
736 Xrv = execl((
const char *)paramline[0],
737 (
const char *)paramline[0],paramline[1], paramline[2],
738 paramline[3],paramline[4],paramline[5],
739 paramline[6],paramline[7], NULL);
740 printf (
"FreeWRL: Fatal problem execing %s\n",paramline[0]);
757 waitpid(child, &pidStatus, 0);
767 return (WIFEXITED(pidStatus) == TRUE);
769 printf (
"System call failed :%s:\n",sysline);
774#elif defined(_MSC_VER)
775int freewrlSystem (
const char *sysline)
777 return system(sysline);
785static TCHAR *singleDot = L
".";
786static TCHAR *doubleDot = L
"..";
787static TCHAR *backslash = L
"\\";
788static TCHAR *star = L
"*";
791static TCHAR *singleDot =
".";
792static TCHAR *doubleDot =
"..";
793static TCHAR *backslash =
"\\";
794static TCHAR *star =
"*";
798BOOL IsDots(
const TCHAR* str) {
799 if(_tcscmp(str,singleDot) && _tcscmp(str,doubleDot))
803BOOL DeleteDirectory0(
const TCHAR* sPath) {
805 WIN32_FIND_DATA FindFileData;
806 TCHAR DirPath[MAX_PATH];
807 TCHAR FileName[MAX_PATH];
810 _tcscpy(DirPath,sPath);
811 _tcscat(DirPath,backslash);
812 _tcscat(DirPath,star);
813 _tcscpy(FileName,sPath);
814 _tcscat(FileName,backslash);
817 hFind = FindFirstFileEx(DirPath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);
820 hFind = FindFirstFile(DirPath,&FindFileData);
822 if(hFind == INVALID_HANDLE_VALUE)
824 _tcscpy(DirPath,FileName);
828 if(FindNextFile(hFind,&FindFileData)) {
829 if(IsDots(FindFileData.cFileName))
continue;
830 _tcscat(FileName,FindFileData.cFileName);
831 if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
833 if(!DeleteDirectory0(FileName)) {
837 RemoveDirectory(FileName);
838 _tcscpy(FileName,DirPath);
841 if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
842 _tchmod(FileName, 777);
843 if(!DeleteFile(FileName)) {
858 _tcscpy(FileName,DirPath);
862 if(GetLastError() == ERROR_NO_MORE_FILES)
872 return RemoveDirectory(sPath);
875BOOL tdirectory_remove_all(TCHAR *sPath){
877 retval = DeleteDirectory0(sPath);
880void tremove_file_or_folder(TCHAR *path){
885 WIN32_FILE_ATTRIBUTE_DATA fad;
886 finfo = GetFileAttributesEx(path, GetFileExInfoStandard, &fad);
889 err = GetLastError();
891 ConsoleMessage(
"GetFileAttribuesEx err=%d maxpath%d pathlen%d", (
int)err,MAX_PATH,_tcslen(path));
892 isDir = ! _tcsstr(path, singleDot);
895 isDir = finfo && (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
899 finfo = GetFileAttributes(path);
900 isDir = FILE_ATTRIBUTE_DIRECTORY & finfo;
903 tdirectory_remove_all(path);
907void remove_file_or_folder(
const char *path){
913 size_t convertedChars = 0;
914 TCHAR wcstring[MAX_PATH];
915 char fname2[MAX_PATH];
918 origsize = strlen(path) + 1;
920 for(jj=0;jj<(int)strlen(fname2);jj++)
921 if(fname2[jj] ==
'/' ) fname2[jj] =
'\\';
925 mbstowcs_s(&convertedChars, wcstring, origsize, fname2, _TRUNCATE);
927 mbstowcs(wcstring, fname2, MB_CUR_MAX);
930 _tcscpy(wcstring,fname2);
932 tremove_file_or_folder(wcstring);
937int directory_remove_all(
const char *path)
939 DIR *d = opendir(path);
940 size_t path_len = strlen(path);
948 while (!r && (p=readdir(d)))
955 if (!strcmp(p->d_name,
".") || !strcmp(p->d_name,
".."))
959 len = path_len + strlen(p->d_name) + 2;
960 buf = MALLOC(
void *, len);
964 snprintf(buf, len,
"%s/%s", path, p->d_name);
965 if (!stat(buf, &statbuf))
967 if (S_ISDIR(statbuf.st_mode))
969 r2 = directory_remove_all(buf);
988void remove_file_or_folder(
const char * path){
990 if (!stat(path, &statbuf))
995 if (S_ISDIR(statbuf.st_mode))
997 r2 = directory_remove_all(path);
1012#define WRITEBUFFERSIZE (8192)
1015int unzip_archive_to_temp_folder(
const char *zipfilename,
const char* tempfolderpath)
1018 const char *filename_to_extract=NULL;
1020 const char *dirname=NULL;
1022 char *fullpath = NULL;
1025 uf = unzOpen(zipfilename);
1028 printf(
"Cannot open %s \n",zipfilename);
1031 printf(
"%s opened\n",zipfilename);
1034 fw_mkdir(tempfolderpath);
1043 err = unzGetGlobalInfo(uf,&gi);
1045 printf(
"error %d with zipfile in unzGetGlobalInfo \n",err);
1049 for (i=0;i<gi.number_entry;i++)
1052 char filename_inzip[256];
1053 char* filename_withoutpath;
1060 unz_file_info file_info;
1062 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,
sizeof(filename_inzip),NULL,0,NULL,0);
1066 printf(
"error %d with zipfile in unzGetCurrentFileInfo\n",err);
1070 size_buf = WRITEBUFFERSIZE;
1071 buf = (
void*)MALLOC(
void *, size_buf);
1074 printf(
"Error allocating memory\n");
1075 return UNZ_INTERNALERROR;
1078 p = filename_withoutpath = filename_inzip;
1079 while ((*p) !=
'\0')
1081 if (((*p)==
'/') || ((*p)==
'\\'))
1082 filename_withoutpath = p+1;
1086 if ((*filename_withoutpath)==
'\0')
1088 printf(
"creating directory: %s\n",filename_inzip);
1089 strcpy(temppath,tempfolderpath);
1090 strcat(temppath,
"/");
1091 strcat(temppath,filename_inzip);
1097 const char* write_filename;
1100 write_filename = filename_inzip;
1102 err = unzOpenCurrentFile(uf);
1105 printf(
"error %d with zipfile in unzOpenCurrentFile\n",err);
1110 strcpy(temppath,tempfolderpath);
1111 strcat(temppath,
"/");
1112 strcat(temppath,write_filename);
1114 fout=fopen(temppath,
"wb");
1119 printf(
" extracting: %s\n",write_filename);
1123 err = unzReadCurrentFile(uf,buf,size_buf);
1126 printf(
"error %d with zipfile in unzReadCurrentFile\n",err);
1130 if (fwrite(buf,err,1,fout)!=1)
1132 printf(
"error in writing extracted file\n");
1145 err = unzCloseCurrentFile (uf);
1148 printf(
"error %d with zipfile in unzCloseCurrentFile\n",err);
1152 unzCloseCurrentFile(uf);
1159 if ((i+1)<gi.number_entry)
1161 err = unzGoToNextFile(uf);
1164 printf(
"error %d with zipfile in unzGoToNextFile\n",err);
1176char* remove_filename_from_path(
const char *path);
1177char *strBackslash2fore(
char *str);
1178void resitem_enqueue(s_list_t *item);
1179void process_x3z(resource_item_t *res){
1182 char* tempfolderpath;
1184 tempfolderpath = TEMPNAM(gglobal()->Mainloop.tmpFileLocation,
"freewrl_download_XXXXXXXX");
1187 tempfolderpath = STRDUP(res->URLrequest);
1188 tempfolderpath = strBackslash2fore(tempfolderpath);
1189 tempfolderpath = remove_filename_from_path(tempfolderpath);
1190 tempfolderpath = TEMPNAM(tempfolderpath,
"freewrl_download_XXXXXXXX");
1192 err = unzip_archive_to_temp_folder(res->actual_file, tempfolderpath);
1194 resource_item_t *docx3d;
1196 strcpy(request,tempfolderpath);
1197 strcat(request,
"/doc.x3d");
1198 docx3d = resource_create_single(request);
1199 docx3d->parent = NULL;
1200 docx3d->type = rest_file;
1201 docx3d->media_type = resm_x3d;
1202 docx3d->treat_as_root = 1;
1204 resitem_enqueue(ml_new(docx3d));
1206 res->cached_files = ml_append(res->cached_files,ml_new(tempfolderpath));
1207 ConsoleMessage(
"unzip folder:%s\n", tempfolderpath);
1210 ConsoleMessage(
"unzip failed to folder:%s\n", tempfolderpath);
1215void process_x3z(resource_item_t *res){
1222 file2blob_task_chain,
1223 file2blob_task_spawn,
1224 file2blob_task_enqueue,
1225} file2blob_task_tactic2;
1227void resource_remove_cached_file(s_list_t *cfe);
1228void delete_temp_file(resource_item_t *res){
1235 if(res->media_type != resm_x3z){
1236 cf = (s_list_t *)res->cached_files;
1238 ml_foreach(cf, resource_remove_cached_file(__l));
1240 ml_foreach(cf, ml_free(__l));
1241 res->cached_files = NULL;
1246int file2blob(
void *resp){
1247 resource_item_t *res;
1250 res = (resource_item_t*)resp;
1251 if(res->media_type == resm_image){
1253 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1255 retval = imagery_load(res);
1256 }
else if(res->media_type == resm_movie){
1257 retval = movie_load(res);
1259 retval = resource_load(res);
1261 delete_temp_file(res);
1264int async_thread_count = 0;
1265static void *thread_load_async (
void *args){
1267 resource_item_t *res = (resource_item_t *)args;
1268 async_thread_count++;
1269 printf(
"[%d]",async_thread_count);
1270 loaded = file2blob(res);
1273 resitem_enqueue_tg(ml_new(res),res->tg);
1274 async_thread_count--;
1277void loadAsync (resource_item_t *res) {
1278 if(!res->_loadThread) res->_loadThread = malloc(
sizeof(pthread_t));
1279 pthread_create ((pthread_t*)res->_loadThread, NULL,&thread_load_async, (
void *)res);
1281void file2blob_task(s_list_t *item){
1283 resource_item_t *res = item->elem;
1284 int tactic = file2blob_task_enqueue;
1285 if(tactic == file2blob_task_chain){
1287 if(res->media_type == resm_image){
1289 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1296 delete_temp_file(res);
1297 resitem_enqueue(item);
1298 }
else if(tactic == file2blob_task_enqueue){
1301 res->_loadFunc = (int(*)(
void*))file2blob;
1304 resitem_enqueue(item);
1305 }
else if(tactic == file2blob_task_spawn){