/**
*
* 1997-2007
* Ericsson AB, All Rights Reserved
*
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Ericsson AB.
*
*/
/**
* InitialReference is a class which generates the INIT reference
* which can be used by the InitialReferences interface.
*
* creation date: 1997-11-04
*/
#include "InitialReference.hh"
InitialReference::InitialReference()
{
host = 0;
iorString = 0;
};
InitialReference::~InitialReference()
{
if(host){
delete host;
delete iorString;
}
};
/**
* Returns the stringified objectreference to the initial reference server
*/
char* InitialReference::stringified_ior(char* newhost, int newport)
{
STRINGSTREAM iorByteString;
STRINGSTREAM profileData;
STRINGBUF *s;
STRINGBUF *profileDataBuf;
STRINGBUF *iorByteStringBuf;
long profileDataLength = 0;
char *str;
// byte_order followed by ' {"", [{0, '
// char iorBytesFirstPart[] = {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0};
char iorBytesFirstPart[48] = {0,0,0,0,0,0,0,32,73,68,76,58,79,114,98,101,114,47,73,110,105,116,105,97,108,82,101,102,101,114,101,110,99,101,115,58,49,46,48,0,0,0,0,1,0,0,0,0};
// the objectkey "INIT
char iorBytesLastPart[8] = {0,0,0,4,73,78,73,84};
// Fix the ProfileData struct.
char pdPrefix[4] = {0,1,0,0};
char hsize[4];
char profileDataLengthBytes[4];
char portbytes[2];
long hostLength = strlen(newhost);
if(host)
if(strcmp(newhost, host) == 0 && newport == port)
return iorString;
else {
delete host;
delete iorString;
}
host = new char[hostLength+1];
memcpy(host, newhost, hostLength+1);
port = newport;
enc_ulong(hostLength + 1, hsize);
enc_ushort(port, portbytes);
profileDataBuf = profileData.rdbuf();
profileDataBuf->sputn(pdPrefix, 4);
profileDataBuf->sputn(hsize, 4);
profileDataBuf->sputn(host, hostLength);
profileDataBuf->sputc(0);
profileDataLength = 4 + 4 + hostLength + 1;
profileDataLength = align(profileDataBuf, profileDataLength, 2);
profileDataBuf->sputn(portbytes, 2);
profileDataLength += 2;
profileDataLength = align(profileDataBuf, profileDataLength, 4);
profileDataBuf->sputn(iorBytesLastPart, 8);
profileDataLength += 8;
//cout << "pd length: " << profileDataLength << "\n";
enc_ulong(profileDataLength, profileDataLengthBytes);
// Fix the whole IOR
iorByteStringBuf = iorByteString.rdbuf();
iorByteStringBuf->sputn(iorBytesFirstPart, 48);
iorByteStringBuf->sputn(profileDataLengthBytes, 4);
#ifdef HAVE_SSTREAM
iorByteStringBuf->sputn(profileData.str().data(), profileDataLength);
#else
str = profileData.str();
iorByteStringBuf->sputn(str, profileDataLength);
delete str;
#endif
createIOR(iorByteString, 48 + 4 + profileDataLength);
return iorString;
}
void InitialReference::enc_ushort(int s, char *byteArray)
{
byteArray[0] = (char) ((s >> 8) & 0xFF);
byteArray[1] = (char) ((s >> 0) & 0xFF);
return;
}
void InitialReference::enc_ulong(long l, char *byteArray)
{
byteArray[0] = (char) ((l >> 24) & 0xFF);
byteArray[1] = (char) ((l >> 16) & 0xFF);
byteArray[2] = (char) ((l >> 8) & 0xFF);
byteArray[3] = (char) ((l >> 0) & 0xFF);
return;
}
void InitialReference::createIOR(strstream& byte, long length)
{
STRINGBUF *stringbuf;
STRINGSTREAM string;
int i;
#ifdef HAVE_SSTREAM
const char *c;
const char *bytestr = byte.str().c_str();
#else
char *c;
char *bytestr = byte.str();
#endif
int b, n1, n2, c1, c2;
stringbuf = string.rdbuf();
stringbuf->sputn("IOR:",4);
for(i = 0, c = bytestr; i < length; c++, i++)
{
b = *c;
if(b<0) b+= 256;
n1 = b / 16;
n2 = b % 16;
c1 = (n1 < 10) ? ('0' + n1) : ('a' + (n1 - 10));
c2 = (n2 < 10) ? ('0' + n2) : ('a' + (n2 - 10));
stringbuf->sputc(c1);
stringbuf->sputc(c2);
}
stringbuf->sputc(0);
delete bytestr;
#ifdef HAVE_SSTREAM
iorString = (char *)string.str().c_str();
#else
iorString = string.str();
#endif
return;
}
long InitialReference::align(STRINGBUF* sbuf, long currentLength,
int alignment)
{
long length = currentLength;
int remainder = alignment - (currentLength % alignment);
if (remainder == alignment) return length;
for (int i = 0; i < remainder; i++)
{
sbuf->sputc(0);
length++;
}
return length;
}