1 /*****************************************************************************\
3 * Name : entity definitions for octopus *
4 * Author : Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 2002-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include "entity_defs.h"
17 #include <configuration/application_configuration.h>
18 #include <mathematics/chaos.h>
19 #include <structures/amorph.h>
20 #include <structures/static_memory_gremlin.h>
21 #include <textual/byte_formatter.h>
22 #include <textual/parser_bits.h>
23 #include <textual/string_manipulation.h>
25 #include <stdio.h> // for sscanf.
27 using namespace basis;
28 using namespace configuration;
29 using namespace mathematics;
30 using namespace textual;
31 using namespace structures;
35 octopus_entity::octopus_entity()
36 : _hostname(new astring),
42 octopus_entity::octopus_entity(const astring &hostname,
43 int process_id, int sequencer, int add_in)
44 : _hostname(new astring(hostname)),
46 _sequencer(sequencer),
50 octopus_entity::octopus_entity(const octopus_entity &to_copy)
52 _hostname(new astring)
53 { operator = (to_copy); }
55 octopus_entity::~octopus_entity() { WHACK(_hostname); }
57 octopus_entity octopus_entity::from_text(const astring &to_convert)
63 breakout(to_convert, host, process_id, sequencer, add_in);
66 byte_formatter::string_to_bytes(host, temp_form);
67 host = astring((char *)temp_form.observe());
69 return octopus_entity(host, process_id, sequencer, add_in);
72 octopus_entity &octopus_entity::operator =(const octopus_entity &to_copy)
74 if (this == &to_copy) return *this;
75 *_hostname = *to_copy._hostname;
77 _sequencer = to_copy._sequencer;
78 _add_in = to_copy._add_in;
82 const astring &octopus_entity::hostname() const { return *_hostname; }
84 int octopus_entity::process_id() const { return _pid; }
86 int octopus_entity::sequencer() const { return _sequencer; }
88 int octopus_entity::add_in() const { return _add_in; }
90 void octopus_entity::process_id(int id) { _pid = id; }
92 void octopus_entity::sequencer(int seq) { _sequencer = seq; }
94 void octopus_entity::add_in(int add) { _add_in = add; }
96 void octopus_entity::hostname(const astring &new_host)
97 { *_hostname = new_host; }
99 bool octopus_entity::blank() const
100 { return !_sequencer && !_add_in && !_pid && _hostname->empty(); }
102 int octopus_entity::packed_size() const
103 { return sizeof(int) * 3 + _hostname->length() + 1; }
105 #define REPLACEMENT_CHARACTER '#'
106 // used to replace unprintable characters in the entity text_form().
108 astring octopus_entity::text_form() const
110 astring chewed_host = *_hostname;
111 // make sure the name we're going to show is totally printable. some
112 // users of entities have odd notions of hostname strings. there are no
113 // rules requiring these to be readable normal strings.
114 for (int i = 0; i < chewed_host.length(); i++) {
115 if (!parser_bits::is_printable_ascii(chewed_host[i]))
116 chewed_host[i] = REPLACEMENT_CHARACTER;
118 return a_sprintf("%d.%d.%d.%s", _add_in, _sequencer, _pid, chewed_host.s());
121 astring octopus_entity::mangled_form() const
124 byte_array temp_form(_hostname->length() + 1, (abyte *)_hostname->observe());
125 byte_formatter::bytes_to_string(temp_form, hostdump, false);
126 return a_sprintf("%d.%d.%d.%s", _add_in, _sequencer, _pid, hostdump.s());
129 void octopus_entity::breakout(const astring &mangled_form, astring &hostname,
130 int &process_id, int &sequencer, int &add_in)
132 // there is pretty much no error checking here.
133 astring dupe = mangled_form; // allows us to destroy the id.
134 sscanf(dupe.s(), "%d", &add_in);
135 dupe.zap(0, dupe.find('.'));
136 sscanf(dupe.s(), "%d", &sequencer);
137 dupe.zap(0, dupe.find('.'));
138 sscanf(dupe.s(), "%d", &process_id);
139 dupe.zap(0, dupe.find('.'));
143 bool octopus_entity::operator == (const octopus_entity &that) const
145 return (_add_in == that._add_in)
146 && (_pid == that._pid)
147 && (_sequencer == that._sequencer)
148 && (*_hostname == *that._hostname);
151 void octopus_entity::pack(byte_array &packed_form) const
153 _hostname->pack(packed_form);
154 attach(packed_form, _pid);
155 attach(packed_form, _sequencer);
156 attach(packed_form, _add_in);
159 bool octopus_entity::unpack(byte_array &packed_form)
161 if (!_hostname->unpack(packed_form)) return false;
162 if (!detach(packed_form, _pid)) return false;
163 if (!detach(packed_form, _sequencer)) return false;
164 if (!detach(packed_form, _add_in)) return false;
170 int octopus_request_id::packed_size() const
171 { return _entity.packed_size() + sizeof(int); }
173 astring octopus_request_id::mangled_form() const
174 { return _entity.mangled_form() + a_sprintf("/%d", _request_num); }
176 astring octopus_request_id::text_form() const
177 { return _entity.text_form() + a_sprintf("/%d", _request_num); }
179 bool octopus_request_id::blank() const
180 { return _entity.blank() || !_request_num; }
182 octopus_request_id octopus_request_id::randomized_id()
185 return octopus_request_id(
186 octopus_entity(string_manipulation::make_random_name(),
187 application_configuration::process_id(), randona.inclusive(0, MAXINT32 / 2),
188 randona.inclusive(0, MAXINT32 / 2)),
189 randona.inclusive(0, MAXINT32 / 2));
192 octopus_request_id octopus_request_id::from_text(const astring &to_convert)
194 // find the slash, starting at the end.
195 int indy = to_convert.find('/', to_convert.end(), true);
196 if (negative(indy)) return octopus_request_id(); // bad format.
197 astring partial = to_convert.substring(0, indy - 1);
198 int req_id = to_convert.substring(indy + 1, to_convert.end()).convert(0);
199 return octopus_request_id(octopus_entity::from_text(partial), req_id);
202 void octopus_request_id::pack(byte_array &packed_form) const
204 _entity.pack(packed_form);
205 attach(packed_form, _request_num);
208 bool octopus_request_id::unpack(byte_array &packed_form)
210 if (!_entity.unpack(packed_form)) return false;
211 if (!detach(packed_form, _request_num)) return false;