/*
* Copyright 1995, 1996 Perforce Software. All rights reserved.
*
* This file is part of Perforce - the FAST SCM System.
*/
# ifdef USE_EBCDIC
# define NEED_EBCDIC
# endif
# include <stdhdrs.h>
# include <debug.h>
# include <strbuf.h>
# include <strdict.h>
# include <strarray.h>
# include <strtable.h>
# include <error.h>
# include <p4tags.h>
# include <msgrpc.h>
# include "rpcbuffer.h"
# include "rpcdebug.h"
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//
// RpcRecvBuffer
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void
RpcRecvBuffer::Parse( Error *e )
{
// do the work of Clear
args.Clear();
syms.Clear();
// Step through variables
char *b = ioBuffer.Text();
char *endB = b + ioBuffer.Length();
while( b < endB )
{
// variable, length, value
StrRef var( b );
b += var.Length() + 5;
int valLen =
(unsigned char)b[-4] * 0x1 +
(unsigned char)b[-3] * 0x100 +
(unsigned char)b[-2] * 0x10000 +
(unsigned char)b[-1] * 0x1000000;
StrRef val( b, valLen );
b += valLen + 1;
if( valLen < 0 || b > endB || b[-1] != '\0')
{
DEBUGPRINTF( DEBUG_VARS, "Rpc Buffer parse failure %s %d!",
var.Text(), b - endB );
e->Set( MsgRpc::NotP4 );
return;
}
# ifdef USE_EBCDIC
// Slog to ebcdic
__atoe_l( var.Text(), var.Length() );
__atoe_l( val.Text(), val.Length() );
# endif
// With var name, into symbol table
// No variable name, into arg list
if( var.Length() )
syms.SetVar( var, val );
else
args.Put( val );
// Tracing
DEBUGPRINTF( DEBUG_VARS, "RpcRecvBuffer %s = %s", var.Text(),
val.Length() < 110 ? val.Text() : "<big>" );
}
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//
// RpcRecvBuffer
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void
RpcSendBuffer::SetVar( const StrPtr &var, const StrPtr &value )
{
// Format on wire is:
//
// var<00><l1><l2><l3><l4>value<00>
//
// That is, var and value are null terminated and value additionally
// has a length indicator. Like lengths for StrPtrs, the it
// does not include the terminating null.
//
MakeVar( var )->Extend( value.Text(), value.Length() );
EndVar();
// Tracing
DEBUGPRINTF( DEBUG_VARS, "RpcSendBuffer %s = %s", var.Text(),
value.Length() < 110 ? value.Text() : "<big>" );
}
void
RpcSendBuffer::SetVar( const char *var, const StrPtr &value )
{
StrBuf key = var;
SetVar( key, value );
}
StrBuf *
RpcSendBuffer::MakeVar( const StrPtr &var )
{
// Tidy up last StarVar
if( lastLength )
EndVar();
// Put var name in buffer
// EBCDIC->ASCII, if necessary
ioBuffer.Append( &var );
# ifdef USE_EBCDIC
__etoa_l( ioBuffer.End() - var.Length(), var.Length() );
# endif
// Make room for var's null plus value's len
// ensure null is null, incase this alloc relocates.
*ioBuffer.Alloc(5) = 0;
lastLength = ioBuffer.Length();
return &ioBuffer;
}
void
RpcSendBuffer::EndVar()
{
int length = ioBuffer.Length() - lastLength;
char *lastVar = ioBuffer.Text() + lastLength;
lastVar[-4] = ( length / 0x1 ) % 0x100;
lastVar[-3] = ( length / 0x100 ) % 0x100;
lastVar[-2] = ( length / 0x10000 ) % 0x100;
lastVar[-1] = ( length / 0x1000000 ) % 0x100;
# ifdef USE_EBCDIC
// back up and translate value to ascii
__etoa_l( lastVar, length );
# endif
ioBuffer.Extend( 0 ); // skip past null
lastLength = 0; // signal StarVar var completed
}
void
RpcSendBuffer::CopyVars( RpcRecvBuffer *from )
{
// XXX don't want to copy the 'func' or 'data' variables
// should have a generic way of excluding variables from the copy.
int i;
StrRef var, val;
for( i = 0; from->syms.GetVar( i, var, val ); i++ )
{
if( var == P4Tag::v_data || var == P4Tag::v_func )
continue;
SetVar( var, val );
}
}
# |
Change |
User |
Description |
Committed |
|
#1
|
14945 |
Newtopian |
Merging
//guest/perforce_software/p4/...
to //guest/Newtopian/p4/... |
|
|
//guest/perforce_software/p4/2015.1/rpc/rpcbuffer.cc |
#1
|
12190 |
Matt Attaway |
Initial drop of 2015.1 p4/p4api source |
|
|