LINUX.ORG.RU

История изменений

Исправление bormant, (текущая версия) :

Посмотрел код, повнимательнее бы надо...

Например, PrepareBuffer:

Потенциальный выход за границы массива:
1) проверки вроде iBuf[Last - 3] хорошо бы предварять (Last>=3) and

Неоптимальности:
1) пачка копирований между KeyBuf, iBuf, oBuf: зачем?
2) если и копировать массивы, почему отдельным циклом поэлементно, а не не по Copy()?
3) внутри циклов SetLength(xBuf, Length(xBuf)+1): зачем?

На первый взгляд, PrepareBuffer мог бы выглядеть как-то так (если правильно идею уловил):

function IsEvCV(const E: input_event; ACode: cuint16; AValue: cint32): boolean; inline;
begin
  with E do Result := (Value = AValue) and (Code = ACode);
end; 

procedure PrepareBuffer;
var
  i, k, Len: integer;
begin
  //get rid of replace keys
  Len := Length(KeyBuf);
  if (Len >= 4) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 3], Key_RPL, 1) and
    (KeyBuf[Len - 2].Value = 0) and (KeyBuf[Len - 2].code in Shifts) and
    (KeyBuf[Len - 4].Value = 1) and (KeyBuf[Len - 4].code in Shifts)
  then
    Dec(Len, 4)
  else if (Len >= 2) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 2], Key_RPL, 1)
  then
    Dec(Len, 2 + Ord((Len >= 3) and (KeyBuf[Len - 3].Value = 1)));

  //cut of last line only
  i := Len - 2;
  while (i >= 0) and not IsEvCV(KeyBuf[i], KEY_ENTER, 0) do Dec(i);
  if i >= 0 then
  begin
    k := Len; Len := 0;
    for i := i + 1 to k - 1 do
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;

  //get rid of shiftdown-shiftup or BS
  k := Len; Len := 0;
  for i := 0 to k - 1 do
  begin
    if (Len > 0) and
      (KeyBuf[i].code in Shifts) and
      (KeyBuf[Len - 1].code in Shifts)
    then
      Dec(Len)
    else if (KeyBuf[i].code = KEY_BACKSPACE) then
    begin
      if Len > 0 then
      begin
        Dec(Len);
        if (KeyBuf[Len].code in Shifts) and (Len > 0) then
          KeyBuf[Len - 1] := KeyBuf[Len];
      end;
    end
    else
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;
  SetLength(KeyBuf, Len);

  sleep(10);
end;

Исправление bormant, :

Посмотрел код, повнимательнее бы надо...

Например, PrepareBuffer:

Потенциальный выход за границы массива:
1) проверки вроде iBuf[Last - 3] хорошо бы предварять (Last>=3) and

Неоптимальности:
1) пачка копирований между KeyBuf, iBuf, oBuf: зачем?
2) если и копировать массивы, почему отдельным циклом поэлементно, а не не по Copy()?
3) внутри циклов SetLength(xBuf, Length(xBuf)+1): зачем?

На первый взгляд, PrepareBuffer мог бы выглядеть как-то так (если правильно идею уловил):

function IsEvCV(const E: input_event; ACode: cuint16; AValue: cint32): boolean; inline;
begin
  with E do Result := (Value = AValue) and (Code = ACode);
end; 

procedure PrepareBuffer;
var
  i, k, Len: integer;
begin
  //get rid of replace keys
  Len := Length(KeyBuf);
  if (Len >= 4) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 3], Key_RPL, 1) and
    (KeyBuf[Len - 2].Value = 0) and (KeyBuf[Len - 2].code in Shifts) and
    (KeyBuf[Len - 4].Value = 1) and (KeyBuf[Len - 4].code in Shifts)
  then
    Dec(Len, 4)
  else if (Len >= 2) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 2], Key_RPL, 1)
  then
    Dec(Len, 2 + Ord((Len >= 3) and (KeyBuf[Len - 3].Value = 1)));

  //cut of last line only
  i := Len - 2;
  while (i >= 0) and not IsEvCV(KeyBuf[i], KEY_ENTER, 0) do Dec(i);
  if i > 0 then
  begin
    k := Len; Len := 0;
    for i := i to k - 1 do
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;

  //get rid of shiftdown-shiftup or BS
  k := Len; Len := 0;
  for i := 0 to k - 1 do
  begin
    if (Len > 0) and
      (KeyBuf[i].code in Shifts) and
      (KeyBuf[Len - 1].code in Shifts)
    then
      Dec(Len)
    else if (KeyBuf[i].code = KEY_BACKSPACE) then
    begin
      if Len > 0 then
      begin
        Dec(Len);
        if (KeyBuf[Len].code in Shifts) and (Len > 0) then
          KeyBuf[Len - 1] := KeyBuf[Len];
      end;
    end
    else
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;
  SetLength(KeyBuf, Len);

  sleep(10);
end;

Исходная версия bormant, :

Посмотрел код, повнимательнее бы надо...

Например, PrepareBuffer:

Потенциальный выход за границы массива:
1) проверки вроде iBuf[Last - 3] хорошо бы предварять (Last>=3) and

Неоптимальности:
1) пачка копирований между KeyBuf, iBuf, oBuf: зачем?
2) если и копировать массивы, почему отдельным циклом поэлементно, а не не по Copy()?
3) внутри циклов SetLength(xBuf, Length(xBuf)+1): зачем?

На первый взгляд, PrepareBuffer мог бы выглядеть как-то так (если правильно идею уловил):

function IsEvCV(const E: input_event; ACode: cuint16; AValue: cint32): boolean; inline;
begin
  with E do Result := (Value = AValue) and (Code = ACode);
end; 

procedure PrepareBuffer;
var
  i, k, Len: integer;
begin
  //get rid of replace keys
  Len := Length(KeyBuf);
  if (Len >= 4) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 3], Key_RPL, 1) and
    (KeyBuf[Len - 2].Value = 0) and (KeyBuf[Len - 2].code in Shifts) and
    (KeyBuf[Len - 4].Value = 1) and (KeyBuf[Len - 4].code in Shifts)
  then
    Dec(Len, 4)
  else
  if (Len >= 2) and
    IsEvCV(KeyBuf[Len - 1], Key_RPL, 0) and
    IsEvCV(KeyBuf[Len - 2], Key_RPL, 1)
  then
    Dec(Len, 2 + Ord((Len >= 3) and (KeyBuf[Len - 3].Value = 1)));

  //cut of last line only
  i := Len - 2;
  while (i >= 0) and not IsEvCV(KeyBuf[i], KEY_ENTER, 0) do Dec(i);
  if i > 0 then
  begin
    k := Len; Len := 0;
    for i := i to k - 1 do
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;

  //get rid of shiftdown-shiftup or BS
  k := Len; Len := 0;
  for i := 0 to k - 1 do
  begin
    if (Len > 0) and
      (KeyBuf[i].code in Shifts) and
      (KeyBuf[Len - 1].code in Shifts)
    then
      Dec(Len)
    else if (KeyBuf[i].code = KEY_BACKSPACE) then
    begin
      if Len > 0 then
      begin
        Dec(Len);
        if (KeyBuf[Len].code in Shifts) and (Len > 0) then
          KeyBuf[Len - 1] := KeyBuf[Len];
      end;
    end
    else
    begin
      KeyBuf[Len] := KeyBuf[i];
      Inc(Len);
    end;
  end;
  SetLength(KeyBuf, Len);

  sleep(10);
end;