fixed serialisation/deserialisation of dir content. Fixed exchange of dir data. First working prototype of file list exchange.

This commit is contained in:
mr-alice 2016-08-27 23:56:23 +02:00
parent eca9ca0e4d
commit fc5176a652
4 changed files with 88 additions and 36 deletions

View File

@ -248,6 +248,7 @@ public:
fe.file_hash = hash;
fe.file_size = size;
fe.file_modtime = modf_time;
fe.file_name = fname;
return true;
}
@ -264,6 +265,7 @@ public:
d.most_recent_time = most_recent_time;
d.dir_modtime = dir_modtime;
d.dir_update_time = time(NULL);
d.dir_name = dir_name;
d.subfiles = subfiles_array ;
d.subdirs = subdirs_array ;
@ -287,6 +289,7 @@ public:
((DirEntry*&)node)->dir_parent_path = d.dir_parent_path + "/" + dir_name ;
node->row = i ;
node->parent_index = indx ;
}
for(uint32_t i=0;i<subfiles_array.size();++i)
{
@ -305,9 +308,10 @@ public:
node = new FileEntry("",0,0);
node->row = subdirs_array.size()+i ;
node->parent_index = indx ;
}
// we should also update the row of each subfile and each subdir
return true;
}
bool getDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
@ -531,7 +535,8 @@ private:
}
DirEntry& d(*static_cast<DirEntry*>(mNodes[node]));
std::cerr << indent << "dir:" << d.dir_name << ", modf time: " << d.dir_modtime << ", recurs_last_modf_time: " << d.most_recent_time << ", subdirs: " ;
std::cerr << indent << "dir:" << d.dir_name << ", modf time: " << d.dir_modtime << ", recurs_last_modf_time: " << d.most_recent_time << ", parent: " << d.parent_index << ", row: " << d.row << ", subdirs: " ;
for(int i=0;i<d.subdirs.size();++i)
std::cerr << d.subdirs[i] << " " ;
std::cerr << std::endl;
@ -542,7 +547,7 @@ private:
for(int i=0;i<d.subfiles.size();++i)
{
FileEntry& f(*static_cast<FileEntry*>(mNodes[d.subfiles[i]]));
std::cerr << indent << " hash:" << f.file_hash << " ts:" << (uint64_t)f.file_modtime << " " << f.file_size << " " << f.file_name << std::endl;
std::cerr << indent << " hash:" << f.file_hash << " ts:" << (uint64_t)f.file_modtime << " " << f.file_size << " " << f.file_name << ", parent: " << f.parent_index << ", row: " << f.row << std::endl;
}
}
@ -961,18 +966,18 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
//
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,dir->dir_name )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,dir->most_recent_time)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,dir->dir_modtime )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)dir->most_recent_time)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)dir->dir_modtime )) return false ;
// serialise number of subdirs and number of subfiles
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,dir->subdirs.size() )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,dir->subfiles.size() )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)dir->subdirs.size() )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)dir->subfiles.size() )) return false ;
// serialise subdirs entry indexes
for(uint32_t i=0;i<dir->subdirs.size();++i)
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,dir->subdirs[i] )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)dir->subdirs[i] )) return false ;
// serialise directory subfiles, with info for each of them
@ -990,11 +995,11 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
continue ;
}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,dir->subfiles[i] )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)dir->subfiles[i] )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,file->file_modtime)) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)file->file_modtime)) return false ;
// now write the whole string into a single section in the file
@ -1005,6 +1010,9 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl;
bindata.bin_data = section_data ;
bindata.bin_len = section_offset ;
return true ;
}
@ -1016,12 +1024,12 @@ bool RemoteDirectoryStorage::deserialiseDirEntry(const EntryIndex& indx,const Rs
{
const unsigned char *section_data = (unsigned char*)bindata.bin_data ;
uint32_t section_size = bindata.bin_len ;
uint32_t section_offset ;
uint32_t section_offset=0 ;
std::cerr << "RemoteDirectoryStorage::deserialiseDirEntry(): deserialising directory content for friend " << peerId() << ", and directory " << indx << std::endl;
std::string dir_name ;
time_t most_recent_time ,dir_modtime ;
uint32_t most_recent_time ,dir_modtime ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,dir_name )) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,most_recent_time)) return false ;
@ -1068,7 +1076,7 @@ bool RemoteDirectoryStorage::deserialiseDirEntry(const EntryIndex& indx,const Rs
std::string entry_name ;
uint64_t entry_size ;
RsFileHash entry_hash ;
time_t entry_modtime ;
uint32_t entry_modtime ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,entry_index )) return false ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,entry_name )) return false ;

View File

@ -1,11 +1,28 @@
#include "retroshare/rsids.h"
#include "serialiser/rsbaseserial.h"
#include "filelist_io.h"
template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const uint32_t & val) { return setRawUInt32(buff,size,&offset,val) ; }
template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const size_t & val) { return setRawUInt64(buff,size,&offset,val) ; }
template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const std::string & val) { return setRawString(buff,size,&offset,val) ; }
template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const Sha1CheckSum & val) { return val.serialise(buff,size,offset) ; }
template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,uint32_t & val) { return getRawUInt32(const_cast<uint8_t*>(buff),size,&offset,&val) ; }
template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,size_t & val) { return getRawUInt64(const_cast<uint8_t*>(buff),size,&offset,&val) ; }
template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,std::string & val) { return getRawString(const_cast<uint8_t*>(buff),size,&offset,val) ; }
template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,Sha1CheckSum & val) { return val.deserialise(const_cast<uint8_t*>(buff),size,offset) ; }
template<> uint32_t FileListIO::serial_size(const uint32_t & ) { return 4 ; }
template<> uint32_t FileListIO::serial_size(const size_t & ) { return 8 ; }
template<> uint32_t FileListIO::serial_size(const std::string & val) { return getRawStringSize(val) ; }
template<> uint32_t FileListIO::serial_size(const Sha1CheckSum & ) { return Sha1CheckSum::serial_size(); }
bool FileListIO::writeField( unsigned char*&buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const unsigned char * val,uint32_t size)
{
if(!checkSectionSize(buff,buff_size,offset,size))
return false;
if(!writeSectionHeader(buff,buff_size,offset,FILE_LIST_IO_TAG_BINARY_DATA,size))
if(!writeSectionHeader(buff,buff_size,offset,section_tag,size))
return false;
memcpy(&buff[offset],val,size) ;
@ -16,7 +33,7 @@ bool FileListIO::writeField( unsigned char*&buff,uint32_t& buff_size,uint32
bool FileListIO::readField (const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag, unsigned char *& val,uint32_t& size)
{
if(!readSectionHeader(buff,buff_size,offset,FILE_LIST_IO_TAG_BINARY_DATA,size))
if(!readSectionHeader(buff,buff_size,offset,check_section_tag,size))
return false;
val = (unsigned char *)rs_malloc(size) ;

View File

@ -32,16 +32,15 @@ public:
template<typename T>
static bool writeField(unsigned char *& buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const T& val)
{
if(!checkSectionSize(buff,buff_size,offset,sizeof(T)))
uint32_t s = serial_size(val) ;
if(!checkSectionSize(buff,buff_size,offset,s))
return false;
if(!writeSectionHeader(buff,buff_size,offset,section_tag,sizeof(T)))
if(!writeSectionHeader(buff,buff_size,offset,section_tag,s))
return false;
memcpy(&buff[offset],reinterpret_cast<const uint8_t*>(&val),sizeof(T)) ;
offset += sizeof(T) ;
return true;
return serialise(buff,buff_size,offset,val) ;
}
template<typename T>
@ -52,18 +51,16 @@ public:
if(!readSectionHeader(buff,buff_size,offset,check_section_tag,section_size))
return false;
if(section_size != sizeof(T))
return false ;
memcpy(reinterpret_cast<uint8_t*>(&val),&buff[offset],sizeof(T)) ;
offset += sizeof(T) ;
return true;
return deserialise(buff,buff_size,offset,val);
}
static bool writeField( unsigned char*&buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const unsigned char * val,uint32_t size) ;
static bool readField (const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag, unsigned char *& val,uint32_t& size) ;
template<class T> static bool serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const T& val) ;
template<class T> static bool deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,T& val) ;
template<class T> static uint32_t serial_size(const T& val) ;
private:
static bool write125Size(unsigned char *data,uint32_t total_size,uint32_t& offset,uint32_t size) ;
static bool read125Size (const unsigned char *data,uint32_t total_size,uint32_t& offset,uint32_t& size) ;
@ -73,7 +70,7 @@ private:
if(offset + S + SECTION_HEADER_MAX_SIZE > buff_size)
{
buff = (unsigned char *)realloc(buff,offset + S + SECTION_HEADER_MAX_SIZE) ;
buff_size = offset + S ;
buff_size = offset + S + SECTION_HEADER_MAX_SIZE;
if(!buff)
return false ;

View File

@ -148,8 +148,8 @@ int p3FileDatabase::tick()
mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ;
}
if(mLastRemoteDirSweepTS + 30 < now)
#warning we need to make sure that one req per directory will not cause to keep re-asking the top level dirs.
if(mLastRemoteDirSweepTS + 5 < now)
{
RS_STACK_MUTEX(mFLSMtx) ;
@ -158,7 +158,12 @@ int p3FileDatabase::tick()
for(uint32_t i=0;i<mRemoteDirectories.size();++i)
if(online_peers.find(mRemoteDirectories[i]->peerId()) != online_peers.end())
{
std::cerr << "Launching recurs sweep of friend directory " << mRemoteDirectories[i]->peerId() << ". Content currently is:" << std::endl;
mRemoteDirectories[i]->print();
locked_recursSweepRemoteDirectory(mRemoteDirectories[i],mRemoteDirectories[i]->root()) ;
}
mLastRemoteDirSweepTS = now;
}
@ -780,15 +785,33 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{
P3FILELISTS_DEBUG() << "Handling sync response for directory with index " << item->entry_index << std::endl;
// remove the original request from pending list
{
RS_STACK_MUTEX(mFLSMtx) ;
std::map<DirSyncRequestId,DirSyncRequestData>::iterator it = mPendingSyncRequests.find(item->request_id) ;
if(it == mPendingSyncRequests.end())
{
std::cerr << " request " << std::hex << item->request_id << std::dec << " cannot be found. ERROR!" << std::endl;
return ;
}
mPendingSyncRequests.erase(it) ;
}
// find the correct friend entry
uint32_t fi = 0 ;
P3FILELISTS_DEBUG() << "Handling sync response for directory with index " << item->entry_index << std::endl;
{
RS_STACK_MUTEX(mFLSMtx) ;
fi = locked_getFriendIndex(item->PeerId());
std::cerr << " friend index is " << fi ;
// make sure we have a remote directory for that friend.
if(mRemoteDirectories.size() <= fi)
@ -813,11 +836,18 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{
P3FILELISTS_DEBUG() << " Item contains directory data. Updating." << std::endl;
mRemoteDirectories[fi]->deserialiseDirEntry(item->entry_index,item->directory_content_data) ;
mRemoteDirectories[fi]->setDirUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
if(mRemoteDirectories[fi]->deserialiseDirEntry(item->entry_index,item->directory_content_data))
{
mRemoteDirectories[fi]->setDirUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
#warning should notify the GUI here
// notify the GUI if the hierarchy has changed
// notify the GUI if the hierarchy has changed
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0);
}
else
std::cerr << "(EE) Cannot deserialise dir entry. ERROR. "<< std::endl;
std::cerr << " new content after update: " << std::endl;
mRemoteDirectories[fi]->print();
}
}