繁体   English   中英

如何从Indy中的SendCmd获得可解析的响应?

[英]How to get a parsable response from SendCmd in Indy?

如果我使用TIdImap4.SendCmd手动将不受支持的命令发送给Indy,我会有点困惑如何检索完整响应以手动分析它。

我正在发送以下命令来手动请求邮件的Gmail标签,因为Indy尚不支持此命令:

  IMAP.SendCmd(ImapCmdNum(),'UID FETCH '+uid+' (X-GM-LABELS)',['OK','BAD','NO'], false);

调用此命令后,我检查了Indy Log文件,它已成功从服务器接收到适当的响应:

Sent 9/19/2015 11:10:40 AM: C5 UID FETCH 2385 (X-GM-LABELS)<EOL>
Recv 9/19/2015 11:10:40 AM: * 542 FETCH (X-GM-LABELS (testlabel) UID 2385)<EOL>C5 OK Success<EOL>

但是现在,除了Indy的“确定”之外,我似乎无法获得其他任何回应。 我在调试器中尝试了以下操作,但它们都没有原始响应或我可能手动解析的任何其他内容:

IMAP.LastCmdResult = ('OK', $2521E60, nil, $2521EC0)
IMAP.LastCmdResult.Text = ()
IMAP.LastCmdResult.Code = 'OK'
IMAP.LastCmdResult.NumericCode = 0
IMAP.LastCmdResult.FormattedReply = ()

从SendCmd文档中:

SendCmd是一个重载函数,用于将AOut中指定的命令发送到对等连接。

SendCmd使用IOHandler将AOut中的命令写入对等连接。

AResponse指示命令允许的响应。

SendCmd调用GetResponse以确定是否允许来自对等连接的响应。 如果不允许响应,则在GetResponse中的处理过程中会引发异常。

当AResponse包含-1时,将使用空数组调用GetResponse,以指示该命令允许使用任何响应代码。 否则,AResponse中的值将用于验证响应代码。

使用LastCmdResult访问 命令响应 的数字和文本部分

我对此的理解是,我应该使用LastCmdResult来访问各种“部分响应”,但是它们都没有原始响应或响应的任何部分(“确定”除外),因此我如何从响应中获取可解析的内容发送到SendCmd?

实际上,您要查找的文本在LastCmdResult.Text属性中。 调试器没有向您显示它,但是标签数据在那里。

正如我2个月前在对您链接到的其他答案的评论中告诉您的那样:

查看TIdIMAP4.UIDRetrieveFlags()的实现。 它调用SendCmd()然后ParseLastCmdResult()解析返回的标志。 你将不得不重复同样的逻辑,代fdGmailLabels其中fdFlags当前正在使用(减去调用ParseMessageFlagString()被解析标志字符串到TIdMessageFlagsSet )。

如果您查看TIdIMAP4.UIDRetrieveFlags()的实现,然后查看您的代码,则您甚至都没有正确地调用SendCmd() 您正在将错误的值传递给ATag参数( unless ImapCmdNum()只是简单地调用TIdIMAP4.NewCmdCounter - TIdIMAP4需要生成命令计数器,以便它可以将它们与答复匹配),并且重要的是,您正在将错误的值传递给AExpectedResponses参数。

尝试以下方法(我对其进行了测试,并且可以正常工作):

type
  TIdIMAP4Access = class(TIdIMAP4);
  TIdIMAPLineStructAccess = class(TIdIMAPLineStruct);

var
  uid: string;
  labels: string;
begin
  ...
  uid := ...;
  labels := '';
  IMAP.SendCmd('UID FETCH ' + uid + ' (X-GM-LABELS)', ['FETCH','UID']);
  if IMAP.LastCmdResult.Code = IMAP_OK then
  begin
    if IMAP.LastCmdResult.Text.Count > 0 then
    begin
      // The requested data is in IMAP.LastCmdResult.Text[0].

      // You can either parse it manually, or use the below
      // code to let TIdIMAP4 parse it for you...

      if TIdIMAP4Access(IMAP).ParseLastCmdResult(IMAP.LastCmdResult.Text[0], 'FETCH', ['X-GM-LABELS']) then begin
        labels := TIdIMAPLineStructAccess(TIdIMAP4Access(IMAP).FLineStruct).IMAPValue;
      end;
    end;
  end;
  ...
end;

暂无
暂无

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

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