Skullcode 0 Posted November 9, 2020 (edited) 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 November 9, 2020 by Skullcode Share this post Link to post
Alexander Sviridenkov 356 Posted November 9, 2020 TBytes and TIdBytes are binary compatible, both are just "array of byte". Share this post Link to post
Skullcode 0 Posted November 9, 2020 (edited) 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 November 9, 2020 by Skullcode Share this post Link to post
Remy Lebeau 1393 Posted November 10, 2020 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); 1 Share this post Link to post
Remy Lebeau 1393 Posted November 10, 2020 (edited) 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 November 10, 2020 by Remy Lebeau 1 Share this post Link to post
Skullcode 0 Posted November 10, 2020 (edited) 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 November 11, 2020 by Skullcode Share this post Link to post
Guest Posted November 11, 2020 8 hours ago, Skullcode said: at this Line Move(EncodedBytes, bytesHead[6], Length(EncodedBytes)); Should be Quote Move(EncodedBytes[0], bytesHead[6], Length(EncodedBytes)); Share this post Link to post