Skip to content

Implementing parts of stdlib in Haxe #1354

Description

@Aidan63

I've been playing around with the Win32 API with the new marshalling extern types and have been quite pleased with how painless and "just works" it's been. This got me thinking that it would be quite nice if we could write the implementation of stuff like the Sys, File, and FileSystem class in Haxe.

E.g. Here's two functions for the file system class.

class FileSystem {
	public static function exists(path:String):Bool {
		final count  = Utf16.getByteCount(path);
		final buffer = Scratch.alloc(count.toInt() + 2);

		if (count != Utf16.encode(path, buffer.view)) {
			throw new Exception("Failed to encode string to UTF16");
		}
		
		return Shell.pathFileExists(buffer.view.reinterpret().ptr);
	}
	
	public static function isDirectory(path:String):Bool {
		final count  = Utf16.getByteCount(path);
		final buffer = Scratch.alloc(count.toInt() + 2);

		if (count != Utf16.encode(path, buffer.view)) {
			throw new Exception("Failed to encode string to UTF16");
		}

		final result = FileApi.getFileAttributes(buffer.view.reinterpret().ptr);
		if (result == FileApi.invalidFileAttributes) {
			throw new Exception("Failed to get file attributes");
		}

		return (result & FileApi.fileAttributeDirectory) != 0;
	}
}

and one for the sys class

class Sys {
	public static function getEnv(v:String):String {
		final nameCount  = Utf16.getByteCount(v);
		final nameBuffer = Scratch.alloc(nameCount.toInt() + 2);

		if (nameCount != Utf16.encode(v, nameBuffer.view)) {
			throw new Exception("Failed to encode string to UTF16");
		}

		final envCount  = Win32.getEnvironmentVariable(nameBuffer.view.reinterpret().ptr, null, 0);
		final envBuffer = Scratch.alloc(envCount * 2);

		if (envCount != Win32.getEnvironmentVariable(nameBuffer.view.reinterpret().ptr, envBuffer.view.reinterpret().ptr, envCount)) {
			throw new Exception("Return value was not the expected size");
		}

		return Utf16.decode(envBuffer.view);
	}
}

Obviously this raises lots of questions, such as

  • The hxcpp build tool would probably need to build and cache shared platform specific obs which are linked with user code (e.g. hxcpp-file-win32.obj, hxcpp-sys-unix.obj).
  • Managing compatibility between haxe versions and std lib implementations in hxcpp could be tricky.
  • Many other things.

I have given these no thoughts yet so don't have any answers, I'm not even sure if it's really worth it in the end. But in general I'm in favour of less C++ and I think the new marshalling types gives us a nice path to have that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions