Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-16 Thread Michael Van Canneyt



On Wed, 16 Aug 2017, Graeme Geldenhuys wrote:


On 2017-07-25 09:54, Bo Berglund wrote:

buffer in an old application, so I need to write efficient
replacements for certain string functions (Delete, Insert, Copy etc).

Now I am wondering if there is a better way to do the Insert() command
than this:



Reading that... All I can think of is the 1000's of Linked-List 
implementations I had to implement when I was studying Turbo Pascal all 
that years ago. Delete, Insert and Copy would be so easy to do. :-)



What does TBytes use internally to store its data?


It is an array. Hence a continuous block of memory.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-16 Thread Graeme Geldenhuys

On 2017-07-25 09:54, Bo Berglund wrote:

buffer in an old application, so I need to write efficient
replacements for certain string functions (Delete, Insert, Copy etc).

Now I am wondering if there is a better way to do the Insert() command
than this:



Reading that... All I can think of is the 1000's of Linked-List 
implementations I had to implement when I was studying Turbo Pascal all 
that years ago. Delete, Insert and Copy would be so easy to do. :-)



What does TBytes use internally to store its data?


Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-07 Thread Michael Schnell

On 02.08.2017 09:29, Michael Van Canneyt wrote:



FPC "forces" nothing. It offers a single-byte string TStrings 
implementation.
If you want to use that for Unicode, you indeed have no choice but to 
use UTF8

or use/write a separate class that uses UTF16.


That is why I said that it is less silly ! :)

But it does force TStrings siblings to handle single-byte strings (While 
Delphi forces TStrings siblings to handle 16-bit-word Strings).


As a huge count of classes in the RTL (and the LCL and MSEGUI and ..., 
and in user code) are or use TStrings siblings the compatibility issues 
and certain other problems are due to happen.


(I hope I will not completely banned now, as I already am under 
monitoring for this kind of posts...)


-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-02 Thread Michael Van Canneyt



On Mon, 31 Jul 2017, Michael Schnell wrote:


On 30.07.2017 12:37, Bo Berglund wrote:
I asked about this problem over at Embarcadero too, but was flamed 
foreven thinking about using any kind of string for storing binary data.
They are silly and defending their completely silly implementation of 
Code aware strings, forcing UTF-16 for any TStrings based classes.


The fpc implementation (forcing UTF-8 for any TStrings based classes) is 
slightly less silly.


Small correction:

FPC "forces" nothing. It offers a single-byte string TStrings implementation.
If you want to use that for Unicode, you indeed have no choice but to use UTF8
or use/write a separate class that uses UTF16.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-01 Thread Michael Schnell

On 30.07.2017 12:37, Bo Berglund wrote:
I asked about this problem over at Embarcadero too, but was flamed 
foreven thinking about using any kind of string for storing binary data.
They are silly and defending their completely silly implementation of 
Code aware strings, forcing UTF-16 for any TStrings based classes.


The fpc implementation (forcing UTF-8 for any TStrings based classes) is 
slightly less silly.


-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-08-01 Thread Michael Schnell

On 30.07.2017 08:06, Bo Berglund wrote:
All of this is because I have found that using AnsiString is 
triggering data changes when the application is running in 
certaincountries (locales) and processing certain data values... 

I am rather sure that this can be avoided.

-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-30 Thread Sven Barth via fpc-pascal
Am 30.07.2017 12:37 schrieb "Bo Berglund" :
>
> On Sun, 30 Jul 2017 09:33:59 +0200, Sven Barth via fpc-pascal
>  wrote:
>
> >> The application was started back in Delphi7 times when "string"
> >> actually meant AnsiString and was a 1-byte per element container.
> >
> >You could always use RawByteString or a string with a fixed codepage
> >instead if plain AnsiString.
>
> I asked about this problem over at Embarcadero too, but was flamed for
> even thinking about using any kind of string for storing binary data.
> THeyn did suggest RawByteString too, though so I went over the
> application changing all buffers to RawByteString and it did work.
> I also tried to set a fixed codepage for the application, but it is
> hard to check if it actually does help.

Not a fixed codepage for the application, but a string with fixed codepage,
e.g. "String(CP_1242)" or so...

> The root problem is what happens with string conversions on different
> locales and some functions could not be easily modified to use
> RawByteString.
> So I decided to bite the bullet and convert the whole unit to TBytes
> instead. Some 7000 code lines to go over...
>
> It has taken a good many hours now and I still have some intricate
> problems to solve. It still won't compile without errors.
>
> >
> >Just declare a type alias so that you can keep it compatible with older
> >Delphi versions as well.
> >
>
> Do you mean:
> type
>   TMyString = RawByteString;

Yes.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-30 Thread Bo Berglund
On Sun, 30 Jul 2017 09:33:59 +0200, Sven Barth via fpc-pascal
 wrote:

>> The application was started back in Delphi7 times when "string"
>> actually meant AnsiString and was a 1-byte per element container.
>
>You could always use RawByteString or a string with a fixed codepage
>instead if plain AnsiString.

I asked about this problem over at Embarcadero too, but was flamed for
even thinking about using any kind of string for storing binary data.
THeyn did suggest RawByteString too, though so I went over the
application changing all buffers to RawByteString and it did work.
I also tried to set a fixed codepage for the application, but it is
hard to check if it actually does help.

The root problem is what happens with string conversions on different
locales and some functions could not be easily modified to use
RawByteString.
So I decided to bite the bullet and convert the whole unit to TBytes
instead. Some 7000 code lines to go over...

It has taken a good many hours now and I still have some intricate
problems to solve. It still won't compile without errors.

>
>Just declare a type alias so that you can keep it compatible with older
>Delphi versions as well.
>

Do you mean:
type
  TMyString = RawByteString;


-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-30 Thread Sven Barth via fpc-pascal
Am 30.07.2017 08:07 schrieb "Bo Berglund" :
>
> On Fri, 28 Jul 2017 16:35:05 +0200, Michael Schnell
>  wrote:
>
> >On 25.07.2017 10:54, Bo Berglund wrote:
> >>   so I need to write efficient replacements for certain string
functions (Delete, Insert, Copy etc).
> >Why do you think the string function (if using strictly just a single
> >UTF-8 or RawByte branded String type) are not efficient ?
> >
> >If all string encoding brands in an operation are the same there will be
> >no conversion.
>
> Sorry,
> I was not clear in my question...
>
> What I meant to say is that I need to convert an existing application
> that uses strings (AnsiString) as binary data buffers to instead use
> TBytes buffers. Thus my quest is for functions operating like the
> convenient string functions but on TBytes arrays.
>
> All of this is because I have found that using AnsiString is
> triggering data changes when the application is running in certain
> countries (locales) and processing certain data values...
>
> The application was started back in Delphi7 times when "string"
> actually meant AnsiString and was a 1-byte per element container.

You could always use RawByteString or a string with a fixed codepage
instead if plain AnsiString.

Just declare a type alias so that you can keep it compatible with older
Delphi versions as well.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-29 Thread Bo Berglund
On Fri, 28 Jul 2017 16:35:05 +0200, Michael Schnell
 wrote:

>On 25.07.2017 10:54, Bo Berglund wrote:
>>   so I need to write efficient replacements for certain string functions 
>> (Delete, Insert, Copy etc).
>Why do you think the string function (if using strictly just a single 
>UTF-8 or RawByte branded String type) are not efficient ?
>
>If all string encoding brands in an operation are the same there will be 
>no conversion.

Sorry,
I was not clear in my question...

What I meant to say is that I need to convert an existing application
that uses strings (AnsiString) as binary data buffers to instead use
TBytes buffers. Thus my quest is for functions operating like the
convenient string functions but on TBytes arrays.

All of this is because I have found that using AnsiString is
triggering data changes when the application is running in certain
countries (locales) and processing certain data values...

The application was started back in Delphi7 times when "string"
actually meant AnsiString and was a 1-byte per element container.

By efficient I meant that I probably would write inefficient code if I
had to create things like the mentioned functions myself and if the
compiler did the job it would be more efficient.


-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-29 Thread Michael Schnell

On 25.07.2017 10:54, Bo Berglund wrote:

  so I need to write efficient replacements for certain string functions 
(Delete, Insert, Copy etc).
Why do you think the string function (if using strictly just a single 
UTF-8 or RawByte branded String type) are not efficient ?


If all string encoding brands in an operation are the same there will be 
no conversion.


-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-29 Thread Michael Schnell


On 25.07.2017 18:00, Martok wrote:

... FPC's intrinsics such as Insert() can already work with arrays:
Nonetheless, IMHO using single-Byte Strings (UTF-8 or RawByte, as a 
proper "uncoded" string type brand does not exist), seems more 
convenient, especially, as here we have lazy copy on top of ref counting.


-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-28 Thread Bo Berglund
On Tue, 25 Jul 2017 10:54:30 +0200, Bo Berglund
 wrote:

>so I need to write efficient
>replacements for certain string functions (Delete, Insert, Copy etc).

What I am now up aginst after a few days work is to find how to code
the Pos() function for strings...
The comm buffer apparently contains the 2-char string as indication of
the last and the existing code uses Pos() to find it.

What about something like:
function PosBytes(SearchItem, Target: TBytes): integer;
begin
  ?
end;

What could I use inside the body of this function to mimik the string
function Pos (for AnsiStrings)?


-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-28 Thread Cyrax

On 27/07/17 18:17, nore...@z505.com wrote:

On 2017-07-25 11:00, Martok wrote:

Ideally the function should be portable between FPC and Delphi XE5...
You'd only need your own functions for Delphi, FPC's intrinsics such 
as Insert()

can already work with arrays:

var
  b, c: TBytes;
begin
  b:= TBytes.Create(1,2,3);
  c:= TBytes.Create(10,11);
  Insert(c,b,2);

-> b is now [1,2,10,11,3]




The fpc wiki should probably be updated?

I cannot find "insert" on this page:
http://wiki.freepascal.org/Array

I cannot find it here either:
https://www.freepascal.org/docs-html/ref/refsu14.html

For the last 10 years or so I've been criticizing occasionally the fact 
that everyone reinvents their own array algorithms for each array! So it 
seems that may solve it. In fact this problem goes back to the 1970's 
and 1980's when arrays were being used.


Please list other functions other than insert that are available? Maybe 
someone add it to the wiki/docs

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


AFAIK, that is avaible only in the trunk version of FPC. You need to 
build the trunk version of the documents by yourself.


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-27 Thread Sven Barth via fpc-pascal
Am 27.07.2017 17:18 schrieb :
>
> On 2017-07-25 11:00, Martok wrote:
>>>
>>> Ideally the function should be portable between FPC and Delphi XE5...
>>
>> You'd only need your own functions for Delphi, FPC's intrinsics such as
Insert()
>> can already work with arrays:
>>
>> var
>>   b, c: TBytes;
>> begin
>>   b:= TBytes.Create(1,2,3);
>>   c:= TBytes.Create(10,11);
>>   Insert(c,b,2);
>>
>> -> b is now [1,2,10,11,3]
>>
>>
>
> The fpc wiki should probably be updated?
>
> I cannot find "insert" on this page:
> http://wiki.freepascal.org/Array

Then update it.

> I cannot find it here either:
> https://www.freepascal.org/docs-html/ref/refsu14.html

The documentation is always for the latest release (currently 3.0.2, soon
3.0.4), but only trunk supports this as well as Delete() (Concat() is not
yet implemented however).

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-27 Thread noreply

On 2017-07-26 06:34, Sven Barth via fpc-pascal wrote:

Am 26.07.2017 10:59 schrieb "Martok" :


> Ideally the function should be portable between FPC and Delphi

XE5...

You'd only need your own functions for Delphi, FPC's intrinsics such

as Insert()

can already work with arrays:

var
  b, c: TBytes;
begin
  b:= TBytes.Create(1,2,3);
  c:= TBytes.Create(10,11);
  Insert(c,b,2);

-> b is now [1,2,10,11,3]


But only in trunk. And Delphi XE8 and newer also support them.

Regards,
Sven


Oh, that would explain why it is not in the wiki/docs yet

Only issue I can see, is with all Create's, programmers expect a 
matching Free.
So that is a bit confusing, but so long as someone remembers arrays are 
garbage (reference rather) collected...

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-27 Thread noreply

On 2017-07-25 11:00, Martok wrote:

Ideally the function should be portable between FPC and Delphi XE5...
You'd only need your own functions for Delphi, FPC's intrinsics such as 
Insert()

can already work with arrays:

var
  b, c: TBytes;
begin
  b:= TBytes.Create(1,2,3);
  c:= TBytes.Create(10,11);
  Insert(c,b,2);

-> b is now [1,2,10,11,3]




The fpc wiki should probably be updated?

I cannot find "insert" on this page:
http://wiki.freepascal.org/Array

I cannot find it here either:
https://www.freepascal.org/docs-html/ref/refsu14.html

For the last 10 years or so I've been criticizing occasionally the fact 
that everyone reinvents their own array algorithms for each array! So it 
seems that may solve it. In fact this problem goes back to the 1970's 
and 1980's when arrays were being used.


Please list other functions other than insert that are available? Maybe 
someone add it to the wiki/docs

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-26 Thread Sven Barth via fpc-pascal
Am 26.07.2017 10:59 schrieb "Martok" :
>
> > Ideally the function should be portable between FPC and Delphi XE5...
> You'd only need your own functions for Delphi, FPC's intrinsics such as
Insert()
> can already work with arrays:
>
> var
>   b, c: TBytes;
> begin
>   b:= TBytes.Create(1,2,3);
>   c:= TBytes.Create(10,11);
>   Insert(c,b,2);
>
> -> b is now [1,2,10,11,3]

But only in trunk. And Delphi XE8 and newer also support them.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-26 Thread Martok
> Ideally the function should be portable between FPC and Delphi XE5...
You'd only need your own functions for Delphi, FPC's intrinsics such as Insert()
can already work with arrays:

var
  b, c: TBytes;
begin
  b:= TBytes.Create(1,2,3);
  c:= TBytes.Create(10,11);
  Insert(c,b,2);

-> b is now [1,2,10,11,3]


--
Martok

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-25 Thread Bo Berglund
On Tue, 25 Jul 2017 11:15:31 +0200 (CEST), Michael Van Canneyt
 wrote:

>There is no better way if you only want to use TBytes. 

Thanks, then I will continue using Move...



-- 
Bo Berglund
Developer in Sweden

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Best way to insert bytes into a TBytes variable?

2017-07-25 Thread Michael Van Canneyt



On Tue, 25 Jul 2017, Bo Berglund wrote:


I am working on moving away from using AnsiString as communications
buffer in an old application, so I need to write efficient
replacements for certain string functions (Delete, Insert, Copy etc).

Now I am wondering if there is a better way to do the Insert() command
than this:

procedure InsertBytes(var Dest: TBytes; Src: TBytes; Index: integer);
var
 Len, LenA: integer;
begin
 Len := Length(Dest);
 LenA := Length(Src);
 if LenA = 0 then exit; //Do nothing
 if Index > Len then Index := Len;  //Make an append instead
 SetLength(Dest, Len + LenA);
 Move(Dest[Index], Dest[Index + LenA], LenA);  //Create space
 Move(Src[0], Dest[Index], LenA);  //Insert data
end;

Ideally the function should be portable between FPC and Delphi XE5...


There is no better way if you only want to use TBytes. 
If you want less reallocations, you must reserve more memory for the array 
from the start (so length is a "capacity"), and keep a second count, the 
count of the number of bytes  actually used.


Then you're maybe better off working with a TMemory stream, which does all this
for you. Or write a TBuffer class.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal