Example #1
0
static GF_Err ft_get_glyphs(GF_FontReader *dr, const char *utf_string, u32 *glyph_buffer, u32 *io_glyph_buffer_size, const char *xml_lang, Bool *is_rtl)
{
	u32 len;
	u32 i;
	u16 *conv;
	char *utf8 = (char*) utf_string;
	FTBuilder *ftpriv = (FTBuilder *)dr->udta;

	if (!ftpriv->active_face) return GF_BAD_PARAM;

	/*TODO: glyph substitution / ligature */

	len = utf_string ? strlen(utf_string) : 0;
	if (!len) {
		*io_glyph_buffer_size = 0;
		return GF_OK;
	}
	if (*io_glyph_buffer_size < len+1) {
		*io_glyph_buffer_size = len+1;
		return GF_BUFFER_TOO_SMALL;
	}
	len = gf_utf8_mbstowcs((u16*) glyph_buffer, *io_glyph_buffer_size, (const char **) &utf8);
	if ((s32)len<0) return GF_IO_ERR;
	if (utf8) return GF_IO_ERR;

	/*perform bidi relayout*/
	conv = (u16*) glyph_buffer;
	*is_rtl = gf_utf8_reorder_bidi(conv, len);
	/*move 16bit buffer to 32bit*/
	for (i=len; i>0; i--) {
		glyph_buffer[i-1] = (u32) conv[i-1];
	}
	*io_glyph_buffer_size = len;
	return GF_OK;
}
Example #2
0
STDMETHODIMP CGPAXPlugin::Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
{
	u16 wurl[MAXLEN_URL];
	const char *sptr;
	u16 len;

    VARIANT value;
    if( pPropBag == NULL) return E_INVALIDARG;

    VariantInit(&value);

    V_VT(&value) = VT_BOOL;
    V_BOOL(&value) = m_bAutoStart ? VARIANT_TRUE : VARIANT_FALSE;
    pPropBag->Write(OLESTR("AutoStart"), &value);
    VariantClear(&value);

    V_VT(&value) = VT_BSTR;

	sptr = (const char *)m_url;
	len = gf_utf8_mbstowcs(wurl, MAXLEN_URL, &sptr);
    V_BSTR(&value) = SysAllocStringLen(NULL, len+1);
	memcpy(V_BSTR(&value) , wurl, len*sizeof(u16));
	V_BSTR(&value) [len] = 0;
	
    pPropBag->Write(OLESTR("src"), &value);
    VariantClear(&value);
    return S_OK;
}
Example #3
0
STDMETHODIMP CGPAXPlugin::get_src(BSTR *url)
{
	u16 wurl[MAXLEN_URL];
	const char *sptr;
	u16 len;
    if (url==NULL) return E_POINTER;

	sptr = (const char *)m_url;
	len = gf_utf8_mbstowcs(wurl, MAXLEN_URL, &sptr);
    *url = SysAllocStringLen(NULL, len+1);
	memcpy(*url, wurl, len*sizeof(u16));
	*url[len] = 0;
    return S_OK;
}
Example #4
0
void CGPAXPlugin::SetStatusText(char *msg)
{
#ifndef _WIN32_WCE
	if (m_pBrowser) {
		if (msg) {
			u16 w_msg[1024];
			gf_utf8_mbstowcs(w_msg, 1024, (const char **)&msg);
			m_pBrowser->put_StatusText((BSTR) w_msg);
		} else {
			m_pBrowser->put_StatusText(L"");
		}
	}
#endif
}
Example #5
0
static wchar_t* utf8_to_wcs(const char* str)
{
	size_t source_len;
	wchar_t* result;
	if (str == 0) return 0;
	source_len = strlen(str);
	result = gf_calloc(source_len + 1, sizeof(wchar_t));
	if (!result)
		return 0;
	if (gf_utf8_mbstowcs(result, source_len, &str) < 0) {
		gf_free(result);
		return 0;
	}
	return result;
}
Example #6
0
static GF_Err IS_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd)
{
	GF_BitStream *bs;
	u32 len, size, i;
	char devName[255];
	u16 termSeq[20];

	ISPriv *is = (ISPriv *)plug->privateStack;
	if (esd->decoderConfig->upstream) return GF_NOT_SUPPORTED;
	if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->dataLength) return GF_NON_COMPLIANT_BITSTREAM;

	/*no more than one UI stream per object*/
	if (is->ES_ID) return GF_NOT_SUPPORTED;
	is->ES_ID = esd->ESID;
	/*parse config*/
	bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ);
	len = gf_bs_read_int(bs, 8);
	for (i=0; i<len; i++) {
		devName[i] = gf_bs_read_int(bs, 8);
	}
	devName[i] = 0;
	is->type = gf_crc_32(devName, len);
	size = len + 1;

	if (!stricmp(devName, "KeySensor")) {
		is->type = IS_KeySensor;
		add_field(is, GF_SG_VRML_SFINT32, "keyPressed");
		add_field(is, GF_SG_VRML_SFINT32, "keyReleased");
		add_field(is, GF_SG_VRML_SFINT32, "actionKeyPressed");
		add_field(is, GF_SG_VRML_SFINT32, "actionKeyReleased");
		add_field(is, GF_SG_VRML_SFBOOL, "shiftKeyPressed");
		add_field(is, GF_SG_VRML_SFBOOL, "controlKeyPressed");
		add_field(is, GF_SG_VRML_SFBOOL, "altKeyPressed");

	} else if (!stricmp(devName, "StringSensor")) {
		is->type = IS_StringSensor;
		add_field(is, GF_SG_VRML_SFSTRING, "enteredText");
		add_field(is, GF_SG_VRML_SFSTRING, "finalText");

		is->termChar = '\r';
		is->delChar = '\b';

		/*get escape chars if any specified*/
		if (size<esd->decoderConfig->decoderSpecificInfo->dataLength) {
			const char *src = esd->decoderConfig->decoderSpecificInfo->data + size;
			gf_utf8_mbstowcs(termSeq, esd->decoderConfig->decoderSpecificInfo->dataLength - size, &src);
			is->termChar = termSeq[0];
			is->delChar = termSeq[1];
		}
	} else if (!stricmp(devName, "Mouse")) {
		is->type = IS_Mouse;
		add_field(is, GF_SG_VRML_SFVEC2F, "position");
		add_field(is, GF_SG_VRML_SFBOOL, "leftButtonDown");
		add_field(is, GF_SG_VRML_SFBOOL, "middleButtonDown");
		add_field(is, GF_SG_VRML_SFBOOL, "rightButtonDown");
		add_field(is, GF_SG_VRML_SFFLOAT, "wheel");
	}
	else {
		GF_InputSensorDevice *ifce;
		/*not found, check all modules*/
		u32 plugCount = gf_modules_get_count(is->scene->root_od->term->user->modules);
		for (i = 0; i < plugCount ; i++) {
			ifce = (GF_InputSensorDevice *) gf_modules_load_interface(is->scene->root_od->term->user->modules, i, GF_INPUT_DEVICE_INTERFACE);
			if (!ifce) continue;
			ifce->input_decoder = plug;
			if (ifce->RegisterDevice && ifce->RegisterDevice(ifce, devName, bs, isdev_add_field) ) {
				is->io_dev = ifce;
				break;
			}
			gf_modules_close_interface((GF_BaseInterface *) ifce);
		}
		if (!is->io_dev) return GF_NOT_SUPPORTED;

		is->io_dev->DispatchFrame = isdev_dispatch_frame;
		plug->module_name = is->io_dev->module_name;
		plug->author_name = is->io_dev->author_name;
	}

	gf_bs_del(bs);
	return GF_OK;
}
Example #7
0
/*enumerate directories*/
GF_EXPORT
GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item enum_dir_fct, void *cbck, const char *filter)
{
#ifdef WIN32
	wchar_t item_path[GF_MAX_PATH];
#else
	char item_path[GF_MAX_PATH];
#endif
	GF_FileEnumInfo file_info;

#if defined(_WIN32_WCE)
	char _path[GF_MAX_PATH];
	unsigned short path[GF_MAX_PATH];
	unsigned short w_filter[GF_MAX_PATH];
	char file[GF_MAX_PATH];
#elif defined(WIN32)
	wchar_t path[GF_MAX_PATH], *file;
	wchar_t w_filter[GF_MAX_PATH];
	wchar_t w_dir[GF_MAX_PATH];
	char *mbs_file, *mbs_item_path;
#else
	char path[GF_MAX_PATH], *file;
#endif

#ifdef WIN32
	WIN32_FIND_DATAW FindData;
	HANDLE SearchH;
#else
	DIR *the_dir;
	struct dirent* the_file;
	struct stat st;
#endif

	if (!dir || !enum_dir_fct) return GF_BAD_PARAM;

	if (filter && (!strcmp(filter, "*") || !filter[0])) filter=NULL;

	memset(&file_info, 0, sizeof(GF_FileEnumInfo) );

	if (!strcmp(dir, "/")) {
#if defined(WIN32) && !defined(_WIN32_WCE)
		u32 len;
		char *drives, *volume;
		len = GetLogicalDriveStrings(0, NULL);
		drives = (char*)gf_malloc(sizeof(char)*(len+1));
		drives[0]=0;
		GetLogicalDriveStrings(len, drives);
		len = (u32) strlen(drives);
		volume = drives;
		file_info.directory = GF_TRUE;
		file_info.drive = GF_TRUE;
		while (len) {
			enum_dir_fct(cbck, volume, "", &file_info);
			volume += len+1;
			len = (u32) strlen(volume);
		}
		gf_free(drives);
		return GF_OK;
#elif defined(__SYMBIAN32__)
		RFs iFs;
		TDriveList aList;
		iFs.Connect();
		iFs.DriveList(aList);
		for (TInt i=0; i<KMaxDrives; i++) {
			if (aList[i]) {
				char szDrive[10];
				TChar aDrive;
				iFs.DriveToChar(i, aDrive);
				sprintf(szDrive, "%c:", (TUint)aDrive);
				enum_dir_fct(cbck, szDrive, "", &file_info);
			}
		}
		iFs.Close();
		FlushItemList();
		return GF_OK;
#endif
	}


#if defined (_WIN32_WCE)
	switch (dir[strlen(dir) - 1]) {
	case '/':
	case '\\':
		sprintf(_path, "%s*", dir);
		break;
	default:
		sprintf(_path, "%s%c*", dir, GF_PATH_SEPARATOR);
		break;
	}
	CE_CharToWide(_path, path);
	CE_CharToWide((char *)filter, w_filter);
#elif defined(WIN32)
	{
		const char* tmpdir = dir;
		gf_utf8_mbstowcs(w_dir, sizeof(w_dir), &tmpdir);
	}
	switch (w_dir[wcslen(w_dir) - 1]) {
	case '/':
	case '\\':
		swprintf(path, MAX_PATH, L"%s*", w_dir);
		break;
	default:
		swprintf(path, MAX_PATH, L"%s%c*", w_dir, GF_PATH_SEPARATOR);
		break;
	}
	{
		const char* tmpfilter = filter;
		gf_utf8_mbstowcs(w_filter, sizeof(w_filter), &tmpfilter);
	}
#else
	strcpy(path, dir);
	if (path[strlen(path)-1] != '/') strcat(path, "/");
#endif

#ifdef WIN32
	SearchH= FindFirstFileW(path, &FindData);
	if (SearchH == INVALID_HANDLE_VALUE) return GF_IO_ERR;

#if defined (_WIN32_WCE)
	_path[strlen(_path)-1] = 0;
#else
	path[wcslen(path)-1] = 0;
#endif

	while (SearchH != INVALID_HANDLE_VALUE) {

#else

	the_dir = opendir(path);
	if (the_dir == NULL) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot open directory %s for enumeration: %d\n", path, errno));
		return GF_IO_ERR;
	}
	the_file = readdir(the_dir);
	while (the_file) {

#endif

		memset(&file_info, 0, sizeof(GF_FileEnumInfo) );


#if defined (_WIN32_WCE)
		if (!wcscmp(FindData.cFileName, _T(".") )) goto next;
		if (!wcscmp(FindData.cFileName, _T("..") )) goto next;
#elif defined(WIN32)
		if (!wcscmp(FindData.cFileName, L".")) goto next;
		if (!wcscmp(FindData.cFileName, L"..")) goto next;
#else
		if (!strcmp(the_file->d_name, "..")) goto next;
		if (the_file->d_name[0] == '.') goto next;
#endif

#ifdef WIN32
		file_info.directory = (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? GF_TRUE : GF_FALSE;
		if (!enum_directory && file_info.directory) goto next;
		if (enum_directory && !file_info.directory) goto next;
#endif

		if (filter) {
#if defined (_WIN32_WCE)
			short ext[30];
			short *sep = wcsrchr(FindData.cFileName, (wchar_t) '.');
			if (!sep) goto next;
			wcscpy(ext, sep+1);
			wcslwr(ext);
			if (!wcsstr(w_filter, ext)) goto next;
#elif defined(WIN32)
			wchar_t ext[30];
			wchar_t *sep = wcsrchr(FindData.cFileName, L'.');
			if (!sep) goto next;
			wcscpy(ext, sep+1);
			wcslwr(ext);
			if (!wcsstr(w_filter, ext)) goto next;
#else
			char ext[30];
			char *sep = strrchr(the_file->d_name, '.');
			if (!sep) goto next;
			strcpy(ext, sep+1);
			strlwr(ext);
			if (!strstr(filter, sep+1)) goto next;
#endif
		}

#if defined(WIN32)
		file_info.hidden = (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? GF_TRUE : GF_FALSE;
		file_info.system = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? GF_TRUE : GF_FALSE;
		file_info.size = MAXDWORD;
		file_info.size += 1;
		file_info.size *= FindData.nFileSizeHigh;
		file_info.size += FindData.nFileSizeLow;
		file_info.last_modified = (u64) ((*(LONGLONG *) &FindData.ftLastWriteTime - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
#endif

#if defined (_WIN32_WCE)
		CE_WideToChar(FindData.cFileName, file);
		strcpy(item_path, _path);
		strcat(item_path, file);
#elif defined(WIN32)
		wcscpy(item_path, path);
		wcscat(item_path, FindData.cFileName);
		file = FindData.cFileName;
#else
		strcpy(item_path, path);
		strcat(item_path, the_file->d_name);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Checking file %s for enum\n", item_path));

		if (stat( item_path, &st ) != 0) goto next;

		file_info.directory = ((st.st_mode & S_IFMT) == S_IFDIR) ? GF_TRUE : GF_FALSE;
		if (enum_directory && !file_info.directory) goto next;
		if (!enum_directory && file_info.directory) goto next;

		file_info.size = st.st_size;

		{
			struct tm _t = * gmtime(& st.st_mtime);
			file_info.last_modified = mktime(&_t);
		}
		file = the_file->d_name;
		if (file && file[0]=='.') file_info.hidden = 1;

		if (file_info.directory) {
			char * parent_name = strrchr(item_path, '/');
			if (!parent_name) {
				file_info.drive = GF_TRUE;
			} else {
				struct stat st_parent;
				parent_name[0] = 0;
				if (stat(item_path, &st_parent) == 0)  {
					if ((st.st_dev != st_parent.st_dev) || ((st.st_dev == st_parent.st_dev) && (st.st_ino == st_parent.st_ino))) {
						file_info.drive = GF_TRUE;
					}
				}
				parent_name[0] = '/';
			}
		}
#endif
		
#ifdef WIN32
		mbs_file = wcs_to_utf8(file);
		mbs_item_path = wcs_to_utf8(item_path);
		if (!mbs_file || !mbs_item_path)
		{
			if (mbs_file) gf_free(mbs_file);
			if (mbs_item_path) gf_free(mbs_item_path);
			return GF_IO_ERR;
		}
		if (enum_dir_fct(cbck, mbs_file, mbs_item_path, &file_info)) {
			BOOL ret = FindClose(SearchH);
			if (!ret) {
				DWORD err = GetLastError();
				GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] FindClose() in gf_enum_directory() returned(1) the following error code: %d\n", err));
			}
#else
		if (enum_dir_fct(cbck, file, item_path, &file_info)) {
#endif
			break;
		}

#ifdef WIN32
		gf_free(mbs_file);
		gf_free(mbs_item_path);
#endif

next:
#ifdef WIN32
		if (!FindNextFileW(SearchH, &FindData)) {
			BOOL ret = FindClose(SearchH);
			if (!ret) {
				DWORD err = GetLastError();
				GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] FindClose() in gf_enum_directory() returned(2) the following error code: %d\n", err));
			}
			break;
		}
#else
		the_file = readdir(the_dir);
#endif
	}
#ifndef WIN32
	closedir(the_dir);
#endif
	return GF_OK;
}

GF_EXPORT
u64 gf_ftell(FILE *fp)
{
#if defined(_WIN32_WCE)
	return (u64) ftell(fp);
#elif defined(GPAC_CONFIG_WIN32) && !defined(__CYGWIN__)	/* mingw or cygwin */
#if (_FILE_OFFSET_BITS >= 64)
	return (u64) ftello64(fp);
#else
	return (u64) ftell(fp);
#endif
#elif defined(WIN32)
	return (u64) _ftelli64(fp);
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	return (u64) ftello64(fp);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	return (u64) ftello(fp);
#else
	return (u64) ftell(fp);
#endif
}

GF_EXPORT
u64 gf_fseek(FILE *fp, s64 offset, s32 whence)
{
#if defined(_WIN32_WCE)
	return (u64) fseek(fp, (s32) offset, whence);
#elif defined(GPAC_CONFIG_WIN32) && !defined(__CYGWIN__)	/* mingw or cygwin */
#if (_FILE_OFFSET_BITS >= 64)
	return (u64) fseeko64(fp, offset, whence);
#else
	return (u64) fseek(fp, (s32) offset, whence);
#endif
#elif defined(WIN32)
	return (u64) _fseeki64(fp, offset, whence);
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	return fseeko64(fp, (off64_t) offset, whence);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	return fseeko(fp, (off_t) offset, whence);
#else
	return fseek(fp, (s32) offset, whence);
#endif
}

GF_EXPORT
FILE *gf_fopen(const char *file_name, const char *mode)
{
	FILE *res = NULL;

#if defined(WIN32)
	wchar_t *wname;
	wchar_t *wmode;

	wname = utf8_to_wcs(file_name);
	wmode = utf8_to_wcs(mode);
	if (!wname || !wmode)
	{
		if (wname) gf_free(wname);
		if (wmode) gf_free(wmode);
		return NULL;
	}
	res = _wfsopen(wname, wmode, _SH_DENYNO);
	gf_free(wname);
	gf_free(wmode);
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	res = fopen64(file_name, mode);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	res = fopen(file_name, mode);
#else
	res = fopen(file_name, mode);
#endif

	if (res) {
		gpac_file_handles++;
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] file %s opened in mode %s - %d file handles\n", file_name, mode, gpac_file_handles));
	} else {
		if (strchr(mode, 'w') || strchr(mode, 'a')) {
#if defined(WIN32)
			u32 err = GetLastError();
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] system failure for file opening of %s in mode %s: 0x%08x\n", file_name, mode, err));
#else
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] system failure for file opening of %s in mode %s: %d\n", file_name, mode, errno));
#endif
		}
	}
	return res;
}

GF_EXPORT
s32 gf_fclose(FILE *file)
{
	if (file) {
		assert(gpac_file_handles);
		gpac_file_handles--;
	}
	return fclose(file);
}

#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! defined(_GNU_SOURCE) && !defined(WIN32)
#define HAVE_STRERROR_R 1
#endif

GF_EXPORT
size_t gf_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
	return fread(ptr, size, nmemb, stream);
}

GF_EXPORT
size_t gf_fwrite(const void *ptr, size_t size, size_t nmemb,
                 FILE *stream)
{
	size_t result = fwrite(ptr, size, nmemb, stream);
	if (result != nmemb) {
#ifdef _WIN32_WCE
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Error writing data: %d blocks to write but %d blocks written\n", nmemb, result));
#else
#if defined WIN32 && !defined(GPAC_CONFIG_WIN32)
		errno_t errno_save;
		_get_errno(&errno_save);
#else
		int errno_save = errno;
#endif
		//if (errno_save!=0)
		{
#ifdef HAVE_STRERROR_R
#define ERRSTR_BUF_SIZE 256
			char errstr[ERRSTR_BUF_SIZE];
			if(strerror_r(errno_save, errstr, ERRSTR_BUF_SIZE) != 0)
			{
				strerror_r(0, errstr, ERRSTR_BUF_SIZE);
			}
#else
			char *errstr = (char*)strerror(errno_save);
#endif
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Error writing data (%s): %d blocks to write but %d blocks written\n", errstr, nmemb, result));
		}
#endif
	}
	return result;
}
Example #8
0
/*enumerate directories*/
GF_EXPORT
GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item enum_dir_fct, void *cbck, const char *filter)
{
	char item_path[GF_MAX_PATH];
	GF_FileEnumInfo file_info;

#if defined(_WIN32_WCE)
	char _path[GF_MAX_PATH];
	unsigned short path[GF_MAX_PATH];
	unsigned short w_filter[GF_MAX_PATH];
	char file[GF_MAX_PATH];
#else
	char path[GF_MAX_PATH], *file;
#endif

#ifdef WIN32
	WIN32_FIND_DATA FindData;
	HANDLE SearchH;
#else
	DIR *the_dir;
	struct dirent* the_file;
	struct stat st;
#endif

	if (!dir || !enum_dir_fct) return GF_BAD_PARAM;

	if (filter && (!strcmp(filter, "*") || !filter[0])) filter=NULL;

	memset(&file_info, 0, sizeof(GF_FileEnumInfo) );

	if (!strcmp(dir, "/")) {
#if defined(WIN32) && !defined(_WIN32_WCE)
		u32 len;
		char *drives, *volume;
		len = GetLogicalDriveStrings(0, NULL);
		drives = (char*)gf_malloc(sizeof(char)*(len+1));
		drives[0]=0;
		GetLogicalDriveStrings(len, drives);
		len = (u32) strlen(drives);
		volume = drives;
		file_info.directory = GF_TRUE;
		file_info.drive = GF_TRUE;
		while (len) {
			enum_dir_fct(cbck, volume, "", &file_info);
			volume += len+1;
			len = (u32) strlen(volume);
		}
		gf_free(drives);
		return GF_OK;
#elif defined(__SYMBIAN32__)
		RFs iFs;
		TDriveList aList;
		iFs.Connect();
		iFs.DriveList(aList);
		for (TInt i=0; i<KMaxDrives; i++) {
			if (aList[i]) {
				char szDrive[10];
				TChar aDrive;
				iFs.DriveToChar(i, aDrive);
				sprintf(szDrive, "%c:", (TUint)aDrive);
				enum_dir_fct(cbck, szDrive, "", &file_info);
			}
		}
		iFs.Close();
		FlushItemList();
		return GF_OK;
#endif
	}


#if defined (_WIN32_WCE)
	switch (dir[strlen(dir) - 1]) {
	case '/':
	case '\\':
		sprintf(_path, "%s*", dir);
		break;
	default:
		sprintf(_path, "%s%c*", dir, GF_PATH_SEPARATOR);
		break;
	}
	CE_CharToWide(_path, path);
	CE_CharToWide((char *)filter, w_filter);
#elif defined(WIN32)
	switch (dir[strlen(dir) - 1]) {
	case '/':
	case '\\':
		sprintf(path, "%s*", dir);
		break;
	default:
		sprintf(path, "%s%c*", dir, GF_PATH_SEPARATOR);
		break;
	}
#else
	strcpy(path, dir);
	if (path[strlen(path)-1] != '/') strcat(path, "/");
#endif

#ifdef WIN32
	SearchH= FindFirstFile(path, &FindData);
	if (SearchH == INVALID_HANDLE_VALUE) return GF_IO_ERR;

#if defined (_WIN32_WCE)
	_path[strlen(_path)-1] = 0;
#else
	path[strlen(path)-1] = 0;
#endif

	while (SearchH != INVALID_HANDLE_VALUE) {

#else

	the_dir = opendir(path);
	if (the_dir == NULL) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot open directory %s for enumeration: %d\n", path, errno));
		return GF_IO_ERR;
	}
	the_file = readdir(the_dir);
	while (the_file) {

#endif

		memset(&file_info, 0, sizeof(GF_FileEnumInfo) );


#if defined (_WIN32_WCE)
		if (!wcscmp(FindData.cFileName, _T(".") )) goto next;
		if (!wcscmp(FindData.cFileName, _T("..") )) goto next;
#elif defined(WIN32)
		if (!strcmp(FindData.cFileName, ".")) goto next;
		if (!strcmp(FindData.cFileName, "..")) goto next;
#else
		if (!strcmp(the_file->d_name, "..")) goto next;
		if (the_file->d_name[0] == '.') goto next;
#endif

#ifdef WIN32
		file_info.directory = (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? GF_TRUE : GF_FALSE;
		if (!enum_directory && file_info.directory) goto next;
		if (enum_directory && !file_info.directory) goto next;
#endif

		if (filter) {
#if defined (_WIN32_WCE)
			short ext[30];
			short *sep = wcsrchr(FindData.cFileName, (wchar_t) '.');
			if (!sep) goto next;
			wcscpy(ext, sep+1);
			wcslwr(ext);
			if (!wcsstr(w_filter, ext)) goto next;
#elif defined(WIN32)
			char ext[30];
			char *sep = strrchr(FindData.cFileName, '.');
			if (!sep) goto next;
			strcpy(ext, sep+1);
			strlwr(ext);
			if (!strstr(filter, ext)) goto next;
#else
			char ext[30];
			char *sep = strrchr(the_file->d_name, '.');
			if (!sep) goto next;
			strcpy(ext, sep+1);
			strlwr(ext);
			if (!strstr(filter, sep+1)) goto next;
#endif
		}

#if defined(WIN32)
		file_info.hidden = (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? GF_TRUE : GF_FALSE;
		file_info.system = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? GF_TRUE : GF_FALSE;
		file_info.size = MAXDWORD;
		file_info.size += 1;
		file_info.size *= FindData.nFileSizeHigh;
		file_info.size += FindData.nFileSizeLow;
		file_info.last_modified = (u64) ((*(LONGLONG *) &FindData.ftLastWriteTime - TIMESPEC_TO_FILETIME_OFFSET) / 10000000);
#endif

#if defined (_WIN32_WCE)
		CE_WideToChar(FindData.cFileName, file);
		strcpy(item_path, _path);
		strcat(item_path, file);
#elif defined(WIN32)
		strcpy(item_path, path);
		strcat(item_path, FindData.cFileName);
		file = FindData.cFileName;
#else
		strcpy(item_path, path);
		strcat(item_path, the_file->d_name);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Checking file %s for enum\n", item_path));

		if (stat( item_path, &st ) != 0) goto next;

		file_info.directory = ((st.st_mode & S_IFMT) == S_IFDIR) ? GF_TRUE : GF_FALSE;
		if (enum_directory && !file_info.directory) goto next;
		if (!enum_directory && file_info.directory) goto next;

		file_info.size = st.st_size;

		{
			struct tm _t = * gmtime(& st.st_mtime);
			file_info.last_modified = mktime(&_t);
		}
		file = the_file->d_name;
		if (file && file[0]=='.') file_info.hidden = 1;

		if (file_info.directory) {
			char * parent_name = strrchr(item_path, '/');
			if (!parent_name) {
				file_info.drive = GF_TRUE;
			} else {
				struct stat st_parent;
				parent_name[0] = 0;
				if (stat(item_path, &st_parent) == 0)  {
					if ((st.st_dev != st_parent.st_dev) || ((st.st_dev == st_parent.st_dev) && (st.st_ino == st_parent.st_ino))) {
						file_info.drive = GF_TRUE;
					}
				}
				parent_name[0] = '/';
			}
		}
#endif
		if (enum_dir_fct(cbck, file, item_path, &file_info)) {
#ifdef WIN32
			BOOL ret = FindClose(SearchH);
			if (!ret) {
				DWORD err = GetLastError();
				GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] FindClose() in gf_enum_directory() returned(1) the following error code: %d\n", err));
			}
#endif
			break;
		}

next:
#ifdef WIN32
		if (!FindNextFile(SearchH, &FindData)) {
			BOOL ret = FindClose(SearchH);
			if (!ret) {
				DWORD err = GetLastError();
				GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] FindClose() in gf_enum_directory() returned(2) the following error code: %d\n", err));
			}
			break;
		}
#else
		the_file = readdir(the_dir);
#endif
	}
#ifndef WIN32
	closedir(the_dir);
#endif
	return GF_OK;
}

GF_EXPORT
u64 gf_ftell(FILE *fp)
{
#if defined(_WIN32_WCE)
	return (u64) ftell(fp);
#elif defined(GPAC_CONFIG_WIN32)	/* mingw or cygwin */
#if (_FILE_OFFSET_BITS >= 64)
	return (u64) ftello64(fp);
#else
	return (u64) ftell(fp);
#endif
#elif defined(WIN32)
	return (u64) _ftelli64(fp);
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	return (u64) ftello64(fp);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	return (u64) ftello(fp);
#else
	return (u64) ftell(fp);
#endif
}

GF_EXPORT
u64 gf_fseek(FILE *fp, s64 offset, s32 whence)
{
#if defined(_WIN32_WCE)
	return (u64) fseek(fp, (s32) offset, whence);
#elif defined(GPAC_CONFIG_WIN32)	/* mingw or cygwin */
#if (_FILE_OFFSET_BITS >= 64)
	return (u64) fseeko64(fp, offset, whence);
#else
	return (u64) fseek(fp, (s32) offset, whence);
#endif
#elif defined(WIN32)
	return (u64) _fseeki64(fp, offset, whence);
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	return fseeko64(fp, (off64_t) offset, whence);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	return fseeko(fp, (off_t) offset, whence);
#else
	return fseek(fp, (s32) offset, whence);
#endif
}

GF_EXPORT
FILE *gf_fopen(const char *file_name, const char *mode)
{
	FILE *res = NULL;

#if defined(WIN32)
	Bool is_create;
	is_create = (strchr(mode, 'w') == NULL) ? GF_FALSE : GF_TRUE;
	if (!is_create) {
		if (strchr(mode, 'a')) {
			res = fopen(file_name, "rb");
			if (res) {
				fclose(res);
				res = fopen(file_name, mode);
			}
		} else {
			res = fopen(file_name, mode);
		}
	}
	if (!res) {
		const char *str_src;
		wchar_t *wname;
		wchar_t *wmode;
		size_t len;
		size_t len_res;
		if (!is_create) {
			GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Could not open file %s mode %s in UTF-8 mode, trying UTF-16\n", file_name, mode));
		}
		len = (strlen(file_name) + 1)*sizeof(wchar_t);
		wname = (wchar_t *)gf_malloc(len);
		str_src = file_name;
		len_res = gf_utf8_mbstowcs(wname, len, &str_src);
		if (len_res == -1) {
			return NULL;
		}
		len = (strlen(mode) + 1)*sizeof(wchar_t);
		wmode = (wchar_t *)gf_malloc(len);
		str_src = mode;
		len_res = gf_utf8_mbstowcs(wmode, len, &str_src);
		if (len_res == -1) {
			return NULL;
		}

		res = _wfsopen(wname, wmode, _SH_DENYNO);
		gf_free(wname);
		gf_free(wmode);
	}
#elif defined(GPAC_CONFIG_LINUX) && !defined(GPAC_ANDROID)
	res = fopen64(file_name, mode);
#elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN))
	res = fopen(file_name, mode);
#else
	res = fopen(file_name, mode);
#endif

	if (res) {
		gpac_file_handles++;
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] file %s opened in mode %s - %d file handles\n", file_name, mode, gpac_file_handles));
	} else {
		if (strchr(mode, 'w') || strchr(mode, 'a')) {
#if defined(WIN32)
			u32 err = GetLastError();
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] system failure for file opening of %s in mode %s: 0x%08x\n", file_name, mode, err));
#else
			GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] system failure for file opening of %s in mode %s: %d\n", file_name, mode, errno));
#endif
		}
	}
	return res;
}
Example #9
0
//GPAC player Event Handler. not yet implemented, just dummies here
Bool CGPAXPlugin::EventProc(GF_Event *evt)
{
	char msg[1024];
	if (!m_term) return 0;

    switch (evt->type) {
	case GF_EVENT_MESSAGE:
		if (evt->message.error) {
			sprintf(msg, "(GPAC) %s (%s)", evt->message.message, gf_error_to_string(evt->message.error));
		} else {
			sprintf(msg, "(GPAC) %s", evt->message.message);
		}
		SetStatusText(msg);
        break;
	case GF_EVENT_PROGRESS:
		if (evt->progress.done == evt->progress.total) {
			SetStatusText(NULL);
			m_iDownload_progress = 100;
		} else {
			char *szTitle = "";
			if (evt->progress.progress_type==0) szTitle = "Buffer ";
			else 
			if (evt->progress.progress_type==1) 
			{
				szTitle = "Download ";
				m_iDownload_progress = (int)floor((100.0*evt->progress.done) / evt->progress.total);
			}
			else if (evt->progress.progress_type==2) szTitle = "Import ";
			sprintf(msg, "(GPAC) %s: %02.2f", szTitle, (100.0*evt->progress.done) / evt->progress.total);
			SetStatusText(msg);
		}
		break;
    case GF_EVENT_CONNECT:
        m_bIsConnected = evt->connect.is_connected;
        break;
	/*IGNORE any scene size, just work with the size allocated in the parent doc*/
	case GF_EVENT_SCENE_SIZE:
        gf_term_set_size(m_term, m_width, m_height);
        break;
	/*window has been resized (full-screen plugin), resize*/
	case GF_EVENT_SIZE:
		m_width = evt->size.width;
		m_height = evt->size.height;
        gf_term_set_size(m_term, m_width, m_height);
        break;
	case GF_EVENT_DBLCLICK:
		gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN));
		break;
	case GF_EVENT_KEYDOWN:
		if ((evt->key.flags  & GF_KEY_MOD_ALT)) {
	    } else {
			switch (evt->key.key_code) {
			case GF_KEY_HOME:
				gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 1);
				break;
			case GF_KEY_ESCAPE:
				gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN));
				break;
			}
		}
	    break;
	case GF_EVENT_NAVIGATE_INFO:
		strcpy(msg, evt->navigate.to_url);
		SetStatusText(msg);
		break;
	case GF_EVENT_NAVIGATE:
		if (gf_term_is_supported_url(m_term, evt->navigate.to_url, 1, 1)) {
			gf_term_navigate_to(m_term, evt->navigate.to_url);
			return 1;
		} 
#ifndef _WIN32_WCE
		else if (m_pBrowser) {
			u32 i;
			const char **sz_ptr;
			u16 w_szTar[1024], w_szURL[1024];
			VARIANT target, flags;
			flags.intVal = 0;
			target.bstrVal = L"_SELF";

			for (i=0; i<evt->navigate.param_count; i++) {
				if (!strcmp(evt->navigate.parameters[i], "_parent")) target.bstrVal = L"_PARENT";
				else if (!strcmp(evt->navigate.parameters[i], "_blank")) target.bstrVal = L"_BLANK";
				else if (!strcmp(evt->navigate.parameters[i], "_top")) target.bstrVal = L"_TOP";
				else if (!strcmp(evt->navigate.parameters[i], "_new")) flags.intVal |= navOpenInNewWindow;
				else if (!strnicmp(evt->navigate.parameters[i], "_target=", 8)) {
					sz_ptr = & evt->navigate.parameters[i]+8;
					gf_utf8_mbstowcs(w_szTar, 1024, (const char **)sz_ptr);
					target.bstrVal = (BSTR) w_szTar;
				}
			}
			sz_ptr = & evt->navigate.to_url;
			gf_utf8_mbstowcs(w_szURL, 1024, (const char **)sz_ptr);
			m_pBrowser->Navigate((BSTR) w_szURL, &flags, &target, NULL, NULL);;
			return 1;
		}
#endif
		break;
    }
    return 0;
}
Example #10
0
/*translate string to glyph sequence*/
static GF_Err svg_font_get_glyphs(void *udta, const char *utf_string, u32 *glyph_buffer, u32 *io_glyph_buffer_size, const char *lang, Bool *is_rtl)
{
	u32 prev_c;
	u32 len;
	u32 i, gl_idx;
	u16 *utf_res;
	GF_Node *node = (GF_Node *)udta;
	GF_ChildNodeItem *child;
	char *utf8 = (char*) utf_string;

	/*FIXME - use glyphs unicode attributes for glyph substitution*/
	len = utf_string ? strlen(utf_string) : 0;
	if (!len) {
		*io_glyph_buffer_size = 0;
		return GF_OK;
	}

	if (*io_glyph_buffer_size < len+1) {
		*io_glyph_buffer_size = len+1;
		return GF_BUFFER_TOO_SMALL;
	}

	len = gf_utf8_mbstowcs((u16*) glyph_buffer, *io_glyph_buffer_size, (const char**)&utf8);
	if ((s32) len < 0) return GF_IO_ERR;
	/*should not happen*/
	if (utf8) return GF_IO_ERR;

	/*perform bidi relayout*/
	utf_res = (u16 *) glyph_buffer;
	*is_rtl = gf_utf8_reorder_bidi(utf_res, len);

	/*move 16bit buffer to 32bit*/
	for (i=len; i>0; i--) {
		glyph_buffer[i-1] = utf_res[i-1];
	}

	gl_idx = 0;
	prev_c = 0;
	for (i=0;i<len; i++) {
		SVG_GlyphStack *missing_glyph = NULL;
		SVG_GlyphStack *st = NULL;
		child = ((GF_ParentNode *) node)->children;
		while (child) {
			u32 tag = gf_node_get_tag(child->node);
			if (tag==TAG_SVG_missing_glyph) {
				missing_glyph = gf_node_get_private(child->node);
			} else if (tag ==TAG_SVG_glyph) {
				Bool glyph_ok = 0;
				SVGAllAttributes atts;
				
				st = gf_node_get_private(child->node);
				if (!st) {
					child = child->next;
					continue;
				}

				if (st->glyph.utf_name==glyph_buffer[i]) {
					u32 j, count;
					gf_svg_flatten_attributes((SVG_Element*)child->node, &atts);
					if (!lang) {
						glyph_ok = 1;
					} else {
						if (!atts.lang) {
							glyph_ok = 1;
						} else {
							count = gf_list_count(*atts.lang);
							for (j=0; j<count; j++) {
								char *name = gf_list_get(*atts.lang, j);
								if (!stricmp(name, lang) || strstr(lang, name)) {
									glyph_ok = 1;
									break;
								}
							}
						}
					}
					if (atts.arabic_form) {
						Bool first = (!prev_c || (prev_c==' ')) ? 1 : 0;
						Bool last = ((i+1==len) || (glyph_buffer[i+1]==' ') ) ? 1 : 0;
						if (!strcmp(*atts.arabic_form, "isolated")) {
							if (!first || !last) glyph_ok = 0;
						}
						if (!strcmp(*atts.arabic_form, "initial")) {
							if (!first) glyph_ok = 0;
						}
						if (!strcmp(*atts.arabic_form, "medial")) {
							if (first || last) glyph_ok = 0;
						}
						if (!strcmp(*atts.arabic_form, "terminal")) {
							if (!last) glyph_ok = 0;
						}
					}
					if (glyph_ok) break;
				}
				/*perform glyph substitution*/
				else if (st->uni_len>1) {
					u32 j;
					for (j=0; j<st->uni_len; j++) {
						if (i+j>=len) break;
						if (glyph_buffer[i+j] != st->unicode[j]) break;
					}
					if (j==st->uni_len)
						break;
				}
				st = NULL;
			}
			child = child->next;
		}
		prev_c = glyph_buffer[i];

		if (!st) 
			st = missing_glyph;
		glyph_buffer[gl_idx] = st ? st->glyph.ID : 0;
		if (st && st->uni_len>1) i++;
		
		gl_idx++;
	}
	*io_glyph_buffer_size = len = gl_idx;
	
	return GF_OK;
}
Example #11
0
void compositor_init_svg_glyph(GF_Compositor *compositor, GF_Node *node)
{
	u16 utf_name[20];
	u8 *utf8;
	u32 len;
	GF_Rect rc;
	GF_Glyph *glyph;
	GF_Font *font;
	SVG_GlyphStack *st;
	SVGAllAttributes atts;
	GF_Node *node_font = gf_node_get_parent(node, 0);

	/*locate the font node*/
	if (node_font) node_font = gf_node_get_parent(node, 0);
	if (!node_font || (gf_node_get_tag(node_font)!=TAG_SVG_font) ) return;
	font = gf_node_get_private(node_font);
	if (!font) return;

	gf_svg_flatten_attributes((SVG_Element*)node, &atts);

	if (gf_node_get_tag(node)==TAG_SVG_missing_glyph) {
		GF_SAFEALLOC(st, SVG_GlyphStack);
		goto reg_common;
	}
	/*we must have unicode specified*/
	if (!atts.unicode) return;

	GF_SAFEALLOC(st, SVG_GlyphStack);
	utf8 = (u8 *) *atts.unicode;
	len = gf_utf8_mbstowcs(utf_name, 200, (const char **) &utf8);
	/*this is a single glyph*/
	if (len==1) {
		st->glyph.utf_name = utf_name[0];
		st->uni_len = 1;
	} else {
		st->glyph.utf_name = (u32) (PTR_TO_U_CAST st);
		st->unicode = gf_malloc(sizeof(u16)*len);
		st->uni_len = len;
		memcpy(st->unicode, utf_name, sizeof(u16)*len);
	}

reg_common:
	st->glyph.ID = (u32) (PTR_TO_U_CAST st);
	st->font = font;
	st->glyph.horiz_advance = font->max_advance_h;
	if (atts.horiz_adv_x) st->glyph.horiz_advance = FIX2INT( gf_ceil(atts.horiz_adv_x->value) );
	if (atts.d) {
		st->glyph.path = atts.d;
		gf_path_get_bounds(atts.d, &rc);
		st->glyph.width = FIX2INT( gf_ceil(rc.width) );
		st->glyph.height = FIX2INT( gf_ceil(rc.height) );
	}
	st->glyph.vert_advance = st->glyph.height;
	if (!st->glyph.vert_advance) 
		st->glyph.vert_advance = font->max_advance_v;

	/*register glyph*/
	if (!font->glyph) {
		font->glyph = &st->glyph;
	} else {
		glyph = font->glyph;
		while (glyph->next) glyph = glyph->next;
		glyph->next = &st->glyph;
	}

	gf_node_set_private(node, st);
	gf_node_set_callback_function(node, svg_traverse_glyph);
}
Example #12
0
static GF_Err IS_AttachStream(GF_BaseDecoder *plug, 
									 u16 ES_ID, 
									 char *decSpecInfo, 
									 u32 decSpecInfoSize, 
									 u16 DependsOnES_ID,
									 u32 objectTypeIndication, 
									 Bool Upstream)
{
	GF_BitStream *bs;
	u32 len, size, i;
	char devName[255];
	u16 termSeq[20];

	ISPriv *is = (ISPriv *)plug->privateStack;
	if (Upstream) return GF_NOT_SUPPORTED;
	if (!decSpecInfo) return GF_NON_COMPLIANT_BITSTREAM;

	/*no more than one UI stream per object*/
	if (is->ES_ID) return GF_NOT_SUPPORTED;
	is->ES_ID = ES_ID;
	/*parse config*/
	bs = gf_bs_new(decSpecInfo, decSpecInfoSize, GF_BITSTREAM_READ);
	len = gf_bs_read_int(bs, 8);
	for (i=0; i<len; i++) {
		devName[i] = gf_bs_read_int(bs, 8);
	}
	devName[i] = 0;
	size = len + 1;

	is->type = 0;
	if (!stricmp(devName, "KeySensor")) {
		is->type = IS_KeySensor;
		add_field(is, GF_SG_VRML_SFINT32, "keyPressed");
		add_field(is, GF_SG_VRML_SFINT32, "keyReleased");
		add_field(is, GF_SG_VRML_SFINT32, "actionKeyPressed");
		add_field(is, GF_SG_VRML_SFINT32, "actionKeyReleased");
		add_field(is, GF_SG_VRML_SFBOOL, "shiftKeyPressed");
		add_field(is, GF_SG_VRML_SFBOOL, "controlKeyPressed");
		add_field(is, GF_SG_VRML_SFBOOL, "altKeyPressed");

	} else if (!stricmp(devName, "StringSensor")) {
		is->type = IS_StringSensor;
		add_field(is, GF_SG_VRML_SFSTRING, "enteredText");
		add_field(is, GF_SG_VRML_SFSTRING, "finalText");

		is->termChar = '\r';
		is->delChar = '\b';

		/*get escape chars if any specified*/
		if (size<decSpecInfoSize) {
			const char *src = decSpecInfo + size;
			gf_utf8_mbstowcs(termSeq, decSpecInfoSize - size, &src);
			is->termChar = termSeq[0];
			is->delChar = termSeq[1];
		}
	} else if (!stricmp(devName, "Mouse")) {
		is->type = IS_Mouse;
		add_field(is, GF_SG_VRML_SFVEC2F, "position");
		add_field(is, GF_SG_VRML_SFBOOL, "leftButtonDown");
		add_field(is, GF_SG_VRML_SFBOOL, "middleButtonDown");
		add_field(is, GF_SG_VRML_SFBOOL, "rightButtonDown");
		add_field(is, GF_SG_VRML_SFFLOAT, "wheel");

#if GPAC_HTK_DEMO
	} else if (!stricmp(devName, "HTKSensor")) {
		FILE *f;
		u32 nb_word, nbPhone, c, j;
		char szPh[3];
		char szName[1024];
		char *szPath = gf_cfg_get_key(is->scene->root_od->term->user->config, "HTK", "HTKDirectory");
		if (!szPath) szPath = gf_cfg_get_key(is->scene->root_od->term->user->config, "General", "ModulesDirectory");
		strcpy(is->szHTKPath, szPath);
		if (szPath[strlen(szPath)-1] != GF_PATH_SEPARATOR) is->szHTKPath[strlen(szPath)] = GF_PATH_SEPARATOR;

		add_field(is, GF_SG_VRML_SFSTRING, "word");
		add_field(is, GF_SG_VRML_SFINT32, "wordIndex");
		add_field(is, GF_SG_VRML_SFFLOAT, "wordScore");
	
		if (!htk_num_users) {
			HTK_Init(is->szHTKPath);
			htk_num_users++;
		}
		
		sprintf(szName, "HTKD_%d", (u32) is);
		strcat(is->szHTKPath, szName);

		f = fopen(is->szHTKPath, "wt");
		szPh[2] = 0;
		nb_word = gf_bs_read_int(bs, 8);
		for (i=0; i<nb_word; i++) {
			nbPhone = gf_bs_read_int(bs, 8);
			while ((c=gf_bs_read_int(bs, 8))) fprintf(f, "%c", c);
			fprintf(f, " ");
			for (j=0; j<nbPhone; j++) {
				gf_bs_read_data(bs, szPh, 2);
				if (j) fprintf(f, " ");
				if (!stricmp(szPh, "vc")) fprintf(f, "vcl");
				else fprintf(f, "%s", szPh);
			}
			fprintf(f, "\n");
		}
		fprintf(f, "RIEN sp\nSENT-END [] endsil\nSENT-START [] inisil\n");
		fclose(f);
		is->type = IS_HTKSensor;

		StartHTK(is);
#endif
	
	}
	gf_bs_del(bs);
	return GF_OK;
}