void FileChunk::parseSubChunks() { uint8* ptr = data + 8; // skip self while (ptr < data + size) { u_map_fcc header = *(u_map_fcc*)ptr; if (IsInterestingChunk(header)) { uint32 subsize = *(uint32*)(ptr + 4); if (subsize < size) { std::swap(header.fcc_txt[0], header.fcc_txt[3]); std::swap(header.fcc_txt[1], header.fcc_txt[2]); FileChunk* chunk = new FileChunk(ptr, subsize); chunk->parseSubChunks(); subchunks.insert({ std::string(header.fcc_txt, 4), chunk }); } // move to next chunk ptr += subsize + 8; } else ++ptr; } }
void ChunkedFile::parseChunks() { uint8* ptr = GetData(); // Make sure there's enough data to read u_map_fcc struct and the uint32 size after it while (ptr <= GetData() + GetDataSize() - 8) { u_map_fcc header = *(u_map_fcc*)ptr; if (IsInterestingChunk(header)) { uint32 size = *(uint32*)(ptr + 4); if (size <= data_size) { std::swap(header.fcc_txt[0], header.fcc_txt[3]); std::swap(header.fcc_txt[1], header.fcc_txt[2]); FileChunk* chunk = new FileChunk(ptr, size); chunk->parseSubChunks(); chunks.insert({ std::string(header.fcc_txt, 4), chunk }); } // move to next chunk ptr += size + 8; } else ++ptr; } }
void ChunkedFile::parseChunks() { uint8* ptr = GetData(); while (ptr < GetData() + GetDataSize()) { u_map_fcc header = *(u_map_fcc*)ptr; uint32 size = 0; if (IsInterestingChunk(header)) { size = *(uint32*)(ptr + 4); if (size <= data_size) { std::swap(header.fcc_txt[0], header.fcc_txt[3]); std::swap(header.fcc_txt[1], header.fcc_txt[2]); FileChunk* chunk = new FileChunk{ ptr, size }; chunk->parseSubChunks(); chunks.insert({ std::string(header.fcc_txt, 4), chunk }); } } // move to next chunk ptr += size + 8; } }
int CacheBase::Read(std::string path, char* buf, size_t size, off_t off) { off_t file_size = GetAttr(path).size; if(off >= file_size) { pf_log[W_WARNING] << "Fuse trying to read out of file"; return 0; } FileContent& file = content_list.GetFile(path); /* Limit the read to the size of the file */ size_t to_read = (size_t) ((off + (off_t)size > file_size) ? file_size - off : size); if(!to_read) { pf_log[W_WARNING] << "Fuse trying to read out of file"; return 0; } FileChunkDesc chunk_to_read(off, to_read); FileContent::chunk_availability chunk_state; while((chunk_state = file.HaveChunk(chunk_to_read)) == FileContent::CHUNK_NOT_READY) usleep(100000); /* 0.1 sec */ if(chunk_state == FileContent::CHUNK_UNAVAILABLE) throw FileUnavailable(); FileChunk chunk = file.GetChunk(chunk_to_read); if(!chunk.GetData()) /* shouldn't happen */ { pf_log[W_WARNING] << "FileContent returned an empty chunk??"; return 0; } memcpy(buf, chunk.GetData(), to_read); /* TODO CHECK THIS CONVERSION. FUSE CAN ONLY RETURN AN INTEGER, SO IT IS NEEDED. */ return (int)to_read; }