.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.TT 1 $SQL$Project Distributed Database System$VBD60$
.tt 2 $$$
.TT 3 $JuergenP$bytestring_handling$1999-09-08$
***********************************************************
.nf
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 2000-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
.nf
.sp
MODULE  : bytestring_handling
=========
.sp
Purpose : bytestring primitives
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b60conlput_bstrleaf (VAR nptr : tbd_node_ptrs;
                    pos           : tsp00_Int4;
                    length        : tsp00_Int4;
                    VAR b         : tsp00_Page;
                    VAR firstcall : boolean;
                    extended      : boolean;
                    VAR filelen   : tsp00_Int4;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              b60extend_bytestr (VAR nptr : tbd_node_ptrs;
                    pos         : tsp00_Int4;
                    length      : tsp00_Int4;
                    use_buf     : boolean;
                    fill_char   : char;
                    buf_size    : tsp00_Int4;
                    buf_addr    : tsp00_MoveObjPtr;
                    bufpos      : tsp00_Int4;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b60get_bytestr (VAR nptr : tbd_node_ptrs;
                    pos         : tsp00_Int4;
                    length      : tsp00_Int4;
                    buf_size    : tsp00_Int4;
                    buf_addr    : tsp00_MoveObjPtr;
                    bufpos      : tsp00_Int4;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b60lput_bstrleaf (VAR nptr : tbd_node_ptrs;
                    pos         : tsp00_Int4;
                    length      : tsp00_Int4;
                    use_buf     : boolean;
                    fill_char   : char;
                    buf_size    : tsp00_Int4;
                    buf_addr    : tsp00_MoveObjPtr;
                    bufpos      : tsp00_Int4;
                    extended    : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b60new_bytestr (VAR current : tbd_current_tree);
 
        PROCEDURE
              b60read_bytestr (nptr : tbd_nodeptr;
                    pos      : tsp00_Int4;
                    length   : tsp00_Int4;
                    buf_size : tsp00_Int4;
                    buf_addr : tsp00_MoveObjPtr;
                    buf_pos  : tsp00_Int4;
                    VAR e    : tgg00_BasisError);
 
        PROCEDURE
              b60release_bytestr (VAR current : tbd_current_tree);
 
        PROCEDURE
              b60rext_bstrroot (VAR nptr : tbd_node_ptrs;
                    pos         : tsp00_Int4;
                    length      : tsp00_Int4;
                    use_buf     : boolean;
                    fill_char   : char;
                    buf_size    : tsp00_Int4;
                    buf_addr    : tsp00_MoveObjPtr;
                    bufpos      : tsp00_Int4;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b60rput_bstrroot (VAR nptr : tbd_node_ptrs;
                    pos         : tsp00_Int4;
                    length      : tsp00_Int4;
                    use_buf     : boolean;
                    fill_char   : char;
                    buf_size    : tsp00_Int4;
                    buf_addr    : tsp00_MoveObjPtr;
                    bufpos      : tsp00_Int4;
                    extended    : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd60CheckByteStr (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
        PROCEDURE
              bd60GetNextByteLeafPage (
                    VAR nextLeafPage : tsp00_PageNo;
                    VAR nptr         : tbd_node_ptrs;
                    VAR current      : tbd_current_tree);
 
        PROCEDURE
              bd60VerifyByteStr (
                    VAR trans        : tgg00_TransContext;
                    VAR fileId       : tgg00_FileId;
                    bUpdateConverter : boolean;
                    VAR numPages     : tsp00_Int4);
 
        PROCEDURE
              bd60ExtractBlob (
                    VAR current      : tbd_current_tree;
                    VAR hostFileName : tsp00_VFilename);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06file_opmsg (
                    msg_no     : tsp00_Int4;
                    VAR fileId : tgg00_FileId);
 
        PROCEDURE
              b06dump_bad_page (pid : tsp00_TaskId;
                    page_type_flag : char;
                    file_ext       : tsp00_C4;
                    bad_pno        : tsp00_Int4;
                    buf_ptr        : tbd_nodeptr;
                    curr_buf_cnt   : integer);
 
      ------------------------------ 
 
        FROM
              pagestore : VBD10;
 
        PROCEDURE
              b10use_pno (VAR t : tgg00_TransContext;
                    data_pno : tsp00_PageNo);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              bd13GetNode (VAR Current : tbd_current_tree;
                    Pno          : tsp00_PageNo;
                    PageLockMode : tbd00_PageLockMode;
                    NodeReq      : tbd_node_request;
                    VAR Nptrs    : tbd_node_ptrs);
 
        PROCEDURE
              b13new_node (lno : tsp00_Int2;
                    VAR nptr    : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b13new_root (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b13free_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b13r_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree;
                    lru_info    : tbd_lru_info);
 
        PROCEDURE
              b13w_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              filedirectory : VBD17;
 
        FUNCTION
              bd17GetFdirRoot : tsp00_PageNo;
 
        FUNCTION
              bd17GetLongFdirRoot : tsp00_PageNo;
 
      ------------------------------ 
 
        FROM
              treehandling : VBD30;
 
        PROCEDURE
              bd30GetTree (
                    VAR trans            : tgg00_TransContext;
                    VAR fileId           : tgg00_FileId;
                    VAR current          : tbd_current_tree;
                    messType             : tgg00_MessType;
                    bLockTreeExcl        : boolean;
                    bSynchronizeExclLock : boolean);
 
        PROCEDURE
              bd30ReleaseTree (
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30ResetBadFile (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              bytestring_indexhandling : VBD61;
 
        PROCEDURE
              b61wsearch_writeleaf (VAR nptr : tbd_node_ptrs;
                    pos               : tsp00_Int4;
                    VAR leaf_pos      : tsp00_Int4;
                    VAR pre_last_page : boolean;
                    VAR current       : tbd_current_tree);
 
        PROCEDURE
              b61add_bstrindex (VAR act_rootptr : tbd_node_ptrs;
                    act_pno     : tsp00_PageNo;
                    pno_1       : tsp00_PageNo;
                    pno_2       : tsp00_PageNo;
                    ins_level   : tsp00_Int2;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61trunc_bstr (VAR nptr : tbd_node_ptrs;
                    new_flength : tsp00_Int4;
                    destroy     : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61gfree_garb_node (pno : tsp00_PageNo;
                    twice       : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61change_content (VAR nptr : tbd_node_ptrs;
                    VAR rootptr : tbd_node_ptrs;
                    t           : tgg00_TransContextPtr);
 
        PROCEDURE
              b61search_leaf (VAR nptr : tbd_node_ptrs;
                    pos          : tsp00_Int4;
                    VAR leaf_pos : tsp00_Int4;
                    VAR current  : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        PROCEDURE
              g01opmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    msg_value : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : char;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20ch4 (pno : tsp00_PageNo;
                    VAR n : tbd_node;
                    pos   : tsp00_Int4);
 
        FUNCTION
              s20or4a (VAR n : tbd_node;
                    pos : tsp00_Int4) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vfopen (
                    VAR hostfile   : tsp00_VFilename;
                    VAR hostfileno : tsp00_Int4;
                    VAR error      : tsp00_VfReturn;
                    VAR errtext    : tsp00_ErrText);
 
        PROCEDURE
              vfwrite (hostfileno : tsp00_Int4;
                    buf         : tsp00_VfBufaddr;
                    VAR error   : tsp00_VfReturn;
                    VAR errtext : tsp00_ErrText);
 
        PROCEDURE
              vfclose (
                    hostfileno  : tsp00_Int4;
                    VAR error   : tsp00_VfReturn;
                    VAR errtext : tsp00_ErrText);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01page (layer : tgg00_Debug;
                    VAR n    : tbd_node;
                    start_p  : tsp00_Int4;
                    stop_p   : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              s20ch4;
 
              tsp00_Int4    tsp00_PageNo
              tsp00_MoveObj tbd_node
 
        FUNCTION
              s20or4a;
 
              tsp00_MoveObj tbd_node
 
        PROCEDURE
              vfwrite;
 
              tsp_vf_bufaddr tsp00_VfBufaddr
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
&             ifdef TRACE
 
        PROCEDURE
              t01page;
 
              tsp00_Page tbd_node
&             endif
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1984-07-10
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-09-08
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
 
.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
      c_bUpdateConverter = true;
 
 
(*------------------------------*) 
 
PROCEDURE
      b60conlput_bstrleaf (VAR nptr : tbd_node_ptrs;
            pos           : tsp00_Int4;
            length        : tsp00_Int4;
            VAR b         : tsp00_Page;
            VAR firstcall : boolean;
            extended      : boolean;
            VAR filelen   : tsp00_Int4;
            VAR current   : tbd_current_tree);
 
VAR
      ready         : boolean;
      pre_last_page : boolean;
      leaf_pos      : tsp00_Int4;
      part_length   : tsp00_Int4;
      buf_pos       : tsp00_Int4;
      rootptr       : tbd_node_ptrs;
      next          : tsp00_PageNo;
 
BEGIN
(* rn_asyn_io is used because b60conlput is called only by *)
(* bd05copy which - on successful execution - is finished  *)
(* by a call to b20flush *)
ready   := false;
buf_pos := 1;
next    := NIL_PAGE_NO_GG00;
IF  firstcall
THEN
    BEGIN
    rootptr := nptr;
    b61wsearch_writeleaf (nptr, pos, leaf_pos, pre_last_page, current);
    firstcall := false
    END
ELSE
    BEGIN
    rootptr.np_ptr   := NIL;
    rootptr.np_cbptr := NIL;
    leaf_pos         := pos MOD MAX_BSTR_COVERING_BD00
    END;
(*ENDIF*) 
WITH current, curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        REPEAT
            IF  next <> NIL_PAGE_NO_GG00
            THEN
                BEGIN
&               ifdef TRACE
                t01page (bd_byte, nptr.np_ptr^, 1, 40);
&               endif
                b13w_release_node (nptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    bd13GetNode (current, next, plmLock_ebd00, nr_for_update, nptr);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (leaf_pos + length) > MAX_BSTR_COVERING_BD00
                THEN
                    part_length := MAX_BSTR_COVERING_BD00 - leaf_pos
                ELSE
                    part_length := length;
                (*ENDIF*) 
                bd60write_bstr (nptr.np_ptr, leaf_pos,
                      part_length, sizeof (b), @b, buf_pos, trError_gg00);
                IF  part_length <> length
                THEN
                    BEGIN
                    length   := length - part_length;
                    buf_pos  := buf_pos + part_length;
                    leaf_pos := 0;
                    next     := nptr.np_ptr^.nd_right
                    END
                ELSE
                    ready := true
                (*ENDIF*) 
                END
            (*ENDIF*) 
        UNTIL
            (trError_gg00 <> e_ok) OR ready;
        (*ENDREPEAT*) 
        IF  (trError_gg00 = e_ok) AND extended AND
            (nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00)
        THEN
            BEGIN
            b61gfree_garb_node (nptr.np_ptr^.nd_right, true, current);
            IF  trError_gg00 = e_ok
            THEN
                nptr.np_ptr^.nd_right := NIL_PAGE_NO_GG00
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (rootptr.np_ptr <> NIL) AND extended
        THEN
            BEGIN
            rootptr.np_ptr^.ndStrFileSize_bd00 := pos + length;
            filelen := rootptr.np_ptr^.ndStrFileSize_bd00;
            b13w_release_node (rootptr, current)
            END
        ELSE
            IF  extended
            THEN
                BEGIN
                bd13GetNode (current, current.curr_tree_id.fileRoot_gg00,
                      plmLock_ebd00, nr_for_update, rootptr);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    rootptr.np_ptr^.ndStrFileSize_bd00 := pos + length;
                    filelen := rootptr.np_ptr^.ndStrFileSize_bd00;
                    b13w_release_node (rootptr, current)
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (rootptr.np_ptr <> NIL)
        THEN
            IF  extended
            THEN
                b13w_release_node (rootptr, current)
            ELSE
                b13r_release_node (rootptr, current, lru_normal)
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (rootptr.np_ptr <> NIL)
    THEN
        b13r_release_node (rootptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60extend_bytestr (VAR nptr : tbd_node_ptrs;
            pos         : tsp00_Int4;
            length      : tsp00_Int4;
            use_buf     : boolean;
            fill_char   : char;
            buf_size    : tsp00_Int4;
            buf_addr    : tsp00_MoveObjPtr;
            bufpos      : tsp00_Int4;
            VAR current : tbd_current_tree);
 
VAR
      change_pno    : boolean;
      pre_last_page : boolean;
      part_length   : tsp00_Int4;
      leaf_pos      : tsp00_Int4;
      act_rootptr   : tbd_node_ptrs;
      inew_nptr     : tbd_node_ptrs;
      iinew_nptr    : tbd_node_ptrs;
      last_nptr     : tbd_node_ptrs;
      inew_pno      : tsp00_PageNo;
      iinew_pno     : tsp00_PageNo;
      new_length    : tsp00_Int4;
 
BEGIN
change_pno           := false;
pre_last_page        := false;
act_rootptr.np_ptr   := NIL;
act_rootptr.np_cbptr := NIL;
inew_nptr.np_ptr     := NIL;
inew_nptr.np_cbptr   := NIL;
iinew_nptr.np_ptr    := NIL;
iinew_nptr.np_cbptr  := NIL;
last_nptr.np_ptr     := NIL;
last_nptr.np_cbptr   := NIL;
iinew_pno            := NIL_PAGE_NO_GG00;
new_length           := pos + length;
WITH current, curr_trans^ DO
    BEGIN
    IF  nptr.np_ptr^.nd_id = curr_tree_id.fileRoot_gg00
    THEN
        BEGIN
        act_rootptr := nptr;
        IF  (pos MOD MAX_BSTR_COVERING_BD00) = 0
        THEN
            BEGIN
            b61wsearch_writeleaf (nptr, pos - 1, leaf_pos,
                  pre_last_page, current);
            leaf_pos := leaf_pos + 1
            END
        ELSE
            b61wsearch_writeleaf (nptr, pos, leaf_pos, pre_last_page,
                  current)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        leaf_pos := MAX_BSTR_COVERING_BD00;
        bd13GetNode (current, current.curr_tree_id.fileRoot_gg00,
              plmLock_ebd00, nr_for_update, act_rootptr);
        END;
    (*ENDIF*) 
    (**************************************************???????????????*)
    IF  (nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00) AND (trError_gg00 = e_ok)
    THEN
        BEGIN
        IF  pre_last_page
        THEN
            change_pno := true;
        (*ENDIF*) 
        bd13GetNode (current, nptr.np_ptr^.nd_right,
              plmLock_ebd00, nr_for_update, inew_nptr);
        END
    ELSE
        b13new_node (LEAF_LEVEL_BD00, inew_nptr, current);
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  leaf_pos <> MAX_BSTR_COVERING_BD00
        THEN
            BEGIN
            part_length := MAX_BSTR_COVERING_BD00 - leaf_pos;
            IF  use_buf
            THEN
                bd60write_bstr (nptr.np_ptr, leaf_pos,
                      part_length, buf_size, buf_addr, bufpos, trError_gg00)
            ELSE
                bd60fill_bstr (nptr.np_ptr, leaf_pos,
                      part_length, fill_char, trError_gg00);
            (*ENDIF*) 
            bufpos := bufpos + part_length;
            length := length - part_length
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            nptr.np_ptr^.nd_right := inew_nptr.np_ptr^.nd_id;
            leaf_pos              := 0;
            IF  length > MAX_BSTR_COVERING_BD00
            THEN
                BEGIN
                part_length := MAX_BSTR_COVERING_BD00;
                IF  inew_nptr.np_ptr^.nd_right = NIL_PAGE_NO_GG00
                THEN
                    b13new_node (LEAF_LEVEL_BD00, iinew_nptr, current)
                ELSE
                    bd13GetNode (current, inew_nptr.np_ptr^.nd_right,
                          plmLock_ebd00, nr_for_update, iinew_nptr);
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                part_length := length;
                IF  inew_nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00
                THEN
                    BEGIN
                    b61gfree_garb_node (inew_nptr.np_ptr^.nd_right,
                          false, current);
                    IF  trError_gg00 = e_ok
                    THEN
                        inew_nptr.np_ptr^.nd_right := NIL_PAGE_NO_GG00
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  use_buf
            THEN
                bd60write_bstr (inew_nptr.np_ptr, leaf_pos,
                      part_length, buf_size, buf_addr, bufpos, trError_gg00)
            ELSE
                bd60fill_bstr (inew_nptr.np_ptr, leaf_pos,
                      part_length, fill_char, trError_gg00);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                inew_nptr.np_ptr^.nd_left := nptr.np_ptr^.nd_id;
                length := length - part_length;
                IF  length <> 0
                THEN
                    BEGIN
                    inew_nptr.np_ptr^.nd_right :=
                          iinew_nptr.np_ptr^.nd_id;
                    bufpos := bufpos + part_length;
                    IF  use_buf
                    THEN
                        bd60write_bstr (iinew_nptr.np_ptr, leaf_pos,
                              length, buf_size, buf_addr, bufpos,
                              trError_gg00)
                    ELSE
                        bd60fill_bstr (iinew_nptr.np_ptr, leaf_pos,
                              length, fill_char, trError_gg00);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        iinew_nptr.np_ptr^.nd_left :=
                              inew_nptr.np_ptr^.nd_id;
                        iinew_pno := iinew_nptr.np_ptr^.nd_id;
&                       ifdef TRACE
                        t01page (bd_byte, iinew_nptr.np_ptr^, 1, 40);
&                       endif
                        IF  use_buf
                        THEN
                            b13w_release_node (iinew_nptr, current)
                        ELSE
                            last_nptr := iinew_nptr
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                inew_pno := inew_nptr.np_ptr^.nd_id;
&               ifdef TRACE
                t01page (bd_byte, inew_nptr.np_ptr^, 1, 40);
&               endif
                IF  (last_nptr.np_ptr <> NIL) OR use_buf
                THEN
                    b13w_release_node (inew_nptr, current)
                ELSE
                    last_nptr := inew_nptr;
                (*ENDIF*) 
&               ifdef TRACE
                t01page (bd_byte, nptr.np_ptr^, 1, 40);
&               endif
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    b13w_release_node (nptr, current);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        nptr := last_nptr;
                        act_rootptr.np_ptr^.ndStrFileSize_bd00 := new_length;
                        IF  change_pno
                        THEN
                            b61add_bstrindex (act_rootptr,
                                  act_rootptr.np_ptr^.nd_id, iinew_pno,
                                  NIL_PAGE_NO_GG00, succ (LEAF_LEVEL_BD00),
                                  current)
                        ELSE
                            b61add_bstrindex (act_rootptr,
                                  act_rootptr.np_ptr^.nd_id, inew_pno,
                                  iinew_pno, succ (LEAF_LEVEL_BD00),
                                  current)
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  inew_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (inew_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  iinew_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (iinew_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  act_rootptr.np_ptr <> NIL
        THEN
            b13r_release_node (act_rootptr, current, lru_normal);
        (*ENDIF*) 
        IF  last_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (last_nptr, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60get_bytestr (VAR nptr : tbd_node_ptrs;
            pos         : tsp00_Int4;
            length      : tsp00_Int4;
            buf_size    : tsp00_Int4;
            buf_addr    : tsp00_MoveObjPtr;
            bufpos      : tsp00_Int4;
            VAR current : tbd_current_tree);
 
VAR
      ready       : boolean;
      part_length : tsp00_Int4;
      n_id, next  : tsp00_PageNo;
 
BEGIN
next := NIL_PAGE_NO_GG00;
ready := false;
WITH  current.curr_trans^ DO
    REPEAT
        IF  next <> NIL_PAGE_NO_GG00
        THEN
            bd13GetNode (current, next, plmLock_ebd00, nr_for_read, nptr);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  (pos + length) >= MAX_BSTR_COVERING_BD00
            THEN
                part_length := MAX_BSTR_COVERING_BD00 - pos
            ELSE
                part_length := length;
            (*ENDIF*) 
            b60read_bytestr (nptr.np_ptr, pos, part_length,
                  buf_size, buf_addr, bufpos, trError_gg00);
            IF  (part_length <> length) AND (trError_gg00 = e_ok)
            THEN
                BEGIN
                length := length - part_length;
                bufpos := bufpos + part_length;
                pos    := 0;
                next   := nptr.np_ptr^.nd_right;
                n_id   := nptr.np_ptr^.nd_id;
                b13r_release_node (nptr, current, lru_normal)
                END
            ELSE
                ready := true;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    UNTIL
        (current.curr_trans^.trError_gg00 <> e_ok) OR ready
    (*ENDREPEAT*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60lput_bstrleaf (VAR nptr : tbd_node_ptrs;
            pos         : tsp00_Int4;
            length      : tsp00_Int4;
            use_buf     : boolean;
            fill_char   : char;
            buf_size    : tsp00_Int4;
            buf_addr    : tsp00_MoveObjPtr;
            bufpos      : tsp00_Int4;
            extended    : boolean;
            VAR current : tbd_current_tree);
 
VAR
      ready         : boolean;
      pre_last_page : boolean;
      leaf_pos      : tsp00_Int4;
      part_length   : tsp00_Int4;
      root_ptr      : tbd_node_ptrs;
      next          : tsp00_Int4;
 
BEGIN
next  := NIL_PAGE_NO_GG00;
ready := false;
root_ptr := nptr;
IF  extended
THEN
    root_ptr.np_ptr^.ndStrFileSize_bd00 := pos + length;
(*ENDIF*) 
WITH current, curr_trans^ DO
    BEGIN
    IF  nptr.np_ptr^.nd_id = current.curr_tree_id.fileRoot_gg00
    THEN
        b61wsearch_writeleaf (nptr, pos, leaf_pos, pre_last_page,
              current);
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        REPEAT
            IF  next <> NIL_PAGE_NO_GG00
            THEN
                BEGIN
&               ifdef TRACE
                t01page (bd_byte, nptr.np_ptr^, 1, 40);
&               endif
                b13w_release_node (nptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    bd13GetNode (current, next, plmLock_ebd00, nr_for_update, nptr);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (leaf_pos + length) > MAX_BSTR_COVERING_BD00
                THEN
                    part_length := MAX_BSTR_COVERING_BD00 - leaf_pos
                ELSE
                    part_length := length;
                (*ENDIF*) 
                IF  use_buf
                THEN
                    bd60write_bstr (nptr.np_ptr, leaf_pos, part_length,
                          buf_size, buf_addr, bufpos, trError_gg00)
                ELSE
                    bd60fill_bstr (nptr.np_ptr, leaf_pos, part_length,
                          fill_char, trError_gg00);
                (*ENDIF*) 
                IF  part_length <> length
                THEN
                    BEGIN
                    length   := length - part_length;
                    bufpos   := bufpos + part_length;
                    leaf_pos := 0;
                    next     := nptr.np_ptr^.nd_right
                    END
                ELSE
                    ready := true
                (*ENDIF*) 
                END
            (*ENDIF*) 
        UNTIL
            (trError_gg00 <> e_ok) OR ready;
        (*ENDREPEAT*) 
        IF  (trError_gg00 = e_ok) AND extended AND
            (nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00)
        THEN
            BEGIN
            b61gfree_garb_node (nptr.np_ptr^.nd_right, true, current);
            IF  trError_gg00 = e_ok
            THEN
                nptr.np_ptr^.nd_right := NIL_PAGE_NO_GG00
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
&           ifdef TRACE
            t01page (bd_byte, nptr.np_ptr^, 1, 40);
&           endif
            IF  use_buf
            THEN
                b13w_release_node (nptr, current);
            (*ENDIF*) 
            IF  extended AND use_buf
            THEN
                b13w_release_node (root_ptr, current)
            ELSE
                b13r_release_node (root_ptr, current, lru_normal)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (root_ptr.np_ptr <> NIL)
    THEN
        b13r_release_node (root_ptr, current, lru_normal);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60new_bytestr (VAR current : tbd_current_tree);
 
VAR
      nptr : tbd_node_ptrs;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    curr_tree_id.fileType_gg00 := [ftsByteStr_egg00, ftsConcurrent_egg00];
    curr_tree_id.fileRoot_gg00 := NIL_PAGE_NO_GG00;
    (*  curr_tree_id.fileRoot_gg00 must be initialized *)
    b13new_root (nptr, current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        current.curr_tree_id.fileRoot_gg00 := nptr.np_ptr^.nd_id;
        b13w_release_node (nptr, current)
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60read_bytestr (nptr : tbd_nodeptr;
            pos      : tsp00_Int4;
            length   : tsp00_Int4;
            buf_size : tsp00_Int4;
            buf_addr : tsp00_MoveObjPtr;
            buf_pos  : tsp00_Int4;
            VAR e    : tgg00_BasisError);
 
BEGIN
pos := pos + BODY_BEG_BD00;
g10mv ('VBD60 ',   1,    
      sizeof (nptr^), buf_size, @nptr^, pos,
      @buf_addr^, buf_pos, length, e)
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60release_bytestr (VAR current : tbd_current_tree);
 
VAR
      aux_error : tgg00_BasisError;
      nptr      : tbd_node_ptrs;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  ((fileRoot_gg00 = bd17GetFdirRoot) OR (fileRoot_gg00 = bd17GetLongFdirRoot))
        AND (ftsPerm_egg00 IN fileType_gg00)
    THEN
        trError_gg00 := e_do_not_drop_fdir;
    (*ENDIF*) 
    IF   trError_gg00 = e_ok
    THEN
        nptr := currRootNptrs_bd00;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        b61trunc_bstr (nptr, 0, true, current);
        IF  (trError_gg00 = e_ok) OR (trError_gg00 = e_bad_datapage)
        THEN
            BEGIN
            aux_error    := trError_gg00;
            trError_gg00 := e_ok;
            b13w_release_node (nptr, current);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                nptr := currRootNptrs_bd00;
                b13free_node (nptr, current);
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                trError_gg00 := aux_error
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    IF  (trError_gg00 <> e_disk_not_accessible) AND
        (trError_gg00 <> e_do_not_drop_fdir)
    THEN
        trError_gg00 := e_ok
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60rext_bstrroot (VAR nptr : tbd_node_ptrs;
            pos         : tsp00_Int4;
            length      : tsp00_Int4;
            use_buf     : boolean;
            fill_char   : char;
            buf_size    : tsp00_Int4;
            buf_addr    : tsp00_MoveObjPtr;
            bufpos      : tsp00_Int4;
            VAR current : tbd_current_tree);
 
VAR
      part_length   : tsp00_Int4;
      leaf_pos      : tsp00_Int4;
      index_pos     : tsp00_Int4;
      inew_nptr     : tbd_node_ptrs;
      iinew_nptr    : tbd_node_ptrs;
      new_rootptr   : tbd_node_ptrs;
      last_nptr     : tbd_node_ptrs;
      n_pno         : tsp00_PageNo;
      inew_pno      : tsp00_PageNo;
      iinew_pno     : tsp00_PageNo;
      new_length    : tsp00_Int4;
 
BEGIN
IF  use_buf
THEN
    leaf_pos := pos
ELSE
    leaf_pos := MAX_BSTR_COVERING_BD00;
(*ENDIF*) 
new_length := pos + length;
last_nptr.np_ptr     := NIL;
last_nptr.np_cbptr   := NIL;
inew_nptr.np_ptr     := NIL;
inew_nptr.np_cbptr   := NIL;
iinew_nptr.np_ptr    := NIL;
iinew_nptr.np_cbptr  := NIL;
new_rootptr.np_ptr   := NIL;
new_rootptr.np_cbptr := NIL;
iinew_pno            := NIL_PAGE_NO_GG00;
b13new_node (LEAF_LEVEL_BD00, new_rootptr, current);
WITH current, curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  nptr.np_ptr^.nd_right = NIL_PAGE_NO_GG00
        THEN
            b13new_node (LEAF_LEVEL_BD00, inew_nptr, current)
        ELSE
            bd13GetNode (current, nptr.np_ptr^.nd_right, plmLock_ebd00,
                  nr_for_update, inew_nptr);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  leaf_pos <> MAX_BSTR_COVERING_BD00
            THEN
                BEGIN
                part_length := MAX_BSTR_COVERING_BD00 - leaf_pos;
                IF  use_buf
                THEN
                    bd60write_bstr (nptr.np_ptr, leaf_pos, part_length,
                          buf_size, buf_addr, bufpos, trError_gg00)
                ELSE
                    bd60fill_bstr (nptr.np_ptr, leaf_pos,
                          part_length, fill_char, trError_gg00);
                (*ENDIF*) 
                bufpos := bufpos + part_length;
                length := length - part_length
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                nptr.np_ptr^.nd_right := inew_nptr.np_ptr^.nd_id;
                leaf_pos := 0;
                IF  length > MAX_BSTR_COVERING_BD00
                THEN
                    BEGIN
                    part_length := MAX_BSTR_COVERING_BD00;
                    IF  inew_nptr.np_ptr^.nd_right = NIL_PAGE_NO_GG00
                    THEN
                        b13new_node (LEAF_LEVEL_BD00, iinew_nptr, current)
                    ELSE
                        bd13GetNode (current, inew_nptr.np_ptr^.nd_right,
                              plmLock_ebd00, nr_for_update, iinew_nptr);
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    part_length := length;
                    IF  inew_nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00
                    THEN
                        BEGIN
                        b61gfree_garb_node (inew_nptr.np_ptr^.nd_right,
                              false, current);
                        IF  trError_gg00 = e_ok
                        THEN
                            inew_nptr.np_ptr^.nd_right :=
                                  NIL_PAGE_NO_GG00
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  use_buf
                THEN
                    bd60write_bstr (inew_nptr.np_ptr, leaf_pos,
                          part_length, buf_size, buf_addr, bufpos,
                          trError_gg00)
                ELSE
                    bd60fill_bstr (inew_nptr.np_ptr, leaf_pos,
                          part_length, fill_char, trError_gg00);
                (*ENDIF*) 
                length := length - part_length;
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    IF  length <> 0
                    THEN
                        BEGIN
                        inew_nptr.np_ptr^.nd_right :=
                              iinew_nptr.np_ptr^.nd_id;
                        bufpos := bufpos + part_length;
                        IF  use_buf
                        THEN
                            bd60write_bstr (iinew_nptr.np_ptr, leaf_pos,
                                  length, buf_size, buf_addr, bufpos,
                                  trError_gg00)
                        ELSE
                            bd60fill_bstr (iinew_nptr.np_ptr, leaf_pos,
                                  length, fill_char, trError_gg00);
                        (*ENDIF*) 
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            iinew_nptr.np_ptr^.nd_left :=
                                  inew_nptr.np_ptr^.nd_id;
                            iinew_pno := iinew_nptr.np_ptr^.nd_id;
&                           ifdef TRACE
                            t01page (bd_byte, iinew_nptr.np_ptr^, 1, 40);
&                           endif
                            IF  use_buf
                            THEN
                                b13w_release_node (iinew_nptr, current)
                            ELSE
                                last_nptr := iinew_nptr
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    inew_pno := inew_nptr.np_ptr^.nd_id;
                    b61change_content (nptr, new_rootptr, curr_trans);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        inew_nptr.np_ptr^.nd_left := nptr.np_ptr^.nd_id;
                        n_pno := nptr.np_ptr^.nd_id;
&                       ifdef TRACE
                        t01page (bd_byte, inew_nptr.np_ptr^, 1, 40);
&                       endif
                        IF  (last_nptr.np_ptr <> NIL) OR use_buf
                        THEN
                            b13w_release_node (inew_nptr, current)
                        ELSE
                            last_nptr := inew_nptr;
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
&                       ifdef TRACE
                        t01page (bd_byte, nptr.np_ptr^, 1, 40);
&                       endif
                        b13w_release_node (nptr, current);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            nptr      := last_nptr;
                            index_pos := BODY_BEG_BD00;
                            s20ch4 (n_pno, new_rootptr.np_ptr^,
                                  index_pos);
                            index_pos := index_pos +
                                  sizeof (tsp00_PageNo);
                            s20ch4 (inew_pno, new_rootptr.np_ptr^,
                                  index_pos);
                            IF  iinew_pno <> NIL_PAGE_NO_GG00
                            THEN
                                BEGIN
                                index_pos :=
                                      index_pos + sizeof (tsp00_PageNo);
                                s20ch4 (iinew_pno, new_rootptr.np_ptr^,
                                      index_pos)
                                END;
                            (*ENDIF*) 
                            WITH new_rootptr.np_ptr^ DO
                                BEGIN
                                nd_bottom :=
                                      index_pos + sizeof (tsp00_PageNo);
                                ndStrFileSize_bd00 := new_length
                                END;
                            (*ENDWITH*) 
                            b13w_release_node (new_rootptr, current)
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  inew_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (inew_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  iinew_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (iinew_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  new_rootptr.np_ptr <> NIL
        THEN
            b13r_release_node (new_rootptr, current, lru_normal);
        (*ENDIF*) 
        IF  last_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (last_nptr, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b60rput_bstrroot (VAR nptr : tbd_node_ptrs;
            pos         : tsp00_Int4;
            length      : tsp00_Int4;
            use_buf     : boolean;
            fill_char   : char;
            buf_size    : tsp00_Int4;
            buf_addr    : tsp00_MoveObjPtr;
            bufpos      : tsp00_Int4;
            extended    : boolean;
            VAR current : tbd_current_tree);
 
VAR
      leaf_pos : tsp00_Int4;
 
BEGIN
WITH  current.curr_trans^ DO
    BEGIN
    IF  nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00
    THEN
        BEGIN
        b61gfree_garb_node (nptr.np_ptr^.nd_right, true, current);
        IF  trError_gg00 = e_ok
        THEN
            nptr.np_ptr^.nd_right := NIL_PAGE_NO_GG00
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        leaf_pos := pos;
        IF  use_buf
        THEN
            bd60write_bstr (nptr.np_ptr, leaf_pos, length,
                  buf_size, buf_addr, bufpos, trError_gg00)
        ELSE
            bd60fill_bstr (nptr.np_ptr, leaf_pos, length, fill_char,
                  trError_gg00);
        (*ENDIF*) 
        IF  extended (* AND use_buf *)
        THEN
            nptr.np_ptr^.ndStrFileSize_bd00 := pos + length;
&       ifdef TRACE
        (*ENDIF*) 
        t01page (bd_byte, nptr.np_ptr^, 1, 40);
&       endif
        IF  (trError_gg00 = e_ok) AND use_buf
        THEN
            b13w_release_node (nptr, current)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60CheckByteStr (
            VAR trans  : tgg00_TransContext;
            VAR fileId : tgg00_FileId);
 
VAR
      bFileWasBad : boolean;
      numPages    : tsp00_Int4;
      current     : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    bd30GetTree (trans, fileId, current, m_verify,
          NOT LOCK_TREE_EXCL_BD00, NOT SYNC_EXCL_LOCK_BD00);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        numPages    := 1;
        bFileWasBad := (f_bad IN current.currRootNptrs_bd00.np_ptr^.nd_file_state);
        IF  current.currRootNptrs_bd00.np_ptr^.nd_level > LEAF_LEVEL_BD00
        THEN
            bd60_CheckByteStr (current.currRootNptrs_bd00, current,
                  NOT c_bUpdateConverter, numPages)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        fileId := current.curr_tree_id;
        IF  bFileWasBad
        THEN
            bd30ResetBadFile (trans, fileId)
        (*ENDIF*) 
        END
    ELSE
        IF  (trError_gg00 <> e_file_not_found     ) AND
            (trError_gg00 <> e_disk_not_accessible) AND
            (trError_gg00 <> e_cancelled          ) AND
            (trError_gg00 <> e_shutdown           )
        THEN
            b06file_opmsg (csp3_bad_long, current.curr_tree_id)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60GetNextByteLeafPage (
            VAR nextLeafPage : tsp00_PageNo;
            VAR nptr         : tbd_node_ptrs;
            VAR current      : tbd_current_tree);
 
VAR
      leafpos : tsp00_Int4;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    IF  nextLeafPage = curr_tree_id.fileRoot_gg00
    THEN
        BEGIN
        bd13GetNode (current, nextLeafPage, plmLock_ebd00, nr_for_read, nptr);
        IF  trError_gg00 = e_ok
        THEN
            b61search_leaf (nptr, 1, leafpos, current)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  nptr.np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_last);
        (*ENDIF*) 
        BEGIN
        IF  nextLeafPage <> NIL_PAGE_NO_GG00
        THEN
            bd13GetNode (current, nextLeafPage, plmLock_ebd00, nr_for_read, nptr);
        (*ENDIF*) 
        END
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        IF  trError_gg00 = e_ok
        THEN
            nextLeafPage := nptr.np_ptr^.nd_right
        ELSE
            b13r_release_node (nptr, current, lru_normal)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60VerifyByteStr (
            VAR trans        : tgg00_TransContext;
            VAR fileId       : tgg00_FileId;
            bUpdateConverter : boolean;
            VAR numPages     : tsp00_Int4);
 
VAR
      bFileWasBad : boolean;
      current     : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    trError_gg00 := e_ok;
    numPages     := 1;
    bd30GetTree (trans, fileId, current, m_verify,
          NOT LOCK_TREE_EXCL_BD00, NOT SYNC_EXCL_LOCK_BD00);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        bFileWasBad := (f_bad IN current.currRootNptrs_bd00.np_ptr^.nd_file_state);
        IF  bUpdateConverter
        THEN
            b10use_pno (trans, fileId.fileRoot_gg00);
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (current.currRootNptrs_bd00.np_ptr^.nd_level > LEAF_LEVEL_BD00)
        THEN
            bd60_CheckByteStr (current.currRootNptrs_bd00, current, bUpdateConverter, numPages)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  (trError_gg00 = e_ok) AND bFileWasBad
    THEN
        BEGIN
        fileId := current.curr_tree_id;
        bd30ResetBadFile (trans, fileId)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60ExtractBlob (
            VAR current      : tbd_current_tree;
            VAR hostFileName : tsp00_VFilename);
 
VAR
      level           : tsp00_Int2;
      nextPageNo      : tsp00_PageNo;
      leftMostPageNo  : tsp00_PageNo;
      pDumpPage       : tsp00_VfBufaddr;
      pNodes          : tbd_node_ptrs;
      hostFile        : tgg00_VfFileref;
      hostFileErr     : tsp00_VfReturn;
      hostFileErrText : tsp00_ErrText;
 
BEGIN
nextPageNo      := current.curr_tree_id.fileRoot_gg00;
leftMostPageNo  := NIL_PAGE_NO_GG00;
(* *)
pNodes.np_ptr   := NIL;
pNodes.np_cbptr := NIL;
WITH current.curr_trans^ DO
    BEGIN
    hostFile.buf_cnt := 0;
    vfopen (hostFileName, hostFile.no, hostFileErr, hostFileErrText);
    IF  hostFileErr <> vf_ok
    THEN
        trError_gg00 := e_hostfile_error
    ELSE
        BEGIN
        WHILE (trError_gg00 = e_ok) AND (nextPageNo <> NIL_PAGE_NO_GG00) DO
            BEGIN
            bd13GetNode (current, nextPageNo, plmLock_ebd00, nr_for_read, pNodes);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                pDumpPage := @pNodes.np_ptr^;
                vfwrite (hostFile.no, pDumpPage, hostFileErr, hostFileErrText);
                IF  hostFileErr <> vf_ok
                THEN
                    trError_gg00 := e_hostfile_error
                ELSE
                    BEGIN
                    level      := pNodes.np_ptr^.nd_level;
                    nextPageNo := pNodes.np_ptr^.nd_right;
                    IF  (level <> LEAF_LEVEL_BD00) AND (leftMostPageNo = NIL_PAGE_NO_GG00)
                    THEN
                        leftMostPageNo := s20or4a (pNodes.np_ptr^, BODY_BEG_BD00);
                    (*ENDIF*) 
                    IF  (nextPageNo = NIL_PAGE_NO_GG00) AND (leftMostPageNo <> NIL_PAGE_NO_GG00)
                    THEN
                        BEGIN
                        nextPageNo     := leftMostPageNo;
                        leftMostPageNo := NIL_PAGE_NO_GG00;
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  pNodes.np_ptr <> NIL
            THEN
                b13r_release_node (pNodes, current, lru_normal)
            (*ENDIF*) 
            END
        (*ENDWHILE*) 
        END;
    (*ENDIF*) 
    IF  (hostFileErr = vf_ok) OR (hostFileErr = vf_eof)
    THEN
        vfclose (hostFile.no, hostFileErr, hostFileErrText);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60fill_bstr (nptr : tbd_nodeptr;
            pos       : tsp00_Int4;
            length    : tsp00_Int4;
            fill_char : char;
            VAR e     : tgg00_BasisError);
 
BEGIN
pos := pos + BODY_BEG_BD00;
SAPDB_PascalFill ('VBD60 ',   2,    
      sizeof (nptr^), @nptr^, pos, length, fill_char, e);
IF  (pos + length) > nptr^.nd_bottom
THEN
    nptr^.nd_bottom := pos + length
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60_CheckByteStr (
            parentNptr       : tbd_node_ptrs;
            VAR current      : tbd_current_tree;
            bUpdateConverter : boolean;
            VAR numPages     : tsp00_Int4);
 
CONST
      LAST_VALID_PAGENO_POS_BD60 = MAX_BOTTOM_BD00 - 4;
 
VAR
      bBottomUpdated  : boolean;
      parentLevel     : tsp00_Int2;
      parentBottom    : tgg00_PagePos;
      childPageNoPos  : tsp00_Int4;
      childNptr       : tbd_node_ptrs;
      childPageNo     : tsp00_PageNo;
      prevChildPageNo : tsp00_PageNo;
      nextChildPageNo : tsp00_PageNo;
 
BEGIN
(* PRECONDITION: parentNptr^.nd_level = FIRST_INDEX_LEVEL_BD00 or SECOND_INDEX_LEVEL_BD00 *)
childNptr.np_ptr   := NIL;
childNptr.np_cbptr := NIL;
childPageNoPos     := BODY_BEG_BD00;
(* *)
parentBottom       := parentNptr.np_ptr^.nd_bottom;
parentLevel        := parentNptr.np_ptr^.nd_level;
(* *)
prevChildPageNo    := NIL_PAGE_NO_GG00;
bBottomUpdated     := false;
(* *)
WITH current, curr_trans^ DO
    BEGIN
    WHILE (trError_gg00 = e_ok) AND (childPageNoPos < parentBottom) DO
        BEGIN
        childPageNo := s20or4a (parentNptr.np_ptr^, childPageNoPos);
        IF  childPageNoPos + sizeof(tsp00_PageNo) < parentBottom
        THEN
            nextChildPageNo := s20or4a (parentNptr.np_ptr^, childPageNoPos + sizeof(tsp00_PageNo))
        ELSE
            nextChildPageNo := NIL_PAGE_NO_GG00;
        (*ENDIF*) 
        IF  (parentLevel = SECOND_INDEX_LEVEL_BD00) AND (nextChildPageNo <> NIL_PAGE_NO_GG00)
        THEN (* possible corrupted nd_bottom of childPage see PTS 1135692 TS 2005-05-20 *)
            bd13GetNode (current, childPageNo, plmLock_ebd00, nr_for_update, childNptr)
        ELSE
            bd13GetNode (current, childPageNo, plmLock_ebd00, nr_for_read, childNptr);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            numPages := succ (numPages);
            IF  bUpdateConverter
            THEN
                b10use_pno (curr_trans^, childPageNo);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (childNptr.np_ptr^.nd_bottom = LAST_VALID_PAGENO_POS_BD60) AND
                    (childNptr.np_ptr^.nd_level  = FIRST_INDEX_LEVEL_BD00    ) AND
                    (nextChildPageNo <> NIL_PAGE_NO_GG00                     )
                THEN
                    BEGIN (* Adjust corrupted nd_bottom *)
                    bBottomUpdated              := true;
                    childNptr.np_ptr^.nd_bottom := MAX_BOTTOM_BD00;
                    END
                ELSE
                    bBottomUpdated := false;
                (*ENDIF*) 
                IF  childNptr.np_ptr^.nd_level > LEAF_LEVEL_BD00
                THEN
                    bd60_CheckByteStr (childNptr, current, bUpdateConverter, numPages)
                ELSE
                    BEGIN
                    IF  ((nextChildPageNo <> NIL_PAGE_NO_GG00          ) AND
                        (nextChildPageNo <> childNptr.np_ptr^.nd_right))
                        OR
                        ((prevChildPageNo <> NIL_PAGE_NO_GG00         ) AND
                        (prevChildPageNo <> childNptr.np_ptr^.nd_left))
                    THEN
                        BEGIN
                        trError_gg00 := e_invalid_index_structure;
                        g01opmsg (sp3p_knldiag, sp3m_error, BD60_INVALID_INDEX_STRUCTURE_SP03,
                              csp3_n_btree, 'Parent data pageNo      ', parentNptr.np_ptr^.nd_id);
                        g01opmsg (sp3p_knldiag, sp3m_error, BD60_INVALID_INDEX_STRUCTURE_SP03,
                              csp3_n_btree, 'Child data pageNo       ', childNptr.np_ptr^.nd_id);
                        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                              parentNptr.np_ptr^.nd_id, parentNptr.np_ptr, 1);
                        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                              childNptr.np_ptr^.nd_id, childNptr.np_ptr, 1)
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  childNptr.np_ptr <> NIL
        THEN
            IF  bBottomUpdated
            THEN
                b13w_release_node (childNptr, current)
            ELSE
                b13r_release_node (childNptr, current, lru_normal);
            (*ENDIF*) 
        (*ENDIF*) 
        childPageNoPos  := childPageNoPos + sizeof (tsp00_PageNo);
        prevChildPageNo := childPageNo;
        (* *)
        IF  (trError_gg00 = e_ok) AND (trRteCommPtr_gg00^.to_cancel)
        THEN
            BEGIN
            trError_gg00 := e_cancelled;
            g01opmsg (sp3p_knldiag, sp3m_info, BD60_CHECK_BLOB_CANCELED_SP03,
                  csp3_n_btree, 'Check blob canceled     ', trTaskId_gg00)
            END
        (*ENDIF*) 
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd60write_bstr (nptr : tbd_nodeptr;
            pos      : tsp00_Int4;
            length   : tsp00_Int4;
            buf_size : tsp00_Int4;
            buf_addr : tsp00_MoveObjPtr;
            buf_pos  : tsp00_Int4;
            VAR e    : tgg00_BasisError);
 
BEGIN
pos := pos + BODY_BEG_BD00;
g10mv ('VBD60 ',   3,    
      buf_size, sizeof (nptr^),
      @buf_addr^, buf_pos, @nptr^, pos, length, e);
IF  (pos + length) > nptr^.nd_bottom
THEN
    nptr^.nd_bottom := pos + length
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
