如果我使用TIdImap4.SendCmd手动向Indy发送不支持的命令,我有点困惑如何检索完整响应以手动解析它。
我发送以下命令手动请求邮件的Gmail标签,因为这是not yet supported by 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>
但是现在我似乎无法获得该回复的任何部分而不是&#39; OK&#39;来自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来访问响应的各个部分&#34;但是没有一个具有原始响应或响应的任何部分,除了&#34; OK&# 34;,那么如何从SendCmd的响应中获取可解析的内容?
答案 0 :(得分:1)
您要查找的文本实际上位于LastCmdResult.Text
属性中。调试器没有向您显示,但这是标签数据的位置。
正如我2个月前在my other answer的评论中告诉你的那样,你链接到:
查看
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;