2d graphic and multimedia

2020-03-11 Thread Noor Wachid via Digitalmars-d-learn
I usually go with SFML (C++) library to write simple 
visualization. Is there any similiar library in D?


Re: DMD 2.090.1: SIGILL, Illegal instruction on (ahem) intel Pentium III

2020-03-11 Thread Johan via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 22:18:04 UTC, kdevel wrote:

On Thursday, 27 February 2020 at 19:24:39 UTC, Johan wrote:
LDC will work fine if told what processor you have: 
https://d.godbolt.org/z/5hrzgm

-m32 -mcpu=pentium3   (-mcpu=native should also work).


When I "cross compile" on an AMD 64 Bit machine for pentium3

   [AMD 64 bit] $ ldc2 -m32 -mcpu=pentium3 --linker=bfd vec.d


If you run
`ldc2 -m32 -mcpu=pentium3 --linker=bfd vec.d --output-s`
you should get file `vec.s` with the assembly that LDC generated. 
I'd be _very_ surprised if it contained SSE2 instructions (i.e. 
the "movsd xmm0" instruction).
Are you sure that the druntime you are linking with was also 
built with -m32 -mcpu=pentium3?


Thanks,
  Johan




Re: DMD 2.090.1: SIGILL, Illegal instruction on (ahem) intel Pentium III

2020-03-11 Thread kinke via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 22:18:04 UTC, kdevel wrote:
Disassembly on the AMD 64 it reveals that ldc also emits the 
movds instructions:


   0x08051ba2 <+434>:	call   0x804f680 
<_D2rt5minfo11ModuleGroup6__ctorMFNbNcNiAyPS6object10ModuleInfoZSQCkQCkQCh>

   0x08051ba7 <+439>: sub$0x8,%esp
   0x08051baa <+442>: movsd  0x30(%esp),%xmm0
   0x08051bb0 <+448>: movsd  0x38(%esp),%xmm1


That's in druntime, not your cross-compiled code; you'll need to 
cross-compile druntime and Phobos first, see 
https://wiki.dlang.org/Building_LDC_runtime_libraries.


Re: Referencing an image in .css file in vibe.d

2020-03-11 Thread GreatSam4sure via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 22:11:24 UTC, GreatSam4sure wrote:
I am trying to reference an image that is in 
public/imgs/pix1.jpg in CSS file using background-image using 
URL but the image does not show.


What is the proper way of reference to the URL of the image?

I will appreciate any help




Solve

The image did not show because I did not give it a height


Re: DMD 2.090.1: SIGILL, Illegal instruction on (ahem) intel Pentium III

2020-03-11 Thread kdevel via Digitalmars-d-learn

On Thursday, 27 February 2020 at 19:24:39 UTC, Johan wrote:
LDC will work fine if told what processor you have: 
https://d.godbolt.org/z/5hrzgm

-m32 -mcpu=pentium3   (-mcpu=native should also work).


When I "cross compile" on an AMD 64 Bit machine for pentium3

   [AMD 64 bit] $ ldc2 -m32 -mcpu=pentium3 --linker=bfd vec.d

and execute the binary on the Pentium-III I get

   [PIII] $ gdb ./vec
   [...]
   This GDB was configured as "i586-suse-linux".
   For bug reporting instructions, please see:
   ...
   Dwarf Error: wrong version in compilation unit header (is 4, 
should be 2) [in module /[...]/tmp/vec]

   (gdb) r
   Starting program: /[...]/tmp/vec
   (no debugging symbols found)
   (no debugging symbols found)
   [Thread debugging using libthread_db enabled]

   Program received signal SIGILL, Illegal instruction.
   0x08051baa in ?? ()

Disassembly on the AMD 64 it reveals that ldc also emits the 
movds instructions:


   0x08051ba2 <+434>:	call   0x804f680 
<_D2rt5minfo11ModuleGroup6__ctorMFNbNcNiAyPS6object10ModuleInfoZSQCkQCkQCh>

   0x08051ba7 <+439>: sub$0x8,%esp
   0x08051baa <+442>: movsd  0x30(%esp),%xmm0
   0x08051bb0 <+448>: movsd  0x38(%esp),%xmm1


Referencing an image in .css file in vibe.d

2020-03-11 Thread GreatSam4sure via Digitalmars-d-learn
I am trying to reference an image that is in public/imgs/pix1.jpg 
in CSS file using background-image using URL but the image does 
not show.


What is the proper way of reference to the URL of the image?

I will appreciate any help


Re: Typescript with vibe.d

2020-03-11 Thread GreatSam4sure via Digitalmars-d-learn

On Tuesday, 10 March 2020 at 08:55:56 UTC, Jacob Carlborg wrote:

On Monday, 9 March 2020 at 09:42:16 UTC, GreatSam4sure wrote:
I want to know if it is possible to use typescript with the 
vibe.d since typescript is a superset of javascript. I will 
appreciate any example if it is possible


There's a Diet filter for TypeScript here [1], but it hasn't 
been updated since 2015.


[1] https://code.dlang.org/packages/diet-typescript

--
/Jacob Carlborg


Thanks, it will be really nice to enable the use of typescript by 
default since it is type-safe. I will appreciate this feature of 
it can be added. I personally don't like dynamic languages due to 
lack of declaring a type for every variable


Re: string to char* in betterC

2020-03-11 Thread 9il via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 16:10:48 UTC, 9il wrote:

On Wednesday, 11 March 2020 at 16:07:06 UTC, Abby wrote:
What is the proper way to get char* from string which is used 
in c functions? toStringz does returns:


/usr/include/dmd/phobos/std/array.d(965,49): Error: TypeInfo 
cannot be used with -betterC


and I think string.ptr is not safe because it's not zero 
termined. So what should I do? realloc each string with /0?


Thank you for your help


3. You can use mir-algorithm for simplicity and speed


/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.18"
+/
import mir.format;
import core.stdc.stdio;

void main() {
printf("some_string %s", (stringBuf() << "other_string" << 
"\0" << getData).ptr);

}


stringBuf() uses stack if the inner string fits into it. So, It 
is a mutch master than malloc/free. However, in this case C 
function should return pointer ownership to the caller.


Re: string to char* in betterC

2020-03-11 Thread rikki cattermole via Digitalmars-d-learn

On 12/03/2020 5:07 AM, Abby wrote:
What is the proper way to get char* from string which is used in c 
functions? toStringz does returns:


/usr/include/dmd/phobos/std/array.d(965,49): Error: TypeInfo cannot be 
used with -betterC


and I think string.ptr is not safe because it's not zero termined. So 
what should I do? realloc each string with /0?


Thank you for your help


String literals are null terminated so you can pass them straight to C.

toStringz will of course not work as that relies on the GC.


Re: string to char* in betterC

2020-03-11 Thread 9il via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 16:07:06 UTC, Abby wrote:
What is the proper way to get char* from string which is used 
in c functions? toStringz does returns:


/usr/include/dmd/phobos/std/array.d(965,49): Error: TypeInfo 
cannot be used with -betterC


and I think string.ptr is not safe because it's not zero 
termined. So what should I do? realloc each string with /0?


Thank you for your help


1. Yes.
2. A compile-time known or constants always contain trailing zero.

static immutable "some text"; // contains \0 after the data.



string to char* in betterC

2020-03-11 Thread Abby via Digitalmars-d-learn
What is the proper way to get char* from string which is used in 
c functions? toStringz does returns:


/usr/include/dmd/phobos/std/array.d(965,49): Error: TypeInfo 
cannot be used with -betterC


and I think string.ptr is not safe because it's not zero 
termined. So what should I do? realloc each string with /0?


Thank you for your help


Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread mark via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 14:01:13 UTC, Simen Kjærås wrote:
[snip]
Yeah, I forgot we cast to immutable to be able to send, so 
receive has to receive immutable(Deb)*, after which you can 
call deb.dup to get a mutable copy:


receive(
(immutable(Deb)* deb) { debForName[deb.name] = deb.dup; 
},

(DoneMessage m) { jobs--; }
);


Thanks, that fixed it.

However, timing-wise the single threaded version (st) is fastest, 
then the task multi-threaded version (mt), and finally this 
version (mto).


Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 12:43:28 UTC, mark wrote:

On Wednesday, 11 March 2020 at 12:22:21 UTC, Simen Kjærås wrote:

On Wednesday, 11 March 2020 at 09:29:54 UTC, mark wrote:

[snip]
Fascinating. It works just fine when compiling for 32-bit 
targets with DMD on Windows, but not for 64-bit targets, nor 
when compiling with LDC. Apparently, this difference is due to 
DMD supporting 80-bit reals, and thus giving a different size 
to Variant (VariantN!20 on DMD on Windows, VariantN!16 or 
VariantN!32 elsewhere). There's a bug in VariantN that then 
causes the compilation to fail 
(https://issues.dlang.org/show_bug.cgi?id=20666).


The issue at hand then, is that Deb is too big until that 
issue if fixed. The simple solution to this is to allocate Deb 
on the heap with new and pass pointers instead of instances 
directly. Since you are already calling .dup whenever you pass 
a Deb somewhere, you can simply modify .dup to return a Deb* 
and the receive function to receive a Deb*, and I think you 
should be good to go.


I did that and it compiles & runs, but no Debs get added to the 
collection.
See https://github.com/mark-summerfield/d-debtest-experiment -- 
the 'mto' version is the one with your fixes.


Yeah, I forgot we cast to immutable to be able to send, so 
receive has to receive immutable(Deb)*, after which you can call 
deb.dup to get a mutable copy:


receive(
(immutable(Deb)* deb) { debForName[deb.name] = deb.dup; },
(DoneMessage m) { jobs--; }
);


--
  Simen


External .o sources + BetterC : undefined symbol: __chkstk

2020-03-11 Thread SrMordred via Digitalmars-d-learn
I got undefined symbol: __chkstk when using some external .o 
sources ( compile with clang ) + betterC flag.


I thought that __chkstk was present on ntdll.lib, so i added 
manually as a lib, but still didn´t work.


How can i solve this? (it must be another lib that D includes 
since it works without the betterC flag.)


Re: How to sort 2D Slice along 0 axis in mir.ndslice ?

2020-03-11 Thread jmh530 via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 06:12:55 UTC, 9il wrote:

[snip]

Almost the same, just fixed import for `each` and a bit polished

/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.18"
+/
import mir.ndslice;
import mir.ndslice.sorting;
import mir.algorithm.iteration: each;

void main() {
auto m = [[1, -1, 3, 2],
  [0, -2, 3, 1]].fuse;
m.byDim!0.each!sort;

import std.stdio;
m.byDim!0.each!writeln;
}


Doh on the 'each' import.

Also, I don't think I had used fuse before. That's definitely 
helpful.


Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread mark via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 12:22:21 UTC, Simen Kjærås wrote:

On Wednesday, 11 March 2020 at 09:29:54 UTC, mark wrote:

[snip]
Fascinating. It works just fine when compiling for 32-bit 
targets with DMD on Windows, but not for 64-bit targets, nor 
when compiling with LDC. Apparently, this difference is due to 
DMD supporting 80-bit reals, and thus giving a different size 
to Variant (VariantN!20 on DMD on Windows, VariantN!16 or 
VariantN!32 elsewhere). There's a bug in VariantN that then 
causes the compilation to fail 
(https://issues.dlang.org/show_bug.cgi?id=20666).


The issue at hand then, is that Deb is too big until that issue 
if fixed. The simple solution to this is to allocate Deb on the 
heap with new and pass pointers instead of instances directly. 
Since you are already calling .dup whenever you pass a Deb 
somewhere, you can simply modify .dup to return a Deb* and the 
receive function to receive a Deb*, and I think you should be 
good to go.


I did that and it compiles & runs, but no Debs get added to the 
collection.
See https://github.com/mark-summerfield/d-debtest-experiment -- 
the 'mto' version is the one with your fixes.


Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 09:29:54 UTC, mark wrote:

Hi Simen,

I think you must have done something else but didn't mention to 
get it to compile. I did the exact changes you said and it 
wouldn't compile. Here's what I get with changes mentioned 
below (with new full source):


Fascinating. It works just fine when compiling for 32-bit targets 
with DMD on Windows, but not for 64-bit targets, nor when 
compiling with LDC. Apparently, this difference is due to DMD 
supporting 80-bit reals, and thus giving a different size to 
Variant (VariantN!20 on DMD on Windows, VariantN!16 or 
VariantN!32 elsewhere). There's a bug in VariantN that then 
causes the compilation to fail 
(https://issues.dlang.org/show_bug.cgi?id=20666).


The issue at hand then, is that Deb is too big until that issue 
if fixed. The simple solution to this is to allocate Deb on the 
heap with new and pass pointers instead of instances directly. 
Since you are already calling .dup whenever you pass a Deb 
somewhere, you can simply modify .dup to return a Deb* and the 
receive function to receive a Deb*, and I think you should be 
good to go.


--
  Simen


Re: Aliases to mutable thread-local data not allowed [solved-ish]

2020-03-11 Thread mark via Digitalmars-d-learn
I finally got a threaded version that works, and a lot more 
cleanly than using send/receive. (But performance is dismal, see 
the end.)


Here's the heart of the solution:

void readPackages() {
import std.algorithm: max;
import std.array: array;
import std.parallelism: taskPool, totalCPUs;
import std.file: dirEntries, FileException, SpanMode;

try {
auto filenames = dirEntries(PACKAGE_DIR, 
PACKAGE_PATTERN,

SpanMode.shallow).array;
foreach (debs; 
taskPool.map!readPackageFile(filenames))

foreach (deb; debs)
debForName[deb.name] = deb.dup;
} catch (FileException err) {
import std.stdio: stderr;
stderr.writeln("failed to read packages: ", err);
}
}

I had to change readPackageFile (and the functions it calls), 
e.g.,:


Deb[] readPackageFile(string filename) {
import std.file: FileException;
import std.range: enumerate;
import std.stdio: File, stderr;

Deb[] debs;
Deb deb;
try {
bool inDescription = false; // Descriptions can by 
multi-line
bool inContinuation = false; // Other things can be 
multi-line

auto file = File(filename);
foreach(lino, line; file.byLine.enumerate(1))
readPackageLine(debs, deb, filename, lino, line, 
inDescription,

inContinuation);
if (deb.valid)
debs ~= deb.dup;
} catch (FileException err) {
stderr.writefln("error: %s: failed to read packages: %s",
filename, err);
}
return debs;
}

I also changed main() to do some timings & to allow me to compare 
outputs:


void main(const string[] args) {
import std.datetime.stopwatch: AutoStart, StopWatch;
import std.stdio: stderr, writeln;

auto model = Model();
auto timer = StopWatch(AutoStart.yes);
model.readPackages();
stderr.writefln("read %,d packages in %s", model.length, 
timer.peek);

if (args.length > 1)
foreach (deb; model.debForName)
writeln(deb);
}


This produces the same output as the single-threaded version.

Here's the output of a typical single-threaded version's run:

read 65,480 packages in 1 sec, 314 ms, 798 μs, and 7 hnsecs

And here's the output of a typical task-based multi-threaded 
version's run:


read 65,480 packages in 1 sec, 377 ms, 605 μs, and 3 hnsecs

In fact, the multi-threaded has never yet been as fast as the 
single-threaded version!


I've put both versions on github in case anyone's interested:
https://github.com/mark-summerfield/d-debtest-experiment


Re: How to sort 2D Slice along 0 axis in mir.ndslice ?

2020-03-11 Thread Pavel Shkadzko via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 06:12:55 UTC, 9il wrote:

On Wednesday, 11 March 2020 at 00:24:13 UTC, jmh530 wrote:

[...]


Almost the same, just fixed import for `each` and a bit polished

/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.18"
+/
import mir.ndslice;
import mir.ndslice.sorting;
import mir.algorithm.iteration: each;

void main() {
auto m = [[1, -1, 3, 2],
  [0, -2, 3, 1]].fuse;
m.byDim!0.each!sort;

import std.stdio;
m.byDim!0.each!writeln;
}


Great, thanks guys!


Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread mark via Digitalmars-d-learn

Hi Simen,

I think you must have done something else but didn't mention to 
get it to compile. I did the exact changes you said and it 
wouldn't compile. Here's what I get with changes mentioned below 
(with new full source):


/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/variant.d(701,26): 
Error: cannot implicitly convert expression rhs of type immutable(Deb) to Deb
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/variant.d(603,17): 
Error: template instance 
std.variant.VariantN!32LU.VariantN.opAssign!(immutable(Deb)) error instantiating
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(126,22):
instantiated from here: __ctor!(immutable(Deb))
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(656,23):
instantiated from here: __ctor!(immutable(Deb))
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(647,10):
instantiated from here: _send!(immutable(Deb))
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(626,10):
instantiated from here: _send!(immutable(Deb))
src/app.d(89,17):instantiated from here: 
send!(immutable(Deb))
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/ldc2 failed with exit 
code 1.


Here is a modified version that names the DoneMessage variable 
and makes readPackageFile and readPackageLine into functions. 
Instead of making them static, I just took them outside the 
struct: after all, they never access struct member data. I also 
now use ownerTid.


// app.d
import std.typecons: Tuple;

void main() {
import std.stdio: writeln, writefln;
auto model = Model();
model.readPackages();
writefln("read %,d packages", model.length);
}

enum PACKAGE_DIR = "/var/lib/apt/lists";
enum PACKAGE_PATTERN = "*Packages";
alias Unit = void[0]; // These two lines allow me to use AAs as 
sets

enum unit = Unit.init;
alias MaybeKeyValue = Tuple!(string, "key", string, "value", 
bool, "ok");

struct DoneMessage {}

struct Deb {
string name;
string description;
Unit[string] tags; // set of tags

Deb dup() const {
Deb deb;
deb.name = name;
deb.description = description;
foreach (key; tags.byKey)
deb.tags[key] = unit;
return deb;
}

bool valid() {
import std.string: empty;
return !name.empty && !description.empty;
}

void clear() {
name = "";
description = "";
tags.clear;
}
}

struct Model {
import std.concurrency: Tid;

private Deb[string] debForName; // Only read once populated

size_t length() const { return debForName.length; }

void readPackages() {
import std.concurrency: receive, spawn;
import std.file: dirEntries, FileException, SpanMode;

Tid[] tids;
try {
foreach (string filename; dirEntries(PACKAGE_DIR,
 PACKAGE_PATTERN,
 
SpanMode.shallow))

tids ~= spawn(, filename);
auto jobs = tids.length;
while (jobs) {
receive(
(Deb deb) { debForName[deb.name] = deb; },
(DoneMessage m) { jobs--; }
);
}
} catch (FileException err) {
import std.stdio: stderr;
stderr.writeln("failed to read packages: ", err);
}
}
}

void readPackageFile(string filename) {
import std.concurrency: ownerTid, send;
import std.file: FileException;
import std.range: enumerate;
import std.stdio: File, stderr;

try {
bool inDescription = false; // Descriptions can by 
multi-line
bool inContinuation = false; // Other things can be 
multi-line

Deb deb;
auto file = File(filename);
foreach(lino, line; file.byLine.enumerate(1))
readPackageLine(filename, lino, line, deb, 
inDescription,

inContinuation);
if (deb.valid)
send(ownerTid, cast(immutable)deb.dup);
} catch (FileException err) {
stderr.writefln("error: %s: failed to read packages: %s",
filename, err);
}
send(ownerTid, DoneMessage());
}

void readPackageLine(const string filename, const int lino,
 const(char[]) line, ref Deb deb,
 ref bool inDescription, ref bool 
inContinuation) {

import std.concurrency: ownerTid, send;
import std.path: baseName;
import std.stdio: stderr;
import std.string: empty, startsWith, strip;

if (strip(line).empty) {
if (deb.valid)
send(ownerTid, cast(immutable)deb.dup);
else if (!deb.name.empty || !deb.description.empty ||
 !deb.tags.empty)
stderr.writefln("error: %s:%,d: incomplete package: 
%s",

baseName(filename), lino, deb);
deb.clear;
   

Re: Aliases to mutable thread-local data not allowed [testable source code]

2020-03-11 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 10 March 2020 at 20:03:21 UTC, mark wrote:

I've managed to make a cut-down version that's < 170 LOC.
It needs to be run on Debian or a Debian-based Linux (e.g., 
Ubuntu).


Hopefully this will help someone understand and be able to help!


This took some time figuring out. Turns out, 
std.concurrency.spawn won't take a delegate as its callable 
argument. There are sensible reasons for this - delegates have a 
context that is not guaranteed to be immutable, so allowing 
delegate callables could lead to mutable aliasing. I've filed an 
issue to improve documentation and error messages: 
https://issues.dlang.org/show_bug.cgi?id=20665


However, knowing that some things are impossible do not 
necessarily help us figure out what we can do to fix the problem, 
and the good news is, the problems can be fixed. Since the 
problem is we're giving a delegate where the API expects a 
function, we can simply turn it into a function. In the code 
you've given, that means making readPackageFile and 
readPackageLine static. This make spawn() run as it should.


In addition, there's a problem with this line in receive():

(DoneMessage) { jobs--; }

That looks sensible, but since DoneMessage doesn't have a name, 
it is parsed as a templated function taking one argument of 
unspecified type and called DoneMessage. For some reason, 
templates passed as function arguments show up in compiler output 
as 'void', giving this weird error message:


template std.concurrency.receive cannot deduce function from 
argument types !()(void delegate(Deb deb) pure nothrow @safe, 
void)


The solution here is to simply give DoneMessage a name:

(DoneMessage d) { jobs--; }

With those changes, things at least compile. Now it's up to you 
to ensure the semantics are correct. :)


One last thing: you're passing parentTid around, and that's not 
actually necessary - std.concurrency.ownerTid does the exact same 
thing, and is available even if not explicitly passed anywhere.


--
  Simen


Re: How to sort 2D Slice along 0 axis in mir.ndslice ?

2020-03-11 Thread 9il via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 00:24:13 UTC, jmh530 wrote:

On Tuesday, 10 March 2020 at 23:31:55 UTC, p.shkadzko wrote:

[snip]


Below does the same thing as the numpy version.

/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.18"
+/
import mir.ndslice.sorting : sort;
import mir.ndslice.topology : byDim;
import mir.ndslice.slice : sliced;

void main() {
auto m = [1, -1, 3, 2, 0, -2, 3, 1].sliced(2, 4);
m.byDim!0.each!(a => a.sort);
}


Almost the same, just fixed import for `each` and a bit polished

/+dub.sdl:
dependency "mir-algorithm" version="~>3.7.18"
+/
import mir.ndslice;
import mir.ndslice.sorting;
import mir.algorithm.iteration: each;

void main() {
auto m = [[1, -1, 3, 2],
  [0, -2, 3, 1]].fuse;
m.byDim!0.each!sort;

import std.stdio;
m.byDim!0.each!writeln;
}



Re: std.bitmanip help - how to combine bitfields and read

2020-03-11 Thread kookman via Digitalmars-d-learn

On Wednesday, 11 March 2020 at 05:25:43 UTC, kookman wrote:
I am using libpcap to read from stored pcap files, and want to 
use std.bitmanip.bitfields to read TCP flags from the file, 
using a struct like:


struct TcpHeader {
align(1):
ushort srcPort;
ushort dstPort;
uint seqNo;
uint ackNo;
mixin(bitfields!(
bool, "flagFin", 1,
bool, "flagSyn", 1,
bool, "flagRst", 1,
bool, "flagPsh", 1,
bool, "flagAck", 1,
bool, "flagUrg", 1,
bool, "flagEce", 1,
bool, "flagCwr", 1,
bool, "flagNs",  1,
ubyte, "reserved", 3,
ubyte, "dataOffsetWords", 4   // in 32bit words, min=5, 
max=15

));
ushort windowSize;
ushort checksum;
ushort urgentPtr;

this(inout ubyte[] bytes)
{
srcPort = bytes.read!ushort();
dstPort = bytes.read!ushort();
seqNo = bytes.read!uint();
ackNo = bytes.read!uint();
// now what? how to read bitfields??
}

const uint dataOffset()// convenience method to get 
offset in bytes

{
return dataOffsetWords * 4;
}
}

How can I get at the private field behind the bitfields to read 
into it. I'm using std.bitmanip.read because I need the network 
order (bigendian) conversion for this data.


Actually, doing it a "smarter" way worked:

struct TcpHeader {
align(1):
ushort srcPort;
ushort dstPort;
uint seqNo;
uint ackNo;
mixin(bitfields!(
bool, "flagFin", 1,
bool, "flagSyn", 1,
bool, "flagRst", 1,
bool, "flagPsh", 1,
bool, "flagAck", 1,
bool, "flagUrg", 1,
bool, "flagEce", 1,
bool, "flagCwr", 1,
bool, "flagNs",  1,
ubyte, "reserved", 3,
ubyte, "dataOffsetWords", 4   // in 32bit words, min=5, 
max=15

));
ushort windowSize;
ushort checksum;
ushort urgentPtr;

this(inout(ubyte)[] bytes)
{
import std.traits: FieldNameTuple;
static foreach (f; FieldNameTuple!TcpHeader) {
pragma(msg, f);
__traits(getMember, this, f) = 
bytes.read!(typeof(__traits(getMember, this, f)));

}
}

const uint dataOffset()// convenience method to get 
offset in bytes

{
return dataOffsetWords * 4;
}
}