Data DirEntryList::serialize() const { Data serialized(_serializedSize()); unsigned int offset = 0; for (auto iter = _entries.begin(); iter != _entries.end(); ++iter) { ASSERT(iter == _entries.begin() || std::less<Key>()((iter-1)->key(), iter->key()), "Invariant hurt: Directory entries should be ordered by key and not have duplicate keys."); iter->serialize(static_cast<uint8_t*>(serialized.dataOffset(offset))); offset += iter->serializedSize(); } return serialized; }
size_t BencodeObject::serialize(void* dest, size_t maxlen) { size_t req = serializedSize(); if (maxlen < req) { return 0; } char* ptr = (char*)dest; switch (_type) { case BencodeTypeInteger: case BencodeTypeByteString: { char* p = ptr; int64_t n; if (_type == BencodeTypeInteger) { *(ptr++) = 'i'; n = _intValue; } else { n = _byteStringSize; } if (n == 0) { *(ptr++) = '0'; } else { if (n < 0) { *(ptr++) = '-'; n *= -1; } int64_t m = 1000000000000000000LL; while (n < m) { m /= 10; } while (m > 0) { *(ptr++) = ('0' + (n / m)); n %= m; m /= 10; } } if (_type == BencodeTypeInteger) { *(ptr++) = 'e'; } else { *(ptr++) = ':'; memcpy(ptr, _byteStringPtr, _byteStringSize); ptr += _byteStringSize; } break; } case BencodeTypeDictionary: { *(ptr++) = 'd'; for (BencodeDictStorage::iterator it = _dictValue->begin(); it != _dictValue->end(); ++it) { // maxlen is passed because we've already ensured that the destination is large enough for everything ptr += ((BencodeObject*)&it->first)->serialize(ptr, maxlen); ptr += ((BencodeObject*)&it->second)->serialize(ptr, maxlen); } *(ptr++) = 'e'; break; } case BencodeTypeList: { *(ptr++) = 'l'; for (BencodeListStorage::iterator it = _listValue->begin(); it != _listValue->end(); ++it) { // maxlen is passed because we've already ensured that the destination is large enough for everything ptr += ((BencodeObject&)*it).serialize(ptr, maxlen); } *(ptr++) = 'e'; break; } default: break; } return req; }
uint32 size() const { return serializedSize(); }