summaryrefslogtreecommitdiff
path: root/plugins/ImportTXT/BqhfIP.inc
blob: 91160dd1ccbfcf1eaeec1c2dfd24222399441903 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
{$IFDEF BIN_IMPORT_}

var
  qhfver: byte;
  szMsgHd: word;
  UIDstr: UTF8String;
  UIDLen, NickLen: word;
  NickStr: UTF8String;

function DecodeQHFMsg(ver: byte; adr: integer; cSize: word): AnsiString;

  function get1(c: AnsiChar): byte;
  begin
    if ShortInt(c) >= 0 then
      Result := byte(c)
    else
      Result := byte(c) + 256;
  end;

  function get2(b: byte): AnsiChar;
  begin
    if b < 128 then
      Result := AnsiChar(b)
    else
      Result := AnsiChar(b - 256);
  end;

var
  i: integer;
begin
  SetLength(Result, cSize);
  for i := 1 to cSize do
  begin
    Result[i] := PAnsiChar(adr + i - 1)^;
    if ver <> $01 then
    begin
      inc(Result[i], i);
      Result[i] := get2(255 - get1(Result[i]));
    end
  end;
end;

{$ELSE}

begin
  pt := uint_ptr(pFileText);
  if FileLen >= $2E then
    if (PAnsiChar(pt)^ = 'Q') and (PAnsiChar(pt + 1)^ = 'H') and (PAnsiChar(pt + 2)^ = 'F') then
    begin
      qhfver := PByte(pt + 3)^;
      if qhfver >= $03 then
        szMsgHd := $23
      else
        szMsgHd := $21;
      fsz := RLInteger(pt + $04);

      UIDLen := RLWord(pt + $2C);
      SetLength(UIDstr, UIDLen);
      if qhfver <= 2 then
        lstrcpynA(PAnsiChar(UIDstr), PAnsiChar(pt + $2E), UIDLen)
      else
        lstrcpynA(PAnsiChar(UIDstr), PAnsiChar(pt + $2E), UIDLen + 1);

      NickLen := RLWord(pt + $2E + UIDLen);
      SetLength(NickStr, NickLen);
      if qhfver <= 2 then
        lstrcpynA(PAnsiChar(NickStr), PAnsiChar(pt + $2E + UIDLen + 2), UIDLen)
      else
        lstrcpynA(PAnsiChar(NickStr), PAnsiChar(pt + $2E + UIDLen + 2), UIDLen + 1);

      inc(pt, $2E + UIDLen + 2 + NickLen);
      if fsz <> FileLen - ($2E + UIDLen + 2 + NickLen) then
        fsz := FileLen - ($2E + UIDLen + 2 + NickLen);

      if (DContact.hContact = 0) or (DContact.hContact = INVALID_HANDLE_VALUE)
      then
      begin
        DContact.ContactUID := UIDstr;
        DContact.ContactNick := UTF8Decode{UTF8ToWideString}(NickStr);
        TryDetermContact(DContact);
      end;
      if (DContact.hContact = 0) or (DContact.hContact = INVALID_HANDLE_VALUE) then
        if (fContact.hContact <> 0) and (fContact.hContact <> INVALID_HANDLE_VALUE) then
          DContact := fContact;
      if (DContact.hContact <> 0) and (DContact.hContact <> INVALID_HANDLE_VALUE) then
      begin
        proto := GetContactProto(DContact.hContact);
        DoMessage(ITXT_THREAD_DEST_CONTACT, DContact.hContact, 0);
        DoMessage(ITXT_THREAD_START, 0, 0);
        DoMessage(ITXT_THREAD_MAXPROGRESS, 0, fsz);
        i := 0;
        while Cardinal(i) < fsz do
        begin
          fillchar(dbei, sizeof(dbei), 0);
          dbei.cbSize := sizeof(dbei);
          dbei.szModule := PAnsiChar(proto);
          dbei.timestamp := RLInteger(pt + i + $12);
          dbei.timestamp := dbei.timestamp -
            (Cardinal(CallService(MS_DB_TIME_TIMESTAMPTOLOCAL, dbei.timestamp, 0)) - dbei.timestamp); // ïðèâîäèì ê GMT
          if PByte(pt + i + $1A)^ = $00 then
            dbei.flags := DBEF_READ or DBEF_UTF
          else
            dbei.flags := DBEF_READ or DBEF_UTF or DBEF_SENT;
          // â ôàéëàõ ëåæàò â utf8 è èìïîðòèðóþòñÿ áåç èçìåíåíèé
          dbei.eventType := EVENTTYPE_MESSAGE;
          dbei.cbBlob := RLWord(pt + i + szMsgHd - 2) + 1;
          // ðàçìåð òåêñòà ñîîáùåíèÿ ñ #0
          dbei.pBlob := AllocMem(dbei.cbBlob);

          try
            Move(DecodeQHFMsg(qhfver, pt + i + szMsgHd, dbei.cbBlob - 1)[1],
              dbei.pBlob^, dbei.cbBlob - 1);
            if not IsDuplicateEvent(DContact.hContact, dbei) then
              if db_event_add(DContact.hContact, @dbei) <> 0 then
                inc(AddedMessages)
              else
              begin
                s := 'Error adding message to database';
                DoMessage(ITXT_THREAD_ERROR, wparam(PWideChar(s)), 0);
                break;
              end

            else
              inc(Duplicates);

          finally
            inc(i, szMsgHd + dbei.cbBlob - 1);
            FreeMem(dbei.pBlob);
          end;
          DoMessage(ITXT_THREAD_PROGRESS, i, 0);
        end;
      end
      else
      begin
        s := TranslateWideString('Can''t determine destination contact');
        DoMessage(ITXT_THREAD_ERROR, wparam(PWideChar(s)), 0);
      end;
    end
    else
    begin
      s := WideFormat(TranslateWideString('It''s not %s file'), ['QHF']);
      DoMessage(ITXT_THREAD_ERROR, wparam(PWideChar(s)), 0);
    end
  else // file len
end;
{$ENDIF}