Just in case I decide to change the implementation some day.
The low level use of this would look like throw new WindowsApiException("MsgWaitForMultipleObjectsEx", GetLastError()) but it is meant to be used from higher level things like Win32Enforce.
An AbstractFile represents a file handle on the operating system level. You cannot do much with it.
Base class representing my exceptions. You should almost never work with this directly, but you might catch it as a generic thing. Catch it before generic object.Exception or object.Throwable in any catch chains.
Calls AcceptEx on Windows and emulates it on other systems.
Initiates a connection request and optionally sends initial data as soon as possible.
Only one operation can be pending at any time in the current implementation.
Represents a generic async, waitable request.
You can write to a file asynchronously by creating one of these.
A socket bound and ready to use receiveFrom
PARTIALLY IMPLEMENTED / NOT STABLE
UNSTABLE, NOT FULLY IMPLEMENTED. DO NOT USE YET.
Base class for when you've requested a feature that is not available. It may not be available because it is possible, but not yet implemented, or it might be because it is impossible on your operating system.
A named pipe ready to accept connections.
This means the feature is not supported by your current operating system. You might be able to get it in an update, but you might just have to find an alternate way of doing things.
This means the feature could be done, but I haven't gotten around to implementing it yet. If you email me, I might be able to add it somewhat quickly and get back to you.
A stream can be used by just one task at a time, but one task can consume multiple streams.
This starts up a local pipe. If it is already claimed, it just communicates with the existing one through the interface.
A set of sockets bound and ready to accept connections on worker threads.
A timer that will trigger your function on a given interval.
Represents a translatable string.
A class to help write a stream of binary data to some target.
Represents a translatable string.
The internal types that will be exposed through other api things.
Note that the order of items called for your delegate is undefined; if you want it sorted, you'll have to collect and sort yourself. But it *might* be sorted by the OS (on Windows, it almost always is), so consider that when choosing a sorting algorithm.
Possible policies for UserProvidedBuffers that run out of space.
You can also pass a handle to a specific thread, if you have one.
Used by makeWindowsString and WCharzBuffer
Initializes the arsd core event loop and creates its worker threads. You don't actually have to call this, since the first use of an arsd.core function that requires it will call it implicitly, but calling it yourself gives you a chance to control the configuration more explicitly if you want to.
Waits for all the requests to complete, giving each one through the range interface as it completes.
Casts value v to type T.
Note that the order of items called for your delegate is undefined; if you want it sorted, you'll have to collect and sort yourself. But it *might* be sorted by the OS (on Windows, it almost always is), so consider that when choosing a sorting algorithm.
Get the event loop associated with this thread
Gets an object that lets you control a schedulable task (which is a specialization of a fiber) and can be used in an if statement.
An int printing function that doesn't need to import Phobos. Can do some of the things std.conv.to and std.format.format do.
Converts the Windows API string str to a D UTF-8 string, storing it in buffer. Returns the slice of buffer actually used.
Converts the Windows API string str to a newly-allocated D UTF-8 string.
Given the string str, converts it to a string compatible with the Windows API and puts the result in buffer, returning the slice of buffer actually used. buffer must be at least sizeOfConvertedWstring elements long.
A trivial wrapper around C's malloc that creates a D slice. It multiples n by T.sizeof and returns the slice of the pointer from 0 to n.
Uses C's malloc to allocate a copy of original with an attached zero terminator. It may return a slice with a null pointer (but non-zero length!) if malloc fails and you are responsible for freeing the returned pointer with core.stdc.stdlib.free(ret.ptr).
This is currently a simplified glob where only the * wildcard in the first or last position gets special treatment or a single * in the middle.
This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.
Some functions that return arrays allow you to provide your own buffer. These are indicated in the type system as UserProvidedBuffer!Type, and you get to decide what you want to happen if the buffer is too small via the OnOutOfSpace parameter.
Reads or writes a file in one call. It might internally yield, but is generally blocking if it returns values. The callback ones depend on the implementation.
Returns a minimum buffer length to hold the string s with the given conversions. It might be slightly larger than necessary, but is guaranteed to be big enough to hold it.
Shortcut for converting some types to string without invoking Phobos (but it may as a last resort).
It returns the request so you can identify it more easily. request.waitForCompletion() is guaranteed to return the response without any actual wait, since it is already complete when this function returns.
Reads or writes a file in one call. It might internally yield, but is generally blocking if it returns values. The callback ones depend on the implementation.
A writeln that actually works, at least for some basic types.
The arsd.core logger works differently than many in that it works as a ring buffer of objects that are consumed (or missed; buffer overruns are possible) by a different thread instead of as strings written to some file.
Implementation details of some requests. You shouldn't need to know any of this, the interface is all public.
This is a dummy type to indicate the end of normal arguments and the beginning of the file/line inferred args. It is meant to ensure you don't accidentally send a string that is interpreted as a filename when it was meant to be a normal argument to the function and trigger the wrong overload.
To opt in to the full functionality of this module with customization opportunity, create one and only one of these objects that is valid for exactly the lifetime of the application.
Waits for all the requests to complete, giving each one through the range interface as it completes.
Alternative for toStringz
This represents a file. Technically, file paths aren't actually strings (for example, on Linux, they need not be valid utf-8, while a D string is supposed to be), even though we almost always use them like that.
Declares a delegate property with several setters to allow for handlers that don't care about the arguments.
An int printing function that doesn't need to import Phobos. Can do some of the things std.conv.to and std.format.format do.
A limited variant to hold just a few types. It is made for the use of packing a small amount of extra data into error messages and some transit across virtual function boundaries.
Basically a scope class you can return from a function or embed in another aggregate.
A packed date/time/datetime representation added for use with LimitedVariant.
This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.
Gets an object that lets you control a schedulable task (which is a specialization of a fiber) and can be used in an if statement.
Basically a Phobos SysTime but standing alone as a simple 6 4 bit integer (but wrapped) for compatibility with LimitedVariant.
For functions that give you an unknown address, you can use this to hold it.
This is primarily a helper for the event queues. It is public in the hope it might be useful, but subject to change without notice; I will treat breaking it the same as if it is private. (That said, it is a simple little utility that does its job, so it is unlikely to change much. The biggest change would probably be letting it grow and changing from inline to dynamic array.)
A tagged union that holds an error code from system apis, meaning one from Windows GetLastError() or C's errno.
Some functions that return arrays allow you to provide your own buffer. These are indicated in the type system as UserProvidedBuffer!Type, and you get to decide what you want to happen if the buffer is too small via the OnOutOfSpace parameter.
A helper object for temporarily constructing a string appropriate for the Windows API from a D UTF-8 string.
A wrapper around a const(char)* to indicate that it is a zero-terminated C string.
This is a generic exception with attached arguments. It is used when I had to throw something but didn't want to write a new class.
Calls the C API function fn. If it returns an error value, it throws an ErrnoApiException (or subclass) after getting errno.
Calls the Windows API function fn. If it returns an error value, it throws a WindowsApiException (or subclass) after calling GetLastError().
This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.
Shared core functionality including exception helpers, library loader, event loop, and possibly more. Maybe command line processor and uda helper and some basic shared annotation types.
I'll probably move the url, websocket, and ssl stuff in here too as they are often shared. Maybe a small internationalization helper type (a hook for external implementation) and COM helpers too. I might move the process helpers out to their own module - even things in here are not considered stable to library users at this time!
If you use this directly outside the arsd library despite its current instability caveats, you might consider using static import since names in here are likely to clash with Phobos if you use them together. static import will let you easily disambiguate and avoid name conflict errors if I add more here. Some names even clash deliberately to remind me to avoid some antipatterns inside the arsd modules!
Contributor notes
arsd.core should be focused on things that enable interoperability primarily and secondarily increased code quality between other, otherwise independent arsd modules. As a foundational library, it is not permitted to import anything outside the druntime core namespace, except in templates and examples not normally compiled in. This keeps it independent and avoids transitive dependency spillover to end users while also keeping compile speeds fast. To help keep builds snappy, also avoid significant use of ctfe inside this module.
On my linux computer, dmd -unittest -main core.d takes about a quarter second to run. We do not want this to grow.
@safe compatibility is ok when it isn't too big of a hassle. @nogc is a non-goal. I might accept it on some of the trivial functions but if it means changing the logic in any way to support, you will need a compelling argument to justify it. The arsd libs are supposed to be reliable and easy to use. That said, of course, don't be unnecessarily wasteful - if you can easily provide a reliable and easy to use way to let advanced users do their thing without hurting the other cases, let's discuss it.
If functionality is not needed by multiple existing arsd modules, consider adding a new module instead of adding it to the core.
Unittests should generally be hidden behind a special version guard so they don't interfere with end user tests.