How to share files between js and wasm c/c++? - filesystems

I'm unable to share file between js and wasm c/c++.
JS code is the following.
let filename = "testFile.dat";
FS.writeFile(filename, data);
// Call WebAssembly/C++ to process the file
console.log(FS.readdir("/"));
console.log(api.processFile(filename));
c/c++ code is the following
string
processFile (string filename)
{
for (const auto &entry : fs::directory_iterator (fs::current_path()))
std::cout << entry.path () << std::endl;
std::fstream fs;
fs.open (filename, std::fstream::in | std::fstream::binary);
if (fs)
{
fs.close ();
return "File '" + filename + "' exists!";
}
else
{
return "File '" + filename + "' does NOT exist!";
}
}
Also the filesystem entries differs too
JS
[
".",
"..",
"tmp",
"home",
"dev",
"proc",
"usr",
"testFile.dat"
]
c/c++
"/tmp", "/home", "/dev", "/proc"

Related

java.io.File's .createNewFile() doesn't create a file

class FileClassOne {
public static void main(String args[]) {
File myDir = new File(File.separator);
System.out.println("myDir.getAbsolutePath() = " + myDir.getAbsolutePath());
System.out.println("myDir.isDirectory() = " + myDir.isDirectory());
System.out.println("myDir.isFile() = " + myDir.isFile());
System.out.println();
myDir = new File(File.separator+"Java"+File.separator+"FilePartOne");
System.out.println("myDir.getAbsolutePath() = " + myDir.getAbsolutePath());
System.out.println("myDir.isDirectory() = " + myDir.isDirectory());
System.out.println("myDir.isFile() = " + myDir.isFile());
System.out.println();
File myFile = new File(myDir, "Temp.txt");
System.out.println("myFile.getAbsolutePath() = " + myFile.getAbsolutePath());
System.out.println("myFile.isDirectory() = " + myFile.isDirectory());
System.out.println("myFile.isFile() = " + myFile.isFile());
System.out.println("myFile.exists() = " + myFile.exists());
try {
myFile.createNewFile();
} catch (IOException e) {
System.out.println(e.getMessage());
}
Output:
myDir.getAbsolutePath() = C:\
myDir.isDirectory() = true
myDir.isFile() = false
myDir.getAbsolutePath() = C:\Java\FilePartOne
myDir.isDirectory() = false
myDir.isFile() = false
myFile.getAbsolutePath() = C:\Java\FilePartOne\Temp.txt
myFile.isDirectory() = false
myFile.isFile() = false
myFile.exists() = false
The system cannot find the path specified
This code if from an online tutorial that works in the video and it's copied verbatim. IDE is eclipse.
I would say its likely because of missing directories along the path "C:\Java\FilePartOne".
The statement:
myFile.createNewFile();
Will attempt to create a file on a given path, not create any missing directories. You therefore get the error "The system cannot find the path specified" if any directories are missing when executing the statement.
A quick way to fix this would be to either create the missing folders yourself or add the code below just before myFile.createNewFile();.
myFile.getParentFile().mkdirs();

Log to file with gradle 4

Until gradle 3, I used this to write gradle's output to a logfile:
def fileLogger = [
onOutput : {
File logfile = new File( 'gradle.log' )
logfile << it
}
] as org.gradle.api.logging.StandardOutputListener
gradle.useLogger( fileLogger )
This does not work with with gradle 4.
Update for Gradle 5:
It works when using logging.addStandardOutputListener instead gradle.useLogger and adding it to all tasks:
// logger
def fileLogger = [
onOutput: {
File logfile = new File('gradle.log')
logfile << it
}
] as org.gradle.api.logging.StandardOutputListener
// for configuration phase
logging.addStandardOutputListener(fileLogger)
// for execution phase
gradle.taskGraph.whenReady { taskGraph ->
taskGraph.allTasks.each { Task t ->
t.doFirst {
logging.addStandardOutputListener(fileLogger)
}
}
}

Using "shared logic" across multiple Typewriter templates?

We have multiple Typewriter .tst templates in our project, and would like to share some common logic/methods between them. Is there a way to do this?
You can use T4 templates to generate the Typewriter templates. Put the code inside a reusable T4 template (*.ttinclude) and create tt-files to pass parameters to the rendering method of this base template.
(I use a Visual Studio extension for File nesting.)
Each tt-file looks something like this;
<## template debug="true" hostSpecific="true" #>
<## output extension=".tst" #>
<## include file="..\ModelsTemplate.ttinclude" #>
<# this.ModelsTemplate_Render("UserSettings"); #>
...and my ttinclude file looks like this (it is a bit project specific, but I included it all so that anyone who wants to try it out can easily get something working);
<## IntelliSenseLanguage processor="tangibleT4Editor" language="C#" #>
<#+
void ModelsTemplate_Render(string #subnamespace) {
ModelsTemplate_Render("MyApp.ViewData", #subnamespace);
}
void ModelsTemplate_Render(string #mainnamespace, string #subnamespace) {
string renderedMainNamespace = #mainnamespace;
#>
// <auto-generated>
// This code was generated by a tool.
// Template: <#= Host.TemplateFile #>
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
${
// Enable extension methods by adding using Typewriter.Extensions.*
using Typewriter.Extensions.Types;
using System.Text.RegularExpressions;
Template(Settings settings)
{
settings.IncludeProject("MyApp.ViewData");
}
static string DebugInfo = "";
string PrintDebugInfo(File f){
if (string.IsNullOrEmpty(DebugInfo)) {
return "";
}
return "/*" + Environment.NewLine + "Template debug info: " + DebugInfo + Environment.NewLine + "*/";
}
string BaseClassFullPath(Class baseClass)
{
//DebugInfo = DebugInfo + Environment.NewLine + "baseClass.FullName:" + baseClass.FullName;
var result = baseClass.Name;
// Until we find a better way to handle implementations of generic base classes...
result = result.Replace("<bool?>", "<boolean>");
result = result.Replace("<int?>", "<number>");
result = result.Replace("<long?>", "<number>");
result = result.Replace("<decimal?>", "<number>");
result = result.Replace("<double?>", "<number>");
result = result.Replace("<System.Double>", "<number>");
result = result.Replace("<System.Double?>", "<number>");
result = result.Replace("<System.DateTime?>", "<Date>");
return result;
}
string NullableFilter(string typeName)
{
return typeName.Replace("?", "");
}
string TypeFilteredPath(Type type)
{
//DebugInfo = DebugInfo + Environment.NewLine + "type:" + type.FullName + " - genericType:" + type.Unwrap().FullName;
return NullableFilter(type.Name);
}
string TypeFiltered(Type type)
{
if (type.IsEnumerable)
{
var genericType = type.Unwrap();
if (!genericType.FullName.StartsWith("System"))
{
return TypeFilteredPath(genericType)+"[]";
}
}
return TypeFilteredPath(type);
}
string PropertyTypeFiltered(Property prop)
{
return TypeFiltered(prop.Type);
}
string ImplementedInterfaces(Class c){
if (!c.Interfaces.Any()){
return string.Empty;
}
return "implements " + string.Join(", ", c.Interfaces.Select(x => x.FullName));
}
string ExtendedInterfaces(Interface i){
if (!i.Interfaces.Any()){
return string.Empty;
}
return "extends " + string.Join(", ", i.Interfaces.Select(x => x.FullName));
}
string DescriptionAttributeValue(Attribute a){
if (!a.FullName.Contains("DescriptionAttribute")){
return string.Empty;
}
return a.Value;
}
string GetPropertyDefinitionWithScope(Property p){
var definition = GetPropertyDefinition(p);
if (definition != "")
return "public " + definition;
else
return definition;
}
string GetPropertyDefinition(Property p){
var ignoreAttribute = p.Attributes.SingleOrDefault(x => x.FullName.Contains("TypeScriptIgnoreMemberAttribute"));
if (ignoreAttribute != null)
return "";
var typeAttribute = p.Attributes.SingleOrDefault(x => x.FullName.Contains("TypeScriptTypeAttribute"));
if (typeAttribute != null) {
return p.name + ": " + typeAttribute.Value + ";";
}
return p.name + ": " + TypeFiltered(p.Type) + ";";
}
string WriteImports(Class theClass){
//return "import { ViewDataEntity } from '../common/ViewDataEntity';";
var list = new List<string>();
var typesToImport = theClass.Properties.Select(x => x.Type.Unwrap()).Where(x => x.Namespace.Contains("MyApp.ViewData.")).ToList();
if (theClass.BaseClass?.Namespace.Contains("MyApp.ViewData.") == true)
typesToImport.Add(theClass.BaseClass);
foreach (var impType in typesToImport)
{
var modules = impType.Namespace.Replace("MyApp.ViewData.", "").Split('.').ToList();
string modPart = string.Join("/", modules.Select(x => CamelCase(x)));
list.Add($"import {{ {impType.Name} }} from '../{modPart}/{impType.Name}';");
}
return string.Join(Environment.NewLine, list.Distinct());
}
string CamelCase(string value){
return value.First().ToString().ToLower() + value.Substring(1);
}
}//namespace <#= renderedMainNamespace #>.<#= #subnamespace #> {
$Classes(c => c.Namespace.StartsWith("<#= #mainnamespace #>.<#= #subnamespace #>"))[
$WriteImports
export class $Name$TypeParameters $BaseClass[extends $BaseClassFullPath ] $ImplementedInterfaces {$Properties[
$GetPropertyDefinitionWithScope]
}]
$Interfaces(<#= #mainnamespace #>.<#= #subnamespace #>.*)[
export interface $Name $ExtendedInterfaces {
$Properties[
$GetPropertyDefinition]
}]
$Enums(<#= #mainnamespace #>.<#= #subnamespace #>.*)[
export class $Name {
$Values[// $Value - "$Attributes[$Value]"
static $Name = "$Name";
]
}]
$PrintDebugInfo
//}<#+
}
#>
Unfortunately there's no way to share code in tst templates. Support for this will probably come in a future version though.

Write list of files into a js file using npm

I'd like to have a script for npm that did the following:
Gets a list of files inside a folder (and subfolders)
Write it into a JS file, with the following format:
module.exports = [
"folder/filename.png",
"folder/subfolder/filename.png"
];
I'm currently doing it like this using the cli in Linux:
echo 'module.exports = [' | tee files.js && find . -name "*png" | sed s:"./":" '": | sed s:".png":".png',": | tee files.js --append && echo '];' | tee files.js --append
Which is a bit contrived and not really cross platform. Are there any npm packages that provide similar functionality? I'm kinda lost on it.
Well don't I feel silly. Had never used node directly but it was trivial to write a script to do this.
#!/usr/bin/env node
var fs = require('fs');
var list = [];
function traverse(folder) {
var files = fs.readdirSync(folder);
for (var i = 0; i < files.length; i++) {
if (files[i].indexOf('.png') > -1 || files[i].indexOf('.jpg') > -1) {
list.push(folder + "/" + files[i]);
console.log(i + folder + "/" + files[i]);
} else {
var path = folder + "/" + files[i];
if (fs.lstatSync(path).isDirectory()) {
traverse(path);
}
}
}
}
function start() {
traverse('./images');
var string = "module.exports = [\n";
for (var i = 0; i < list.length; i++) {
string += " '" + list[i];
if (list[i] !== list[list.length - 1]) {
string += "',\n";
} else {
string += "'\n];"
}
}
fs.writeFile("./src/assets.js", string, function (err) {
if (err) {
return console.log(err);
}
console.log("Assets file was updated!");
});
}
start();

PhoneGap, File copy error: Code = 1,

file copy error, detail information:
2012-06-12 09:21:38.557 mead_debug[10314:fb03] [INFO] parent_entry := /Users/laiqinyi/Library/Application Support/iPhone Simulator/4.3.2/Applications/5EFBD6D1-66EB-4DEC-8AE7-D386729744E9/Documents/dest/
2012-06-12 09:22:34.640 mead_debug[10314:fb03] [INFO] upload error source undefined
2012-06-12 09:22:34.641 mead_debug[10314:fb03] [INFO] upload error target undefined
I follow the API instruction, and do not think there are some thing wrong with this "copyTo" code.
In addition, there are folder "Documents/dest" and file "Documents/readme.txt"
http://docs.phonegap.com/en/1.8.0/cordova_file_file.md.html#File
**var FileSystem = {
copy : function(src, dest){
var parentEntry = new DirectoryEntry({fullPath:("/dest")});
console.log("parent_entry := " + FileSystem.root_path+"/dest");
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", null, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.copyTo(parentEntry, "file.copy", function(e){console.log("copy okay");}, fail);
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
}**
copy : function(fromUrl, toPath, toName){
console.log("copyFile - From: [" + fromUrl + "] To: " + toPath + " Name: " + toName);
// Set up some storage
var destPath = '';
var destName = '';
doMoveFile(fromUrl);
// Called when file needs to be moved / after capture
function doMoveFile(fileUrl){
//console.log("doMoveFile - fileUrl: " + JSON.stringify(fileUrl));
// Remember the source file name just in case it was not passed so reuse it, and for logging
var destName = fileUrl.name;
var destPath = fileUrl;
// Resolve the file system
window.resolveLocalFileSystemURI(fileUrl,resFSSuccess, resFSError);
// Called upon successful File System resolution
function resFSSuccess(entry){
//console.log("resFSSuccess Success - entry: " + JSON.stringify(entry));
// Request a file system
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
requestFileSystemSuccess, requestFileSystemError);
// Called upon successful File System request
function requestFileSystemSuccess(fileSys){
// Get the source directory
fileSys.root.getDirectory(toPath, {create: true, exclusive:false}, getDestDirSuccess, getDestDirError);
// Called upon successful Get Of Destination Directory
function getDestDirSuccess(directory){
// Get the destination file name, set it if it is blank or not passed by the App
toName = (toName) ? toName : destName;
// Remember the full path name for the console log
fullDestPath = directory.fullPath + '/' + toName;
// Make the move
entry.copyTo(directory, toName, moveSuccess, moveError);
function moveSuccess(){
console.log("Successful copy of " + destPath + " to " + fullDestPath);
};
function moveError(error){
console.log("copyError code: " + JSON.stringify(error));
};
}
// Get Destination Dir Failure
function getDestDirError(error){
console.log("getDestDirError code: " + JSON.stringify(error));
};
}
// File System Request Failure
function requestFileSystemError(error){
console.log("requestFileSystemError code: " + JSON.stringify(error));
};
}
// Note File System failure
function resFSError(error){
console.log("resFSError code: " + JSON.stringify(error));
};
}
}

Resources