void ClusterImpl::read(std::istream& in) { log_debug1("read"); // read first offset, which specifies, how many offsets we need to read size_type offset; in.read(reinterpret_cast<char*>(&offset), sizeof(offset)); if (in.fail()) return; offset = fromLittleEndian(&offset); size_type n = offset / 4; size_type a = offset; log_debug1("first offset is " << offset << " n=" << n << " a=" << a); // read offsets offsets.clear(); data.clear(); offsets.reserve(n); offsets.push_back(0); while (--n) { in.read(reinterpret_cast<char*>(&offset), sizeof(offset)); if (in.fail()) { log_debug1("fail at " << n); return; } offset = fromLittleEndian(&offset); log_debug1("offset=" << offset << '(' << offset-a << ')'); offsets.push_back(offset - a); } // last offset points past the end of the cluster, so we know now, how may bytes to read if (offsets.size() > 1) { n = offsets.back() - offsets.front(); if (n > 0) { data.resize(n); log_debug1("read " << n << " bytes of data"); in.read(&(data[0]), n); } else log_warn("read empty cluster"); } }
void ClusterImpl::write(std::ostream& out) const { size_type a = offsets.size() * sizeof(size_type); for (Offsets::const_iterator it = offsets.begin(); it != offsets.end(); ++it) { size_type o = *it; o += a; o = fromLittleEndian(&o); out.write(reinterpret_cast<const char*>(&o), sizeof(size_type)); } out.write(&(data[0]), data.size()); }
/* This return the number of char read */ offset_type ClusterImpl::read_header(std::istream& in) { log_debug1("read_header"); // read first offset, which specifies, how many offsets we need to read size_type offset; in.read(reinterpret_cast<char*>(&offset), sizeof(offset)); if (in.fail()) { std::cerr << "fail at read offset" << std::endl; throw ZimFileFormatError("fail at read first offset"); } offset = fromLittleEndian(&offset); size_type n = offset / 4; size_type a = offset; log_debug1("first offset is " << offset << " n=" << n << " a=" << a); // read offsets offsets.clear(); offsets.reserve(n); offsets.push_back(0); while (--n) { in.read(reinterpret_cast<char*>(&offset), sizeof(offset)); if (in.fail()) { log_debug("fail at " << n); throw ZimFileFormatError("fail at read offset"); } offset = fromLittleEndian(&offset); log_debug1("offset=" << offset << '(' << offset-a << ')'); offsets.push_back(offset - a); } return a; }