Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / utils / logWalker / GIOP_Buffer.cpp
blobfdf08f63fc7de6b39fa4eb5d2e8f357347a96ac3
1 #include "GIOP_Buffer.h"
2 #include "ace/OS_NS_string.h"
3 #include "ace/Log_Msg.h"
5 static const char *size_leadin_1_5 = "GIOP v1."; //"x msg, ";
6 static size_t leadin_len_1_5 = 15;
7 static const char *size_leadin_1_6 = "GIOP message v1."; //2, ";
8 static size_t leadin_len_1_6 = 19;
11 const char *GIOP_Buffer::size_leadin = 0;
12 size_t GIOP_Buffer::leadin_len = 0;
13 const size_t GIOP_Buffer::giop_header_len = 12;
15 void
16 GIOP_Buffer::init_leadin (int version)
18 if (size_leadin == 0)
20 if (version == 150)
22 size_leadin = size_leadin_1_5;
23 leadin_len = leadin_len_1_5;
25 else
27 size_leadin = size_leadin_1_6;
28 leadin_len = leadin_len_1_6;
33 // GIOP 1.2 header: 12 bytes
34 // Magic: 4
35 // ver: 2
36 // flags: 1 // bo
37 // type: 1 // req/repl/lf/excp
38 // len: 4
40 // Request 1.2 header:
41 // req_id: 4
42 // flags: 1
43 // RESVD: 3
44 // Address disposition: 4
45 // target: <4 len, + len> [0-3 pad]
46 // opname: <4 len, + len>
48 // GIOP 1.0 header: 12 bytes
49 // Magic: 4
50 // ver: 2
51 // byte_order: 1
52 // type: 1 // req/repl/lf/excp
53 // len: 4
55 // Request 1.0 header:
57 struct RequestHeader_1_0 { // Renamed from RequestHeader
58 IOP::ServiceContextList service_context;
59 unsigned long request_id;
60 boolean response_expected;
61 sequence <octet> object_key;
62 string operation;
63 CORBA::OctetSeq requesting_principal;
66 // service_context: 4(count)+contexts.
67 // context id: 4
68 // content blob: 4(len) + len octets + (0-3)pad
69 // request_id: 4
70 // respexp: 1
71 // RESVD: 3
72 // Address disposition: 4
73 // target: <4 len, + len> [0-3 pad]
74 // opname: <4 len, + len>
77 struct ReplyHeader_1_0 { // Renamed from ReplyHeader
78 IOP::ServiceContextList service_context;
79 unsigned long request_id;
80 ReplyStatusType_1_0 reply_status;
82 // GIOP 1.1
83 typedef ReplyHeader_1_0 ReplyHeader_1_1;
84 // Same Header contents for 1.0 and 1.1
85 #else
86 // GIOP 1.2, 1.3
87 enum ReplyStatusType_1_2 {
88 NO_EXCEPTION,
89 USER_EXCEPTION,
90 SYSTEM_EXCEPTION,
91 LOCATION_FORWARD,
92 LOCATION_FORWARD_PERM,// new value for 1.2
93 NEEDS_ADDRESSING_MODE // new value for 1.2
95 struct ReplyHeader_1_2 {
96 unsigned long request_id;
97 ReplyStatusType_1_2 reply_status;
98 IOP::ServiceContextList service_context;
105 //static const size_t target_offset_12 = GIOP_Buffer::giop_header_len + 12;
107 // 12 = req_id + flags + RESVD + addr disp.
109 GIOP_Buffer::GIOP_Buffer(void)
110 : cdr_ (0),
111 preamble_(),
112 log_offset_(0),
113 thr_(0),
114 time_(),
115 expected_req_id_(0),
116 expected_size_(0),
117 expected_type_(0),
118 buffer_size_(0),
119 wr_pos_ (0),
120 octets_ (0),
121 owner_ (0),
122 buffer_lost_ (false),
123 sending_(false),
124 oid_ (0),
125 oid_len_ (0),
126 opname_ (0),
127 req_id_ (0),
128 resp_exp_ (0),
129 reply_status_ (0),
130 ver_minor_ (0),
131 msg_size_ (0),
132 num_contexts_ (0),
133 header_parsed_ (false),
134 payload_start_ (0),
135 payload_size_ (0)
139 GIOP_Buffer::GIOP_Buffer(const char *text,
140 size_t offset,
141 Thread *thread,
142 Invocation *owner)
143 : cdr_ (0),
144 preamble_(text),
145 log_offset_(offset),
146 thr_(thread),
147 time_(ACE_Time_Value::zero),
148 expected_req_id_(0),
149 expected_size_(0),
150 expected_type_(0),
151 buffer_size_(0),
152 wr_pos_ (0),
153 octets_ (0),
154 owner_ (owner),
155 buffer_lost_ (false),
156 sending_(false),
157 oid_ (0),
158 oid_len_ (0),
159 opname_ (0),
160 req_id_ (0),
161 resp_exp_ (0),
162 reply_status_ (0),
163 ver_minor_ (0),
164 msg_size_ (0),
165 num_contexts_ (0),
166 header_parsed_ (false),
167 payload_start_ (0),
168 payload_size_ (0)
170 const char *size_str = ACE_OS::strstr(text, size_leadin);
171 if (size_str != 0)
173 size_str += leadin_len; //ACE_OS::strlen (size_leadin);
174 // size_str += 3;
175 this->expected_size_ = ACE_OS::strtol(size_str, 0, 10);
176 const char *id = ACE_OS::strchr(size_str, '[') + 1;
177 this->expected_req_id_ = ACE_OS::strtol(id, 0, 10);
179 this->sending_ = ACE_OS::strstr(text,"send") ? 0 : 1;
180 this->expected_type_ = ACE_OS::strstr(text,"Request") ? 0 : 1;
183 void
184 GIOP_Buffer::owner (Invocation *owner)
186 this->owner_ = owner;
189 Invocation *
190 GIOP_Buffer::owner (void)
192 return this->owner_;
195 void
196 GIOP_Buffer::init_buf (const char *text, size_t offset)
198 // GIOP message - HEXDUMP
199 this->log_offset_ = offset;
200 const char * size_str = ACE_OS::strstr (text,"HEXDUMP ") + 8;
201 this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10);
202 this->payload_size_ = this->buffer_size_ - 12;
203 size_str = ACE_OS::strstr (text,"showing first ");
204 if (size_str != 0)
206 size_str += 14;
207 this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10);
209 if (this->octets_ != 0)
211 delete [] this->octets_;
213 this->octets_ = new char [this->buffer_size_];
214 ACE_OS::memset (this->octets_, 0, this->buffer_size_);
215 this->wr_pos_ = this->octets_;
218 GIOP_Buffer::~GIOP_Buffer(void)
220 delete [] this->octets_;
224 GIOP_Buffer::add_octets (const char *text, size_t offset)
226 if (this->octets_ == 0)
228 this->init_buf(text, offset);
229 return 0;
232 const char *c = text;
233 char *err;
234 for (int count = 0;
235 count < 16 && this->cur_size() < this->buffer_size_;
236 count++)
238 if (count == 8)
239 ++c;
240 int o = ::strtol(c, &err, 16);
241 if (err == c || *err == 0)
242 return -1;
243 *this->wr_pos_++ = o;
244 c = err+1;
246 size_t cs = this->cur_size();
247 int rtn = 0;
248 if (!this->header_parsed_)
250 this->header_parsed_ = this->parse_header();
251 if (this->header_parsed_ )
252 rtn = 1;
254 if (cs == this->buffer_size_)
256 char vmaj = this->octets_[4];
257 char order = this->octets_[6];
259 delete this->cdr_;
260 this->cdr_ = new ACE_InputCDR (this->octets_,
261 this->cur_size(),
262 order, vmaj, this->ver_minor_);
263 this->cdr_->skip_bytes (this->payload_start_ - this->octets_);
264 rtn = -1;
266 return rtn;
269 bool
270 GIOP_Buffer::sending (void) const
272 return this->sending_;
275 bool
276 GIOP_Buffer::is_full (void) const
278 return this->buffer_size_ > 0 && this->cur_size() == this->buffer_size_;
281 char
282 GIOP_Buffer::type (void) const
284 if (this->octets_ == 0)
285 return 127;
286 return this->octets_[7];
289 char
290 GIOP_Buffer::expected_type (void) const
292 return this->expected_type_;
295 char
296 GIOP_Buffer::minor_version (void) const
298 return this->ver_minor_;
301 size_t
302 GIOP_Buffer::reply_status (void) const
304 return this->reply_status_;
307 size_t
308 GIOP_Buffer::num_contexts (void) const
310 return this->num_contexts_;
313 bool
314 GIOP_Buffer::is_oneway (void)
316 if (this->octets_ == 0)
318 return false;
321 if (!this->header_parsed_)
322 this->header_parsed_ = this->parse_header();
324 return (resp_exp_ &1) == 0;
327 size_t
328 GIOP_Buffer::log_posn (void) const
330 return this->log_offset_;
333 Thread *
334 GIOP_Buffer::thread (void)
336 return this->thr_;
339 const ACE_Time_Value &
340 GIOP_Buffer::time (void) const
342 return this->time_;
345 void
346 GIOP_Buffer::time (const ACE_Time_Value &t)
348 this->time_ = t;
351 const ACE_CString &
352 GIOP_Buffer::preamble (void) const
354 return this->preamble_;
357 size_t
358 GIOP_Buffer::expected_size (void) const
360 return this->expected_size_;
363 size_t
364 GIOP_Buffer::msg_size (void)
366 if (this->cur_size() < 12)
367 return 0;
368 if (!this->header_parsed_)
369 this->header_parsed_ = this->parse_header();
370 return (size_leadin == size_leadin_1_5) ? this->payload_size_ : this->msg_size_;
373 size_t
374 GIOP_Buffer::expected_req_id (void) const
376 return this->expected_req_id_;
379 size_t
380 GIOP_Buffer::actual_req_id (void)
382 if (this->octets_ == 0)
383 return 0;
385 if (!this->header_parsed_)
386 this->header_parsed_ = this->parse_header();
388 return this->req_id_;
391 size_t
392 GIOP_Buffer::cur_size (void) const
394 return this->wr_pos_ - this->octets_;
397 bool
398 GIOP_Buffer::parse_svc_contexts (void)
400 ACE_CDR::ULong temp;
401 ACE_CDR::ULong num_svc_cont;
402 if ( !(*this->cdr_ >> num_svc_cont))
403 return false;
404 this->num_contexts_ = static_cast<size_t>(num_svc_cont);
405 while (num_svc_cont > 0)
407 if (!(*this->cdr_ >> temp)) // tag really
408 return false;
409 if (!(*this->cdr_ >> temp))
410 return false;
411 if ((this->cur_size() == this->buffer_size_) && (this->cdr_->length() < temp))
413 return this->cdr_->skip_bytes (this->cdr_->length());
415 if (!this->cdr_->skip_bytes(temp))
417 return this->cur_size() == this->buffer_size_;
419 --num_svc_cont;
421 return true;
424 bool
425 GIOP_Buffer::parse_header (void)
427 if (this->octets_ == 0 || this->cur_size() < 12)
429 return false;
432 char vmaj = this->octets_[4];
433 this->ver_minor_ = this->octets_[5];
434 char order = this->octets_[6];
436 char mtype = this->octets_[7];
437 if (mtype > 1) // not a request or reply
439 return false;
441 delete this->cdr_;
442 this->cdr_ = new ACE_InputCDR (this->octets_,
443 this->cur_size(),
444 order, vmaj, this->ver_minor_);
445 this->cdr_->skip_bytes (8);
446 this->payload_start_ = this->cdr_->rd_ptr();
447 ACE_CDR::ULong len_ulong;
448 if (!(*this->cdr_ >> len_ulong))
449 return false;
450 this->msg_size_ = len_ulong;
452 if (this->ver_minor_ < 2)
454 if (!this->parse_svc_contexts())
456 return false;
460 if (!(*this->cdr_ >> len_ulong))
462 return false;
464 this->req_id_ = static_cast<size_t>(len_ulong);
466 switch (mtype) {
467 case 0: //Request
468 if (!(*this->cdr_ >> this->resp_exp_))
470 return false;
472 if (this->ver_minor_ > 1 &&
473 !(*this->cdr_ >> len_ulong)) // address disposition
475 return false;
477 if (!(*this->cdr_ >> len_ulong))
479 return false;
481 this->oid_len_ = static_cast<size_t>(len_ulong);
482 this->oid_ = this->cdr_->rd_ptr();
483 if (!this->cdr_->skip_bytes(len_ulong))
486 return false;
488 if (!(*this->cdr_ >> len_ulong))
490 return false;
492 this->opname_ = this->cdr_->rd_ptr();
493 if (!this->cdr_->skip_bytes(len_ulong))
495 return false;
497 break;
498 case 1: //Reply
499 if (!(*this->cdr_ >> len_ulong))
501 return false;
503 this->reply_status_ = static_cast<size_t>(len_ulong);
504 break;
505 default:
506 return true;
508 if (this->ver_minor_ > 1)
510 if (!this->parse_svc_contexts())
511 return false;
513 this->cdr_->align_read_ptr (8);
514 this->payload_start_ = this->cdr_->rd_ptr();
515 return true;
518 const char *
519 GIOP_Buffer::target_oid (size_t &len)
521 if (this->octets_ == 0)
523 return 0;
526 if (!this->header_parsed_)
527 this->header_parsed_ = this->parse_header();
529 if (this->oid_ == 0)
530 return 0;
532 len = this->oid_len_;
533 return this->oid_;
536 const char *
537 GIOP_Buffer::operation (void)
539 if (octets_ == 0)
540 return 0;
542 if (!this->header_parsed_)
543 this->header_parsed_ = this->parse_header();
545 return this->opname_;
548 ACE_InputCDR &
549 GIOP_Buffer::payload (void)
551 if (octets_ != 0 && !this->header_parsed_)
552 this->header_parsed_ = this->parse_header();
553 return *this->cdr_;
556 bool
557 GIOP_Buffer::has_octets (void) const
559 return (octets_ != 0);
562 bool
563 GIOP_Buffer::validate (void)
565 return
566 this->expected_req_id_ == this->actual_req_id() &&
567 this->expected_type_ == this->type() &&
568 this->expected_size_ == this->msg_size();
571 bool
572 GIOP_Buffer::matches (GIOP_Buffer *other) const
574 if (other->header_parsed_)
576 return this->expected_req_id_ == other->actual_req_id() &&
577 this->expected_type_ == other->type() &&
578 (this->expected_size_ == other->msg_size() ||
579 this->expected_size_ == other->msg_size() + 4);
581 return this->expected_req_id_ == other->expected_req_id() &&
582 this->expected_type_ == other->expected_type() &&
583 this->sending_ == other->sending() &&
584 this->expected_size_ == other->expected_size();
587 void
588 GIOP_Buffer::reset (void)
590 this->octets_ = 0;
591 this->wr_pos_ = 0;
592 this->buffer_size_ = 0;
593 this->payload_size_ = 0;
594 this->buffer_lost_ = true;
595 this->header_parsed_ = false;
596 this->opname_ = 0;
599 void
600 GIOP_Buffer::transfer_from (GIOP_Buffer *other)
602 delete this->octets_;
603 this->octets_ = other->octets_;
604 this->wr_pos_ = other->wr_pos_;
605 this->buffer_size_ = other->buffer_size_;
606 this->payload_size_ = other->payload_size_;
607 this->header_parsed_ = false;
608 other->reset();
611 void
612 GIOP_Buffer::swap (GIOP_Buffer *other)
614 char *tmp_octets = this->octets_;
615 char *tmp_wr_pos = this->wr_pos_;
616 size_t tmp_bsize = this->buffer_size_;
617 size_t tmp_psize = this->payload_size_;
619 this->octets_ = other->octets_;
620 this->wr_pos_ = other->wr_pos_;
621 this->buffer_size_ = other->buffer_size_;
622 this->payload_size_ = other->payload_size_;
624 other->octets_ = tmp_octets;
625 other->wr_pos_ = tmp_wr_pos;
626 other->buffer_size_ = tmp_bsize;
627 other->payload_size_= tmp_psize;