.pb '~'
.ad 8
.ll 73
.bm 3
.fm 2
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 5
.hm 2
.hs 3
.tt 1 $SQL$Project Distributed Database System$VSP26$
.tt 2 $$$
.tt 3 $JuergenA$Packet_handling$1999-12-30$
***********************************************************
.nf
 
 .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
 
 
.fo
.nf
.sp
MODULE  : Packet_handling
=========
.sp
Purpose : Packet_handling
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              s26find_part (VAR segm : tsp1_segment;
                    part_kind        : tsp1_part_kind;
                    VAR part_ptr     : tsp1_part_ptr);
 
        PROCEDURE
              s26finish_part (packet_ptr : tsp1_packet_ptr;
                    VAR finish_part      : tsp1_part);
 
        PROCEDURE
              s26first_segment_init (packet_ptr : tsp1_packet_ptr;
                    segm_kind                   : tsp1_segment_kind;
                    VAR first_segm_ptr          : tsp1_segment_ptr);
 
        PROCEDURE
              s26init_cmd_packet (packet_ptr : tsp1_packet_ptr;
                    VAR first_segm_ptr       : tsp1_segment_ptr);
 
        PROCEDURE
              s26new_part_init (packet_ptr : tsp1_packet_ptr;
                    VAR segm               : tsp1_segment;
                    VAR new_part_ptr       : tsp1_part_ptr);
 
        PROCEDURE
              s26new_segment_init (packet_ptr : tsp1_packet_ptr;
                    segm_kind                 : tsp1_segment_kind;
                    VAR new_segm_ptr          : tsp1_segment_ptr;
                    VAR first_part_ptr        : tsp1_part_ptr);
 
        PROCEDURE
              s26next_segment (VAR segm_ptr : tsp1_segment_ptr);
 
        PROCEDURE
              s26nextpart (VAR part_ptr : tsp1_part_ptr);
 
        FUNCTION
              s26packet_len (packet_ptr : tsp1_packet_ptr) : tsp00_Int4;
 
        FUNCTION
              s26partlen (VAR part : tsp1_part) : tsp00_Int4;
 
        FUNCTION
              s26partptr (VAR part : tsp1_part) : tsp1_part_ptr;
 
        PROCEDURE
              s26reset_part (VAR segm : tsp1_segment;
                    VAR part_ptr : tsp1_part_ptr);
 
        FUNCTION
              s26segmptr (VAR segm : tsp1_segment) : tsp1_segment_ptr;
 
        FUNCTION
              s26size_new_part (packet_ptr : tsp1_packet_ptr;
                    VAR segm : tsp1_segment) : tsp00_Int4;
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20int4_to_buf_swap (val    : tsp00_Int4;
                    sourceswap : tsp00_SwapKind;
                    VAR dest   : tsp00_C4;
                    di         : tsp00_Int4;
                    destswap   : tsp00_SwapKind);
&       ifdef kernel
 
      ------------------------------ 
 
        FROM
              Pascal Wrapper FOR SQLManager : VAK101;
 
        PROCEDURE
              a101PacketError (
                    fmt  : tsp00_C50;
                    val1 : tsp00_Int4;
                    val2 : tsp00_Int4;
                    val3 : tsp00_Int4);
&       endif
 
      ------------------------------ 
 
        FROM
              RTE_driver : VEN102;
 
        PROCEDURE
              sqlabort;
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              s20int4_to_buf_swap;
 
              tsp00_MoveObj tsp00_C4
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenA
.sp
.cp 3
Created : 1995-04-27
.sp
.cp 3
.sp
.cp 3
Release :      Date : 1999-12-30
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
.sp 2;.cp 5
S26FIND_PART
.sp
Liefert den PART_PTR auf den durch PART_KIND spezifizierten Part
innerhalb des angegebenen SEGMents.
.sp 2;.cp 5
S26FINISH_PART
.sp
Beendet einen PART und erh?oht die Segmentl?ange
entsprechend (mit Alignment). Die zus?atzlich f?ur das Alignment
ben?otigten Bytes werden mit CGG_UNDEF_BYTE aufgef?ullt.
.sp 2;.cp 5
S26FIRST_SEGMENT_INIT
.sp
Initialisiert das erste Segment eines Packets (ohne den
ersten PART). Die Segmentl?ange umfa?zt danach die des Header.
Au?zerdem werden NO_OF_PARTS mit '0' und NO_OF_SEGM mit '1' initialisiert.
.br;Der Pointer auf das erste Segment wird zur?uckgeliefert.
.sp 2;.cp 5
S26INIT_CMD_PACKET
.sp
Initialisiert ein Command-Packet zusammen mit dem ersten Segment (nicht
jedoch dem ersten PART). Die Segmentl?ange umfa?zt danach
den Segment- und Part-Header.
Au?zerdem werden NO_OF_PARTS auf '0' und NO_OF_SEGM mit '1' initialisiert.
.br;Der Pointer auf das erste Segmentwird zur?uckgeliefert.
.sp 2;.cp 5
S26NEW_PART_INIT
.sp
Initialisiert einen weiteren PART.
Die Segmentl?ange wird um den neuen PART-Header erweitert und
NO_OF_PARTS entsprechend erh?oht.
.sp 2;.cp 5
S26NEW_SEGMENT_INIT
.sp
Initialisiert ein weiteres Segment zusammen mit seinem
ersten PART. Die Segmentl?ange umfa?zt danach beide Header.
Au?zerdem wird NO_OF_SEGM entsprechend erh?oht und
NO_OF_PARTS mit '1' initialisiert.
.br;Neben dem Pointer auf das neue Segment wird auch der Pointer auf
dessen ersten Part zur?uckgeliefert.
.sp 2;.cp 5
S26NEXT_SEGMENT
.sp
Setzt den SEGM_PTR auf das nachfolgende Segment um.
.sp 2;.cp 5
S26NEXTPART
.sp
Setzt den PART_PTR auf den nachfolgenden Part um.
.sp 2;.cp 5
S26PACKET_LEN
.sp
Liefert die benutzte L?ange eines PACKETs.
.sp 2;.cp 5
S26PARTLEN
.sp
Liefert die L?ange eines PARTs, bestehend aus dem PART-Header,
der BUF_LEN und dem Alignment-Filler.
.sp 2;.cp 4
S26PARTPTR
.sp
Liefert den Pointer auf den spezifizierten PART.
.br;Im Kern sollte anstelle dieser Funktion der entsprechende
Pointer direkt mittels '@' belegt werden.
.sp 2;.cp 4
S26SEGMPTR
.sp
Liefert den Pointer auf das spezifizierte SEGMent.
.br;Im Kern sollte anstelle dieser Funktion der entsprechende
Pointer direkt mittels '@' belegt werden.
.sp 2;.cp 5
S26SIZE_NEW_PART
.sp
Liefert die Gr?o?ze, auf die sich der Puffer
eines weiteren (mit S26NEW_PART_INIT zu erstellenden) PARTs
maximal ausdehnen k?onnte.
.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
      csp26_zero_c8          = '\00\00\00\00\00\00\00\00';
      csp26_zero_sqlstate    = '00000';
 
 
(*------------------------------*) 
 
PROCEDURE
      sp26abort(
            fmt  : tsp00_C50;
            val1 : tsp00_Int4;
            val2 : tsp00_Int4;
            val3 : tsp00_Int4);
 
BEGIN
&ifdef kernel
a101PacketError (fmt, val1, val2, val3);
&else
sqlabort;
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26find_part (VAR segm : tsp1_segment;
            part_kind        : tsp1_part_kind;
            VAR part_ptr     : tsp1_part_ptr);
 
VAR
      found   : boolean;
      part_no : tsp00_Int2;
 
BEGIN
IF  segm.sp1s_no_of_parts = 0
THEN
    part_ptr := NIL
ELSE
    BEGIN
    part_ptr := @segm.sp1p_part;
    part_no := 1;
    found   := false;
    REPEAT
        IF  part_ptr^.sp1p_part_kind = part_kind
        THEN
            found := true
        ELSE
            IF  part_no < segm.sp1s_no_of_parts
            THEN
                BEGIN
                part_no := part_no + 1;
                s26nextpart (part_ptr)
                END
            ELSE
                part_ptr := NIL
            (*ENDIF*) 
        (*ENDIF*) 
    UNTIL
        found OR (part_ptr = NIL)
    (*ENDREPEAT*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26finish_part (packet_ptr : tsp1_packet_ptr;
            VAR finish_part      : tsp1_part);
 
VAR
      i        : tsp00_Int4;
      len      : tsp00_Int4;
      segm_ptr : tsp1_segment_ptr;
 
BEGIN
len := s26partlen (finish_part) - sizeof (finish_part.sp1p_part_header);
IF  len > finish_part.sp1p_buf_size
THEN
    sp26abort('s26finish_part : len %d, size %d, %d              ',
          len, finish_part.sp1p_buf_size, 0)
ELSE
    BEGIN
    FOR i := finish_part.sp1p_buf_len + 1 TO len DO
        finish_part.sp1p_buf [i] := csp_undef_byte;
    (*ENDFOR*) 
    segm_ptr := @packet_ptr^.sp1_varpart [finish_part.sp1p_segm_offset + 1];
    WITH segm_ptr^ DO
        sp1s_segm_len := sp1s_segm_len + len
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26first_segment_init (packet_ptr : tsp1_packet_ptr;
            segm_kind                   : tsp1_segment_kind;
            VAR first_segm_ptr          : tsp1_segment_ptr);
 
CONST
      c_segm_offset_0 = 0;
 
BEGIN
packet_ptr^.sp1_header.sp1h_no_of_segm  := 1;
packet_ptr^.sp1_header.sp1h_varpart_len := 0;
sp26init_segment (packet_ptr, packet_ptr^.sp1_segm,
      segm_kind, c_segm_offset_0);
first_segm_ptr := @packet_ptr^.sp1_segm;
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26new_segment_init (packet_ptr : tsp1_packet_ptr;
            segm_kind                 : tsp1_segment_kind;
            VAR new_segm_ptr          : tsp1_segment_ptr;
            VAR first_part_ptr        : tsp1_part_ptr);
 
VAR
      i           : tsp00_Int2;
      segm_offset : tsp00_Int4;
      curr_segm   : tsp1_segment_ptr;
 
BEGIN
segm_offset := 0;
FOR i := 1 TO packet_ptr^.sp1_header.sp1h_no_of_segm DO
    BEGIN
    curr_segm := @packet_ptr^.sp1_varpart [segm_offset+1];
    segm_offset := segm_offset + curr_segm^.sp1s_segm_len
    END;
(*ENDFOR*) 
WITH packet_ptr^.sp1_header DO
    sp1h_no_of_segm := sp1h_no_of_segm + 1;
(*ENDWITH*) 
new_segm_ptr   := @packet_ptr^.sp1_varpart [segm_offset+1];
first_part_ptr := @new_segm_ptr^.sp1p_part;
sp26init_segment (packet_ptr, new_segm_ptr^, segm_kind, segm_offset)
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26init_cmd_packet (packet_ptr : tsp1_packet_ptr;
            VAR first_segm_ptr       : tsp1_segment_ptr);
 
CONST
      c_zero_c8 =  '\00\00\00\00\00\00\00\00';
 
VAR
      i4 : tsp00_Int4;
      s4 : tsp00_C4;
 
BEGIN
WITH packet_ptr^.sp1_header DO
    BEGIN
    sp1h_mess_code := csp_ascii;
    i4 := 1;
    s20int4_to_buf_swap (i4, sw_normal, s4, 1, sw_normal);
    IF  s4 [4] = chr(1)
    THEN
        sp1h_mess_swap := sw_normal
    ELSE
        IF  s4 [1] = chr(1)
        THEN
            sp1h_mess_swap := sw_full_swapped
        ELSE
            sp1h_mess_swap := sw_part_swapped;
        (*ENDIF*) 
    (*ENDIF*) 
    sp1h_filler1      := 0;
    sp1h_filler2      := 0;
    sp1h_filler3      := c_zero_c8;
    sp1h_appl_version := csp1_first_sp1_version;
    sp1h_application  := csp_comp_xci
    END;
(*ENDWITH*) 
s26first_segment_init (packet_ptr, sp1sk_cmd,
      first_segm_ptr)
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26new_part_init (packet_ptr : tsp1_packet_ptr;
            VAR segm               : tsp1_segment;
            VAR new_part_ptr       : tsp1_part_ptr);
 
VAR
      part_offset : tsp00_Int4;
 
BEGIN
WITH segm DO
    part_offset := sp1s_segm_offset + sp1s_segm_len;
(*ENDWITH*) 
IF  part_offset + sizeof (packet_ptr^.sp1_segm.sp1p_part_header)
    > packet_ptr^.sp1_header.sp1h_varpart_size
THEN
    BEGIN
    sp26abort('s26new_part_init : offset %d, size %d, %d         ', part_offset,
          packet_ptr^.sp1_header.sp1h_varpart_size, 0);
    new_part_ptr := NIL;
    END
ELSE
    BEGIN
    new_part_ptr := @packet_ptr^.sp1_varpart [part_offset+1];
    WITH segm DO
        BEGIN
        sp1s_segm_len    := sp1s_segm_len +
              sizeof (packet_ptr^.sp1_segm.sp1p_part_header);
        sp1s_no_of_parts := sp1s_no_of_parts  + 1
        END;
    (*ENDWITH*) 
    WITH new_part_ptr^ DO
        BEGIN
        sp1p_part_kind   := sp1pk_data;
        sp1p_attributes  := [ ];
        sp1p_arg_count   := 1;
        sp1p_segm_offset := segm.sp1s_segm_offset;
        sp1p_buf_len     := 0;
        sp1p_buf_size    := packet_ptr^.sp1_header.sp1h_varpart_size
              -             part_offset
              -             sizeof (packet_ptr^.sp1_segm.sp1p_part_header)
        END
    (*ENDWITH*) 
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26next_segment (VAR segm_ptr : tsp1_segment_ptr);
 
VAR
      next_offset : tsp00_Int4;
      last_segm   : tsp1_segment_ptr;
 
BEGIN
last_segm := segm_ptr;
(* PTS 1105175 E.Z. *)
WITH last_segm^ DO
    BEGIN
    IF  sp1s_no_of_parts = 0
    THEN
        segm_ptr := @last_segm^.sp1p_part
    ELSE
        BEGIN
        next_offset := sp1s_segm_len
              -        sizeof (sp1s_segm_header)
              -        sizeof (sp1p_part_header);
        segm_ptr := @last_segm^.sp1p_buf [next_offset+1];
        IF  next_offset + segm_ptr^.sp1s_segm_len > last_segm^.sp1p_buf_size
        THEN
            BEGIN
            sp26abort ('s26next_segment : offset %d, segm_len %d, size %d ',
                  next_offset, segm_ptr^.sp1s_segm_len, last_segm^.sp1p_buf_size);
            segm_ptr := NIL;
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26nextpart (VAR part_ptr : tsp1_part_ptr);
 
VAR
      part_len  : tsp00_Int4;
      next_pos  : tsp00_Int4;
      last_part : tsp1_part_ptr;
 
BEGIN
last_part := part_ptr;
part_len  := s26partlen (last_part^);
next_pos  := part_len - sizeof (part_ptr^.sp1p_part_header) + 1;
part_ptr := @last_part^.sp1p_buf [next_pos];
IF  part_len + part_ptr^.sp1p_buf_len > last_part^.sp1p_buf_size
THEN
    BEGIN
    sp26abort ('s26nextpart : part_len %d, buf_len %d, size %d    ',
          part_len, part_ptr^.sp1p_buf_len, last_part^.sp1p_buf_size);
    part_ptr := NIL;
    END;
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      s26packet_len (packet_ptr : tsp1_packet_ptr) : tsp00_Int4;
 
VAR
      segm_no   : integer;
      len       : tsp00_Int4;
      segm_pos  : tsp00_Int4;
      curr_segm : tsp1_segment_ptr;
 
BEGIN
(* valid for cmd and return segments *)
len := sizeof (packet_ptr^.sp1_header);
segm_pos := 1;
FOR segm_no := 1 TO packet_ptr^.sp1_header.sp1h_no_of_segm DO
    BEGIN
    curr_segm := @packet_ptr^.sp1_varpart [segm_pos];
    len      := len      + curr_segm^.sp1s_segm_len;
    segm_pos := segm_pos + curr_segm^.sp1s_segm_len
    END;
(*ENDFOR*) 
s26packet_len := len
END;
 
(*------------------------------*) 
 
FUNCTION
      s26partlen (VAR part : tsp1_part) : tsp00_Int4;
 
BEGIN
s26partlen :=
      ((sizeof (part.sp1p_part_header)
      + part.sp1p_buf_len + csp1_part_align_length - 1)
      DIV csp1_part_align_length) * csp1_part_align_length
END;
 
(*------------------------------*) 
 
FUNCTION
      s26partptr (VAR part : tsp1_part) : tsp1_part_ptr;
 
BEGIN
s26partptr := @part;
END;
 
(*------------------------------*) 
 
PROCEDURE
      s26reset_part (VAR segm : tsp1_segment;
            VAR part_ptr : tsp1_part_ptr);
 
BEGIN
WITH segm DO
    BEGIN
    sp1s_segm_len    := sp1s_segm_len - sizeof (part_ptr^.sp1p_part_header);
    sp1s_no_of_parts := sp1s_no_of_parts - 1
    END;
(*ENDWITH*) 
part_ptr := NIL
END;
 
(*------------------------------*) 
 
FUNCTION
      s26segmptr (VAR segm : tsp1_segment) : tsp1_segment_ptr;
 
BEGIN
s26segmptr := @segm;
END;
 
(*------------------------------*) 
 
FUNCTION
      s26size_new_part (packet_ptr : tsp1_packet_ptr;
            VAR segm : tsp1_segment) : tsp00_Int4;
 
BEGIN
s26size_new_part := packet_ptr^.sp1_header.sp1h_varpart_size
      - segm.sp1s_segm_offset
      - segm.sp1s_segm_len
      - sizeof (packet_ptr^.sp1_segm.sp1p_part_header)
END;
 
(*------------------------------*) 
 
PROCEDURE
      sp26init_segment (packet_ptr : tsp1_packet_ptr;
            VAR segm    : tsp1_segment;
            segm_kind   : tsp1_segment_kind;
            segm_offset : tsp00_Int4);
 
BEGIN
WITH segm DO
    BEGIN
    sp1s_segm_len    := sizeof (sp1s_segm_header);
    sp1s_segm_offset := segm_offset;
    sp1s_no_of_parts := 0;
    sp1s_own_index   := packet_ptr^.sp1_header.sp1h_no_of_segm;
    sp1s_segm_kind   := segm_kind;
    IF  segm_kind = sp1sk_cmd
    THEN
        BEGIN
        sp1c_mess_type          := sp1m_dbs;
        sp1c_sqlmode            := sp1sm_session_sqlmode;
        sp1c_producer           := sp1pr_user_cmd;
        sp1c_commit_immediately := false;
        sp1c_ignore_costwarning := false;
        sp1c_prepare            := false;
        sp1c_with_info          := false;
        sp1c_mass_cmd           := false;
        sp1c_parsing_again      := false;
        sp1c_command_options    := [ ];
        sp1c_filler1            := false;
        sp1c_filler2            := csp26_zero_c8;
        sp1c_filler3            := csp26_zero_c8
        END
    ELSE
        BEGIN
        sp1r_sqlstate       := csp26_zero_sqlstate;
        sp1r_returncode     := 0;
        sp1r_errorpos       := 0;
        sp1r_extern_warning := [ ];
        sp1r_intern_warning := [ ];
        sp1r_function_code  := csp1_nil_fc;
        sp1r_tracelevel     := 0;
        sp1r_filler1        := false;
        sp1r_filler2        := csp26_zero_c8
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
