简体   繁体   English

从Oxygene中的Delphi流加载字符串

[英]Load string from Delphi stream in Oxygene

I'm new to Oxygene and I want to read strings from a stream that was generated by Delphi. 我是Oxygene的新手,我想从Delphi生成的流中读取字符串。 I receive this stream via TCP. 我通过TCP收到此流。 Here is how I save strings to a stream on the client side: 这是我将字符串保存到客户端流上的方法:

procedure SaveStringToStream(AStream: TStream; AString: String);
var
  StringSize: Integer;
  StringToSave: AnsiString;
begin
  StringToSave := Utf8Encode(AString);
  StringSize := Length(StringToSave);
  AStream.WriteBuffer(StringSize, SizeOf(StringSize));
  AStream.WriteBuffer(Pointer(StringToSave)^, StringSize);
end;

As you can See I first add the size of the string to the stream and then the content. 如您所见,我首先将字符串的大小添加到流中,然后添加内容。 My existing method to load strings from a stream on the server side (Oxygene) looks like this: 我现有的从服务器端(Oxygene)流中加载字符串的方法如下所示:

function LoadStringFromStream(const aStream: NSInputStream): String;
begin
  var buf: array[1024] of uint8_t;
  var len: Integer:= 0;   
  len := aStream.&read(buf) maxLength(1024);
  if len > 0 then
  begin    
    nslog(len.stringValue);
    var data: NSMutableData := NSMutableData.alloc().initWithLength(0);
    data.appendBytes(@buf) length(buf[0]); 

    exit NSString.alloc().initWithData(data) encoding(NSStringEncoding.NSASCIIStringEncoding);             
  end;    
end;

But this returns the hole content and not the current part. 但这会返回孔的内容,而不是当前零件。

EDIT: Oh, I had a mistake in the server application... Now I'm able to read strings, but not to read integer values (only upto 256 bit). 编辑:哦,我在服务器应用程序中犯了一个错误...现在,我可以读取字符串,但不能读取整数值(最多256位)。 For Objective-C I found this code 对于Objective-C,我找到了这段代码

- (int32_t)readInt32
{
    int32_t value = 0;

    if ([self read:(uint8_t *)&value maxLength:4] != 4)
    {
        NSlog(@"***** Couldn't read int32");
    }
    return value;
}

Thats the Oxygene code: 多数民众赞成在Oxygene代码:

function readInt32(const aStream: NSInputStream): Integer;
begin
  var value: int32_t := 0;
  var tmp:= uint8_t(@value);
  if aStream.&read(@tmp) maxLength(4) <> 4 then
    NSLog('***** Couldn''t read int32');  
  exit value;
end;

But something goes wrong, I don't get any value. 但是出了点问题,我没有任何价值。 Do you guys know what I have to do? 你们知道我该怎么办吗?

You need to read the length first, and then the UTF-8 encoded bytes. 您需要先读取长度,然后读取UTF-8编码的字节。 I don't know Oxygene at all, but the code might be like this: 我一点都不了解Oxygene,但是代码可能像这样:

var len: Integer:= 0;   
aStream.&read(len) maxLength(sizeof(Integer));
var buf := new uint8_t[len];
aStream.&read(buf) maxLength(len);

I fully expect that I have got the syntax wrong, but this is the general idea! 我完全希望自己的语法有误,但这是总的想法!

I think you have converted the Objective-C code (slightly, but significantly) incorrectly: 我认为您错误地(但很明显地)转换了Objective-C代码:

function readInt32(const aStream: NSInputStream): Integer;
begin
  var value: int32_t := 0;
  var tmp:= uint8_t(@value);
  if aStream.&read(@tmp) maxLength(4) <> 4 then
    NSLog('***** Couldn''t read int32');  
  exit value;
end;

In the above code tmp is declared as a single byte and initialised using a type cast of the address of the value variable. 在上面的代码中, tmp被声明为一个字节,并使用变量地址的类型强制转换进行初始化。

So if the value variable is being stored at the memory address $12345678 (stupid example kept to 32-bit for brevity) then tmp will be initialised with the value $78 . 因此,如果将变量存储在内存地址$ 12345678 (为简便起见,愚蠢的示例保持在32位),则tmp将初始化为值$ 78 You then pass the address of the tmp variable to aStream.read() which tries to read 4 bytes into the location of the tmp variable. 然后,您将tmp变量的地址传递给aStream.read() ,它尝试将4个字节读取到tmp变量的位置。 But tmp is only a 1 byte value ! 但是tmp只是一个1字节的值

I think you need to change the declaration of tmp to make it a pointer to unit8_t , and then pass this directly to aStream.read() : 我认为您需要更改tmp的声明以使其成为对unit8_t指针 ,然后将其直接传递给aStream.read()

  var value: int32_t := 0;
  var tmp:= ^uint8_t(@value);
  if aStream.&read(tmp) maxLength(4) <> 4 then
    NSLog('***** Couldn''t read int32'); 

Or eliminate the tmp variable and pass the address of value directly, with an appropriate cast: 或消除tmp变量并通过适当的强制转换直接传递的地址:

  var value: int32_t := 0;
  if aStream.&read(^uint8_t(@value)) maxLength(4) <> 4 then
    NSLog('***** Couldn''t read int32'); 

This latter approach is more directly comparable to the Objective-C original. 后一种方法可以与Objective-C原始方法直接比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM