/* @lastChanged: "2000-05-30"
 
 * @filename:   vxt04
 * @purpose:    "XT_logscan"
 * @release:    7.2.0.0
 * @see:        "-.-"
 *
 * @copyright:  (c) 1999-2004 SAP AG"
 */
 
.tt 1 $SAP$LiveCache$VXT04$
.tt 3 $$XT_logscan$2000-10-18$
 
.nf
 
 .nf
 
 .nf

    ========== licence begin  GPL
    Copyright (c) 1999-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo

 
.fo
 
 
.fo
***********************************************************
 
Module  : XT_logscan
 
Define  :
 
        PROCEDURE
              x04logpage_display (VAR term : tut_terminal;
                    VAR protfile    : tut_vf_fileref;
                    scan            : tut_diag_scan;
                    VAR file_pos    : tut_file_pos;
                    VAR buf         : tsp00_MoveObj;
                    buf_size        : tsp00_Int4;
                    one_entryoffset : tsp00_Int4;
                    VAR pfkey       : tut_pfkey);
 
        PROCEDURE
              x04afterimagehead_display (VAR term : tut_terminal;
                    VAR protfile      : tut_vf_fileref;
                    scan              : tut_diag_scan;
                    VAR buf           : tsp00_MoveObj;
                    buf_size          : tsp00_Int4;
                    entry_offset      : tsp00_Int2;
                    entry_length      : tsp00_Int4;
                    currentIOSequence : tsp00_Int4;
                    VAR pfkey         : tut_pfkey;
                    VAR ln            : tsp00_Line;
                    VAR ln_len        : integer;
                    VAR err           : integer);
 
        FUNCTION
              x04offset_is_valid (VAR buf : tsp00_MoveObj;
                    buf_size     : tsp00_Int4;
                    entryOffset  : tsp00_Int4) : boolean;
 
        FUNCTION
              x04search_iosequence (VAR page : tsp00_MoveObj;
                    iosequence : tsp00_Int4) : boolean;
 
        FUNCTION
              x04search_for_transno (VAR buf : tsp00_MoveObj;
                    buf_size           : tsp00_Int4;
                    VAR wanted_transno : tgg91_TransNo;
                    wanted_action_id   : tsp00_Int4;
                    VAR end_of_trans   : boolean;
                    VAR entryOffset    : tsp00_Int4) : boolean;
 
        FUNCTION
              x04search_for_oid (VAR buf : tsp00_MoveObj;
                    buf_size         : tsp00_Int4;
                    VAR wanted_oid   : tgg00_OidSpace;
                    wanted_action_id : tsp00_Int4;
                    VAR entryOffset  : tsp00_Int4) : boolean;
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              XT_auxiliary_procedures : VXT05;
 
        PROCEDURE
              x05blockno_to_line (VAR file_pos : tut_file_pos;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_Line);
 
      ------------------------------ 
 
        FROM
              XT_dump_display : VXT08;
 
        PROCEDURE
              x08edit_display_action (VAR term : tut_terminal;
                    VAR protfile : tut_vf_fileref;
                    scan         : tut_diag_scan;
                    VAR buf      : tsp00_MoveObj;
                    buf_size     : tsp00_Int4;
                    buf_offset   : tsp00_Int4;
                    VAR pfkey    : tut_pfkey;
                    entry_length : tsp00_Int4;
                    actiontype   : tsp00_Uint1;
                    forRedo      : boolean);
 
      ------------------------------ 
 
        FROM
              GG_edit_routines : VGG17;
 
        PROCEDURE
              g17date_to_line (date : tsp00_Date (*ptocSynonym char**);
                    VAR ln_len      : integer;
                    VAR ln          : tsp00_Line (*ptocSynonym char**));
 
        PROCEDURE
              g17intdate_time (
                    int_date     : tsp00_Int4;
                    int_time     : tsp00_Int4;
                    VAR str_date : tsp00_Date (*ptocSynonym char**);
                    VAR str_time : tsp00_Time (*ptocSynonym char**));
 
        PROCEDURE
              g17nameto_line (n : tsp00_Name;
                    VAR ln_len  : integer;
                    VAR ln      : tsp00_Line);
 
        PROCEDURE
              g17time_to_line (time : tsp00_Time (*ptocSynonym char**);
                    VAR ln_len      : integer;
                    VAR ln          : tsp00_Line (*ptocSynonym char**));
 
        PROCEDURE
              g17trimint4_to_line (int : tsp00_Int4;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_Line);
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        FUNCTION
              gg06IsEqOidPnoPos (
                    VAR oid1 : tgg00_OidSpace;
                    VAR oid2 : tgg00_OidSpace): boolean;
 
        PROCEDURE
              gg06TransToLine (VAR TransNo : tgg91_TransNo;
                    VAR LineLen : integer;
                    VAR Line    : tsp00_Line);
 
        PROCEDURE
              gg06LogActionToLine (ActionType : integer;
                    VAR LineLen : integer;
                    VAR Line    : tsp00_Line);
 
      ------------------------------ 
 
        FROM
              TA_terminal_IO : VTA09;
 
        PROCEDURE
              t09put (VAR t09 : tut_terminal;
                    VAR text  : tsp00_Line;
                    text_attr : char);
 
      ------------------------------ 
 
        FROM
              TA_write_protfile : VTA12;
 
        PROCEDURE
              t12write_prot (VAR fileref : tut_vf_fileref;
                    VAR ln    : tsp00_Line;
                    length    : integer;
                    VAR error : integer);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              t09put;
 
              tsp00_C80 tsp00_Line
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : UweH
.sp
.cp 3
Created : 1986-01-17
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-10-18
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 18
.fo
.oc _/1
Description:
.fo
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      ALIGNMENT                  = 4;
      KERNEL74_PAGE_TRAILER_SIZE = 4;
      COMMIT_ENTRY_SIZE_WITH_TIMESTAMP = 32;
 
TYPE
 
      t_logpage_header = RECORD
            last_iosequence     : tsp00_Int4;
            pagetype            : tsp00_Uint1;
            parityalg           : tsp00_Uint1;
            parityvalue         : tsp00_Int2;
            (* *)
            date                : tsp00_Int4;
            time                : tsp00_Int4;
            (* *)
            queue_iosequence    : tsp00_Int4;
            queueid             : tsp00_Int2;
            offsetcount         : tsp00_Uint1;
            filler              : tsp00_Uint1;
      END;
 
 
      t_afterimage_header = RECORD
            actiontype            : tsp00_Uint1;
            isDone                : boolean;
            filler1               : tsp00_Int2;
            entrySequence         : tsp00_Int4;
            lastUndoEntrySequence : tsp00_Int4;
            transno               : tgg91_TransNo;
            filler2               : tsp00_Int2;
      END;
 
 
      t_action_object = RECORD
            oid              : tgg00_OidSpace;
            fileno           : tgg00_ObjFileNo;
            bodySize         : tsp00_Uint2;
            keySize          : tsp00_Uint2;
            objversion       : tgg91_PageRef;
            filler2          : tsp00_Int2;
      END;
 
 
 
(*------------------------------*) 
 
PROCEDURE
      x04logpage_display (VAR term : tut_terminal;
            VAR protfile    : tut_vf_fileref;
            scan            : tut_diag_scan;
            VAR file_pos    : tut_file_pos;
            VAR buf         : tsp00_MoveObj;
            buf_size        : tsp00_Int4;
            one_entryoffset : tsp00_Int4;
            VAR pfkey       : tut_pfkey);
 
VAR
      err                          : integer;
      ln_len                       : integer;
      ln                           : tsp00_Line;
      pHead                        : ^t_logpage_header;
      str_date                     : tsp00_Date;
      str_time                     : tsp00_Time;
      pOffset                      : ^tsp00_Int2;
      firstFreeOffset              : tsp00_Int4;
      currEntryNo                  : tsp00_Int4;
      currentIOSequence            : tsp00_Int4;
      currentOffsetCount           : tsp00_Int2;
      nextOffsetToChangeIOSequence : tsp00_Int4;
      entry_offset                 : tsp00_Int4;
      rest_length                  : tsp00_Int4;
      entry_length                 : tsp00_Int4;
      pInt4                        : ^tsp00_Int4;
 
BEGIN
pHead       := @buf;
pfkey       := pf_none;
ln          := term.blankline;
ln_len      := 0;
(* *)
g17nameto_line ('LOG PAGE          ', ln_len, ln);
ln_len := ln_len + 1;
(* *)
IF  pHead^.last_iosequence = -1 (* FFFFFFFF/UINT4 *)
THEN
    BEGIN
    (* is cleared *)
    g17nameto_line ('cleared           ', ln_len, ln);
    ln_len := ln_len + 1;
    (* *)
    x05blockno_to_line (file_pos, ln_len, ln);
    (* *)
    t12write_prot (protfile, ln, ln_len, err);
    t09put (term, ln, cut_bright_protected);
    END
ELSE
    BEGIN
    IF  pHead^.offsetcount > 1
    THEN
        BEGIN
        g17trimint4_to_line (pHead^.last_iosequence-pHead^.offsetcount+1, ln_len, ln);
        ln_len := ln_len + 1;
        ln[ln_len+1] := '-';
        ln_len := ln_len + 2;
        END;
    (*ENDIF*) 
    g17trimint4_to_line (pHead^.last_iosequence, ln_len, ln);
    ln_len := ln_len + 1;
    (* *)
    ln_len := ln_len + 1;
    ln[ln_len] := '(';
    g17trimint4_to_line (pHead^.queueid, ln_len, ln);
    ln_len := ln_len + 1;
    ln[ln_len] := '/';
    g17trimint4_to_line (pHead^.queue_iosequence, ln_len, ln);
    ln_len := ln_len + 1;
    ln[ln_len] := ')';
    ln_len := ln_len + 1;
    (* *)
    g17intdate_time (pHead^.date, pHead^.time, str_date, str_time);
    g17date_to_line (str_date, ln_len, ln);
    ln_len := ln_len + 1;
    g17time_to_line (str_time, ln_len, ln);
    ln_len := ln_len + 1;
    (* *)
    x05blockno_to_line (file_pos, ln_len, ln);
    (* *)
    t12write_prot (protfile, ln, ln_len, err);
    t09put (term, ln, cut_bright_protected);
    ln       := term.blankline;
    ln_len   := 0;
    (* *)
    IF  (utds_logentry_full_info in scan)
        OR
        (utds_logentry_header in scan)
    THEN
        BEGIN
        entry_offset := sizeof(tsp00_Page) - KERNEL74_PAGE_TRAILER_SIZE -
              (pHead^.offsetcount*sizeof(tsp00_Int2));
        pOffset         := @(buf[entry_offset+1]);
        firstFreeOffset := pOffset^;
        (* *)
        g17nameto_line ('first free offset:', ln_len, ln);
        ln_len := ln_len + 1;
        g17trimint4_to_line (firstFreeOffset, ln_len, ln);
        ln_len := ln_len + 1;
        (* *)
        t12write_prot (protfile, ln, ln_len, err);
        t09put (term, ln, cut_protected);
        ln       := term.blankline;
        ln_len   := 0;
        (* *)
        IF  firstFreeOffset = sizeof(t_logpage_header)
        THEN
            BEGIN
            (* page is empty *)
            g17nameto_line ('page is empty     ', ln_len, ln);
            (* *)
            t12write_prot (protfile, ln, ln_len, err);
            t09put (term, ln, cut_protected);
            ln       := term.blankline;
            ln_len   := 0;
            END
        ELSE
            BEGIN
            currEntryNo        := 1;
            entry_offset       := sizeof(t_logpage_header);
            currentIOSequence  := pHead^.last_iosequence-pHead^.offsetcount+1;
            currentOffsetCount := 1;
            pOffset            :=
                  @(buf[sizeof(tsp00_Page) - KERNEL74_PAGE_TRAILER_SIZE -
                  (currentOffsetCount*sizeof(tsp00_Int2)) + 1]);
            nextOffsetToChangeIOSequence := pOffset^;
            WHILE entry_offset < firstFreeOffset DO
                BEGIN
                IF  entry_offset >= nextOffsetToChangeIOSequence
                THEN
                    BEGIN
                    currentIOSequence  := currentIOSequence  + 1;
                    currentOffsetCount := currentOffsetCount + 1;
                    pOffset :=
                          @(buf[sizeof(tsp00_Page) - KERNEL74_PAGE_TRAILER_SIZE -
                          (currentOffsetCount*sizeof(tsp00_Int2)) + 1]);
                    nextOffsetToChangeIOSequence := pOffset^;
                    END;
                (*ENDIF*) 
                pInt4           := @buf[entry_offset+1];
                rest_length     := pInt4^;
                entry_length    := firstFreeOffset - entry_offset;
                IF  rest_length < entry_length
                THEN
                    (* logentry is split *)
                    entry_length := rest_length;
                (*ENDIF*) 
                IF  (one_entryoffset = 0)
                    OR
                    ((one_entryoffset <> 0)
                    AND
                    (one_entryoffset = entry_offset))
                THEN
                    xt04archivlog_entry_display (term, protfile, scan,
                          currEntryNo, currentIOSequence,
                          entry_offset, entry_length, rest_length,
                          buf, buf_size, pfkey);
                (*ENDIF*) 
                entry_offset := entry_offset + entry_length;
                entry_offset := ((entry_offset + ALIGNMENT - 1) DIV ALIGNMENT) * ALIGNMENT;
                currEntryNo  := currEntryNo + 1;
                END;
            (*ENDWHILE*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      xt04archivlog_entry_display (VAR term : tut_terminal;
            VAR protfile      : tut_vf_fileref;
            scan              : tut_diag_scan;
            entry_no          : tsp00_Int4;
            currentIOSequence : tsp00_Int4;
            entry_offset      : tsp00_Int4;
            entry_length      : tsp00_Int4;
            rest_length       : tsp00_Int4;
            VAR buf           : tsp00_MoveObj;
            buf_size          : tsp00_Int4;
            VAR pfkey         : tut_pfkey);
 
VAR
      err               : integer;
      ln_len            : integer;
      ln                : tsp00_Line;
 
BEGIN
ln                := term.blankline;
ln_len            := 0;
t12write_prot (protfile, ln, ln_len, err);
t09put (term, ln, cut_protected);
g17trimint4_to_line (entry_no, ln_len, ln);
ln_len := ln_len + 2;
ln[ln_len] := '(';
g17trimint4_to_line (entry_offset, ln_len, ln);
ln_len := ln_len + 1;
ln[ln_len] := ')';
ln_len := ln_len + 1;
(* *)
g17nameto_line ('length:           ', ln_len, ln);
ln_len := ln_len + 1;
g17trimint4_to_line (entry_length, ln_len, ln);
ln_len := ln_len + 2;
ln[ln_len] := '(';
g17trimint4_to_line (rest_length, ln_len, ln);
ln_len := ln_len + 1;
ln[ln_len] := ')';
ln_len := ln_len + 1;
x04afterimagehead_display (term, protfile, scan,
      buf, buf_size, entry_offset + sizeof(entry_length),
      entry_length, currentIOSequence,
      pfkey, ln, ln_len, err);
END;
 
(*------------------------------*) 
 
PROCEDURE
      x04afterimagehead_display (VAR term : tut_terminal;
            VAR protfile      : tut_vf_fileref;
            scan              : tut_diag_scan;
            VAR buf           : tsp00_MoveObj;
            buf_size          : tsp00_Int4;
            entry_offset      : tsp00_Int2;
            entry_length      : tsp00_Int4;
            currentIOSequence : tsp00_Int4;
            VAR pfkey         : tut_pfkey;
            VAR ln            : tsp00_Line;
            VAR ln_len        : integer;
            VAR err           : integer);
 
CONST
      c_for_redo = true;
 
VAR
      pHead : ^t_afterimage_header;
 
BEGIN
pHead  := @buf[entry_offset+1];
(* *)
IF  buf_size < entry_offset + sizeof(t_afterimage_header)
THEN
    BEGIN
    g17nameto_line ('AfterImage is corr', ln_len, ln);
    g17nameto_line ('upt. (current_leng', ln_len, ln);
    g17nameto_line ('th must be at leas', ln_len, ln);
    g17nameto_line ('t:                ', ln_len, ln);
    g17trimint4_to_line (sizeof(t_afterimage_header), ln_len, ln);
    t12write_prot (protfile, ln, ln_len, err);
    t09put (term, ln, cut_protected);
    END
ELSE
    BEGIN
    g17nameto_line ('T                 ', ln_len, ln);
    gg06TransToLine (pHead^.transno, ln_len, ln);
    ln_len := ln_len + 1;
    g17nameto_line ('#                 ', ln_len, ln);
    g17trimint4_to_line (pHead^.entrySequence, ln_len, ln);
    ln_len := ln_len + 1;
    ln[ln_len] := '(';
    g17trimint4_to_line (pHead^.lastUndoEntrySequence, ln_len, ln);
    ln_len := ln_len + 1;
    ln[ln_len] := ')';
    ln_len := ln_len + 2;
    ln[ln_len] := '[';
    g17trimint4_to_line (currentIOSequence, ln_len, ln);
    ln_len := ln_len + 1;
    ln[ln_len] := ']';
    ln_len := ln_len + 1;
    IF  pHead^.isDone
    THEN
        BEGIN
        g17nameto_line ('is done           ', ln_len, ln);
        ln_len := ln_len + 1;
        END;
    (*ENDIF*) 
    g17nameto_line ('type:             ', ln_len, ln);
    ln_len := ln_len + 1;
    gg06LogActionToLine (pHead^.actiontype, ln_len, ln);
    IF  (pHead^.actiontype = 1) (*Log_Commit*)
        OR
        (pHead^.actiontype = 2) (*Log_Rollback*)
        OR
        (pHead^.actiontype = 3) (*Log_PartialRollback*)
        OR
        (pHead^.actiontype = 29) (*Log_FinishOpenTrans*)
        OR
        (pHead^.actiontype = 30) (*Log_Savepoint*)
    THEN
        t09put (term, ln, cut_bright_protected)
    ELSE
        t09put (term, ln, cut_protected);
    (*ENDIF*) 
    t12write_prot (protfile, ln, ln_len, err);
    x08edit_display_action (term, protfile, scan, buf, buf_size,
          entry_offset+sizeof(t_afterimage_header), pfkey,
          entry_length, pHead^.actiontype, c_for_redo);
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      x04search_for_transno (VAR buf : tsp00_MoveObj;
            buf_size           : tsp00_Int4;
            VAR wanted_transno : tgg91_TransNo;
            wanted_action_id   : tsp00_Int4;
            VAR end_of_trans   : boolean;
            VAR entryOffset    : tsp00_Int4) : boolean;
 
VAR
      pLogPageHead    : ^t_logpage_header;
      pAfterImage     : ^t_afterimage_header;
      pOffset         : ^tsp00_Int2;
      pEntryLength    : ^tsp00_Int4;
      firstFreeOffset : tsp00_Int4;
      found           : boolean;
 
BEGIN
pLogPageHead := @buf;
IF  pLogPageHead^.last_iosequence = -1 (* FFFFFFFF/UINT4 means cleared *)
THEN
    x04search_for_transno := false
ELSE
    BEGIN
    firstFreeOffset := sizeof(tsp00_Page) - KERNEL74_PAGE_TRAILER_SIZE -
          (pLogPageHead^.offsetcount*sizeof(tsp00_Int2));
    pOffset         := @(buf[firstFreeOffset+1]);
    firstFreeOffset := pOffset^;
    (* *)
    IF  firstFreeOffset = sizeof(t_logpage_header) (* empty page *)
    THEN
        x04search_for_transno := false
    ELSE
        BEGIN
        IF  entryOffset = 0
        THEN
            entryOffset := sizeof(t_logpage_header)
        ELSE
            BEGIN
            pEntryLength := @buf[entryOffset + 1];
            entryOffset  := entryOffset + pEntryLength^;
            entryOffset  := ((entryOffset + ALIGNMENT - 1) DIV ALIGNMENT) * ALIGNMENT;
            END;
        (*ENDIF*) 
        found       := false;
        WHILE (entryOffset < firstFreeOffset)
              AND
              (entryOffset < buf_size)
              AND
              (entryOffset > 0)
              AND
              NOT found DO
            BEGIN
            pEntryLength := @buf[entryOffset + 1];
            IF  pEntryLength^ >= sizeof(pEntryLength^) + sizeof(t_afterimage_header)
            THEN
                BEGIN
                pAfterImage := @buf[entryOffset + sizeof(pEntryLength^) + 1];
                found       :=
                      ((wanted_action_id = 0) OR (wanted_action_id = pAfterImage^.actiontype))
                      AND
                      (wanted_transno = pAfterImage^.transno);
                end_of_trans := found
                      AND
                      ((pAfterImage^.actiontype = 1) OR (pAfterImage^.actiontype = 2));
                END;
            (*ENDIF*) 
            IF  NOT found
            THEN
                BEGIN
                entryOffset := entryOffset + pEntryLength^;
                entryOffset := ((entryOffset + ALIGNMENT - 1) DIV ALIGNMENT) * ALIGNMENT;
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        x04search_for_transno := found;
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      x04search_for_oid (VAR buf : tsp00_MoveObj;
            buf_size         : tsp00_Int4;
            VAR wanted_oid   : tgg00_OidSpace;
            wanted_action_id : tsp00_Int4;
            VAR entryOffset  : tsp00_Int4) : boolean;
 
VAR
      pLogPageHead    : ^t_logpage_header;
      pAfterImage     : ^t_afterimage_header;
      pObjectAction   : ^t_action_object;
      pOffset         : ^tsp00_Int2;
      pEntryLength    : ^tsp00_Int4;
      firstFreeOffset : tsp00_Int4;
      found           : boolean;
 
BEGIN
pLogPageHead := @buf;
IF  pLogPageHead^.last_iosequence = -1 (* FFFFFFFF/UINT4 means cleared *)
THEN
    x04search_for_oid := false
ELSE
    BEGIN
    firstFreeOffset := sizeof(tsp00_Page) - KERNEL74_PAGE_TRAILER_SIZE -
          (pLogPageHead^.offsetcount*sizeof(tsp00_Int2));
    pOffset         := @(buf[firstFreeOffset+1]);
    firstFreeOffset := pOffset^;
    (* *)
    IF  firstFreeOffset = sizeof(t_logpage_header) (* empty page *)
    THEN
        x04search_for_oid := false
    ELSE
        BEGIN
        IF  entryOffset = 0
        THEN
            entryOffset := sizeof(t_logpage_header)
        ELSE
            BEGIN
            pEntryLength := @buf[entryOffset + 1];
            entryOffset  := entryOffset + pEntryLength^;
            entryOffset  := ((entryOffset + ALIGNMENT - 1) DIV ALIGNMENT) * ALIGNMENT;
            END;
        (*ENDIF*) 
        found       := false;
        WHILE (entryOffset < firstFreeOffset)
              AND
              (entryOffset < buf_size)
              AND
              (entryOffset > 0)
              AND
              NOT found DO
            BEGIN
            pEntryLength := @buf[entryOffset + 1];
            IF  pEntryLength^ >= sizeof(pEntryLength^) + sizeof(t_afterimage_header)
            THEN
                BEGIN
                pAfterImage  := @buf[entryOffset + sizeof(pEntryLength^) + 1];
                IF  pAfterImage^.actiontype in [4,5,6,7,8,31]
                THEN
                    BEGIN
                    pObjectAction := @buf[entryOffset + sizeof(pEntryLength^) + sizeof(t_afterimage_header) +1];
                    found         :=
                          ((wanted_action_id = 0) OR (wanted_action_id = pAfterImage^.actiontype))
                          AND
                          gg06IsEqOidPnoPos (wanted_oid, pObjectAction^.oid);
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  NOT found
            THEN
                BEGIN
                entryOffset := entryOffset + pEntryLength^;
                entryOffset := ((entryOffset + ALIGNMENT - 1) DIV ALIGNMENT) * ALIGNMENT;
                END;
            (*ENDIF*) 
            END;
        (*ENDWHILE*) 
        x04search_for_oid := found;
        END;
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      x04search_iosequence (VAR page : tsp00_MoveObj;
            iosequence : tsp00_Int4) : boolean;
 
VAR
      pHead : ^t_logpage_header;
 
BEGIN
pHead := @page;
x04search_iosequence :=
      (iosequence >= pHead^.last_iosequence-pHead^.offsetcount+1)
      AND
      (iosequence <= pHead^.last_iosequence);
END;
 
(*------------------------------*) 
 
FUNCTION
      x04offset_is_valid (VAR buf : tsp00_MoveObj;
            buf_size     : tsp00_Int4;
            entryOffset  : tsp00_Int4) : boolean;
 
VAR
      pLogPageHead    : ^t_logpage_header;
      pOffset         : ^tsp00_Int2;
      firstFreeOffset : tsp00_Int4;
 
BEGIN
pLogPageHead := @buf;
IF  pLogPageHead^.last_iosequence = -1 (* FFFFFFFF/UINT4 means cleared *)
THEN
    x04offset_is_valid := false
ELSE
    BEGIN
    firstFreeOffset := buf_size - KERNEL74_PAGE_TRAILER_SIZE -
          (pLogPageHead^.offsetcount*sizeof(tsp00_Int2));
    pOffset         := @(buf[firstFreeOffset+1]);
    firstFreeOffset := pOffset^;
    (* *)
    IF  firstFreeOffset = sizeof(t_logpage_header) (* empty page *)
    THEN
        x04offset_is_valid := false
    ELSE
        x04offset_is_valid :=
              (entryOffset < firstFreeOffset)
              AND
              (entryOffset < buf_size)
              AND
              (entryOffset > 0);
    (*ENDIF*) 
    END;
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
