--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/prophet/OfferTLV.cc Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2007 Baylor University
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <arpa/inet.h> // for hton[ls] and ntoh[ls]
+#include "OfferTLV.h"
+
+namespace prophet
+{
+
+OfferTLV::OfferTLV(const BundleOfferList& bl)
+ : BundleTLV(BaseTLV::OFFER_TLV,0,bl.guess_size(BundleEntrySize)),
+ list_(bl) {}
+
+OfferTLV::OfferTLV()
+ : BundleTLV(BaseTLV::OFFER_TLV) {}
+
+size_t
+OfferTLV::serialize(u_char* bp, size_t len) const
+{
+ // weed out the oddball
+ if (bp == NULL) return 0;
+ if (typecode_ != BaseTLV::OFFER_TLV) return 0;
+
+ // check that lengths match up
+ if (BundleTLVHeaderSize +
+ list_.guess_size(BundleEntrySize) > len)
+ return 0;
+
+ // account for bytes written
+ length_ = 0;
+
+ // start writing out to buffer
+ BundleTLVHeader* hdr = (BundleTLVHeader*) bp;
+ memset(hdr, 0, BundleTLVHeaderSize);
+ hdr->type = BaseTLV::OFFER_TLV;
+ hdr->flags = 0;
+ hdr->offer_count = htons(list_.size());
+
+ length_ += BundleTLVHeaderSize;
+ bp += BundleTLVHeaderSize;
+ len -= BundleTLVHeaderSize;
+
+ // write out each Bundle offer
+ for (BundleOfferList::const_iterator i = list_.begin();
+ i != list_.end();
+ i++)
+ {
+ const BundleOfferEntry* b = *i;
+ size_t bytes_written =
+ BundleTLV::write_bundle_entry(b->creation_ts(),
+ b->seqno(), b->sid(), b->custody(),
+ b->accept(), b->ack(), b->type(),
+ bp, len);
+
+ if (BundleEntrySize > bytes_written) break;
+
+ length_ += bytes_written;
+ len -= bytes_written;
+ bp += bytes_written;
+ }
+
+ hdr->length = htons(length_);
+ return length_;
+}
+
+bool
+OfferTLV::deserialize(const u_char* bp, size_t len)
+{
+ // weed out the oddball
+ if (bp == NULL) return false;
+ if (typecode_ != OFFER_TLV) return false;
+ if (! list_.empty()) return false;
+
+ // check that lengths match up
+ if (BundleTLVHeaderSize > len) return false;
+
+ // zero out accounting
+ size_t amt_read = 0;
+ length_ = 0;
+
+ // parse the header
+ BundleTLVHeader* b = (BundleTLVHeader*) bp;
+ if (b->type != typecode_) return false;
+ length_ = ntohs(b->length);
+ if (length_ > len) return false;
+ flags_ = b->flags;
+ size_t offer_count = ntohs(b->offer_count);
+
+ // now move past the header
+ bp += BundleTLVHeaderSize;
+ len -= BundleTLVHeaderSize;
+ amt_read += BundleTLVHeaderSize;
+
+ while (len >= BundleTLVHeaderSize &&
+ amt_read + BundleTLVHeaderSize <= length_ &&
+ offer_count-- > 0)
+ {
+ u_int32_t cts = 0;
+ u_int32_t seq = 0;
+ u_int16_t sid = 0;
+ bool custody = false,
+ accept = false,
+ ack = false;
+ BundleTLVEntry::bundle_entry_t type = BundleTLVEntry::UNDEFINED;
+
+ size_t bytes_read =
+ BundleTLV::read_bundle_entry(&cts,&seq,&sid,&custody,
+ &accept,&ack,&type,bp,len);
+
+ if (BundleEntrySize > bytes_read)
+ return false;
+
+ if (type != BundleTLVEntry::OFFER)
+ return false;
+
+ if (! list_.add_offer(cts,seq,sid,custody,ack))
+ return false;
+
+ // account for what's been read
+ amt_read += bytes_read;
+ len -= bytes_read;
+ bp += bytes_read;
+ }
+
+ return (amt_read == length_);
+}
+
+}; // namespace prophet