Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / ASNMP / asnmp / octet.cpp
blob6a3da66f41d29999f4376faf9ec043ead7d59ef1
2 //=============================================================================
3 /**
4 * @file octet.cpp
6 * Implements the SMI Octet datatype (RFC 1155)
7 * This class is fully contained and does not rely on or any other
8 * SNMP libraries. Ported to ACE by Michael MacFaden mrm@cisco.com
10 * @author Peter E Mellquist
12 //=============================================================================
14 /*===================================================================
15 Copyright (c) 1996
16 Hewlett-Packard Company
18 ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
19 Permission to use, copy, modify, distribute and/or sell this software
20 and/or its documentation is hereby granted without fee. User agrees
21 to display the above copyright notice and this license notice in all
22 copies of the software and any documentation of the software. User
23 agrees to assume all liability for the use of the software; Hewlett-Packard
24 makes no representations about the suitability of this software for any
25 purpose. It is provided "AS-IS without warranty of any kind,either express
26 or implied. User hereby grants a royalty-free license to any and all
27 derivatives based upon this software code base.
28 =====================================================================*/
30 #include "asnmp/octet.h" // include definition for octet class
31 #include "ace/OS_Memory.h"
32 #include "ace/OS_NS_string.h"
33 #include "ace/OS_NS_stdio.h"
34 #include "ace/OS_NS_ctype.h"
35 #include "ace/os_include/os_ctype.h"
37 //============[ syntax type ]=========================================
38 SmiUINT32 OctetStr::get_syntax()
40 return sNMP_SYNTAX_OCTETS;
43 inline
44 void init_octet_smi(SmiVALUE& smi)
46 smi.syntax = sNMP_SYNTAX_OCTETS;
47 smi.value.string.ptr = 0;
48 smi.value.string.len = 0;
51 inline
52 void reset_octet_smi(SmiVALUE& smi)
54 delete [] smi.value.string.ptr;
55 smi.value.string.ptr = 0;
56 smi.value.string.len = 0;
59 inline
60 int copy_octet_smi(SmiVALUE& smi, int size, const char *src, int& valid_flag)
62 valid_flag = 0;
64 if (smi.value.string.ptr)
65 delete [] smi.value.string.ptr;
67 ACE_NEW_RETURN(smi.value.string.ptr, SmiBYTE[size], 1);
68 ACE_OS::memcpy( smi.value.string.ptr, src, size);
69 smi.value.string.len = size;
70 valid_flag = 1;
71 return 0;
74 //============[ default constructor ]=========================
75 OctetStr::OctetStr( const char * string, long size):
76 output_buffer(0), validity(0)
78 init_octet_smi(smival);
80 // check for null string
81 if ( !string)
82 return;
84 if (size == -1) // calc if no length given - assume c style string
85 size = ACE_OS::strlen( string);
87 copy_octet_smi(smival, size, string, validity);
91 //============[ set the data on an already constructed Octet ]============
92 // TODO: should return status since it can fail in so many places
93 void OctetStr::set_data( const SmiBYTE* string, long size)
95 // invalid args, set octetStr to not valid
96 if ( !string || !size) {
97 validity = 0;
98 return;
101 // assume non-zero terminated string
102 if (size == -1) // calc if no length given - assume c style string
103 size = ACE_OS::strlen( (char *)string);
105 // free up already used space
106 if ( smival.value.string.ptr ) {
107 reset_octet_smi(smival);
109 smival.value.string.len = 0;
112 copy_octet_smi(smival, size, (const char *)string, validity);
115 //============[ constructor using another octet object ]==============
116 OctetStr::OctetStr ( const OctetStr &octet):
117 SnmpSyntax (octet), output_buffer(0), validity(1)
119 init_octet_smi(smival);
120 // check for zero len case
121 if ( octet.smival.value.string.len == 0) {
122 return;
125 // must be a valid object
126 if ( octet.validity == 0) {
127 validity = 0;
128 return;
131 // get the mem needed
132 copy_octet_smi(smival, octet.smival.value.string.len,
133 (const char *)octet.smival.value.string.ptr, validity);
136 //=============[ destructor ]=========================================
137 OctetStr::~OctetStr()
139 reset_octet_smi(smival);
140 delete [] output_buffer;
144 //=============[ assignment to a string operator overloaded ]=========
145 OctetStr& OctetStr::operator=( const char *string)
147 // get the string size
148 size_t nz;
150 // free up previous memory if needed
151 if ( smival.value.string.ptr ) {
152 reset_octet_smi(smival);
155 // if empty then we are done
156 if (!string || !(nz = ACE_OS::strlen( string))) {
157 validity = 1;
158 return *this;
161 // get memory needed
162 copy_octet_smi(smival, nz, string, validity);
163 return *this;
166 //=============[ assignment to another oid object overloaded ]========
167 OctetStr& OctetStr::operator=( const OctetStr &octet)
169 // protect against assignment from self
170 if ( this == &octet )
171 return *this;
173 // don't assign from invalid objs
174 if (!octet.validity) {
175 return *this;
178 // free up previous memory if needed
179 if ( smival.value.string.len ) {
180 reset_octet_smi(smival);
183 if (!octet.smival.value.string.len) {
184 validity = 1;
185 return *this;
188 // get some memory
189 copy_octet_smi(smival, octet.smival.value.string.len,
190 (const char*) octet.smival.value.string.ptr, validity);
191 return *this; // return self reference
194 //==============[ equivlence operator overloaded ]====================
195 bool operator==( const OctetStr &lhs, const OctetStr &rhs)
197 if( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)
198 return true;
199 else
200 return false;
203 //==============[ not equivlence operator overloaded ]================
204 bool operator!=( const OctetStr &lhs, const OctetStr &rhs)
206 if( lhs.left_comparison( rhs.smival.value.string.len, rhs)!=0)
207 return true;
208 else
209 return false;
212 //==============[ less than < overloaded ]============================
213 bool operator<( const OctetStr &lhs, const OctetStr &rhs)
215 if( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0)
216 return true;
217 else
218 return false;
221 //==============[ less than <= overloaded ]===========================
222 bool operator<=( const OctetStr &lhs, const OctetStr &rhs)
224 if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) ||
225 ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0))
226 return true;
227 else
228 return false;
231 //===============[ greater than > overloaded ]========================
232 bool operator>( const OctetStr &lhs, const OctetStr &rhs)
234 if( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0)
235 return true;
236 else
237 return false;
240 //===============[ greater than >= overloaded ]=======================
241 bool operator>=( const OctetStr &lhs, const OctetStr &rhs)
243 if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) ||
244 ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0))
245 return true;
246 else
247 return false;
250 //===============[ equivlence operator overloaded ]===================
251 bool operator==( const OctetStr &lhs,const char *rhs)
253 OctetStr to( rhs);
254 if( lhs.left_comparison( to.smival.value.string.len,to)==0)
255 return true;
256 else
257 return false;
260 //===============[ not equivlence operator overloaded ]===============
261 bool operator!=( const OctetStr &lhs,const char *rhs)
263 OctetStr to( rhs);
264 if ( lhs.left_comparison( to.smival.value.string.len,to)!=0)
265 return true;
266 else
267 return false;
270 //===============[ less than < operator overloaded ]==================
271 bool operator<( const OctetStr &lhs,const char *rhs)
273 OctetStr to( rhs);
274 if ( lhs.left_comparison( to.smival.value.string.len,to)<0)
275 return true;
276 else
277 return false;
280 //===============[ less than <= operator overloaded ]=================
281 bool operator<=( const OctetStr &lhs,char *rhs)
283 OctetStr to( rhs);
284 if (( lhs.left_comparison( to.smival.value.string.len,to)<0) ||
285 ( lhs.left_comparison( to.smival.value.string.len,to)==0))
286 return true;
287 else
288 return false;
291 //===============[ greater than > operator overloaded ]===============
292 bool operator>( const OctetStr &lhs,const char *rhs)
294 OctetStr to( rhs);
295 if ( lhs.left_comparison( to.smival.value.string.len,to)>0)
296 return true;
297 else
298 return false;
301 //===============[ greater than >= operator overloaded ]==============
302 bool operator>=( const OctetStr &lhs,const char *rhs)
304 OctetStr to( rhs);
305 if (( lhs.left_comparison( to.smival.value.string.len,to)>0) ||
306 ( lhs.left_comparison( to.smival.value.string.len,to)==0))
307 return true;
308 else
309 return false;
312 //===============[ append operator, appends a string ]================
313 OctetStr& OctetStr::operator+=( const char *a)
315 SmiBYTE *tmp; // temp pointer
316 size_t slen,nlen;
318 // get len of string
319 if ( !a || ((slen = ACE_OS::strlen( a)) == 0))
320 return *this;
322 // total len of octet
323 nlen = slen + (size_t) smival.value.string.len;
324 ACE_NEW_RETURN(tmp, SmiBYTE [ nlen], *this);
325 ACE_OS::memcpy ( tmp, smival.value.string.ptr,
326 (size_t) smival.value.string.len);
327 ACE_OS::memcpy( tmp + smival.value.string.len, a, (size_t) slen);
328 // delete the original
329 if ( smival.value.string.ptr )
330 reset_octet_smi(smival);
331 smival.value.string.ptr = tmp;
332 smival.value.string.len = nlen;
333 return *this;
336 //================[ append one OctetStr to another ]==================
337 OctetStr& OctetStr::operator+=( const OctetStr& octetstr)
339 SmiBYTE *tmp; // temp pointer
340 size_t slen,nlen;
342 if (!octetstr.validity ||
343 !(slen = (size_t)octetstr.length()))
344 return *this;
346 // total len of octet
347 nlen = slen + (size_t) smival.value.string.len;
348 // get mem needed
349 ACE_NEW_RETURN(tmp, SmiBYTE[ nlen], *this);
350 ACE_OS::memcpy ( tmp, smival.value.string.ptr,
351 (size_t) smival.value.string.len);
352 ACE_OS::memcpy( tmp + smival.value.string.len, octetstr.data(),
353 (size_t) slen);
354 if ( smival.value.string.ptr )
355 reset_octet_smi(smival);
356 smival.value.string.ptr = tmp;
357 smival.value.string.len = nlen;
358 return *this;
361 //================[ appends an int ]==================================
362 OctetStr& OctetStr::operator+=( const char c)
364 SmiBYTE *tmp;
365 // get the memory needed plus one extra byte
366 ACE_NEW_RETURN(tmp, SmiBYTE[ smival.value.string.len + 1], *this);
367 ACE_OS::memcpy ( tmp, smival.value.string.ptr,
368 (size_t) smival.value.string.len); // len of original
369 tmp[ smival.value.string.len ] = c; // assign in byte
370 if ( smival.value.string.ptr ) // delete the original
371 reset_octet_smi(smival);
373 smival.value.string.ptr = tmp; // point to one
374 smival.value.string.len++; // up the len
375 return *this;
379 //================[ compare n elements of an Octet ]==================
380 int OctetStr::left_comparison( const long n, const OctetStr &o) const
382 long z, w;
384 // both are empty, they are equal
385 if (( smival.value.string.len == 0) &&
386 ( o.smival.value.string.len == 0))
387 return 0; // equal
389 // self is empty and param has something
390 if (( smival.value.string.len == 0) &&
391 ( o.smival.value.string.len >0) &&
392 (n>0))
393 return -1;
395 // self has something and param has nothing
396 if (( smival.value.string.len > 0) &&
397 ( o.smival.value.string.len ==0) &&
398 (n>0))
399 return 1;
401 // special case
402 if (( smival.value.string.len == 0) &&
403 ( o.smival.value.string.len > 0) &&
404 ( n == 0))
405 return 0;
407 // pick the Min of n, this and the param len
408 // this is the maximum # to iterate a search
409 w = smival.value.string.len < o.smival.value.string.len
410 ? smival.value.string.len : o.smival.value.string.len;
411 if (n<w) w=n;
413 z = 0;
414 while( z < w) {
415 if ( smival.value.string.ptr[z] < o.smival.value.string.ptr[z])
416 return -1; // less than
417 if ( smival.value.string.ptr[z] > o.smival.value.string.ptr[z])
418 return 1; // greater than
419 z++;
422 if (( z == 0) &&
423 ( smival.value.string.len == 0) &&
424 ( o.smival.value.string.len > 0))
425 return -1;
427 if (( z == 0) &&
428 ( o.smival.value.string.len == 0) &&
429 ( smival.value.string.len > 0))
430 return 1;
432 return 0;
435 //================[ return the length of the oid ]=======================
436 size_t OctetStr::length() const
438 return (size_t) smival.value.string.len;
441 //================[ operator[]: access as if array ]==================
442 SmiBYTE& OctetStr::operator[]( int position)
444 return smival.value.string.ptr[position];
447 //===============[ reuturns pointer to internal data ]===============
448 SmiBYTE * OctetStr::data() const
450 return smival.value.string.ptr;
453 //================[ returns validity ]================================
454 int OctetStr::valid() const
456 return validity;
459 //================[ clone() ]=========================================
460 SnmpSyntax * OctetStr::clone() const
462 OctetStr *tmp = new OctetStr(*this);
463 return ( SnmpSyntax *) tmp;
466 //================[ ASCII format return ]=============================
467 const char * OctetStr::to_string()
469 for ( unsigned long i=0; i < smival.value.string.len; i++) {
470 if (( smival.value.string.ptr[i] != '\r')&&
471 ( smival.value.string.ptr[i] != '\n')&&
472 (ACE_OS::ace_isprint((int) (smival.value.string.ptr[i]))==0))
473 return(to_string_hex());
476 if ( output_buffer != 0)
477 delete [] output_buffer;
479 ACE_NEW_RETURN(output_buffer, char[smival.value.string.len + 1], "");
480 if (smival.value.string.len)
481 ACE_OS::memcpy(output_buffer, smival.value.string.ptr,
482 (int) smival.value.string.len);
483 output_buffer[smival.value.string.len] = '\0';
484 return output_buffer;
488 //================[ general Value = operator ]========================
489 SnmpSyntax& OctetStr::operator=( SnmpSyntax &val)
491 // protect against assignment from self
492 if ( this == &val )
493 return *this;
495 // blow away the old value
496 validity=0;
497 if (smival.value.string.ptr) {
498 reset_octet_smi(smival);
500 smival.value.string.len = 0;
501 if (val.valid()){
502 switch (val.get_syntax()) {
503 case sNMP_SYNTAX_OCTETS:
504 case sNMP_SYNTAX_IPADDR:
505 set_data( ((OctetStr &)val).smival.value.string.ptr,
506 ((OctetStr &)val).smival.value.string.len);
507 break;
510 return *this;
513 //================[ format the output into hex ]========================
514 const char *OctetStr::to_string_hex()
516 int cnt;
517 char char_buf[80]; // holds ASCII representation of data
518 char *buf_ptr; // pointer into ASCII listing
519 char *line_ptr; // pointer into Hex listing
520 int storageNeeded; // how much space do we need ?
521 int local_len = (int) smival.value.string.len;
522 SmiBYTE *bytes = smival.value.string.ptr;
525 storageNeeded = (int) ((smival.value.string.len/16)+1) * 72 + 1;
527 if ( output_buffer != 0)
528 delete [] output_buffer;
530 ACE_NEW_RETURN(output_buffer, char[storageNeeded], "");
532 line_ptr = output_buffer;
534 /*----------------------------------------*/
535 /* processing loop for entire data buffer */
536 /*----------------------------------------*/
537 while (local_len > 0) {
538 cnt = 16; /* print 16 bytes per line */
539 buf_ptr = char_buf;
540 ACE_OS::sprintf(line_ptr, " ");
541 line_ptr += 2; /* indent */
543 /*-----------------------*/
544 /* process a single line */
545 /*-----------------------*/
546 while (cnt-- > 0 && local_len-- > 0) {
547 ACE_OS::sprintf(line_ptr, "%2.2X ", *bytes);
549 line_ptr +=3; /* the display of a byte always 3 chars long */
550 if (ACE_OS::ace_isprint(*bytes))
551 ACE_OS::sprintf(buf_ptr, "%c", *bytes);
552 else
553 ACE_OS::sprintf(buf_ptr, ".");
554 bytes++;
555 buf_ptr++;
557 cnt++;
559 /*----------------------------------------------------------*/
560 /* this is to make sure that the ASCII displays line up for */
561 /* incomplete lines of hex */
562 /*----------------------------------------------------------*/
563 while (cnt-- > 0) {
564 ACE_OS::sprintf(line_ptr," ");
565 line_ptr += 3;
568 /*------------------------------------------*/
569 /* append the ASCII display to the Hex line */
570 /*------------------------------------------*/
572 // TODO: verify ACE_OS:: on NT works like this or not
574 #if defined(ACE_WIN32)
575 const char *fmt = " %s\r\n";
576 #else
577 const char *fmt = " %s\n";
578 #endif // ACE_WIN32
580 ACE_OS::sprintf(line_ptr, fmt, char_buf);
581 line_ptr += 3 + ACE_OS::strlen(char_buf);
584 return output_buffer;