Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
HOR / TOTAL.DOC
Скачиваний:
8
Добавлен:
16.04.2013
Размер:
312.83 Кб
Скачать

9.6. Эргономика окружающей среды.

Для производительности труда программиста важное значение имеет оборудование рабочего места мебелью, соответствующей эргономическим стандартам, подбор цветовой гаммы при отделке поверхности стен и др. Особое внимание следует уделять правильному освещению рабочего места. Правильно спроектированное и выполненное производственное освещение оказывает благоприятное психологическое воздействие, повышает безопасность труда. Производственное освещение должно удовлетворять следующим требованиям:

  1. освещенность на рабочем месте должна соответствовать гигиеническим нормам - удовлетворительная степень освещенности может быть достигнута применением трех ламп накаливания, рассчитанных на напряжение 220 В и имеющих мощность в 40 Вт каждая, также в дневное время освещение может быть естественным;

  2. равномерное распределение яркости - может быть достигнута, например за счет использования нескольких источников света, либо применением ламп дневного освещения;

  3. отсутствие резких теней в рабочей зоне, что достигается правильным выбором места в пространстве для источника освещения;

  4. отсутствие в поле зрения прямой и отраженной блестности, для чего следует избегать использования гладких, блестящих поверхностей в зоне видимости с рабочего места оператора;

  5. величина освещенности должна быть постоянной во времени - это означает отсутствие мигания источников освещения;

  6. оптимальная направленность светового потока - рекомендуемый угол падения света на рабочую поверхность 60 градусов к ее нормали;

  7. выбор спектрального состава, то есть естественное освещение плюс искусственный источник со спектральной характеристикой, близкой к солнечной.

9.7. Экологическая безопасность.

Современное вычислительное устройство - компьютер является устройством, которое практически не оказывает никакого вредного воздействия на экологическое состояние внешней окружающей среды. Ввиду этого можно считать, что вычислительные машины, с которыми работает программист экологически безопасны.

9.8. Выводы.

В данной главе были рассмотрены следующие факторы, которые влияют на организацию рабочего места программиста:

  1. производственные вредные факторы;

  2. эргономические требования;

  3. экологические внешние факторы.

Приведены допустимые различными стандартами максимальные значения тех или иных вредных факторов и даны рекомендации по устранению или минимизации ущерба здоровью человека, наносимого различными вредными воздействиями.

Заключение.

В результате работы над системой Брокер Объектных Запросов были решены следующие задачи:

  • Разработана технология взаимодействия объектов, находящихся в разных приложениях и выполняющихся возможно на разных компьютерах.

  • Разработана структура и осуществлена реализация программного комплекса, позволяющая осуществлять взаимодействие распределенных объектов прозрачным для программиста способом.

  • Разработаны дополнительные библиотеки, которые существенно облегчают использование системы при программировании на языках C++ иObject Pascal.Для языкаObject Pascal разработаны дополнительные методы программирования, расширяющие функциональные возможности языка.

  • Произведена оптимизация критических участков программы с целью увеличения производительности.

Общий объем исходных текстов составляющих компонентов системы составляют более 500 Кбайт. Ввиду большого объема полностью воспроизвести их здесь невозможно, но часть приведена в приложении В.

При работе над системой был получен опыт использования всевозможных программных ресурсов, предосталяемых операционной системой Windows NT. Итогом изучение большого количества различных технических документов и спецификаций, а также разнообразных самостоятельных опытов и исследований расширилось представление об объектно-ориентированном программировании.

Но при всех своих достоинствах данная программная система не рассматривается как окончательный продукт, а лишь как первая пробная версия. Имеется большое количество возможностей, на данном этапе нереализованных, но являющихся мощными дополнениями к системе. Реализация части из них запланирована в ближайшем будущем.

Ожидается, что данная реализация Брокера Объектных Запросов найдет применение при разработке сложных распределенных систем и займет достойное место среди имеющихся и планируемых к реализации технологиях взаимодействия распределенных объектов.

Приложение А. Подборка статей из периодической литературы.

А.1. Журнал PC Week RE N 40 `96 от 8.10.96

А.2. Журнал Computer Week N 40 `96 31.10.96-6.11.96

А.3. ЖурналComputer Week N 41 `96 7.11.96-13.11.96

А.4. Журнал PC Week RE N 48 `96 от 3.12.96

Приложение Б. Листинг методов WriteLong иPutLong.

Б.1. Листинг метода WriteLong.

TStreamable.WriteLong: begin

:00423284 55 push ebp

:00423285 8BEC mov ebp,esp

:00423287 83C4F8 add esp,FFFFFFF8

:0042328A 53 push ebx

:0042328B 8955F8 mov [ebp-08],edx

:0042328E 8945FC mov [ebp-04],eax

strmable.200: Align4;

:00423291 8B45FC mov eax,[ebp-04]

:00423294 E83FFFFFFF call TStreamable.Align4

strmable.201: Stream.Write(L, 4);

:00423299 8D55F8 lea edx,[ebp-08]

:0042329C B904000000 mov ecx,00000004

:004232A1 8B45FC mov eax,[ebp-04]

:004232A4 8B4004 mov eax,[eax+04]

:004232A7 8B18 mov ebx,[eax]

:004232A9 FF5304 call [ebx+04]

strmable.202: end;

:004232AC 5B pop ebx

:004232AD 59 pop ecx

:004232AE 59 pop ecx

:004232AF 5D pop ebp

:004232B0 C3 ret

Б.2. Листинг методаPutLong.

TStreamable.PutULong: push ebx

:004234FC 53 push ebx

strmable.372: push edx

:004234FD 52 push edx

strmable.373: push eax

:004234FE 50 push eax

strmable.374: call TStreamable.Align4

:004234FF E8D4FCFFFF call TStreamable.Align4

strmable.375: pop eax

:00423504 58 pop eax

strmable.376: push eax

:00423505 50 push eax

strmable.377: mov eax,[eax+TStreamable.FStream]

:00423506 8B4004 mov eax,[eax+04]

strmable.378: lea edx,[esp+4]

:00423509 8D542404 lea edx,[esp+04]

strmable.379: mov ecx,4

:0042350D B904000000 mov ecx,00000004

strmable.380: mov ebx,[eax]

:00423512 8B18 mov ebx,[eax]

strmable.381: call dword ptr [ebx+vtWrite]

:00423514 FF5304 call [ebx+04]

strmable.382: pop eax

:00423517 58 pop eax

strmable.383: pop edx

:00423518 5A pop edx

strmable.384: pop ebx

:00423519 5B pop ebx

strmable.389: end;

:0042351A C3 ret

Приложение В. Фрагменты исходных текстов

В.1. Модуль “baseio.h” - файл заголовков подсистемы обработки запросов.

#if !defined(_BASEIO_H_)

#define _BASEIO_H_

#include "common\thread.h"

#include "common\pipe.h"

class Owned;

class Owner {

protected:

void addObject(Owned *);

void removeObject(Owned *);

void deleteObject(ULong);

Owned ** list;

ULong ownedCount;

public:

Owner();

virtual ~Owner();

const Owned* operator[](ULong) const;

ULong count() { return ownedCount; };

Boolean valid(Owned *, ULong&);

friend class Owned;

};

class Owned {

Owner * objOwner;

public:

Owned(Owner *);

virtual ~Owned();

Owner * owner() { return objOwner; };

};

class Ownered : public Owner, public Owned {

public:

Ownered(Owner * anOwner) : Owned(anOwner) {};

};

typedef void (*OnReceive)(void * info, Octet * message, ULong size);

class IOException {

};

class Receiver : public Owned {

protected:

void * info;

public:

OnReceive onReceive;

Receiver(Owner * owner, void * anInfo)

: Owned(owner), info(anInfo) {};

void receive(Octet * message, ULong size)

{ if(onReceive != NULL) onReceive(info, message, size); };

};

class Sender : public Owned {

public:

Sender(Owner * owner) : Owned(owner) {};

virtual ULong send(Octet * message, ULong size) = 0;

};

extern Char * defaultPipeName;

extern Char * corePipeName;

class PipeReceiver : public Receiver {

Pipe * input;

Thread * inthread;

public:

PipeReceiver(Owner * owner, void * anInfo, OnReceive onReceiveFunc, String inpipe);

virtual ~PipeReceiver();

friend class PipeinThread;

};

class PipeinThread : public Thread {

PipeReceiver * receiver;

public:

PipeinThread(PipeReceiver * aReceiver)

: Thread(True), receiver(aReceiver) {};

virtual void execute(void);

};

class PipeSender : public Sender {

Pipe * output;

public:

PipeSender(Owner * owner, String outpipe);

virtual ~PipeSender();

virtual ULong send(Octet * message, ULong size);

};

typedef void (* PropertyIterator)(void * info, String prop, String val);

class Context : public Owner, public Owned {

class Pair : public Owned {

public:

Char * property;

Char * value;

Pair(Owner * anOwner, Char * prop, Char * val)

: Owned(anOwner), property(prop), value(val) {};

~Pair();

};

public:

Owner * pairs;

Context(Owner * owner);

virtual ~Context();

void add(Char * prop, Char * val);

void add(const Char * prop, const Char * val);

void del(Char * prop);

Boolean find(Char * prop, void * info, PropertyIterator propIter);

};

class Stream {

public:

Octet * data;

ULong size;

ULong pos;

Stream();

~Stream();

void align2();

void align4();

void align8();

void putData(void * aData, ULong dataSize);

void putOctet(Octet value);

void putUShort(UShort value);

void putULong(ULong value);

void putDouble(Double value);

void putString(String value);

void getData(void * aData, ULong dataSize);

Octet getOctet();

UShort getUShort();

ULong getULong();

Double getDouble();

void getString(String& value);

};

class OperationRequest : public Owned {

Context * context;

CORBA_Object object;

Identifier operation;

CORBA_NamedValue * result;

Flags flags;

Stream stream;

GIOP_ReplyStatusType status;

typedef enum { created, invoked, replied } RequestState;

RequestState state;

public:

OperationRequest(Owner *, CORBA_Object, Identifier, CORBA_NamedValue *, Flags, Context * = NULL);

virtual ~OperationRequest();

void send(Flags invoke_flags);

void reply(GIOP_ReplyStatusType status, Octet * data, ULong size);

friend CORBA_Status CORBACALL CORBA_Request_add_arg(CORBA_Request, CORBA_Identifier,

CORBA_TypeCode, CORBA_void *, CORBA_long, CORBA_Flags, CORBA_Environment *);

friend CORBA_Status CORBACALL CORBA_Request_get_response(CORBA_Request req,

CORBA_Flags response_flags, CORBA_Environment * env);

};

class RequestManager : public Ownered {

public:

RequestManager(Owner * anOwner) : Ownered(anOwner) {};

void reply(CORBA_Request req, GIOP_ReplyStatusType status, Octet * data, ULong size);

};

class ServerRequest : public Owned {

//Context * context;

CORBA_Object object;

Identifier operation;

Flags flags;

Stream stream;

public:

ServerRequest(Owner *, CORBA_Object, Identifier, Flags, Octet *, ULong);

virtual ~ServerRequest();

};

class RequestAnalyser : public Ownered {

public:

RequestAnalyser(Owner * anOwner) : Ownered(anOwner) {};

void request(CORBA_Object, Identifier, Flags, Octet *, ULong);

};

class Inbox : public Owner, public Owned {

public:

Inbox(Owner *);

void messageIn(Octet * message, ULong size);

};

class Outbox : public Owner, public Owned {

Sender * coreSender;

public:

Outbox(Owner *);

Sender * defaultSender() { return coreSender; };

void send(void *, ULong, Sender * = NULL);

};

class Daemon : public Owner {

public:

Inbox * inbox;

Outbox * outbox;

RequestManager * requestManager;

RequestAnalyser * requestAnalyser;

Ownered * contextManager;

Daemon();

virtual ~Daemon();

};

#endif

В.2. Модуль “baseio.cpp” - реализация подсистемы обработки запросов.

#include <dos.h>

#include <string.h>

#pragma hdrstop

#include "common\c\corba.h"

#include "common\c\easytyps.h"

#include "common\baseio.h"

/* Owner **************************************************/

const Owned* Owner::operator[](ULong index) const

{

return index < ownedCount ? list[index] : NULL;

};

void Owner::addObject(Owned * owned)

{

Owned ** newList = new Owned * [ownedCount + 1];

memmove(newList, list, ownedCount * sizeof(Owned *));

newList[ownedCount++] = owned;

delete[] list;

list = newList;

};

void Owner::removeObject(Owned * owned)

{

ULong i;

if(valid(owned, i)) deleteObject(i);

};

void Owner::deleteObject(ULong index)

{

Owned ** newList = new Owned * [ownedCount - 1];

memmove(newList, list, index * sizeof(Owned *));

memmove(newList + index, list + index + 1,

(ownedCount - index - 1) * sizeof(Owned *));

ownedCount--;

delete[] list;

list = newList;

};

Owner::Owner()

: list(NULL), ownedCount(0)

{};

Owner::~Owner()

{

while(ownedCount > 0) delete list[ownedCount - 1];

};

Boolean Owner::valid(Owned * owned, ULong& index)

{

for(ULong i = 0; i < ownedCount; i++)

if(list[i] == owned) { index = i; return True; };

return False;

};

/* Owned **************************************************/

Owned::Owned(Owner * anOwner)

{

objOwner = anOwner;

objOwner->addObject(this);

};

Owned::~Owned()

{

objOwner->removeObject(this);

};

/* Receiver * (empty) *************************************/

/* Sender * (empty) ***************************************/

/* PipeReceiver *******************************************/

PipeReceiver::PipeReceiver(Owner * owner, void * anInfo, OnReceive onReceiveFunc, String inpipe)

: Receiver(owner, anInfo)

{

onReceive = onReceiveFunc;

input = inpipe ? new Pipe(inpipe, True, Pipe::read) : NULL;

inthread = input ? new PipeinThread(this) : NULL;

};

PipeReceiver::~PipeReceiver()

{

delete inthread;

delete input;

};

#define MAGIC_LENGTH 4

#define SIZE_OFFSET 8

#define MESSAGE_LENGTH 12

void PipeinThread::execute(void)

{

Char message[MESSAGE_LENGTH];

ULong size;

Char * buffer;

while(True)

{

// to error recovery if such occure

while(1)

{ // read magic

receiver->input->readBuffer(message, MAGIC_LENGTH);

if(receiver->input->lastError == 0 &&

strncmp(message, GIOP_MAGIC, MAGIC_LENGTH )== 0) break;

sleep(1);

};

// read message header

receiver->input->readBuffer(message + MAGIC_LENGTH, SIZE_OFFSET);

size = *(CORBA_unsigned_long *)(message + SIZE_OFFSET);

buffer = new CORBA_char[size + MESSAGE_LENGTH];

memmove(buffer, message, MESSAGE_LENGTH);

// read the message

receiver->input->readBuffer(buffer + MESSAGE_LENGTH, size);

// process message received

receiver->receive(buffer, size + MESSAGE_LENGTH);

delete[] buffer;

};

};

/* PipeSender *********************************************/

PipeSender::PipeSender(Owner * owner, String outpipe)

: Sender(owner)

{

output = outpipe ? new Pipe(outpipe, False, Pipe::write) : NULL;

};

PipeSender::~PipeSender()

{

delete output;

};

ULong PipeSender::send(Octet * message, ULong size)

{

if(output != NULL) output->writeBuffer(message, size);

return output->lastError;

};

/* Context ************************************************/

Context::Pair::~Pair()

{

delete[] property;

delete[] value;

};

Context::Context(Owner * owner)

: Owned(owner)

{

pairs = new Owner;

};

Context::~Context()

{

delete pairs;

};

void Context::add(Char * prop, Char * val)

{

new Pair(pairs, prop, val);

};

void Context::add(const Char * prop, const Char * val)

{

add((Char *)strdup(prop), (Char *)strdup(val));

};

void Context::del(Char * prop)

{

ULong l = strlen(prop);

Boolean multi = False;

Pair * pair;

if(prop[l-1] == '*') { l--; multi = True; };

for(ULong i = pairs->count()-1; i >= 0; i--)

{

pair = dynamic_cast<Pair *>((Owned *)(*pairs)[i]);

if(multi)

{

if(strncmpi(prop, pair->property, l) <= 0) delete pair;

} else

{

if(stricmp(prop, pair->property) == 0)

{

delete pair;

break;

};

};

}

};

Boolean Context::find(Char * prop, void * info, PropertyIterator propIter)

{

ULong l = strlen(prop);

Boolean multi = False;

Boolean result = False;

Pair * pair;

if(prop[l-1] == '*') { l--; multi = True; };

for(ULong i = 0; i < pairs->count(); i++)

{

pair = dynamic_cast<Pair *>((Owned *)(*pairs)[i]);

if(multi)

{

if(strncmpi(prop, pair->property, l) <= 0)

{

result = True;

propIter(info, pair->property, pair->value);

}

} else

{

if(stricmp(prop, pair->property) == 0)

{

result = True;

propIter(info, pair->property, pair->value);

break;

};

};

}

return result;

};

/* Stream *************************************************/

Stream::Stream()

{

data = new Octet[size = 1024];

pos = 0;

};

Stream::~Stream()

{

delete[] data;

};

void Stream::align2()

{

if(size & 1) size++;

};

void Stream::align4()

{

if(size & 3) size += 4 - (size & 3);

};

void Stream::align8()

{

if(size & 7) size += 8 - (size & 7);

};

void Stream::putOctet(Octet value)

{

putData(&value, sizeof(value));

};

void Stream::putUShort(UShort value)

{

align2();

putData(&value, sizeof(value));

};

void Stream::putULong(ULong value)

{

align4();

putData(&value, sizeof(value));

};

void Stream::putDouble(Double value)

{

align8();

putData(&value, sizeof(value));

};

void Stream::putString(String value)

{

ULong ul = strlen(value) + 1;

putULong(ul);

putData(value, ul);

};

void Stream::putData(void * aData, ULong dataSize)

{

if(pos+dataSize > size)

{

while(pos+dataSize > size) size += 1024;

Octet * buffer = new Octet[size];

memmove(buffer, data, pos);

delete[] data;

data = buffer;

};

memmove(data+pos, aData, dataSize);

pos += dataSize;

};

void Stream::getData(void * aData, ULong dataSize)

{

if(pos + dataSize <= size)

{

memmove(aData, data + pos, dataSize);

pos += dataSize;

};

};

Octet Stream::getOctet()

{

return pos < size ? data[pos++] : 0;

};

UShort Stream::getUShort()

{

align2();

UShort us = 0;

if(pos+1 < size)

{

us = *(UShort *)(data + pos);

pos += 2;

};

return us;

};

ULong Stream::getULong()

{

align4();

ULong ul = 0;

if(pos+3 < size)

{

ul = *(ULong *)(data + pos);

pos += 4;

};

return ul;

};

Double Stream::getDouble()

{

align8();

Double d = 0;

if(pos+7 < size)

{

d = *(Double *)(data + pos);

pos += 8;

};

return d;

};

void Stream::getString(String& value)

{

ULong l = getULong();

value = strdup(data + pos);

pos += l;

};

/* OperationRequest ***************************************/

OperationRequest::OperationRequest(Owner * owner, CORBA_Object obj,

Identifier anOperation, CORBA_NamedValue * aResult, Flags aFlags, Context * ctx)

: Owned(owner), object(obj), operation(anOperation), result(aResult),

flags(aFlags), context(ctx), state(created)

{ };

OperationRequest::~OperationRequest()

{

};

void OperationRequest::send(Flags invoke_flags)

{

Stream strm;

strm.putData(GIOP_MAGIC, 4);

strm.putOctet(1);

strm.putOctet(0);

strm.putOctet(1);

strm.putOctet(Request);

strm.putULong(0); // length - while 0

strm.putULong(0); // list of service_context

strm.putULong(ULong(this)); // request_id

strm.putOctet((invoke_flags & CORBA_INV_NO_RESPONSE) != 0); // response_expected

strm.putULong(4); //// object_key

strm.putULong(ULong(object)); //

strm.putString(operation);

strm.putULong(0); // principal

strm.putData(stream.data, stream.pos); // request body

*(ULong *)(strm.data + 8) = strm.pos - 12;

dynamic_cast<Daemon *>(dynamic_cast<RequestManager *>(owner())->owner())->outbox->send(strm.data, strm.pos);

};

void OperationRequest::reply(GIOP_ReplyStatusType aStatus, Octet * data, ULong size)

{

state = replied;

status = aStatus;

CORBA_Environment env;

CORBA_TCKind kind = CORBA_TypeCode_kind(result->argument->_type, &env);

if(env._major != CORBA_NO_EXCEPTION) status = env._major;

else switch(kind)

{

case tk_octet: case tk_boolean: case tk_char:

*(Octet *)result->argument->_value = *(Octet *)data;

break;

case tk_short: case tk_ushort:

*(UShort *)result->argument->_value = *(UShort *)data;

break;

case tk_long: case tk_ulong: case tk_float: case tk_objref:

*(ULong *)result->argument->_value = *(ULong *)data;

break;

case tk_double:

*(Double *)result->argument->_value = *(Double *)data;

break;

};

};

/* RequestManager ****************************************/

void RequestManager::reply(CORBA_Request req, GIOP_ReplyStatusType status, Octet * data, ULong size)

{

ULong i;

if(valid((OperationRequest *)req, i)) dynamic_cast<OperationRequest *>(list[i])->reply(status, data, size);

};

/* ServerRequest ******************************************/

ServerRequest::ServerRequest(Owner * anOwner, CORBA_Object anObject,

Identifier anOperation, Flags anFlags, Octet * data, ULong size)

: Owned(anOwner), object(anObject), flags(anFlags)

{

operation = strdup(anOperation);

stream.putData(data, size);

};

ServerRequest::~ServerRequest()

{

delete[] operation;

};

/* Inbox **************************************************/

void messageIn(void * inbox, Octet * message, ULong size)

{

((Inbox *)inbox)->messageIn(message, size);

};

Inbox::Inbox(Owner * owner)

: Owned(owner)

{

new PipeReceiver(this, (void *)NULL, ::messageIn, (Char *)defaultPipeName);

};

void Inbox::messageIn(Octet * message, ULong size)

{

Stream strm;

if(!strncmp(message, GIOP_MAGIC, 4))

{

strm.putData(message, size);

strm.pos = 4;

strm.getOctet(); //major

strm.getOctet(); //minor

strm.getOctet(); //byte_order

switch(strm.getOctet()) // message_type

{

case Request:

case Reply:

{

ULong l = strm.getULong();

String s;

while(l) // service_context

{

strm.getULong();

ULong len = strm.getULong();

strm.pos += len;

l--;

};

CORBA_Request req = CORBA_Request(strm.getULong());

GIOP_ReplyStatusType status = strm.getULong();

dynamic_cast<Daemon *>(owner())->requestManager->

reply(req, status, strm.data + strm.pos, strm.size - strm.pos);

};

};

};

};

/* Outbox *************************************************/

Outbox::Outbox(Owner * anOwner)

: Owned(anOwner)

{

coreSender = new PipeSender(this, corePipeName);

};

void Outbox::send(void * message, ULong size, Sender * sender)

{

if(sender == NULL) sender = coreSender;

if(sender != NULL) sender->send((Octet *)message, size);

};

/* LibraryDaemon ******************************************/

Daemon::Daemon()

{

inbox = new Inbox(this);

outbox = new Outbox(this);

requestManager = new RequestManager(this);

contextManager = new Ownered(this);

};

Daemon::~Daemon()

{

delete requestManager;

delete outbox;

delete inbox;

};

В.3. Модуль “giop.pas” - абстрактные классы для работы по протоколуGIOP.

unit Giop;

interface

uses

Corba2, Iop;

type

MsgType = type Octet;

const

Request = MsgType(0);

Reply = MsgType(1);

CancelRequest = MsgType(2);

LocateRequest = MsgType(3);

LocateReply = MsgType(4);

CloseConnection = MsgType(5);

MessageError = MsgType(6);

type

Version = packed record

Major: Char;

Minor: Char;

end;

const

GiopMagic: array [0..3] of Char = 'GIOP';

type

{ general message header }

MessageHeader = packed record

Magic: array [0..3] of Char; // 'GIOP'

GIOPVersion: Version; // '1'.'0'

ByteOrder: Boolean; // True

MessageType: Octet;

MessageSize: ULong;

end;

type

{ request message header }

RequestHeader = packed record

ServiceContext: IOP.ServiceContextList;

RequestId: ULong;

ResponseExpected: Boolean;

ObjectKey: OctetSeq;

Operation: string;

RequestingPrincipial: CORBA2.Principal;

end;

type

{ reply message header }

ReplyStatusType = {type} ULong;

const

NO_EXCEPTION = ReplyStatusType(0);

USER_EXCEPTION = ReplyStatusType(1);

SYSTEM_EXCEPTION = ReplyStatusType(2);

LOCATION_FORWARD = ReplyStatusType(3);

type

ReplyHeader = packed record

ServiceContext: IOP.ServiceContextList;

RequestId: ULong;

ReplyStatus: ReplyStatusType;

end;

type

{ cancel request message header }

CancelRequestHeader = packed record

RequestId: ULong;

end;

type

{ locate request message header }

LocateRequestHeader = packed record

RequestId: ULong;

ObjectKey: OctetSeq;

end;

type

{ locate reply message header }

LocateStatusType = type ULong;

const

UNKNOWN_OBJECT = LocateStatusType(0);

OBJECT_HERE = LocateStatusType(0);

OBJECT_FORWARD = LocateStatusType(0);

type

LocateReplyHeader = packed record

RequestId: ULong;

LocateStatus: LocateStatusType;

end;

implementation

end.

В.4. Модуль“giopimp.pas” - реализация поддержки протоколаGIOP.

unit GiopImp;

interface

uses

SysUtils, Classes, Windows,

Corba2, {CorbaImp, }Iop, Giop, Strmable;

type

{ Header common class }

TBody = class(TStreamable)

protected

procedure Write; override;

procedure Read; override;

public

constructor Create;

end;

THeader = class(TStreamable)

protected

FBody: TBody;

public

constructor Create;

constructor CreateFromStream(Stream: TStream);

destructor Destroy; override;

function MsgType: MsgType; virtual; abstract;

property Body: TBody read FBody write FBody;

end;

{ MessageHeader wrapper }

TMessageHeader = class(TStreamable)

private

FHeader: THeader;

FMsgType: MsgType;

procedure SetHeader(AHeader: THeader);

protected

procedure Write; override;

procedure Read; override;

public

constructor Create;

destructor Destroy; override;

property Header: THeader read FHeader write SetHeader;

property MsgType: MsgType read FMsgType;

end;

{ RequestHeader wrapper }

TRequestHeader = class(THeader)

private

FId: ULong;

FResponseExpected: Boolean;

FObjectKey: Pointer; // wrong

FOperation: string;

protected

procedure Write; override;

procedure Read; override;

public

constructor CreateWithData(const AnOperation: string; AResponseExpected: Boolean);

function MsgType: MsgType; override;

property Id: ULong read FId write FId;

property ResponseExpected: Boolean read FResponseExpected write FResponseExpected;

property ObjectKey: Pointer read FObjectKey write FObjectKey; //wrong

property Operation: string read FOperation write FOperation;

end;

{ ReplyHeader wrapper }

TReplyHeader = class(THeader)

private

FId: ULong;

FReplyStatus: ReplyStatusType;

protected

procedure Write; override;

procedure Read; override;

public

function MsgType: MsgType; override;

property Id: ULong read FId write FId;

property ReplyStatus: ReplyStatusType read FReplyStatus write FReplyStatus;

end;

{ RequestHeader wrapper }

TCancelRequestHeader = class(THeader)

private

FId: ULong;

protected

procedure Write; override;

procedure Read; override;

public

function MsgType: MsgType; override;

property Id: ULong read FId write FId;

end;

implementation

constructor TBody.Create;

begin

Stream := TMemoryStream.Create;

end;

procedure TBody.Write;

begin

end;

procedure TBody.Read;

begin

end;

constructor THeader.Create;

begin

inherited Create;

FBody := TBody.Create;

end;

constructor THeader.CreateFromStream(Stream: TStream);

begin

inherited Create;

FBody := TBody.Create;

ReadFromStream(Stream);

FBody.Stream.CopyFrom(Stream, Stream.Size - Stream.Position);

FBody.Stream.Position := 0;

end;

destructor THeader.Destroy;

begin

FBody.Free;

end;

constructor TMessageHeader.Create;

begin

inherited Create;

FMsgType := MessageError;

end;

destructor TMessageHeader.Destroy;

begin

FHeader.Free;

inherited Destroy;

end;

procedure TMessageHeader.SetHeader(AHeader: THeader);

begin

FHeader := AHeader;

if FHeader = nil then FMsgType := MessageError

else FMsgType := Header.MsgType;

end;

procedure TMessageHeader.Write;

var

S: TStream;

begin

Stream.Write(GiopMagic, 4);

PutChar('1').PutChar('0').PutBoolean(True).PutOctet(MsgType);

if Header = nil then PutULong(0) else

begin

S := TMemoryStream.Create;

try

Header.WriteToStream(S);

Header.Body.Stream.Position := 0; // ???

S.CopyFrom(Header.Body.Stream, Header.Body.Stream.Size);

S.Position := 0;

PutStream(S);

finally

S.Free;

end;

end;

end;

procedure TMessageHeader.Read;

var

S: array [0..3] of Char;

Version: Giop.Version;

ByteOrder: Boolean;

MessageSize: ULong;

begin

Header.Free;

Stream.Read(S, 4);

if(StrLComp(S, GiopMagic, 4) <> 0) then BadStreamFormat;

GetChar(Version.Major).GetChar(Version.Minor).GetBoolean(ByteOrder).

GetOctet(Octet(FMsgType)).GetULong(MessageSize);

case MsgType of

Request : FHeader := TRequestHeader.CreateFromStream(Stream);

Reply : FHeader := TReplyHeader.CreateFromStream(Stream);

CancelRequest : FHeader := TCancelRequestHeader.CreateFromStream(Stream);

LocateRequest : BadStreamFormat;

LocateReply : BadStreamFormat;

CloseConnection : FHeader := nil;

MessageError : FHeader := nil;

end;

end;

constructor TRequestHeader.CreateWithData(const AnOperation: string; AResponseExpected: Boolean);

begin

inherited Create;

FOperation := AnOperation;

FResponseExpected := AResponseExpected;

end;

function TRequestHeader.MsgType: MsgType;

begin

Result := Giop.Request;

end;

procedure TRequestHeader.Write;

begin

PutULong(0).PutULong(Id).PutBoolean(ResponseExpected).

PutULong(ULong(ObjectKey)).PutString(Operation).PutULong(0);

end;

procedure TRequestHeader.Read;

var

CtxLen: ULong;

ObjectKeyAsULong: ULong;

PrnLen: ULong;

begin

GetULong(CtxLen);

if CtxLen <> 0 then BadStreamFormat; // Context

GetULong(FId).GetBoolean(FResponseExpected).GetULong(ObjectKeyAsULong).

GetString(FOperation).GetULong(PrnLen);

ObjectKey := Pointer(ObjectKeyAsULong); // wrong

if PrnLen <> 0 then BadStreamFormat; // Principal

end;

function TReplyHeader.MsgType: MsgType;

begin

Result := Giop.Reply;

end;

procedure TReplyHeader.Write;

begin

PutULong(0).PutULong(Id).PutULong(ReplyStatus);

end;

procedure TReplyHeader.Read;

var

CtxLen: ULong;

begin

GetULong(CtxLen);

if CtxLen <> 0 then BadStreamFormat; // Context

GetULong(FId).GetULong(FReplyStatus);

end;

function TCancelRequestHeader.MsgType: MsgType;

begin

Result := Giop.CancelRequest;

end;

procedure TCancelRequestHeader.Write;

begin

PutULong(Id);

end;

procedure TCancelRequestHeader.Read;

begin

GetULong(FId);

end;

end.

Приложение Г. Графические листы

Г.1. Лист 1. Структура ядра системы.

Г.2. Лист 2. Структура библиотеки.

Г.3. Лист 3. Структура подсистемы обработки запросов.

Г.4. Лист 4. Схемы алгоритмов кодирования сообщения, запроса, ответа.

Г.5. Лист 5. Схема алгоритма кодирования значения произвольного типа.

Г.6. Лист 6. Этапы создания приложений с распределенными объектами.

Г.7. Лист 7. Пример: Библиотека. Разработка сервера объекта.

Г.8. Лист 8. Пример: Библиотека. Разработка клиента объекта.

Г.9. Лист 9. Исследование конкурентоспособности программного продукта.

Приложение Д. Использованная литература

  1. Thomas J. Mowbray, Ron Zahavi, The Essential CORBA: System Integration Using Distributed Objects, (Wiley, 1995)

  2. Robert Orfali, Dan Harkey, Jery Edwards, The Essential Distributed Objects/Survival Guide, (Wiley, 1996).

  3. CORBA: Common Object Request Broker Architecture and Specification.

  4. AP-526. Application Note. Optimizations For Intel’s 32-Bit Processors, Intel, October 1995, Order No 242816-001.

  5. Журнал Монитор-Аспект 2.94 стр. 80-84.

  6. Журнал Мир ПК 10.96 стр. 10-20.

  7. Журнал PC Magazine/RE 12.96 стр. 25-49.

1Соответственно в данном разделе тип объекта называется классом. Если упоминается термин объект, то имеется ввиду конкретный представитель, экземпляр класса.

2С целью упрощения изложения не рассматриваются некоторые частные случаи, такие как статические функции - члены класса, виртуальные функции и др.

3В скобках приводится название класса C++, который выполняет соответствующую функцию.

4В ОС Windows окно - это некоторая структура, которая может получать сообщения, и от которого может осуществляться посылка некоторых специальных сообщений. Для посылки большинства сообщений окна-отправителя не требуется. При переносе под UNIX окна возможно будут заменены очередями.

5Без потери общности можно предположить, что не метод объекта вызывается из откуда-нибудь, а один объект вызывает метод другого.

6Вообще говоря, байт может иметь и другую разрядность, например состоять из девяти бит.

7В языке Object Pascal внутри тела функции имеется предопределенная переменная Result типа, возвращаемого функцией.

8Насчет наглядности и удобности можно спорить, поэтому были оставлены и первоначальные определения функций.

9Такой тип определяется через примерно такую конструкцию: FooClass = class of Foo; .

10Так как все экземпляры динамические, то переменная типа класса в языке Object Pascal всегда является указателем на экземпляр этого класса. При обращении к методам и полям класса не нужно разыменовывать ссылку с помощью знака ^. Соответственно и при передаче объекта как параметра функции и процедуре передается всегда указатель.

11Секция initialization ... end. в языке Object Pascal заменила секцию begin ... end. инициализации модуля, имеющуюся в языке Turbo Pascal. Также имеется и аналогичная секция finalization, которая выполняется при завершении программы.

12То есть если явно не указан базовый класс для нового класса, по умолчанию им является класс TObject, то есть Foo = class эквивалентно Foo = class(TObject).

13Delphiверсии 2.0 является 32-разрядным компилятором, использующую модель памяти FLAT, реализованную в Win 32. Поэтому все адреса передаются через 32-разрядные регистры процессоров i386 и выше.

14Следует иметь ввиду, что объектная ориентированность технологии OLE представляется несколько надуманной. Не вдаваясь в подробности реализации, следует иметь ввиду, что использование объектов в этой технологии имеет частично условный характер и практически никак не соотносится с иерархией классов/объектов в приложении. Но тем не менее эта технология оперирует понятиями объекта, почему продукт OLEnterprise и рассматривается в списке конкурентов.

135

Соседние файлы в папке HOR