Ejemplo n.º 1
0
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;
  }
}