Code Monkey home page Code Monkey logo

nstack's Introduction

NStack

Build Version Downloads License Bugs

NOTE: NStack has moved to the gui-cs org.

Currently, this library contains a port of the Go string, and Go rune support as well as other Unicode helper methods.

You can browse the API documentation.

Install the NuGet package from NuGet.org by installing NStack.Core.

Future Additions

The long term goal is to make this module an exploration of what the .NET APIs for IO looked like if they only used exceptions for either invalid parameters being passed to methods and used results/error codes for most IO operations:

  • Exceptions have a role, but IO code tends to become ugly in its presence.

  • Other areas include making an IO layer that does not surface "string" for filenames, as in Unix there are really no filenames as we treat them in .NET, but rather file names are a collection of bytes, which do not necessarily can be decoded into UTF8 [1].

To make things simple, this assumes that UTF8 strings (ustring in this code) can exist without them being valid UTF8 strings, but rather a collection of bytes.

[1] For example, older file systems can have filenames that made sense with a particular character set and are effectively not possible to map into strings.

nstack's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nstack's Issues

String concatenation with fewer allocations

ustring design is amazing because it allows you to bring your own string. That said, the default stack should at least contain an implementation that does allocation-less string concatenation by holding a chain of ustrings internally.

class ChainUString : ustring {
    ustring this;
    ustring next;
}

IntPtrUString liveness issues

  1. IDisposable implementation is hidden to ustring API users, thus IntPtrUString will always end up being finalized, unless people explicitly Dispose the string.

  2. IntPtrUString design assumes that the parent string outlives the child string, failing code would look like:

IntPtr mem = grab_native_string(out int count);
var parent = ustring.Make (mem, count, str => release_native_string (str));
var child = parent [0, 5]; // Let's assume these values are correct
// somewhere here GC happens, parent is reclaimed
child.ToString(); // accessing bad memory

Maybe a SafeHandle mechanism is better here than an opaque pointer? The wrappers can get reclaimed while the SafeHandle still lives, so that's ๐Ÿ‘.

That would make the IntPtrUString slightly larger - Marshal.SizeOf(SafeHandle) + sizeof(int) for an offset.

"gethexaformat" messes up column widths

This patch and this patch seem to have messed up column widths. E.g. the Unicode character "๐”น" (U+1D539) is counted as double-width. Before these patches, it did not fall in any of the double-width ranges. However, after these patches, gethexaformat conflates U+1D539 with U+D539 (ํ”น), which is considered as a wide character.

I don't understand what the purpose of gethexaformat is -- it seems to just be performing the bitwise operation x & 0xFFFF, but using text parsing? Why are only the least significant 16 bits considered when determining whether a character is wide? This seems like it would cause many characters beside my example to have the wrong width...

Perhaps a mistake in RuneCount()

    public static int RuneCount(byte[] buffer, int offset = 0, int count = -1)
    {
        if (buffer == null)
            throw new ArgumentNullException(nameof(buffer));
        if (count == -1)
            count = buffer.Length;
        int n = 0;
        for (int i = offset; i < count;) {    <<---- the loop should be from 0 to count, obviously it won't work if offset is greater than count.
            n++;
            var c = buffer[i];
            ......
        }
    }

A way to write ustring literally using a FormattableString

Wonder if there is any interest in being able to write a literal ustring that may contain embedded non-UTF16 friendly bytes? I was thinking that if you provide a parser for a FormattableString, you can use some Format Item format code to intermix literal character strings with raw bytes.

Something like:

var us = ustring.Make($"Sample {0xff::} Embedded");

This would yield a ustring (us) with the content:

Char Byte
'S' 83
'a' 97
'm' 109
'p' 112
'l' 108
'e' 101
' ' 32
ff 255
' ' 32
'E' 69
'm' 109
'b' 98
'e' 101
'd' 100
'd' 100
'e' 101
'd' 100

Number of columns occupied by a Rune.

Is there any way to obtain the number of columns occupied by a Rune other than by the range of Unicode characters as currently done by the ColumnWidth method?

Support unicode chars

This is an issue I filed in gui.cs a while ago.
I took a look in NStack and I think I found the reason, so I'll open this issue to be able to fix it with a PR.

Issue

I am currently using some unicode signs like in gui.cs: โ‰ก โŒ‚ โ†‘ โ†“ โ€ฆ

unicodesguics

While rendering them in a ListView or TextField, I got a IndexOutOfRangeException. In Labels, everything is okay.

   at System.Rune.bisearch(UInt32 rune, UInt32[,] table, Int32 max)
   at System.Rune.ColumnWidth(Rune rune)
   at Terminal.Gui.ListView.ListWrapper.RenderUstr(ustring ustr, Int32 col, Int32 line, Int32 width)
   at Terminal.Gui.ListView.ListWrapper.Render(Boolean marked, Int32 item, Int32 col, Int32 line, Int32 width)
   at Terminal.Gui.ListView.Redraw(Rect region)
   at Terminal.Gui.View.Redraw(Rect region)
   at Terminal.Gui.Window.Redraw(Rect bounds)
   at Terminal.Gui.View.Redraw(Rect region)
   at Terminal.Gui.Application.Redraw(View view)
   at Terminal.Gui.Application.Begin(Toplevel toplevel)
   at Terminal.Gui.Application.Run(Toplevel view)
   at grrui.Program.Main(String[] args) in D:\Develop\GitHub\RepoZ\grrui\Program.cs:line 43

It turns out that "\u2261" for example, returns Rune 8801. Rune.ColumnWidth(8801) throws.

indexoutofrangeexception

ustring.ColumnWidth

Need to surface this one, based on Rune.ColumnWidth, to easily compute the console-visible length of a ustring.

Rename ustring?

Perhaps ustring should be "u8string" to indicate the utf8 nature of it, and we introduce a "ustring" that is rune-indexable, which is a List

Overload for Make (IntPtr, ...)

Currently, there is:
ustring Make (IntPtr block, int size, Action<ustring, IntPtr> releaseFunc = null)

The option to avoid allocating here is to make the caller cache the lambda at callsite, this can lead to lots of static delegates being declared, and possibly captures, etc. I'm not sure there is a better way to handle this though, so the users will have to deal with the delegate allocations.

It's not necessary to know the ustring that's being released. I don't have enough information to understand why we also pass in the ustring that's being reclaimed. Done this way, the user can still shoot themselves in the foot, since they don't know the implementation details of IntPtrUString, thus if they decide to use the string after free-ing the IntPtr, it'll lead to invalid memory accesses.

Maybe trim down the Action parameters to IntPtr? That way, you can use built-in methods like Marshal.FreeHGlobal and use it as a method group at call-site?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.