void BARReader::TransferFile(const BAREntry& file, OutputStream& stream) const { m_Stream.Seek((off_t)file.offset, Stream::FROM_START); const size_t bufSize = 128*1024; // people static char* buffer[bufSize]; size_t bytesLeft = file.filesize; while (bytesLeft) { size_t bytesRead = m_Stream.Read(buffer, std::min(bufSize, bytesLeft)); stream.Write(buffer, bytesRead); bytesLeft -= bytesRead; if (bytesRead == 0) break; } }
void PropertyMapWriter::Write (OutputStream& stream, const common::PropertyMap& properties) { size_t saved_position = stream.Position (); try { bool need_send_layout_id = false; //поиск карты и лэйаута const common::PropertyLayout& layout = properties.Layout (); Impl::LayoutDescPtr layout_desc; Impl::MapDescPtr map_desc; Impl::MapDescMap::iterator map_iter = impl->property_maps.find (properties.Id ()); if (map_iter != impl->property_maps.end ()) { map_desc = map_iter->second; layout_desc = map_desc->layout; if (properties.Hash () == map_desc->hash) return; if (layout_desc->id != layout.Id ()) { layout_desc = Impl::LayoutDescPtr (); Impl::LayoutMap::iterator layout_iter = impl->layouts.find (layout.Id ()); if (layout_iter != impl->layouts.end ()) layout_desc = layout_iter->second; } } else { Impl::LayoutMap::iterator layout_iter = impl->layouts.find (layout.Id ()); if (layout_iter != impl->layouts.end ()) layout_desc = layout_iter->second; } //синхронизация идентификатора карты PropertyMapHeader header = {static_cast<object_id_t> (properties.Id ()), false, false}; if (!layout_desc || layout_desc->hash != layout.Hash ()) { header.has_layout = true; } else //we always send layout id so reader will have possibility to restore layout after exception { header.has_layout_id = true; } stream.BeginCommand (CommandId_UpdatePropertyMap); stream.Write (header); //синхронизация лэйаута if (header.has_layout) { impl->WriteLayout (stream, layout, layout_desc); } if (header.has_layout_id) { write (stream, static_cast<object_id_t> (layout.Id ())); } //создание объекта слежения за картой свойств bool need_add_new_map = !map_desc; if (!map_desc) { map_desc = Impl::MapDescPtr (new Impl::MapDesc, false); map_desc->layout = layout_desc; } //синхронизация буфера карты свойств write (stream, static_cast<uint32> (properties.BufferSize ())); stream.WriteData (properties.BufferData (), properties.BufferSize ()); //синхронизация строк for (IndexArray::iterator iter=layout_desc->string_indices.begin (), end=layout_desc->string_indices.end (); iter!=end; ++iter) write (stream, properties.GetString (*iter)); //обновление полей и карт if (need_add_new_map) { properties.Trackable ().connect_tracker (xtl::bind (&Impl::RemovePropertyMap, impl.get (), properties.Id ()), *impl); impl->property_maps.insert_pair (properties.Id (), map_desc); } if (map_desc->layout != layout_desc) map_desc->layout = layout_desc; //обновление хэша map_desc->hash = properties.Hash (); //закрытие команды stream.EndCommand (); } catch (xtl::exception& e) { stream.SetPosition (saved_position); e.touch ("render::scene::interchange::PropertyMapWriter::Write"); throw; } catch (...) { stream.SetPosition (saved_position); throw; } }