Re: dmd Regression(?): bigEndianToNative buffer slice allows only literals

2015-05-13 Thread Lucas Burson via Digitalmars-d-learn
I reported this as a regression 
https://issues.dlang.org/show_bug.cgi?id=14582


dmd Regression(?): bigEndianToNative buffer slice allows only literals

2015-05-13 Thread Lucas Burson via Digitalmars-d-learn
The std.batmanip bigEndianToNative has a regression where the 
slice range doesn't work with variables (only literals).

Is the syntax incorrect or is this a regression in dmd?

Using this main.d:
import std.bitmanip;

int main(string args[])
{
   auto datain = new ubyte[16];

   // this syntax works
   ushort descriptorLength = 
bigEndianToNative!ushort(datain[2..4]);


   // this syntax fails (worked in previous version)
   int offset = 2;
   descriptorLength = bigEndianToNative!ushort(cast(ubyte[2]) 
datain[offset..offset+2]);


   return 0;
}


I get this error on the command line:
main.d(14): Error: cannot cast expression 
datain[cast(uint)offset..cast(uint)(offset + 2)] of type ubyte[] 
to ubyte[2]


Re: bitmanip bigEndianToNative using a buffer slice?

2014-10-21 Thread Lucas Burson via Digitalmars-d-learn
On Wednesday, 22 October 2014 at 01:08:52 UTC, ketmar via 
Digitalmars-d-learn wrote:

the short answer:

 uint fromBuf =
 bigEndianToNative!uint(cast(ubyte[4])buffer[offset..offset+4]);



ketmar, we meet again! Your explanation is great and that solved 
my problem. Thank you. Maybe I'll try out templates next...


bitmanip bigEndianToNative using a buffer slice?

2014-10-21 Thread Lucas Burson via Digitalmars-d-learn
I'm trying to create a primitive type given a specific buffer 
slice. I can place the uint into a sliced buffer but I'm getting 
compiler errors when using a slice to create the uint. Still new 
to Dlang and unfamiliar with the template system.


How do I get this working?

import std.bitmanip;
int main()
{
   size_t offset = 3;
   ubyte[10] buffer;
   buffer[offset..offset+4] = nativeToBigEndian!uint(cast(uint) 
104387);


   // compiler error
   uint fromBuf = 
bigEndianToNative!uint(buffer[offset..offset+4]);

   return 0;
}

The compiler error:
./test.d(11): Error: template std.bitmanip.bigEndianToNative does 
not match any function template declaration. Candidates are:
/usr/include/dmd/phobos/std/bitmanip.d(1689):
std.bitmanip.bigEndianToNative(T, ulong n)(ubyte[n] val) if 
(canSwapEndianness!(T) && n == T.sizeof)
./test.d(11): Error: template std.bitmanip.bigEndianToNative(T, 
ulong n)(ubyte[n] val) if (canSwapEndianness!(T) && n == 
T.sizeof) cannot deduce template function from argument types 
!(uint)(ubyte[])
./test.d(11): Error: template instance bigEndianToNative!(uint) 
errors instantiating template


Re: String created from buffer has wrong length and strip() result is incorrect

2014-10-18 Thread Lucas Burson via Digitalmars-d-learn
On Saturday, 18 October 2014 at 00:53:57 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Sat, 18 Oct 2014 00:32:09 +
Lucas Burson via Digitalmars-d-learn
 wrote:




Wow, your changes made it much simpler. Thank you for the 
suggestions and expertise ketmar :)


Re: String created from buffer has wrong length and strip() result is incorrect

2014-10-17 Thread Lucas Burson via Digitalmars-d-learn
On Friday, 17 October 2014 at 17:40:09 UTC, ketmar via 
Digitalmars-d-learn wrote:



i developed a habit of making such buffers one byte bigger than
necessary and just setting the last byte to 0 before 
converting. this

way it's guaranteed to be 0-terminated.


Perfect, great idea. Below is my utility method to pull strings 
out of a buffer.



/**
 * Get a string from buffer where the string spans [offset_start, 
offset_end).

 * Params:
 *buffer = Buffer with an ASCII string to obtain.
 *offset_start = Beginning byte offset within the buffer 
where the string starts.
 *offset_end = Ending byte offset which is not included in 
the string.

 */
string bufferGetString(ubyte[] buffer, ulong offset_start, ulong 
offset_end)

in
{
   assert(buffer != null);
   assert(offset_start < offset_end);
   assert(offset_end <= buffer.length);
}
body
{
   ulong bufflen = offset_end - offset_start;

   // add one to the lenth for null-termination
   ubyte[] temp = new ubyte[bufflen+1];
   temp[0..bufflen] = buffer[offset_start..offset_end];
   temp[bufflen] = '\0';

   return strip(to!string(cast(const char*) temp.ptr));
}

unittest
{
   ubyte[] no_null = [' ', 'A', 'B', 'C', ' '];
   assert("ABC" == bufferGetString(no_null, 0, no_null.length));
   assert("ABC" == bufferGetString(no_null, 1, no_null.length-1));
   assert("A" == bufferGetString(no_null, 1, 2));
}


Re: String created from buffer has wrong length and strip() result is incorrect

2014-10-17 Thread Lucas Burson via Digitalmars-d-learn
On Friday, 17 October 2014 at 15:30:52 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Fri, 17 Oct 2014 15:24:21 +
Lucas Burson via Digitalmars-d-learn
 wrote:

So given the below buffer would I use fromStringz (is this in 
the stdlib?) to cast it from a null-terminated buffer to a 
good string? Shouldn't the compiler give a warning about 
casting a buffer to a string without using fromStringz?
if you are really-really sure that your buffer is 
null-terminated, you

can use this trick:

  import std.conv;
  string s = to!string(cast(char*)buff.ptr);

please note, that this is NOT SAFE. you'd better doublecheck 
that your

buffer is not empty and is null-terminated.


The buffer is populated from a scsi ioctl so it "should" be only 
ascii and null-terminated but it's a good idea to harden the code 
a bit.

Thank you for your help!


Re: String created from buffer has wrong length and strip() result is incorrect

2014-10-17 Thread Lucas Burson via Digitalmars-d-learn
On Friday, 17 October 2014 at 08:31:04 UTC, spir via 
Digitalmars-d-learn wrote:

On 17/10/14 09:29, thedeemon via Digitalmars-d-learn wrote:

On Friday, 17 October 2014 at 06:29:24 UTC, Lucas Burson wrote:


  // This is where things breaks
  {
 ubyte[] buff = new ubyte[16];
 buff[0..ATA_STR.length] = cast(ubyte[])(ATA_STR);

 // read the string back from the buffer, stripping 
whitespace
 string stringFromBuffer = 
strip(cast(string)(buff[0..16]));

 // this shows strip() doesn't remove all whitespace
 writefln("StrFromBuff is '%s'; length %d", 
stringFromBuffer,

stringFromBuffer.length);

 // !! FAILS. stringFromBuffer is length 15, not 3.
 assert(stringFromBuffer.length == strip(ATA_STR).length);


Unlike C, strings in D are not zero-terminated by default, 
they are just arrays,
i.e. a pair of pointer and size. You create an array of 16 
bytes and cast it to
string, now you have a 16-chars string. You fill first few 
chars with data from
ATA_STR but the rest 10 bytes of the array are still part of 
the string, not
initialized with data, so having zeroes. Since this tail of 
zeroes is not

whitespace (tabs or spaces etc.) 'strip' doesn't remove it.


Side-note: since your string has those zeroes at the end, strip 
only removes the space at start (thus, final size=15), instead 
of at both ends.


d


Okay things are becoming more clear. The cast to string is 
nothing like the C++ string ctor, I made a bad assumption.


So given the below buffer would I use fromStringz (is this in the 
stdlib?) to cast it from a null-terminated buffer to a good 
string? Shouldn't the compiler give a warning about casting a 
buffer to a string without using fromStringz?


Buffer = [ 0x20, 0x41, 0x54, 0x41, 0x20, 0x00, 0x00, ...]?


String created from buffer has wrong length and strip() result is incorrect

2014-10-16 Thread Lucas Burson via Digitalmars-d-learn
When creating a string from a ubyte[], I have an invalid length 
and string.strip() doesn't strip off all whitespace. I'm new to 
the language. Is this a compiler issue?



import std.string : strip;
import std.stdio  : writefln;

int main()
{
   const string ATA_STR = " ATA ";

   // this works fine
   {
  ubyte[] buffer = [' ', 'A', 'T', 'A', ' ' ];
  string test = strip(cast(string)(buffer));
  assert(test == strip(ATA_STR));
   }

   // This is where things breaks
   {
  ubyte[] buff = new ubyte[16];
  buff[0..ATA_STR.length] = cast(ubyte[])(ATA_STR);

  // read the string back from the buffer, stripping 
whitespace

  string stringFromBuffer = strip(cast(string)(buff[0..16]));
  // this shows strip() doesn't remove all whitespace
  writefln("StrFromBuff is '%s'; length %d", 
stringFromBuffer, stringFromBuffer.length);


  // !! FAILS. stringFromBuffer is length 15, not 3.
  assert(stringFromBuffer.length == strip(ATA_STR).length);

   }

   return 0;
}