Jump to content
Skullcode

converting this TidBytes code To Tbytes

Recommended Posts

i found this code in another forum 

 

var Bytes: TidBytes;

Bytes :=  RawToBytes(data^, len);

SetLength(Bytes, 6 + Buffersize);
CopyTIdString('Audio1', Bytes, 0);
CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, Bytes, 6, Buffersize);

any idea how to convert it To  TBytes

 

 

i am not sure how to assign the Pointer data and do the exact same things with copying string using Tbytes  

 

var
Bytes: TBytes;

SetLength(Bytes, len);
Move(data^, Bytes[0], len);

 

Edited by Skullcode

Share this post


Link to post

i already Converted the RawToBytes To Tbytes 

 

as i posted up there 

 

var
Bytes: TBytes;

SetLength(Bytes, len);
Move(data^, Bytes[0], len);

i am confused to do the copying line 

 

CopyTIdString('Audio1', Bytes, 0);
CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, Bytes, 6, Buffersize);

 

CopyTidstring requires TidBytes

Edited by Skullcode

Share this post


Link to post

CopyTIdBytes() is just a Move() from one TIdBytes to another, using starting source/target indexes and a byte length:

procedure CopyTIdBytes(const ASource: TIdBytes; const ASourceIndex: Integer;
  var VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer);
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
  {$IFDEF DOTNET}
  System.array.Copy(ASource, ASourceIndex, VDest, ADestIndex, ALength);
  {$ELSE}
  //if these asserts fail, then it indicates an attempted buffer overrun.
  Assert(ASourceIndex >= 0);
  Assert((ASourceIndex+ALength) <= Length(ASource));
  Move(ASource[ASourceIndex], VDest[ADestIndex], ALength);
  {$ENDIF}
end;

CopyTIdString(), on the other hand, is a little more involved, as it first has to convert the input String to bytes in a specified encoding, and then it moves those bytes into the target TIdBytes where specified:

procedure CopyTIdString(const ASource: String; var VDest: TIdBytes;
  const ADestIndex: Integer; const ALength: Integer = -1;
  ADestEncoding: IIdTextEncoding = nil
  {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
  ); overload;
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
  CopyTIdString(ASource, 1, VDest, ADestIndex, ALength, ADestEncoding
    {$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}
    );
end;

procedure CopyTIdString(const ASource: String; const ASourceIndex: Integer;
  var VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer = -1;
  ADestEncoding: IIdTextEncoding = nil
  {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
  ); overload;
{$IFDEF USE_INLINE}inline;{$ENDIF}
var
  LLength: Integer;
  {$IFDEF STRING_IS_ANSI}
  LTmp: TIdWideChars;
  {$ENDIF}
begin
  {$IFDEF STRING_IS_ANSI}
  LTmp := nil; // keep the compiler happy
  {$ENDIF}
  LLength := IndyLength(ASource, ALength, ASourceIndex);
  if LLength > 0 then begin
    EnsureEncoding(ADestEncoding);
    {$IFDEF STRING_IS_UNICODE}
    ADestEncoding.GetBytes(ASource, ASourceIndex, LLength, VDest, ADestIndex);
    {$ELSE}
    EnsureEncoding(ASrcEncoding, encOSDefault);
    LTmp := ASrcEncoding.GetChars(RawToBytes(ASource[ASourceIndex], LLength)); // convert to Unicode
    ADestEncoding.GetBytes(LTmp, 0, Length(LTmp), VDest, ADestIndex);
    {$ENDIF}
  end;
end;

So, given your example, the simplest translation to TBytes would look like this:

var
  Bytes: TBytes;

SetLength(Bytes, 6 + Buffersize);
TEncoding.Default.GetBytes('Audio1', 1, 6, Bytes, 0);
Move(Buffer^, Bytes[6], Buffersize);

 

  • Thanks 1

Share this post


Link to post
21 hours ago, Alexander Sviridenkov said:

TBytes and TIdBytes are binary compatible, both are just "array of byte".

Binary compatible, in that they have the same memory layout, yes.  But you can't pass a TBytes to a 'var TIdBytes' function parameter, and vice versa, unless you use a type-cast, eg:

type
  PIdBytes = ^TIdBytes;

var
  Bytes: TBytes;

SetLength(Bytes, 6 + Buffersize);
CopyTIdString('Audio1', PIdBytes(@Bytes)^, 0);
CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, PIdBytes(@Bytes)^, 6, Buffersize);

Or maybe just:

var
  Bytes: TBytes;

SetLength(Bytes, 6 + Buffersize);
CopyTIdString('Audio1', TIdBytes(Bytes), 0);
CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, TIdBytes(Bytes), 6, Buffersize);

 

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post

in my example i am stuck in sending those Bytes i am using Twsocket UDP 

 

 

that's what i do 

 

var
ABytes: TBytes;
EncodedBytes: TBytes;
bytesHead : TBytes;
baseaudio : string;
begin
baseaudio := 'Audio1'; 
SetLength(ABytes, len);
Move(data^, ABytes[0], len);
EncodedBytes := Encodeaudio(ABytes);

SetLength(bytesHead, 6 + Length(EncodedBytes));
TEncoding.UTF8.GetBytes(baseaudio, 1, 6, bytesHead, 0);
Move(EncodedBytes, bytesHead[6], Length(EncodedBytes));

wsocketudp.Send(bytesHead, Length(bytesHead))

 

 

when i send the data without adding header it sent just fine what is my Mistake ?

 

the exception raised 

 

First chance exception at $004072A3. Exception class $C0000005 with message 'access violation at 0x004072a3: read of address 0x0bd600d8'. Process room.exe (5680)

at this Line Move(EncodedBytes, bytesHead[6], Length(EncodedBytes));

 

Edited by Skullcode

Share this post


Link to post
8 hours ago, Skullcode said:

at this Line Move(EncodedBytes, bytesHead[6], Length(EncodedBytes));

Should be

Quote

Move(EncodedBytes[0], bytesHead[6], Length(EncodedBytes));

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×