summaryrefslogtreecommitdiff
path: root/ACE/apps/JAWS/clients/Caching
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/apps/JAWS/clients/Caching')
-rw-r--r--ACE/apps/JAWS/clients/Caching/ID_Generator.cpp61
-rw-r--r--ACE/apps/JAWS/clients/Caching/ID_Generator.h62
-rw-r--r--ACE/apps/JAWS/clients/Caching/Local_Locator.cpp248
-rw-r--r--ACE/apps/JAWS/clients/Caching/Local_Locator.h119
-rw-r--r--ACE/apps/JAWS/clients/Caching/Local_Locator.i43
-rw-r--r--ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp459
-rw-r--r--ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h220
-rw-r--r--ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.i138
-rw-r--r--ACE/apps/JAWS/clients/Caching/Makefile.am44
-rw-r--r--ACE/apps/JAWS/clients/Caching/README83
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp43
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h40
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Locator.cpp52
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Locator.h112
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Properties.cpp139
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Properties.h201
-rw-r--r--ACE/apps/JAWS/clients/Caching/URL_Properties.i203
-rw-r--r--ACE/apps/JAWS/clients/Caching/caching.mpc12
-rw-r--r--ACE/apps/JAWS/clients/Caching/http_client.cpp79
-rw-r--r--ACE/apps/JAWS/clients/Caching/http_handler.cpp238
-rw-r--r--ACE/apps/JAWS/clients/Caching/http_handler.h81
-rw-r--r--ACE/apps/JAWS/clients/Caching/test_URL.cpp34
22 files changed, 2711 insertions, 0 deletions
diff --git a/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp b/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp
new file mode 100644
index 00000000000..6e868611835
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/ID_Generator.cpp
@@ -0,0 +1,61 @@
+// $Id$
+
+#if !defined (ACE_ID_GENERATOR_C)
+#define ACE_ID_GENERATOR_C
+
+#include "ace/Object_Manager.h"
+#include "ID_Generator.h"
+
+ACE_RCSID(Caching, ID_Generator, "$Id$")
+
+time_t ACE_ID_Generator::last_time_ = 0;
+
+size_t ACE_ID_Generator::last_number_ = 0;
+
+ACE_SYNCH_MUTEX *ACE_ID_Generator::lock_ = 0;
+
+char *
+ACE_ID_Generator::get_new_id (char *id)
+{
+ time_t t;
+ size_t sn;
+
+ ACE_ID_Generator::get_serial_id (t, sn);
+ ACE_NEW_RETURN (id, char [ACE_OFFER_ID_LENGTH], 0);
+
+ ACE_OS::sprintf (id, "%014d%06d", t, sn);
+ return id;
+}
+
+void
+ACE_ID_Generator::get_serial_id (time_t &t, size_t &s)
+{
+ ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, *ACE_ID_Generator::get_lock ()));
+ ACE_OS::time (&t);
+
+ if (t != ACE_ID_Generator::last_time_)
+ {
+ ACE_ID_Generator::last_time_ = t;
+ s = ACE_ID_Generator::last_number_ = 0;
+ }
+ else
+ s = ACE_ID_Generator::last_number_++;
+}
+
+ACE_SYNCH_MUTEX *
+ACE_ID_Generator::get_lock (void)
+{
+#if defined (ACE_HAS_THREADS)
+ if (ACE_ID_Generator::lock_ == 0)
+ {
+ ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance (), 0));
+
+ // Double-checked Locking Optimization.
+ if (ACE_ID_Generator::lock_ == 0)
+ ACE_NEW_RETURN (ACE_ID_Generator::lock_, ACE_SYNCH_MUTEX, 0);
+ }
+#endif /* ACE_HAS_THREADS */
+ return ACE_ID_Generator::lock_;
+}
+
+#endif /* ACE_ID_GENERATOR_C */
diff --git a/ACE/apps/JAWS/clients/Caching/ID_Generator.h b/ACE/apps/JAWS/clients/Caching/ID_Generator.h
new file mode 100644
index 00000000000..73c78fc5506
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/ID_Generator.h
@@ -0,0 +1,62 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// ID_Generator.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_ID_GENERATOR_H
+#define ACE_ID_GENERATOR_h
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#define ACE_OFFER_ID_LENGTH 21
+
+class ACE_ID_Generator
+ // = TITLE
+ // An unique ID generator.
+ //
+ // = DESCRIPTION
+
+ // Generate an offer ID according to current time and avoid
+ // duplicate ID. It guarantees ID uniqueness within a process,
+ // i.e. no two threads may get the same ID string. Using a
+ // similar method like the backery algorithm.
+{
+public:
+ static char *get_new_id (char *id);
+ // allocate a new ID string and point <id> to it.
+
+private:
+ static void get_serial_id (time_t &t, size_t &s);
+ // Atomically get info required to generate an offer ID.
+
+ static ACE_SYNCH_MUTEX *get_lock (void);
+ // Get the lock instance.
+
+ static time_t last_time_;
+ // Record the time last offer ID generated.
+
+ static size_t last_number_;
+ // Record serial number of last offer ID with same
+ // generation time.
+
+ static ACE_SYNCH_MUTEX *lock_;
+ // mutex to access private member.
+};
+
+#endif /* ACE_ID_GENERATOR_H */
diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp b/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp
new file mode 100644
index 00000000000..c4502c1bc87
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.cpp
@@ -0,0 +1,248 @@
+// $Id$
+
+#if !defined (ACE_LOCAL_LOCATOR_C)
+#define ACE_LOCAL_LOCATOR_C
+
+#include "Local_Locator.h"
+
+#if !defined (__ACE_INLINE__)
+#include "Local_Locator.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(Caching, Local_Locator, "$Id$")
+
+int
+ACE_URL_Local_Locator::url_query (const ACE_URL_Locator::ACE_Selection_Criteria how,
+ const ACE_URL_Property_Seq *pseq,
+ const size_t how_many,
+ size_t &num_query,
+ ACE_URL_Offer_Seq *offer)
+{
+ ACE_URL_Record *item = 0;
+
+ ACE_NEW_RETURN (offer, ACE_URL_Offer_Seq (how_many), -1);
+
+ if (how >= ACE_URL_Locator::INVALID_SELECTION)
+ {
+ errno = ACE_URL_Locator::INVALID_ARGUMENT;
+ return -1;
+ }
+
+ num_query = 0;
+ for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
+ iter.next (item) != 0;
+ iter.advance ())
+ {
+ size_t i_query;
+ size_t i_db;
+ int found = 0;
+
+ // Now this is a stupid implementation. Perhaps we can
+ // implement this using Hash_Map. Better yet, I think we should
+ // put this in a database and put SQL query here.
+ for (i_query = 0; found == 0 && i_query < pseq->size (); i_query++)
+ for (i_db = 0; i_db < item->offer_->url_properties ().size (); i_db++)
+ {
+ if ((*pseq)[i_query].name () == item->offer_->url_properties ()[i_db].name ())
+ if (how == ACE_URL_Locator::SOME)
+ ;
+
+ // if match and Some, copy to <offer>, inc <num_query>, advance iterator
+
+ // else if All, advance iterator
+
+ // else if None, check next property in <pseq>.
+
+ if (all properties checked and found and ALL)
+ copy to <offer>; inc <num_query>;
+ else if (all properties checked and not found and NONE)
+ copy to <offer>; inc <num_query>;
+ else
+ shouldn't happen, internal error
+
+ if (num_query == how_many)
+ break;
+ }
+
+ return 0;
+}
+
+int
+ACE_URL_Local_Locator::export_offer (ACE_URL_Offer *offer,
+ ACE_WString &offer_id)
+{
+ ACE_URL_Record *item = 0;
+
+ // First check if we have registered this URL already.
+ for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
+ iter.next (item) != 0;
+ iter.advance ())
+ if (*item->offer_->url () == *offer->url ())
+ {
+ errno = ACE_URL_Locator::OFFER_EXIST;
+ return -1;
+ }
+
+ ACE_URL_Record *new_offer;
+
+ // Offer is not in repository, we can add new one in safely.
+ ACE_NEW_RETURN (new_offer, ACE_URL_Record (offer),
+ ACE_URL_Locator::NOMEM);
+
+ this->repository_.push (*new_offer);
+
+ offer_id = *new_offer->id_;
+ return 0;
+}
+
+int
+ACE_URL_Local_Locator::withdraw_offer (const ACE_WString &offer_id)
+{
+ ACE_URL_Record *item = 0;
+
+ // Iterate thru repository and remove offer with <offer_id>.
+ for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
+ iter.next (item) != 0;
+ iter.advance ())
+ if (offer_id == *item->id_)
+ {
+ if (this->repository_.remove (*item) == 0)
+ return 0
+ else
+ {
+ errno = ACE_URL_Locator::UNKNOWN;
+ return -1;
+ }
+ }
+
+ errno = ACE_URL_Locator::NO_SUCH_OFFER;
+ return 0;
+}
+
+int
+ACE_URL_Local_Locator::describe_offer (const ACE_WString &offer_id,
+ ACE_URL_Offer *offer)
+{
+ ACE_URL_Record *item = 0;
+
+ // Iterate thru the repository and produce a copy of offer's
+ // description.
+ for (ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
+ iter.next (item) != 0;
+ iter.advance ())
+ if (offer_id == *item->id_)
+ {
+ ACE_NEW_RETURN (offer, ACE_URL_Offer (*item->offer_), -1);
+ return 0;
+ }
+
+ errno = ACE_URL_Locator::NO_SUCH_OFFER;
+ return -1;
+}
+
+int
+ACE_URL_Local_Locator::modify_offer (const ACE_WString &offer_id,
+ const ACE_WString *url,
+ const ACE_URL_Property_Seq *del,
+ const ACE_URL_Property_Seq *modify)
+{
+ ACE_Unbounded_Set_Iterator<ACE_URL_Record> iter (this->repository_);
+ ACE_URL_Record *item = 0;
+ ACE_URL_Record *target = 0;
+
+ // Errno Checking
+
+ for (; iter.next (item) != 0; iter.advance ())
+ {
+ if (url != 0 && *url == item->offer_->url ())
+ {
+ errno = ACE_URL_Locator::OFFER_EXIST;
+ return -1;
+ }
+ if (offer_id == *item->id_)
+ target = item;
+ }
+
+ if (target != 0) // Aha, we found a target to work on
+ {
+ if (del != 0 && modify != 0)
+ {
+ // We need to make a copy of the original property sequence
+ // so if any error occurs, we can revert our change easily.
+
+ // First we need to calculate the maximum number of perperties.
+ int psize = target->offer_->url_properties ().size ();
+ if (del != 0)
+ if ((psize -= del->size ()) < 0)
+ {
+ // If you try to delete more properties than we have,
+ // you are doomed. No need to proceed.
+ errno = ACE_URL_Locator::INVALID_ARGUMENT;
+ return -1;
+ }
+ if (modify != 0)
+ // In the worst case, all properties in <modify> will be added.
+ psize += modify->size ();
+
+ // Now, create a temporary work space.
+ ACE_URL_Property_Seq working (psize);
+ size_t sz = 0;
+ for (; sz < item->offer_->url_properties ().size ())
+ working[sz] = item->offer_->url_properties() [sz];
+
+ if (del != 0)
+ {
+ // Argh, this is really a stupid design.
+ // Go thru every property we want to delete
+ for (size_t i = 0; i < del->size () && sz > 0; i++)
+ // For earch, go thru our property sequence and
+ // search for the property.
+ for (size_t j = 0; j < sz; j++)
+ if ((*del)[i].name () == working[j].name ())
+ {
+ sz -= 1;
+ working[j] = working[sz]; // pack the array.
+ break;
+ }
+ // Doesn't generate error when we want to delete an
+ // imaginary property. Is this appropriate?
+ }
+
+ if (modify != 0)
+ {
+ // This is also stupid.
+ // Go thru every property we want to modify/add
+ for (size_t i = 0; i < modify->size () && sz > 0; i++)
+ {
+ // For each property, go thru our property list
+ // and search for the matching property
+ for (size_t j = 0; j < sz; j++)
+ if ((*modify)[i].name () == working[j].name ())
+ {
+ // A match found.
+ working[j].value ((*modify)[i].value ().fast_rep ());
+ break;
+ }
+
+ // No matching property name were found,
+ // We want to add this property into the list.
+ if (j == sz)
+ working[sz++] = (*modify)[i];
+ }
+ }
+ }
+
+ // Yes, all operations passed. We can now copy the working version back.
+ item->offer_->url_properties (ACE_URL_Property_Seq (sz));
+ for (size_t i = 0; i < sz; i ++)
+ item->offer_->url_properties ()[i] = working[i];
+
+ if (url != 0)
+ item->offer_->url (url->fast_rep ()); // replace URL location.
+ return 0;
+ }
+ errno = ACE_URL_Locator::NO_SUCH_OFFER;
+ return -1;
+}
+
+#endif /* ACE_LOCAL_LOCATOR_C */
diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.h b/ACE/apps/JAWS/clients/Caching/Local_Locator.h
new file mode 100644
index 00000000000..2c2569db1c8
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.h
@@ -0,0 +1,119 @@
+// -*- C++ -*-
+//
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// Local_Locator.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_LOCAL_LOCATOR_H
+#define ACE_LOCAL_LOCATOR_H
+
+#include "URL_Locator.h"
+#include "ace/Containers.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ID_Generator.h"
+
+class ACE_Svc_Export ACE_URL_Record
+ // = TITLE
+ // A URL Record.
+ //
+ // = DESCRIPTION
+ // A record placed in URL repository. Notice that
+ // both member pointers are own by URL_Record.
+ // They will get deallocated when the object goes
+ // out of scope.
+{
+ friend class ACE_URL_Local_Locator;
+ friend class ACE_Node<ACE_URL_Record>;
+ // We are making ACE_Node as friend class because we don't want
+ // others to access default constructor and pushing in an invalid
+ // record. However, container classes need to use default constructor
+ // for its head record.
+public:
+ ACE_URL_Record (ACE_URL_Offer *offer);
+ // ctor.
+
+ ~ACE_URL_Record (void);
+ // dtor.
+
+ /// Two records are equal if they have the same offer id.
+ bool operator== (const ACE_URL_Record &rhs) const;
+
+ /// Unequal, complement of equal.
+ bool operator!= (const ACE_URL_Record &rhs) const;
+
+
+private:
+ ACE_URL_Record (void);
+ // Default ctor. This is put here to prevent users from
+ // pushing in an invalid record.
+
+ ACE_WString *id_;
+ // Offer ID in the repository.
+
+ ACE_URL_Offer *offer_;
+ // Offer (and its properties).
+};
+
+class ACE_Svc_Export ACE_URL_Local_Locator
+ // = TITLE
+ // A simple URL repository to store URL offer locally.
+ //
+ // = DESCRIPTION
+ // This class manage a collection of URL offers
+ // for local query and registration. But we should
+ // really use it within a server.
+{
+ virtual ~ACE_URL_Local_Locator (void);
+ // Default destructor.
+
+ virtual int url_query (const ACE_URL_Locator::ACE_Selection_Criteria how,
+ const ACE_URL_Property_Seq *pseq,
+ const size_t how_many,
+ size_t &num_query,
+ ACE_URL_Offer_Seq *offer);
+ // Query the locator for HTTP with designate properties (none, some,
+ // or all). The locator being queried will return a sequence of
+ // offers with <how_many> offers in it. This interface allocates
+ // <offer> so users must deallocate it after use.
+
+ virtual int export_offer (ACE_URL_Offer *offer,
+ ACE_WString &offer_id);
+ // Export an offer to the locator.
+
+ virtual int withdraw_offer (const ACE_WString &offer_id);
+ // Withdraw an offer. return 0 if succeed, -1 otherwise.
+
+ virtual int describe_offer (const ACE_WString &offer_id,
+ ACE_URL_Offer *offer);
+ // Query a specific offer.
+
+ virtual int modify_offer (const ACE_WString &offer_id,
+ const ACE_WString *url = 0,
+ const ACE_URL_Property_Seq *del = 0,
+ const ACE_URL_Property_Seq *modify = 0);
+ // Modify a previously registered offer.
+
+protected:
+ ACE_Unbounded_Set<ACE_URL_Record> repository_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "Local_Locator.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_LOCAL_LOCATOR_H */
diff --git a/ACE/apps/JAWS/clients/Caching/Local_Locator.i b/ACE/apps/JAWS/clients/Caching/Local_Locator.i
new file mode 100644
index 00000000000..0ef8e595f86
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Local_Locator.i
@@ -0,0 +1,43 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_INLINE
+ACE_URL_Record::ACE_URL_Record (void)
+ : id_ (0),
+ offer_ (0)
+{
+}
+
+ACE_INLINE
+ACE_URL_Record::ACE_URL_Record (ACE_URL_Offer *offer)
+ : offer_ (offer)
+{
+ char buf[ACE_OFFER_ID_LENGTH];
+
+ ACE_NEW (this->id_, ACE_WString (ACE_ID_Generator::get_new_id (buf)));
+}
+
+ACE_INLINE
+ACE_URL_Record::~ACE_URL_Record (void)
+{
+ delete this->id_;
+ delete this->offer_;
+}
+
+ACE_INLINE bool
+ACE_URL_Record::operator== (const ACE_URL_Record &rhs) const
+{
+ return this == &rhs || *this->id_ == *rhs.id_;
+}
+
+ACE_INLINE bool
+ACE_URL_Record::operator!= (const ACE_URL_Record &rhs) const
+{
+ return !(*this == rhs);
+}
+
+ACE_INLINE
+ACE_URL_Local_Locator::~ACE_URL_Local_Locator (void)
+{
+}
diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp
new file mode 100644
index 00000000000..6f7a7898e59
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.cpp
@@ -0,0 +1,459 @@
+// $Id$
+
+#if !defined (ACE_LOCATOR_REQUEST_REPLY_C)
+#define ACE_LOCATOR_REQUEST_REPLY_C
+
+#include "Locator_Request_Reply.h"
+
+#if !defined (__ACE_INLINE__)
+#include "Locator_Request_Reply.i"
+#endif
+
+#include "ace/Auto_Ptr.h"
+#include "URL_Properties.h"
+#include "URL_Array_Helper.h"
+#include "URL_Locator.h"
+
+ACE_RCSID(Caching, Locator_Request_Reply, "$Id$")
+
+int
+ACE_URL_Locator_Request::url_query (const int how,
+ const ACE_URL_Property_Seq &pseq,
+ const int how_many)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::url_query");
+
+ if (how >= ACE_URL_Locator::INVALID_SELECTION)
+ return -1;
+ ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (pseq), -1);
+ this->how_ = how;
+ this->how_many_ = how_many;
+ this->code_ = ACE_URL_Locator::QUERY;
+ return 0;
+}
+
+int
+ACE_URL_Locator_Request::export_offer (const ACE_URL_Offer &offer)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::export_offer");
+
+ ACE_NEW_RETURN (this->offer_, ACE_URL_Offer (offer), -1);
+ this->code_ = ACE_URL_Locator::EXPORT;
+ return 0;
+}
+
+int
+ACE_URL_Locator_Request::withdraw_offer (const ACE_WString &offer_id)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::withdraw_offer");
+
+ this->id_ = offer_id;
+ this->code_ = ACE_URL_Locator::WITHDRAW;
+ return 0;
+}
+
+int
+ACE_URL_Locator_Request::describe_offer (const ACE_WString &offer_id)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::describe_offer");
+
+ this->id_ = offer_id;
+ this->code_ = ACE_URL_Locator::DESCRIBE;
+ return 0;
+}
+
+int
+ACE_URL_Locator_Request::modify_offer (const ACE_WString &offer_id,
+ const ACE_WString *url,
+ const ACE_URL_Property_Seq &del,
+ const ACE_URL_Property_Seq &modify)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::modify_offer");
+
+ ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (del), -1);
+ ACE_NEW_RETURN (this->seq2_, ACE_URL_Property_Seq (modify), -1);
+
+ if (url != 0)
+ this->url_ = *url;
+
+ this->id_ = offer_id;
+ this->code_ = ACE_URL_Locator::MODIFY;
+ return 0;
+}
+
+#define ENCODE_UINT32(ADDR,LEN,V) \
+ * (ACE_UINT32 *) (ADDR+LEN) = htonl (V); \
+ LEN += sizeof (ACE_UINT32);
+
+#define DECODE_UINT32(ADDR,LEN,V) \
+ V = ntohl (* (ACE_UINT32 *) (ADDR+LEN)); \
+ LEN += sizeof (ACE_UINT32);
+
+size_t
+ACE_URL_Locator_Request::encode (void)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::encode");
+
+ size_t buf_size = this->size ();
+ size_t total_length = 0;
+
+ ACE_NEW_RETURN (this->buffer_, char [buf_size], 0);
+
+ ENCODE_UINT32 (this->buffer_, total_length, buf_size);
+ // Encode buffer size.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->code_);
+ // Encode Op code.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->how_);
+ // Encode selection criteria.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->how_many_);
+ // Encode number of offers interested.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->valid_ptr_);
+ // Encode valide pointer flag.
+
+ if (this->seq1_ != 0)
+ {
+ ENCODE_UINT32 (this->buffer_, total_length, this->seq1_->size ());
+ total_length += ace_array_encode (this->buffer_ + total_length, *this->seq1_);
+ }
+ if (this->seq2_ != 0)
+ {
+ ENCODE_UINT32 (this->buffer_, total_length, this->seq2_->size ());
+ total_length += ace_array_encode (this->buffer_ + total_length, *this->seq2_);
+ }
+ if (this->offer_ != 0)
+ total_length += this->offer_->encode (this->buffer_ + total_length);
+
+ total_length += ACE_WString_Helper::encode (this->buffer_ + total_length,
+ this->id_);
+ total_length += ACE_WString_Helper::encode (this->buffer_ + total_length,
+ this->url_);
+
+ ACE_ASSERT (total_length == buf_size);
+ return total_length;
+}
+
+size_t
+ACE_URL_Locator_Request::decode (void *buffer)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::decode");
+
+ if (buffer == 0)
+ return 0;
+ // Check if we have a valid buffer available.
+
+ char *cbuffer = (char *) buffer;
+
+ size_t buf_size;
+ size_t total_length = 0;
+
+ DECODE_UINT32 (cbuffer, total_length, buf_size);
+ // Decode length of buffer size first.
+
+ DECODE_UINT32 (cbuffer, total_length, this->code_);
+ // Get the operation code.
+
+ DECODE_UINT32 (cbuffer, total_length, this->how_);
+ // Decode selection criteria.
+
+ DECODE_UINT32 (cbuffer, total_length, this->how_many_);
+ // Decode number of offers interested.
+
+ DECODE_UINT32 (cbuffer, total_length, this->valid_ptr_);
+ // Decode valide pointer flag.
+
+ if ((this->valid_ptr_ & VALID_SEQ1) != 0)
+ {
+ size_t n;
+ DECODE_UINT32 (cbuffer, total_length, n);
+ ACE_NEW_RETURN (this->seq1_, ACE_URL_Property_Seq (n), 0);
+ total_length += ace_array_decode (cbuffer + total_length, *this->seq1_);
+ }
+ if ((this->valid_ptr_ & VALID_SEQ2) != 0)
+ {
+ size_t n;
+ DECODE_UINT32 (cbuffer, total_length, n);
+ ACE_NEW_RETURN (this->seq2_, ACE_URL_Property_Seq (n), 0);
+ total_length += ace_array_decode (cbuffer + total_length, *this->seq2_);
+ }
+ if ((this->valid_ptr_ & VALID_OFFER) != 0)
+ {
+ ACE_NEW_RETURN (this->offer_, ACE_URL_Offer, 0);
+ total_length += this->offer_->decode (cbuffer + total_length);
+ }
+
+ this->id_ = ACE_WString ((ACE_USHORT16 *) (cbuffer + total_length));
+ total_length += ACE_WString_Helper::decode (cbuffer + total_length);
+ this->url_ = ACE_WString ((ACE_USHORT16 *) (cbuffer + total_length));
+ total_length += ACE_WString_Helper::decode (cbuffer + total_length);
+
+ ACE_ASSERT (total_length == buf_size);
+ return total_length;
+}
+
+
+size_t
+ACE_URL_Locator_Request::size (void)
+{
+ ACE_TRACE ("ACE_URL_Locator_Request::size");
+
+ size_t total_length = 5 * sizeof (ACE_UINT32);
+ // There are 5 UINT32 variables at the beginning
+ // of the buffer. <buffer size>, <code>, <how>,
+ // <how_many>, <valid_ptr>.
+
+ this->valid_ptr_ = 0;
+ // Check valid pointers and mark corresponding flag in <valid_prt>.
+
+ if (this->seq1_ != 0)
+ {
+ this->valid_ptr_ |= VALID_SEQ1;
+ total_length += ace_array_size (*this->seq1_);
+ }
+ if (this->seq2_ != 0)
+ {
+ this->valid_ptr_ |= VALID_SEQ2;
+ total_length += ace_array_size (*this->seq2_);
+ }
+ if (this->offer_ != 0)
+ {
+ this->valid_ptr_ |= VALID_OFFER;
+ total_length += this->offer_->size ();
+ }
+
+ total_length += ACE_WString_Helper::size (this->id_);
+ total_length += ACE_WString_Helper::size (this->url_);
+
+ return total_length;
+}
+
+void
+ACE_URL_Locator_Request::dump (void) const
+{
+ //ACE_TRACE ("ACE_URL_Locator_Request::dump");
+
+ size_t i;
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ if (this->code_ < ACE_URL_Locator::INVALID_OPERATION)
+ ACE_DEBUG ((LM_DEBUG, "%s Request:\n", ACE_URL_Locator::opname[this->code_]));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Invalid Operation: %d\n", this->code_));
+
+ if (this->how_ < ACE_URL_Locator::INVALID_SELECTION)
+ ACE_DEBUG ((LM_DEBUG, "Select: %s\n", ACE_URL_Locator::selection_name[this->how_]));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Invalid selection method: %d\n", this->how_));
+
+ ACE_DEBUG ((LM_DEBUG, "At most %d reply.\n", this->how_many_));
+
+ ACE_DEBUG ((LM_DEBUG, "Valid pointer pattern: %x\n", this->valid_ptr_));
+
+ ACE_DEBUG ((LM_DEBUG, "Property sequence 1: %x\n", this->seq1_));
+ if (this->seq1_ != 0)
+ for (i = 0; i < this->seq1_->size (); i++)
+ (*this->seq1_)[i].dump ();
+
+ ACE_DEBUG ((LM_DEBUG, "Property sequence 2: %x\n", this->seq2_));
+ if (this->seq2_ != 0)
+ for (i = 0; i < this->seq2_->size (); i++)
+ (*this->seq2_)[i].dump();
+
+ ACE_DEBUG ((LM_DEBUG, "Offer: %x\n", this->offer_));
+ if (this->offer_ != 0)
+ this->offer_->dump ();
+
+ if (this->id_.length () > 0)
+ ACE_DEBUG ((LM_DEBUG, "Offer ID: %s\n",
+ ACE_Auto_Basic_Array_Ptr<char> (this->id_.char_rep ()).get ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Offer ID: \"\"\n"));
+
+ if (this->url_.length () > 0)
+ ACE_DEBUG ((LM_DEBUG, "URL: %s\n",
+ ACE_Auto_Basic_Array_Ptr<char> (this->url_.char_rep ()).get ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, "URL: \"\"\n"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+int
+ACE_URL_Locator_Reply::status_reply (u_int op, int result)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply::status_reply");
+
+ this->code_ = op;
+ this->status_ = result;
+ return 0;
+}
+
+int
+ACE_URL_Locator_Reply::query_reply (int result, size_t num,
+ const ACE_URL_Offer_Seq &offers)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply::query_reply");
+
+ this->code_ = ACE_URL_Locator::QUERY;
+ this->status_ = result;
+ ACE_NEW_RETURN (this->offers_, ACE_URL_Offer_Seq (offers), -1);
+ return 0;
+}
+
+int
+ACE_URL_Locator_Reply::describe_reply (int result,
+ const ACE_URL_Offer &offer)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply::describe_reply");
+
+ this->code_ = ACE_URL_Locator::DESCRIBE;
+ this->status_ = result;
+ ACE_NEW_RETURN (this->offer_, ACE_URL_Offer (offer), -1);
+ return 0;
+}
+
+size_t
+ACE_URL_Locator_Reply::encode (void)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply::encode");
+
+ size_t buf_size = this->size ();
+ size_t total_length = 0;
+
+ ACE_NEW_RETURN (this->buffer_, char [buf_size], 0);
+
+ ENCODE_UINT32 (this->buffer_, total_length, buf_size);
+ // Encode buffer size.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->code_);
+ // Encode Op code.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->status_);
+ // Encode Op result status.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->num_offers_);
+ // Encode number of offers in this->offers_.
+
+ ENCODE_UINT32 (this->buffer_, total_length, this->valid_ptr_);
+ // Encode valid pointers mask.
+
+ if (this->offer_ != 0)
+ total_length += this->offer_->encode (this->buffer_ + total_length);
+
+ if (this->offers_ != 0)
+ {
+ ENCODE_UINT32 (this->buffer_, total_length, this->offers_->size ());
+ total_length += ace_array_encode (this->buffer_ + total_length, *this->offers_);
+ }
+
+ ACE_ASSERT (total_length == buf_size);
+ return 0;
+}
+
+size_t
+ACE_URL_Locator_Reply::decode (void *buffer)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply::decode");
+
+ if (buffer == 0)
+ return 0;
+ // Check if we have a buffer available.
+
+ char *cbuffer = (char *) buffer;
+
+ size_t buf_size;
+ size_t total_length = 0;
+
+ DECODE_UINT32 (cbuffer, total_length, buf_size);
+ // Get the length of the buffer first.
+
+ DECODE_UINT32 (cbuffer, total_length, this->code_);
+ // Decode Op code.
+
+ DECODE_UINT32 (cbuffer, total_length, this->status_);
+ // Decode Op result status.
+
+ DECODE_UINT32 (cbuffer, total_length, this->num_offers_);
+ // Decode number of offers in this->offers_.
+
+ DECODE_UINT32 (cbuffer, total_length, this->valid_ptr_);
+ // Decode valid pointers mask.
+
+ if ((this->valid_ptr_ & VALID_OFFER) != 0)
+ {
+ ACE_NEW_RETURN (this->offer_, ACE_URL_Offer, 0);
+ total_length += this->offer_->decode (cbuffer + total_length);
+ }
+
+ if ((this->valid_ptr_ & VALID_OFFERS) != 0)
+ {
+ size_t n;
+ DECODE_UINT32 (cbuffer, total_length, n);
+ ACE_NEW_RETURN (this->offers_, ACE_URL_Offer_Seq (n), 0);
+ total_length += ace_array_decode (cbuffer + total_length, *this->offers_);
+ }
+
+ ACE_ASSERT (total_length ==buf_size);
+ return 0;
+}
+
+size_t
+ACE_URL_Locator_Reply::size (void)
+{
+ ACE_TRACE ("ACE_URL_Locator_Reply:size");
+
+ size_t total_length = 5 * sizeof (ACE_UINT32);
+ // size for 5 ACE_UINT32 objects: <buffer size>, <code_>,
+ // <status_>, <num_offers_>, and <valid_ptr_>.
+
+ this->valid_ptr_ = 0;
+ if (this->offer_ != 0)
+ {
+ this->valid_ptr_ |= VALID_OFFER;
+ total_length += this->offer_->size ();
+ }
+ if (this->offers_ != 0)
+ {
+ this->valid_ptr_ |= VALID_OFFERS;
+ total_length += ace_array_size (*this->offers_);
+ }
+ return total_length;
+}
+
+void
+ACE_URL_Locator_Reply::dump (void) const
+{
+ //ACE_TRACE ("ACE_URL_Locator_Reply::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ if (this->code_ < ACE_URL_Locator::INVALID_OPERATION)
+ ACE_DEBUG ((LM_DEBUG, "Original request: %s\n", ACE_URL_Locator::opname[this->code_]));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Invalid Original Request: %d\n", this->code_));
+
+ if (this->status_ < ACE_URL_Locator::MAX_URL_ERROR)
+ ACE_DEBUG ((LM_DEBUG, "Reply status: %s\n", ACE_URL_Locator::err_name[this->status_]));
+ else
+ ACE_DEBUG ((LM_DEBUG, "Invalid reply status: %d\n", this->status_));
+
+ ACE_DEBUG ((LM_DEBUG, "Number of offers: %d\n", this->num_offers_));
+
+ ACE_DEBUG ((LM_DEBUG, "Valid pointer pattern: %x\n", this->valid_ptr_));
+
+ ACE_DEBUG ((LM_DEBUG, "Offer: %x\n", this->offer_));
+ if (this->offer_ != 0)
+ this->offer_->dump ();
+
+ ACE_DEBUG ((LM_DEBUG, "Offer sequence: %x\n", this->offers_));
+ if (this->offers_ != 0)
+ for (size_t i = 0; i < this->offers_->size (); i++)
+ (*this->offers_)[i].dump();
+
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+#endif /* ACE_LOCATOR_REQUEST_REPLY_C */
diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h
new file mode 100644
index 00000000000..057607c351d
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.h
@@ -0,0 +1,220 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// Locator_Request_Response.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_LOCATOR_REQUEST_REPLY_H
+#define ACE_LOCATOR_REQUEST_REPLY_H
+
+#include "URL_Properties.h"
+
+class ACE_Svc_Export ACE_URL_Locator_Request
+ // = TITLE
+ // A URL request message formater/wrapper.
+ //
+ // = DESCRIPTION
+ // This class defines a URL request data. It is used
+ // to transform requests to an object so that we can
+ // ship them across network.
+{
+public:
+ ACE_URL_Locator_Request (void);
+ // Default ctor.
+
+ ~ACE_URL_Locator_Request (void);
+ // Default dtor.
+
+ int url_query (const int how,
+ const ACE_URL_Property_Seq &pseq,
+ const int how_many);
+ // Query the locator for HTTP with designate properties (none, some,
+ // or all). The locator being queried will return a sequence of
+ // offers with <how_many> offers in it. This interface allocates
+ // <offer> so users must deallocate it after use.
+
+ int export_offer (const ACE_URL_Offer &offer);
+ // Export an offer to the locator.
+
+ int withdraw_offer (const ACE_WString &offer_id);
+ // Withdraw an offer. return 0 if succeed, -1 otherwise.
+
+ int describe_offer (const ACE_WString &offer_id);
+ // Query a specific offer.
+
+ int modify_offer (const ACE_WString &offer_id,
+ const char *url = 0,
+ const ACE_URL_Property_Seq &del = 0,
+ const ACE_URL_Property_Seq &modify = 0);
+ // Modify a previously registered offer.
+
+ int modify_offer (const ACE_WString &offer_id,
+ const ACE_WString *url = 0,
+ const ACE_URL_Property_Seq &del = 0,
+ const ACE_URL_Property_Seq &modify = 0);
+ // Modify a previously registered offer.
+
+ size_t encode (void);
+ // Encode request for network communication. If succeed,
+ // returns the size of the buffer, otherwise, return 0.
+
+ size_t decode (void *buffer);
+ // Restore from network data. Returns size of the buffer
+ // if succeed, 0 otherwise. When passing in a buffer,
+ // caller must take the responsibility to delete the buffer
+ // afterward, if so needed.
+
+ const int how (void) const;
+ const int how_many (void) const;
+ const u_int opcode (void) const;
+ const ACE_URL_Property_Seq *seq (void) const;
+ const ACE_URL_Property_Seq *del (void) const;
+ const ACE_URL_Property_Seq *modify (void) const;
+ const ACE_URL_Offer *offer (void) const;
+ const ACE_WString &id (void) const;
+ const ACE_WString &url (void) const;
+ const char *buffer (void) const;
+ // A bunch of methods to access internal data.
+
+ void dump (void) const;
+ // Print out this object.
+
+protected:
+ size_t size (void);
+ // Return the size of the buffer required to encode
+ // this request.
+
+ enum {
+ VALID_SEQ1 = 0x1,
+ VALID_SEQ2 = 0X2,
+ VALID_OFFER = 0X4
+ };
+ // These constants used to indicate which pointers are valid.
+
+ u_int code_;
+ // Request type code.
+
+ int how_;
+ // Query method (if code_ == QUERY.)
+
+ int how_many_;
+ // How many offers are we interested in in this query.
+
+ int valid_ptr_;
+ // Bit flag to mark valid pointers within this object.
+
+ ACE_URL_Property_Seq *seq1_;
+ // For query or del in modify_offer.
+
+ ACE_URL_Property_Seq *seq2_;
+ // For modify seq. in modify_offer.
+
+ ACE_URL_Offer *offer_;
+ // Offer to export.
+
+ ACE_WString id_;
+ // Offer ID.
+
+ ACE_WString url_;
+ // URL of this offer.
+
+ char *buffer_;
+ // Buffer to store encoded data.
+};
+
+class ACE_Svc_Export ACE_URL_Locator_Reply
+ // = TITLE
+ // A URL reply message formater/wrapper.
+ //
+ // = DESCRIPTION
+ // This class defines a URL reply data. It is used
+ // to transform reply messages to an object so that we can
+ // ship them across network.
+{
+public:
+ ACE_URL_Locator_Reply (void);
+ // Default ctor.
+
+ ~ACE_URL_Locator_Reply (void);
+ // Default dtor.
+
+ int status_reply (u_int op, int result);
+ // Setup a reply message for EXPORT, WITHDRAW, or MODIFY operations.
+
+ int query_reply (int result, size_t num,
+ const ACE_URL_Offer_Seq &offers);
+ // Setup a reply for QUERY operation.
+
+ int describe_reply (int result,
+ const ACE_URL_Offer &offer);
+ // Construct a reply for DESCRIBE operation.
+
+ size_t encode (void);
+ // Encode request for network communication. If succeed,
+ // returns the size of the buffer, otherwise, return 0.
+
+ size_t decode (void *buffer);
+ // Restore from network data. Returns size of the buffer
+ // if succeed, 0 otherwise. When passing in a buffer,
+ // caller must take the responsibility to delete the buffer
+ // afterward, if so needed.
+
+ // Accessor function.
+ const size_t num_offers (void) const;
+ const ACE_URL_Offer *offer (void) const;
+ const ACE_URL_Offer_Seq *offers (void) const;
+ const u_int opcode (void) const;
+ const u_int status (void) const;
+ const char *buffer (void) const ;
+
+ void dump (void) const ;
+ // Print out this object.
+
+protected:
+ size_t size (void);
+ // Return the size of the buffer required to encode
+ // this request.
+
+ enum {
+ VALID_OFFER = 0x1,
+ VALID_OFFERS = 0x2
+ };
+ // Valid pointer masks.
+
+ u_int code_;
+ // Holds the original op code.
+
+ int status_;
+ // Holds the result of an operation from the Location Server.
+
+ size_t num_offers_;
+ // Holds the number of valid offers in the offers_ sequence.
+
+ int valid_ptr_;
+ // Flag that marks valid internal pointers.
+
+ ACE_URL_Offer *offer_;
+ // Holds a single offer. Used in query offer property.
+
+ ACE_URL_Offer_Seq *offers_;
+ // Holds the replying offer sequence from a Locator.
+
+ char *buffer_;
+ // Buffer to store encoded data.
+};
+#if defined (__ACE_INLINE__)
+#include "Locator_Request_Reply.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_LOCATOR_REQUEST_REPLY_H */
diff --git a/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.i b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.i
new file mode 100644
index 00000000000..9dd2f851ceb
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Locator_Request_Reply.i
@@ -0,0 +1,138 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+#include "URL_Locator.h"
+
+ACE_INLINE
+ACE_URL_Locator_Request::ACE_URL_Locator_Request (void)
+ : code_(ACE_URL_Locator::INVALID_OPERATION),
+ seq1_ (0),
+ seq2_ (0),
+ offer_ (0),
+ buffer_ (0)
+{
+}
+
+ACE_INLINE
+ACE_URL_Locator_Request::~ACE_URL_Locator_Request (void)
+{
+ delete this->seq1_;
+ delete this->seq2_;
+ delete this->offer_;
+ delete [] this->buffer_;
+}
+
+ACE_INLINE const int
+ACE_URL_Locator_Request::how (void) const
+{
+ return this-> how_;
+}
+
+ACE_INLINE const int
+ACE_URL_Locator_Request::how_many (void) const
+{
+ return this->how_many_;
+}
+
+ACE_INLINE const u_int
+ACE_URL_Locator_Request::opcode (void) const
+{
+ return this->code_;
+}
+
+ACE_INLINE const ACE_URL_Property_Seq *
+ACE_URL_Locator_Request::seq (void) const
+{
+ return this->seq1_;
+}
+
+ACE_INLINE const ACE_URL_Property_Seq *
+ACE_URL_Locator_Request::del (void) const
+{
+ return this->seq1_;
+}
+
+ACE_INLINE const ACE_URL_Property_Seq *
+ACE_URL_Locator_Request::modify (void) const
+{
+ return this->seq2_;
+}
+
+ACE_INLINE const ACE_URL_Offer *
+ACE_URL_Locator_Request::offer (void) const
+{
+ return this->offer_;
+}
+
+ACE_INLINE const ACE_WString &
+ACE_URL_Locator_Request::id (void) const
+{
+ return this->id_;
+}
+
+ACE_INLINE const ACE_WString &
+ACE_URL_Locator_Request::url (void) const
+{
+ return this->url_;
+}
+
+ACE_INLINE const char *
+ACE_URL_Locator_Request::buffer (void) const
+{
+ return this->buffer_;
+}
+
+ACE_INLINE
+ACE_URL_Locator_Reply::ACE_URL_Locator_Reply (void)
+ : code_ (ACE_URL_Locator::INVALID_OPERATION),
+ offer_ (0),
+ offers_ (0),
+ buffer_ (0)
+{
+}
+
+ACE_INLINE
+ACE_URL_Locator_Reply::~ACE_URL_Locator_Reply (void)
+{
+ delete this->offer_;
+ delete this->offers_;
+ delete [] this->buffer_;
+}
+
+ACE_INLINE const size_t
+ACE_URL_Locator_Reply::num_offers (void) const
+{
+ return this->num_offers_;
+}
+
+
+ACE_INLINE const ACE_URL_Offer *
+ACE_URL_Locator_Reply::offer (void) const
+{
+ return this->offer_;
+}
+
+ACE_INLINE const ACE_URL_Offer_Seq *
+ACE_URL_Locator_Reply::offers (void) const
+{
+ return this->offers_;
+}
+
+ACE_INLINE const u_int
+ACE_URL_Locator_Reply::opcode (void) const
+{
+ return this->code_;
+}
+
+ACE_INLINE const u_int
+ACE_URL_Locator_Reply::status (void) const
+{
+ return this->status_;
+}
+
+ACE_INLINE const char *
+ACE_URL_Locator_Reply::buffer (void) const
+{
+ return this->buffer_;
+}
diff --git a/ACE/apps/JAWS/clients/Caching/Makefile.am b/ACE/apps/JAWS/clients/Caching/Makefile.am
new file mode 100644
index 00000000000..d7f00231ad6
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/Makefile.am
@@ -0,0 +1,44 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+
+## Makefile.http_client.am
+
+if BUILD_ACE_FILECACHE
+if !BUILD_ACE_FOR_TAO
+noinst_LTLIBRARIES = libhttp_client.la
+
+libhttp_client_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+libhttp_client_la_SOURCES = \
+ http_client.cpp \
+ http_handler.cpp
+
+noinst_HEADERS = \
+ Local_Locator.i \
+ Locator_Request_Reply.i \
+ URL_Properties.i \
+ http_handler.h
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_ACE_FILECACHE
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/apps/JAWS/clients/Caching/README b/ACE/apps/JAWS/clients/Caching/README
new file mode 100644
index 00000000000..3dcfcd32815
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/README
@@ -0,0 +1,83 @@
+# -*- text -*-
+# Hey, Emacs! This is a TEXT file.
+
+----------------------------------
+README for the caching http_client
+----------------------------------
+
+This is the README file for the simple caching http_client.
+
+------------
+1. Compiling
+------------
+
+1a. Compiling on UNIX.
+
+ On UNIX, with a properly configured ACE distribution, just
+type make (using GNU make, of course).
+
+1b. Compiling on NT.
+
+ Thus far, this code has only been tested under UNIX. A
+Windows NT version will be out soon.
+
+------------
+2. Executing
+------------
+
+2a. Command line parameters.
+
+ The program does not support any command line parameters.
+
+2b. General information.
+
+ When the program runs, the client offers a ``*'' as a prompt.
+At the prompt, you may enter a URL. The client will check to see if
+the filename portion of the URL has already been cached. If so, a
+message appears saying so. If not, the client will fetch the file
+from the HTTP server and then cache it.
+
+ Furthermore, the client supports the ``!'' shell escape
+command. The content after the ``!'' will be executed by a shell.
+
+ To exit the session, send the end-of-file character
+(typically, ^D in UNIX).
+
+ unix$ ./http_client
+ * http://www.cs.wustl.edu/cs/Art/brookings.gif
+ [1] sending request --
+ GET /cs/Art/brookings.gif HTTP/1.0
+ Accept: HTTP/1.0
+
+ ``brookings.gif'' is now cached.
+ * http://www.cs.wustl.edu/cs/Art/brookings.gif
+ ``brookings.gif'' is already cached.
+ * !ls
+ Makefile http_client http_handler.cpp zJAWSAAAa000Yg
+ brookings.gif http_client.cpp http_handler.h
+ * ^D
+ Bye!
+ unix$ ls
+ Makefile http_client http_handler.cpp
+ brookings.gif http_client.cpp http_handler.h
+ unix$
+
+--------------
+3. Limitations
+--------------
+
+ The caching mechanism as currently implemented requires a
+``Content-length:'' to appear in the response header of the HTTP
+response. This is because the caching utilizes mmap () to allocate
+space for the file to be cached before the file is received. Unitl
+the caching mecahnism is extended, you are limited to using servers
+which will report the size of the file being transmitted.
+
+ Currently, the cache creates temporary files (see the above
+sample execution).
+
+ The cache is not persistent between executions.
+
+ Suggestions and other correspondence should be sent to me:
+
+James Hu <jxh@cs.wustl.edu>
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp
new file mode 100644
index 00000000000..c8dbb55e197
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.cpp
@@ -0,0 +1,43 @@
+// $Id$
+
+// URL_Array_Helper.cpp
+
+#ifndef ACE_URL_ARRAY_HELPER_C
+#define ACE_URL_ARRAY_HELPER_C
+
+#include "URL_Array_Helper.h"
+
+ACE_RCSID(Caching, URL_Array_Helper, "$Id$")
+
+// Some helper functions for encoding/decoding
+
+template <class T>
+size_t ace_array_size (const T &x)
+{
+ size_t sum = sizeof (ACE_UINT32);
+ for (size_t i = 0; i < x.size (); i++)
+ sum += x[i].size ();
+ return sum;
+}
+
+template <class T>
+size_t ace_array_encode (void *buf, const T &x)
+{
+ size_t len = 0;
+ for (size_t i = 0; i < x.size (); i++)
+ len+= x[i].encode ((void *) ((char *) buf + len));
+ return len ;
+}
+
+template <class T>
+size_t ace_array_decode (void *buf, T &x)
+{
+ size_t len = 0;
+ for (size_t i = 0; i < x.size (); i++)
+ len += x[i].decode ((void *) ((char *) buf + len));
+ return len;
+}
+
+
+
+#endif /* ACE_URL_ARRAY_HELPER_C */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h
new file mode 100644
index 00000000000..f38f9ebf5dd
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Array_Helper.h
@@ -0,0 +1,40 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// URL_Array_Helper.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_URL_ARRAY_HELPER_H
+#define ACE_URL_ARRAY_HELPER_H
+
+// ### These template functions are probably named improperly.
+// You should find some way to avoid name space polution.
+
+template <class T>
+size_t ace_array_size (const T &x);
+
+template <class T>
+size_t ace_array_encode (void *buf, const T &x);
+
+template <class T>
+size_t ace_array_decode (void *buf, T &x);
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "URL_Array_Helper.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("URL_Array_Helper.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* ACE_URL_ARRAY_HELPER_H */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp b/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp
new file mode 100644
index 00000000000..e7f6fb6c05b
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Locator.cpp
@@ -0,0 +1,52 @@
+// $Id$
+
+#if !defined (ACE_URL_LOCATOR_C)
+#define ACE_URL_LOCATOR_C
+
+#include "URL_Locator.h"
+
+ACE_RCSID(Caching, URL_Locator, "$Id$")
+
+const char * const
+ACE_URL_Locator::opname[] =
+// Human readable operation name
+{
+ "Query",
+ "Export",
+ "Withdraw",
+ "Describe",
+ "Modify",
+ "Invalid Operation"
+};
+
+const char * const
+ACE_URL_Locator::selection_name[] =
+{
+ "None",
+ "Some",
+ "All",
+ "Invalid Selection"
+};
+
+const char * const
+ACE_URL_Locator::err_name[] =
+{
+ "No error",
+ "Offer already exist",
+ "no such offer",
+ "invalid argument",
+ "function not implemented",
+ "unknown error"
+};
+
+ACE_URL_Locator::~ACE_URL_Locator (void)
+{
+}
+
+const char *
+ACE_URL_Locator::error_status (void)
+{
+ return "Not implemented yet.";
+}
+
+#endif /* ACE_URL_LOCATOR_C */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Locator.h b/ACE/apps/JAWS/clients/Caching/URL_Locator.h
new file mode 100644
index 00000000000..751de52cfe5
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Locator.h
@@ -0,0 +1,112 @@
+/* -*- C++ -*- */
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// URL_Locator.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_URL_LOCATOR_H
+#define ACE_URL_LOCATOR_H
+
+#include "URL_Properties.h"
+
+class ACE_Svc_Export ACE_URL_Locator
+ // = TITLE
+ // Abstract Base class designates what interfaces a URL_Locator
+ // should provide.
+ //
+ // = DESCRIPTION
+ // This class defines the basic URL_Locator APIs.
+ // An URL locator provides services for URL clients to
+ // query specific URL location that has certain properties
+ // and URL providers to export their services and a set of
+ // APIs to maintain their offers.
+{
+public:
+ // Request type
+ enum ACE_URL_Locator_Op_Type
+ {
+ QUERY = 0,
+ EXPORT,
+ WITHDRAW,
+ DESCRIBE,
+ MODIFY,
+ INVALID_OPERATION // LAST
+ };
+
+ static const char * const opname[];
+ // Human Readable operation name.
+
+ // = Specify how to select offers.
+ enum ACE_Selection_Criteria
+ {
+ NONE = 0, // URL that contains none of the properties.
+ SOME, // URL that contains some of the properties.
+ ALL, // URL that contains all of the properties.
+ INVALID_SELECTION // Invalid.
+ };
+
+ static const char * const selection_name[];
+
+ enum ACE_URL_Locator_Error
+ // errno will set to one of these value.
+ {
+ OK, // Everything is fine.
+ OFFER_EXIST, // trying to register an offer.
+ // that is already exist in repository.
+ NO_SUCH_OFFER, // No such offer in the repository.
+ INVALID_ARGUMENT, // Invalid argument encountered.
+ UNIMPLEMENTED, // function not implemented.
+ UNKNOWN, // Unknown error.
+ MAX_URL_ERROR
+ };
+ // Possible error code of URL_Locator.
+
+ static const char * const err_name[];
+ // Human readable error status.
+
+ virtual ~ACE_URL_Locator (void) = 0;
+ // Default destructor.
+
+ virtual int url_query (const ACE_Selection_Criteria how,
+ const ACE_URL_Property_Seq *pseq,
+ const size_t how_many,
+ size_t &num_query,
+ ACE_URL_Offer_Seq *offer) = 0;
+ // Query the locator for HTTP with designate properties (none, some,
+ // or all). The locator being queried will return a sequence of
+ // offers with <how_many> offers in it. This interface allocates
+ // <offer> so users must deallocate it after use.
+
+ virtual int export_offer (ACE_URL_Offer *offer,
+ ACE_WString &offer_id) = 0;
+ // Export an offer to the locator.
+
+ virtual int withdraw_offer (const ACE_WString &offer_id) = 0;
+ // Withdraw an offer. return 0 if succeed, -1 otherwise.
+
+ virtual int describe_offer (const ACE_WString &offer_id,
+ ACE_URL_Offer *offer) = 0;
+ // Query a specific offer.
+
+ virtual int modify_offer (const ACE_WString &offer_id,
+ const ACE_WString *url = 0,
+ const ACE_URL_Property_Seq *del = 0,
+ const ACE_URL_Property_Seq *modify = 0) = 0;
+ // Modify a previously registered offer.
+
+ virtual const char *error_status (void);
+ // Provide a human readable error status.
+};
+
+#endif /* ACE_WEB_LOCATOR_H */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp b/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp
new file mode 100644
index 00000000000..6568fb0ff8d
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.cpp
@@ -0,0 +1,139 @@
+// $Id$
+
+#if !defined (ACE_URL_PROPERTIES_C)
+#define ACE_URL_PROPERTIES_C
+
+#include "URL_Properties.h"
+
+#if !defined (__ACE_INLINE__)
+#include "URL_Properties.i"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/Auto_Ptr.h"
+#include "URL_Array_Helper.h"
+
+ACE_RCSID(Caching, URL_Properties, "$Id$")
+
+size_t
+ACE_WString_Helper::encode (void *buf, const ACE_WString &wstr)
+{
+ ACE_USHORT16 *wptr = (ACE_USHORT16 *) buf;
+ size_t i;
+
+ for (i= 0; i <= wstr.length (); i++)
+ wptr[i] = htons (wstr[i]);
+
+ return i * sizeof (ACE_USHORT16);
+}
+
+size_t
+ACE_WString_Helper::decode (void *buf)
+{
+ ACE_USHORT16 *wptr = (ACE_USHORT16 *) buf;
+ size_t i;
+
+ for (i = 0; wptr[i] != 0; i++)
+ wptr[i] = ntohs (wptr[i]);
+
+ return (i + 1) * sizeof (ACE_USHORT16);
+}
+
+size_t
+ACE_URL_Property::encode (void *buf) const
+{
+ size_t blen = ACE_WString_Helper::encode (buf, this->name_);
+ blen += ACE_WString_Helper::encode ((void *) ((char *) buf + blen),
+ this->value_);
+ return blen;
+}
+
+size_t
+ACE_URL_Property::decode (void *buf)
+{
+ char *cbuf = (char *) buf;
+ size_t len = ACE_WString_Helper::decode(buf);
+ this->name ((ACE_USHORT16 *) cbuf);
+
+ cbuf += len;
+ len += ACE_WString_Helper::decode ((void *) cbuf);
+ this->value ((ACE_USHORT16 *) cbuf);
+ return len;
+}
+
+void
+ACE_URL_Property::dump (void) const
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ if (this->name_.length () > 0)
+ ACE_DEBUG ((LM_DEBUG, "\n name_: \"%s\"\n",
+ ACE_Auto_Basic_Array_Ptr<char> (this->name_.char_rep ()).get ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, "\n name_: \"\"\n"));
+
+ if (this->value_.length () > 0)
+ ACE_DEBUG ((LM_DEBUG, " value_: \"%s\"\n",
+ ACE_Auto_Basic_Array_Ptr<char> (this->value_.char_rep ()).get ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, " value_: \"\"\n"));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+size_t
+ACE_URL_Offer::size (void) const
+{
+ size_t sum = (this->url_.length () + 1) * sizeof (ACE_USHORT16);
+ sum += ::ace_array_size (this->prop_);
+ return sum;
+}
+
+size_t
+ACE_URL_Offer::encode (void *buf) const
+{
+ ACE_UINT32 *s_buf = (ACE_UINT32 *) buf;
+ *s_buf = htonl (this->prop_.size ());
+
+ size_t len = sizeof (ACE_UINT32);
+ len += ACE_WString_Helper::encode ((void *) ((char *) buf + len),
+ this->url_);
+
+ len += ::ace_array_encode ((void *) ((char *) buf + len),
+ this->prop_);
+ return len;
+}
+
+size_t
+ACE_URL_Offer::decode (void *buf)
+{
+ size_t len = sizeof (ACE_UINT32);
+ size_t a_size = (size_t) ntohl (*(ACE_UINT32 *) buf);
+ len += ACE_WString_Helper::decode ((void *) ((char *) buf + len));
+ this->url ((ACE_USHORT16 *) ((char *) buf + len));
+
+ ACE_URL_Property_Seq prop_seq (a_size);
+ this->url_properties (prop_seq);
+
+ len += ::ace_array_decode ((void *)((char *) buf + len),
+ this->prop_);
+ return len;
+}
+
+void
+ACE_URL_Offer::dump (void) const
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ if (this->url_.length () > 0)
+ ACE_DEBUG ((LM_DEBUG, "\n url_: \"%s\"\n",
+ ACE_Auto_Basic_Array_Ptr<char> (this->url_.char_rep ()).get ()));
+ else
+ ACE_DEBUG ((LM_DEBUG, "\n url_: \"\"\n"));
+
+ for (size_t i = 0; i < this->prop_.size (); i++)
+ this->prop_[i].dump ();
+
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+#endif /* ACE_URL_PROPERTIES_C */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.h b/ACE/apps/JAWS/clients/Caching/URL_Properties.h
new file mode 100644
index 00000000000..e62eb9102f6
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.h
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// none
+//
+// = FILENAME
+// URL_Locator.h
+//
+// = AUTHOR
+// Nanbor Wang
+//
+// ============================================================================
+
+#ifndef ACE_URL_PROPERTIES_H
+#define ACE_URL_PROPERTIES_H
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Containers.h"
+
+class ACE_Svc_Export ACE_WString_Helper
+ // = TITLE
+ // Some helper functions for manipulate ACE_WString.
+ //
+ // = DESCRIPTION
+ // These functions simplify encoding/decoding of
+ // ACE_WString objects for network communication.
+{
+public:
+ static size_t size (const ACE_WString &wstr);
+ // Returns the actual size (in bytes) required to contain the
+ // ACE_WString.
+
+ static size_t encode (void *buf, const ACE_WString &wstr);
+ // Encode <wstr> into <buf> for network communication.
+ // Return total octets consumed.
+
+ static size_t decode (void *buf);
+ // This function doesn't relate to ACE_WString directly.
+ // It converts an ACE_USHORT16 string from network
+ // byte order to host byte order. Returns size of the string.
+};
+
+class ACE_Svc_Export ACE_URL_Property
+ // = TITLE
+ // Defines a property of a URL.
+ //
+ // = DESCRIPTION
+ // A property contains a <name> and a <value>.
+ // A URL may contain some properties and we can "locate"
+ // the URL's we are looking for by examming URL for certain
+ // properties that match our need.
+{
+public:
+ ACE_URL_Property (const char *name = 0,
+ const char *value=0);
+ // Create a new property.
+
+ ACE_URL_Property (const ACE_USHORT16 *name,
+ const ACE_USHORT16 *value);
+ // Create a new property using wchar strings. This is mostly used
+ // to support DBCS or UNICODE.
+
+ ACE_URL_Property (const ACE_URL_Property &p);
+ // Copy constructor.
+
+ ~ACE_URL_Property (void);
+ // Destructor.
+
+ ACE_URL_Property &operator= (const ACE_URL_Property &rhs);
+ // Assignment operator.
+
+ bool operator== (const ACE_URL_Property &rhs) const;
+ // Equals operator.
+
+ bool operator!= (const ACE_URL_Property &rhs) const;
+ // Inequality operator.
+
+ // = Query property name.
+ ACE_WString &name_rep (void);
+ const ACE_WString &name (void) const;
+
+ // = Set property name.
+ void name (const ACE_USHORT16 *n);
+ void name (const char *n);
+
+ // = Query property value.
+ ACE_WString &value_rep (void);
+ const ACE_WString &value (void) const;
+
+ // = Set property value.
+ void value (const ACE_USHORT16 *v);
+ void value (const char *v);
+
+ // = Helper functions for encoding and decoding.
+ size_t size (void) const;
+ // Returns memory size (in bytes) required to encode this object.
+
+ size_t encode (void *buf) const;
+ // Encodes this object into buf for network transmission.
+
+ size_t decode (void *buf);
+ // Decodes buf and modifies this object, you should
+ // probably create this with default ctor.
+
+ void dump (void) const;
+ // Dump out this object for debug.
+
+protected:
+ ACE_WString name_;
+ // Property name pointer.
+
+ ACE_WString value_;
+ // Property value.
+} ;
+
+typedef ACE_Array<ACE_URL_Property> ACE_URL_Property_Seq;
+// type of URL_Property collections.
+
+class ACE_Svc_Export ACE_URL_Offer
+ // = TITLE
+ // Defines a URL offer.
+ //
+ // = DESCRIPTION
+ // A URL offer is defined by a <url> and an
+ // <ACE_URL_Property_Seq>. An offer is stored at server end
+ // thru registering or reported back to querying client from the
+ // sever.
+{
+public:
+ ACE_URL_Offer (const size_t size = 1, const char *url = 0);
+ // Create an offer.
+
+ ACE_URL_Offer (const ACE_URL_Offer &o);
+ // Copy ctor.
+
+ ~ACE_URL_Offer (void);
+ // Default destructor.
+
+ ACE_URL_Offer &operator= (const ACE_URL_Offer &rhs);
+ // Assignment operator.
+
+ bool operator== (const ACE_URL_Offer &rhs) const;
+ // Equality operator.
+
+ bool operator!= (const ACE_URL_Offer &rhs) const;
+ // Inequality operator.
+
+ // = Get URL string.
+ ACE_WString &url_rep (void);
+ const ACE_WString &url (void) const;
+
+ // = Set URL.
+ void url (const char *url);
+ void url (const ACE_USHORT16 *url);
+
+ ACE_URL_Property_Seq &url_properties (void);
+ // Get properties of this offer.
+
+ void url_properties (const ACE_URL_Property_Seq &prop);
+ // Set properties of this offer. This operation virtually get a
+ // copy of the passed in prop.
+
+ // = Helper functions for encoding and decoding.
+ size_t size (void) const;
+ // Returns memory size (in bytes) required to encode this object.
+
+ size_t encode (void *buf) const;
+ // Encodes this object into buf for network transmission.
+
+ size_t decode (void *buf);
+ // Decodes buf into current object, you better use
+ // the default ctor.
+
+ void dump (void) const;
+ // Dump this object for debug.
+
+protected:
+ ACE_WString url_;
+ // URL of this offer.
+
+ ACE_URL_Property_Seq prop_;
+ // Properties associate with this offer.
+};
+
+typedef ACE_Array<ACE_URL_Offer> ACE_URL_Offer_Seq;
+// type of URL offer collections.
+
+#if defined (__ACE_INLINE__)
+#include "URL_Properties.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_WEB_PROPERTIES_H */
diff --git a/ACE/apps/JAWS/clients/Caching/URL_Properties.i b/ACE/apps/JAWS/clients/Caching/URL_Properties.i
new file mode 100644
index 00000000000..768ad967d94
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/URL_Properties.i
@@ -0,0 +1,203 @@
+// -*- C++ -*-
+//
+// $Id$
+
+ACE_INLINE size_t
+ACE_WString_Helper::size (const ACE_WString &wstr)
+{
+ return (wstr.length () + 1) * sizeof (ACE_USHORT16);
+}
+
+ACE_INLINE
+ACE_URL_Property::ACE_URL_Property (const char *name, const char *value)
+ : name_ (name),
+ value_ (value)
+{
+}
+
+ACE_INLINE
+ACE_URL_Property::ACE_URL_Property (const ACE_USHORT16 *name,
+ const ACE_USHORT16 *value)
+ : name_ (name),
+ value_ (value)
+{
+}
+
+ACE_INLINE
+ACE_URL_Property::ACE_URL_Property (const ACE_URL_Property &p)
+ : name_ (p.name_),
+ value_ (p.value_)
+{
+}
+
+ACE_INLINE
+ACE_URL_Property::~ACE_URL_Property (void)
+{
+}
+
+ACE_INLINE ACE_URL_Property &
+ACE_URL_Property::operator= (const ACE_URL_Property &rhs)
+{
+ if (this != &rhs)
+ {
+ this->name_ = rhs.name_;
+ this->value_ = rhs.value_;
+ }
+ return *this;
+}
+
+ACE_INLINE bool
+ACE_URL_Property::operator== (const ACE_URL_Property &rhs) const
+{
+ if (this == &rhs || this->name_ != rhs.name_ ||
+ this->value_ != rhs.value_)
+ return true;
+ else
+ return false;
+}
+
+ACE_INLINE bool
+ACE_URL_Property::operator!= (const ACE_URL_Property &rhs) const
+{
+ return !(*this == rhs);
+}
+
+ACE_INLINE ACE_WString &
+ACE_URL_Property::name_rep (void)
+{
+ return this->name_;
+}
+
+ACE_INLINE const ACE_WString &
+ACE_URL_Property::name (void) const
+{
+ return this->name_;
+}
+
+ACE_INLINE void
+ACE_URL_Property::name (const char *n)
+{
+ this->name_ = ACE_WString (n);
+}
+
+ACE_INLINE void
+ACE_URL_Property::name (const ACE_USHORT16 *n)
+{
+ this->name_ = ACE_WString (n);
+}
+
+ACE_INLINE ACE_WString &
+ACE_URL_Property::value_rep (void)
+{
+ return this->value_;
+}
+
+ACE_INLINE const ACE_WString &
+ACE_URL_Property::value (void) const
+{
+ return this->value_;
+}
+
+ACE_INLINE void
+ACE_URL_Property::value (const char *v)
+{
+ this->value_ = ACE_WString (v);
+}
+
+ACE_INLINE void
+ACE_URL_Property::value (const ACE_USHORT16 *v)
+{
+ this->value_ = ACE_WString (v);
+}
+
+
+ACE_INLINE size_t
+ACE_URL_Property::size (void) const
+{
+ size_t len = 2;
+ len += this->name_.length () + this->value_.length ();
+ return len * sizeof (ACE_USHORT16);
+}
+
+ACE_INLINE
+ACE_URL_Offer::ACE_URL_Offer (const size_t size, const char *url)
+ : url_ (url),
+ prop_ (size)
+{
+}
+
+ACE_INLINE
+ACE_URL_Offer::ACE_URL_Offer (const ACE_URL_Offer &o)
+ : url_ (o.url_),
+ prop_ (o.prop_)
+{
+}
+
+ACE_INLINE
+ACE_URL_Offer::~ACE_URL_Offer (void)
+{
+}
+
+ACE_INLINE ACE_URL_Offer &
+ACE_URL_Offer::operator= (const ACE_URL_Offer &rhs)
+{
+ if (this != &rhs)
+ {
+ this->url_ = rhs.url_;
+ this->prop_ = rhs.prop_;
+ }
+ return *this;
+}
+
+ACE_INLINE bool
+ACE_URL_Offer::operator== (const ACE_URL_Offer &rhs) const
+{
+ if (this == &rhs
+ && this->url_ == rhs.url_
+ && this->prop_ == rhs.prop_)
+ return true;
+ else
+ return false;
+}
+
+ACE_INLINE bool
+ACE_URL_Offer::operator!= (const ACE_URL_Offer &rhs) const
+{
+ return !(*this == rhs);
+}
+
+ACE_INLINE ACE_WString &
+ACE_URL_Offer::url_rep (void)
+{
+ return this->url_;
+}
+
+ACE_INLINE const ACE_WString &
+ACE_URL_Offer::url (void) const
+{
+ return this->url_;
+}
+
+ACE_INLINE void
+ACE_URL_Offer::url (const ACE_USHORT16 *url)
+{
+ this->url_ = ACE_WString (url);
+}
+
+ACE_INLINE void
+ACE_URL_Offer::url (const char *url)
+{
+ this->url_ = ACE_WString (url);
+}
+
+ACE_INLINE ACE_URL_Property_Seq &
+ACE_URL_Offer::url_properties (void)
+{
+ return this->prop_;
+}
+
+ACE_INLINE void
+ACE_URL_Offer::url_properties (const ACE_URL_Property_Seq &prop)
+{
+ this->prop_ = prop;
+}
diff --git a/ACE/apps/JAWS/clients/Caching/caching.mpc b/ACE/apps/JAWS/clients/Caching/caching.mpc
new file mode 100644
index 00000000000..fce9d81df4f
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/caching.mpc
@@ -0,0 +1,12 @@
+// -*- MPC -*-
+// $Id$
+
+project(http_client) : aceexe {
+ avoids += ace_for_tao
+ requires += ace_filecache
+
+ Source_Files {
+ http_handler.cpp
+ http_client.cpp
+ }
+}
diff --git a/ACE/apps/JAWS/clients/Caching/http_client.cpp b/ACE/apps/JAWS/clients/Caching/http_client.cpp
new file mode 100644
index 00000000000..f0bb20b6d56
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/http_client.cpp
@@ -0,0 +1,79 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// apps/JAWS/clients/Caching
+//
+// = FILENAME
+// http_client.cpp
+//
+// = DESCRIPTION
+// This is a very simple client. It accepts URLs from a prompt, and
+// will try to fetch them. Also accepts shell escapes.
+//
+// = AUTHOR
+// James Hu
+//
+// ============================================================================
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
+#include "ace/os_include/os_ctype.h"
+#include "http_handler.h"
+
+ACE_RCSID(Caching, http_client, "$Id$")
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ // Present a command line.
+ // * Accept a URL.
+ // Pass it to the HTTP_Connector.
+ // Connect.
+ // Report status.
+ // * Accept shell escape character.
+
+ char buf[BUFSIZ];
+
+ ACE_DEBUG ((LM_DEBUG, "* "));
+
+ while (ACE_OS::fgets (buf, sizeof (buf), stdin) != NULL)
+ {
+ char *s = buf;
+
+ // get rid of trailing '\n'
+ int len = ACE_OS::strlen (s);
+
+ if (len > 0 && s[len - 1] == '\n')
+ s[len - 1] = 0;
+
+ while (isspace (*s))
+ s++;
+
+ if (*s == '!')
+ {
+ do
+ s++;
+ while (isspace (*s));
+
+ // Shell command.
+ if (ACE_OS::system (ACE_TEXT_CHAR_TO_TCHAR (s)) == -1)
+ ACE_ERROR ((LM_ERROR, ACE_TEXT (" ! Error executing: %C\n"), s));
+ }
+ else if (ACE_OS::strncmp (s, "http://", 7) == 0)
+ {
+ // URL
+ HTTP_Connector connector;
+ connector.connect (s);
+ }
+ else
+ ACE_ERROR ((LM_ERROR, ACE_TEXT (" ? I don't understand: %C\n"), s));
+
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("* ")));
+ }
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nBye!\n")));
+
+ return 0;
+}
diff --git a/ACE/apps/JAWS/clients/Caching/http_handler.cpp b/ACE/apps/JAWS/clients/Caching/http_handler.cpp
new file mode 100644
index 00000000000..bfeda511176
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/http_handler.cpp
@@ -0,0 +1,238 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// apps/JAWS/clients/Caching
+//
+// = FILENAME
+// http_handler.cpp
+//
+// = AUTHOR
+// James Hu
+//
+// ============================================================================
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
+#include "ace/Filecache.h"
+#include "http_handler.h"
+
+ACE_RCSID(Caching, http_handler, "$Id$")
+
+HTTP_Handler::HTTP_Handler (void)
+{
+}
+
+HTTP_Handler::HTTP_Handler (const char * path)
+{
+ // How long is the request going to be?
+ this->request_[0] = '\0';
+ this->request_size_ =
+ ACE_OS::strlen ("GET ")
+ + ACE_OS::strlen (path)
+ + ACE_OS::strlen (" HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n");
+
+ // Make the request.
+ if ((u_int) this->request_size_ < sizeof (this->request_))
+ ACE_OS::sprintf (this->request_,
+ "GET %s HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n",
+ path);
+
+ // Find the filename.
+ const char *last = ACE_OS::strrchr (path, '/');
+
+ if (last == 0)
+ last = path;
+ else if (last[1] == '\0')
+ last = "index.html";
+ else
+ last = last+1;
+
+ ACE_OS::sprintf (this->filename_, "%s", last);
+}
+
+int
+HTTP_Handler::open (void *)
+{
+ // If you want threads, use the activate stuff.
+#if 0
+ if (this->activate () != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, "HTTP_Handler::open, whups!\n"), -1);
+ }
+
+ return 0;
+#else
+ return this->svc ();
+#endif /* 0 */
+}
+
+int
+HTTP_Handler::svc (void)
+{
+ static char buf[BUFSIZ];
+ int count = 0;
+
+ ACE_DEBUG ((LM_DEBUG, "[%t] sending request --\n%s", this->request_));
+
+ this->peer ().send_n (this->request_, this->request_size_);
+
+ // Read in characters until encounter \r\n\r\n
+ int done = 0;
+ char *contentlength;
+
+ do
+ {
+ while (((count += this->peer ().recv_n (buf + count, 1)) > 0)
+ && ((u_int) count < sizeof (buf)))
+ {
+ buf[count] = '\0';
+
+ if (count < 2)
+ continue;
+ done = ACE_OS::strcmp (buf + count - 4, "\n\n") == 0;
+
+ if (done)
+ break;
+
+ if (count < 4)
+ continue;
+
+ done = ACE_OS::strcmp (buf + count - 4, "\r\n\r\n") == 0;
+
+ if (done)
+ break;
+ }
+
+ if (!done)
+ {
+ char *last = ACE_OS::strrchr (buf, '\n');
+ last[0] = '\0';
+
+ if ((contentlength = ACE_OS::strstr (buf, "\nContent-length:"))
+ || (contentlength = ACE_OS::strstr (buf, "\nContent-Length:")))
+ done = 1;
+ else
+ {
+ last[0] = '\n';
+ count = ACE_OS::strlen (last);
+ ACE_OS::memmove (buf, last, count + 1);
+ }
+ }
+ else
+ {
+ contentlength = ACE_OS::strstr (buf, "\nContent-length:");
+
+ if (!contentlength)
+ contentlength =
+ ACE_OS::strstr (buf, "\nContent-Length:");
+ }
+
+ }
+ while (!done);
+
+ // ASSERT (contentlength != 0)
+ if (contentlength
+ && (::sscanf (contentlength, "\nContent-%*[lL]ength: %d ",
+ &this->response_size_) == 1))
+ {
+ ACE_Filecache_Handle afh (ACE_TEXT_CHAR_TO_TCHAR (this->filename_),
+ this->response_size_);
+
+ this->peer ().recv_n (afh.address (), this->response_size_);
+
+ ACE_DEBUG ((LM_DEBUG,
+ " ``%s'' is now cached.\n",
+ this->filename_));
+ }
+ else
+ {
+ // Maybe we should do something more clever here, such as extend
+ // ACE_Filecache_Handle to allow the creation of cache objects
+ // whose size is unknown?
+
+ // Another possibility is to write the contents out to a file,
+ // and then cache it.
+
+ // Perhaps make ACE_Filecache_Handle more savvy, and allow a
+ // constructor which accepts a PEER as a parameter.
+ ACE_DEBUG ((LM_DEBUG,
+ "HTTP_Handler, no content-length header!\n"));
+ }
+
+ return 0;
+}
+
+const char *
+HTTP_Handler::filename (void) const
+{
+ return this->filename_;
+}
+
+int
+HTTP_Connector::connect (const char * url)
+{
+ char host[BUFSIZ];
+ u_short port;
+ char path[BUFSIZ];
+
+ if (this->parseurl (url, host, &port, path) == -1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "HTTP_Connector, error parsing url: %s\n",
+ url));
+ return -1;
+ }
+
+ HTTP_Handler hh (path);
+ HTTP_Handler *hhptr = &hh;
+
+ // First check the cache.
+ if (ACE_Filecache::instance ()->find (ACE_TEXT_CHAR_TO_TCHAR (hh.filename ())) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, " ``%s'' is already cached.\n",
+ hh.filename ()));
+ return 0;
+ }
+
+ return this->connector_.connect (hhptr, ACE_INET_Addr (port, host));
+}
+
+#define DEFAULT_SERVER_PORT 80
+
+// extract the main components of a URL
+int
+HTTP_Connector::parseurl (const char *url,
+ char *host,
+ u_short *port,
+ char *path)
+{
+ int status = 0;
+
+ // hackish, but useful
+ if (3 != ::sscanf (url, "http://%[^:/]:%hu%s", host, port, path))
+ {
+ if (2 != ::sscanf (url, "http://%[^:/]:%hu", host, port))
+ {
+ if (2 != ::sscanf (url, "http://%[^:/]%s", host, path))
+ {
+ if (1 != ::sscanf (url, "http://%[^:/]", host))
+ status = -1;
+ else
+ {
+ *port = DEFAULT_SERVER_PORT;
+ ACE_OS::strcpy (path, "/");
+ }
+ }
+ else
+ *port = DEFAULT_SERVER_PORT;
+ }
+ else ACE_OS::strcpy (path, "/");
+ }
+
+ // 0 => success
+ // -1 => error
+ return status;
+}
+
diff --git a/ACE/apps/JAWS/clients/Caching/http_handler.h b/ACE/apps/JAWS/clients/Caching/http_handler.h
new file mode 100644
index 00000000000..3922c1ab857
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/http_handler.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+// Hey, Emacs! This is a C++ file.
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// apps/JAWS/clients/Caching
+//
+// = FILENAME
+// http_handler.h
+//
+// = AUTHOR
+// James Hu
+//
+// ============================================================================
+
+#include "ace/SOCK_Connector.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Connector.h"
+#include "ace/Svc_Handler.h"
+
+class HTTP_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = TITLE
+ // A simple HTTP protocol handler for clients.
+ //
+ // = DESCRIPTION
+ // Checks to see if the requested file is already cached. If
+ // so, it says so. If not, the request is issued to the
+ // connection. The fetched file is cached.
+{
+public:
+ // = Initialization methods.
+ HTTP_Handler (void);
+ HTTP_Handler (const char * path);
+
+ virtual int open (void *);
+ // Open hook.
+
+ virtual int svc (void);
+ // Entry points defined by the abstract Svc_Handler.
+
+ const char *filename (void) const;
+ // Accessor to the file being fetched.
+
+private:
+ char request_[BUFSIZ];
+ int request_size_;
+
+ char filename_[BUFSIZ];
+ int response_size_;
+};
+
+class HTTP_Connector
+ // = TITLE
+ // A simple HTTP connector.
+ //
+ // = DESCRIPTION
+ // Creates an HTTP Handler based on the URL, and then delegates
+ // to to the SOCK_CONNECTOR. Adapter pattern.
+{
+public:
+ int connect (const char * url);
+ // User entry point into the HTTP connector.
+
+private:
+ int parseurl (const char *url,
+ char *host,
+ u_short *port,
+ char *path);
+ // Helper function.
+
+private:
+ ACE_Connector<HTTP_Handler, ACE_SOCK_CONNECTOR> connector_;
+ // Factory that actively establishes a connection with an HTTP
+ // server.
+};
diff --git a/ACE/apps/JAWS/clients/Caching/test_URL.cpp b/ACE/apps/JAWS/clients/Caching/test_URL.cpp
new file mode 100644
index 00000000000..7e81a359f45
--- /dev/null
+++ b/ACE/apps/JAWS/clients/Caching/test_URL.cpp
@@ -0,0 +1,34 @@
+// $Id$
+
+#include "Locator_Request_Reply.h"
+
+ACE_RCSID(Caching, test_URL, "$Id$")
+
+int main (int argc, char *argv[])
+{
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+
+ ACE_URL_Locator_Request original, derived;
+
+ ACE_URL_Property_Seq ouch1(3);
+ ouch1[0].name ("name 1");
+ ouch1[0].value ("value 1");
+ ouch1[1].name ("name 2");
+ ouch1[1].value ("value 2");
+ ouch1[2].name ("name 3");
+ ouch1[2].value ("value 3");
+
+ original.url_query (1, ouch1, 3);
+
+ original.dump ();
+ derived.dump ();
+
+ original.encode ();
+
+ derived.decode ((void*) original.buffer ());
+
+ derived.dump ();
+
+ return 0;
+}