<commit_before>// QT includes
#include <QLayout>
#include <QDebug>
#include <QMap>

// Visomics includes
#include "voPCABarPlot.h"
#include "voDataObject.h"

// VTK includes
#include <QVTKWidget.h>
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContext2D.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkPlot.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkTable.h>
//#include <vtkVariantArray.h> //Needed by splitTable
#include <vtkStringArray.h>
#include <vtkDoubleArray.h>

// --------------------------------------------------------------------------
class voPCABarPlotPrivate
{
public:
  voPCABarPlotPrivate();

  vtkSmartPointer<vtkContextView> ChartView;
  vtkSmartPointer<vtkChartXY>     Chart;
  QVTKWidget*                     Widget;
};

// --------------------------------------------------------------------------
// voPCABarPlotPrivate methods

// --------------------------------------------------------------------------
voPCABarPlotPrivate::voPCABarPlotPrivate()
{
  this->Widget = 0;
}

// --------------------------------------------------------------------------
// voPCABarPlot methods

// --------------------------------------------------------------------------
voPCABarPlot::voPCABarPlot(QWidget * newParent):
    Superclass(newParent), d_ptr(new voPCABarPlotPrivate)
{
	//std::cout<<"we are in the bar plot initialization" <<std::endl;
}

// --------------------------------------------------------------------------
voPCABarPlot::~voPCABarPlot()
{

}

// --------------------------------------------------------------------------
void voPCABarPlot::setupUi(QLayout *layout)
{
  Q_D(voPCABarPlot);

  d->ChartView = vtkSmartPointer<vtkContextView>::New();
  d->Chart = vtkSmartPointer<vtkChartXY>::New();
  d->Widget = new QVTKWidget();
  d->ChartView->SetInteractor(d->Widget->GetInteractor());
  d->Widget->SetRenderWindow(d->ChartView->GetRenderWindow());
  d->ChartView->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
  d->ChartView->GetScene()->AddItem(d->Chart);

  layout->addWidget(d->Widget);
}

// --------------------------------------------------------------------------
void voPCABarPlot::setDataObject(voDataObject *dataObject)
{
  Q_D(voPCABarPlot);
  if (!dataObject)
    {
    qCritical() << "voPCABarPlot - Failed to setDataObject - dataObject is NULL";
    return;
    }

  vtkTable * table = vtkTable::SafeDownCast(dataObject->data());
  if (!table)
    {
    qCritical() << "voPCABarPlot - Failed to setDataObject - vtkTable data is expected !";
    return;
    }

  // Transpose table - this is pretty much unavoidable: vtkPlot expects each dimension
  // to be a column, but the information should be presented to the user with each
  // data point (principle component) in its own column
  vtkSmartPointer<vtkTable> transpose = vtkSmartPointer<vtkTable>::New();
  // Note: dont actually need to keep header, but will for consistancy
  vtkSmartPointer<vtkStringArray> header = vtkSmartPointer<vtkStringArray>::New();
  header->SetName("header");
  header->SetNumberOfTuples(table->GetNumberOfColumns()-1);
  for (vtkIdType c = 1; c < table->GetNumberOfColumns(); ++c)
    {
    header->SetValue(c-1, table->GetColumnName(c));
    }
  transpose->AddColumn(header);
  for (vtkIdType r = 0; r < table->GetNumberOfRows(); ++r)
    {
    vtkSmartPointer<vtkDoubleArray> newcol = vtkSmartPointer<vtkDoubleArray>::New();
    newcol->SetName(table->GetValue(r, 0).ToString().c_str());
    newcol->SetNumberOfTuples(table->GetNumberOfColumns() - 1);
    for (vtkIdType c = 1; c < table->GetNumberOfColumns(); ++c)
      {
      newcol->SetValue(c-1, table->GetValue(r, c).ToDouble());
      }
    transpose->AddColumn(newcol);
    }

  unsigned char colors[10][3] =
    {
      {166, 206, 227}, {31, 120, 180}, {178, 223, 13},
      {51, 160, 44}, {251, 154, 153}, {227, 26, 28},
      {253, 191, 111}, {255, 127, 0}, {202, 178, 214}, {106, 61, 154}
    };
  int i = 0;

  vtkPlot* p = d->Chart->GetPlot(0);
	if (!p)
    {
    p = d->Chart->AddPlot(vtkChart::BAR);
    }

  p->SetInput(transpose, 1,2);
  p->SetColor(colors[i][0], colors[i][1], colors[i][2], 255);
  p->SetWidth(10);

  d->Chart->GetAxis(vtkAxis::BOTTOM)->SetTitle(transpose->GetColumnName(1)); // x
  d->Chart->GetAxis(vtkAxis::LEFT)->SetTitle(transpose->GetColumnName(2)); // y

  d->ChartView->GetRenderWindow()->SetMultiSamples(4);
  d->ChartView->Render();
}
<commit_msg>In pca bar plot, use voUtils::transposeTable with Headers option<commit_after>// Qt includes
#include <QDebug>
#include <QLayout>
#include <QMap>

// Visomics includes
#include "voDataObject.h"
#include "voPCABarPlot.h"
#include "voUtils.h"

// VTK includes
#include <QVTKWidget.h>
#include <vtkAxis.h>
#include <vtkChartXY.h>
#include <vtkContext2D.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkNew.h>
#include <vtkPlot.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkTable.h>
//#include <vtkVariantArray.h> //Needed by splitTable
#include <vtkStringArray.h>
#include <vtkDoubleArray.h>

// --------------------------------------------------------------------------
class voPCABarPlotPrivate
{
public:
  voPCABarPlotPrivate();

  vtkSmartPointer<vtkContextView> ChartView;
  vtkSmartPointer<vtkChartXY>     Chart;
  QVTKWidget*                     Widget;
};

// --------------------------------------------------------------------------
// voPCABarPlotPrivate methods

// --------------------------------------------------------------------------
voPCABarPlotPrivate::voPCABarPlotPrivate()
{
  this->Widget = 0;
}

// --------------------------------------------------------------------------
// voPCABarPlot methods

// --------------------------------------------------------------------------
voPCABarPlot::voPCABarPlot(QWidget * newParent):
    Superclass(newParent), d_ptr(new voPCABarPlotPrivate)
{
	//std::cout<<"we are in the bar plot initialization" <<std::endl;
}

// --------------------------------------------------------------------------
voPCABarPlot::~voPCABarPlot()
{

}

// --------------------------------------------------------------------------
void voPCABarPlot::setupUi(QLayout *layout)
{
  Q_D(voPCABarPlot);

  d->ChartView = vtkSmartPointer<vtkContextView>::New();
  d->Chart = vtkSmartPointer<vtkChartXY>::New();
  d->Widget = new QVTKWidget();
  d->ChartView->SetInteractor(d->Widget->GetInteractor());
  d->Widget->SetRenderWindow(d->ChartView->GetRenderWindow());
  d->ChartView->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
  d->ChartView->GetScene()->AddItem(d->Chart);

  layout->addWidget(d->Widget);
}

// --------------------------------------------------------------------------
void voPCABarPlot::setDataObject(voDataObject *dataObject)
{
  Q_D(voPCABarPlot);
  if (!dataObject)
    {
    qCritical() << "voPCABarPlot - Failed to setDataObject - dataObject is NULL";
    return;
    }

  vtkTable * table = vtkTable::SafeDownCast(dataObject->data());
  if (!table)
    {
    qCritical() << "voPCABarPlot - Failed to setDataObject - vtkTable data is expected !";
    return;
    }

  // Transpose table - this is pretty much unavoidable: vtkPlot expects each dimension
  // to be a column, but the information should be presented to the user with each
  // data point (principle component) in its own column
  vtkNew<vtkTable> transpose;
  voUtils::transposeTable(table, transpose.GetPointer(), voUtils::Headers);

  unsigned char colors[10][3] =
    {
      {166, 206, 227}, {31, 120, 180}, {178, 223, 13},
      {51, 160, 44}, {251, 154, 153}, {227, 26, 28},
      {253, 191, 111}, {255, 127, 0}, {202, 178, 214}, {106, 61, 154}
    };
  int i = 0;

  vtkPlot* p = d->Chart->GetPlot(0);
	if (!p)
    {
    p = d->Chart->AddPlot(vtkChart::BAR);
    }

  p->SetInput(transpose, 1,2);
  p->SetColor(colors[i][0], colors[i][1], colors[i][2], 255);
  p->SetWidth(10);

  d->Chart->GetAxis(vtkAxis::BOTTOM)->SetTitle(transpose->GetColumnName(1)); // x
  d->Chart->GetAxis(vtkAxis::LEFT)->SetTitle(transpose->GetColumnName(2)); // y

  d->ChartView->GetRenderWindow()->SetMultiSamples(4);
  d->ChartView->Render();
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "CEventLog.h"
#include "CWordPerfectFilter.h"
#include "LogMessages.h"
#include <librevenge/librevenge.h>
#include <librevenge-generators/librevenge-generators.h>
#include <librevenge-stream/librevenge-stream.h>
#include <libwpd/libwpd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class CWordPerfectFilter::Private
{
public:
	librevenge::RVNGTextTextGenerator *Generator;
	bool CanParse = true;
	CEventLog EventLog = CEventLog(_T("WordPerfect Indexer"));
	size_t LastOffset = 0;
	CString BodyText;
};

HRESULT CWordPerfectFilter::OnInit()
{
	librevenge::RVNGString BodyTextRVNG;
	if (priv == nullptr) priv = new CWordPerfectFilter::Private;
	if (priv->Generator != nullptr) delete priv->Generator;
	priv->Generator = new librevenge::RVNGTextTextGenerator(BodyTextRVNG);

	priv->EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_BEGIN_IMPORT);

	STATSTG statStg;
	ZeroMemory(&statStg, sizeof(statStg));
	HRESULT hr = m_pStream->Stat(&statStg, STATFLAG_NONAME);
	if (hr != S_OK)
	{
		CString str; str.Format(L"0x%08llX", hr);
		CAtlArray<CString> args; args.Add(str);

		priv->EventLog.ReportEvent(EVENTLOG_ERROR_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_GETISTREAMLENGTH_FAILURE, args);
		return E_UNEXPECTED;
	}

	size_t StreamLength = statStg.cbSize.QuadPart;
	unsigned char *Buffer = (unsigned char *)malloc(StreamLength * sizeof(unsigned char));
	hr = m_pStream->Read(Buffer, StreamLength * sizeof(unsigned char), nullptr);

	librevenge::RVNGStringStream RevengeStream(Buffer, StreamLength * sizeof(unsigned char));
	libwpd::WPDResult wpdError = libwpd::WPDocument::parse(&RevengeStream, priv->Generator, nullptr);

	if (wpdError != libwpd::WPD_OK)
	{
		priv->EventLog.ReportEvent(EVENTLOG_ERROR_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_WPD_DOC_CORRUPT);

		switch (wpdError)
		{
		case libwpd::WPD_FILE_ACCESS_ERROR:
			return STG_E_READFAULT;
		case libwpd::WPD_PARSE_ERROR:
		case libwpd::WPD_OLE_ERROR:
			return STG_E_DOCFILECORRUPT;
		case libwpd::WPD_UNSUPPORTED_ENCRYPTION_ERROR:
			return STG_E_ACCESSDENIED;
		default:
			return E_UNEXPECTED;
		}
	}

	priv->BodyText = CA2W(BodyTextRVNG.cstr(), CP_UTF8);
	priv->LastOffset = 0;
	free(Buffer);

	return S_OK;
}

HRESULT CWordPerfectFilter::GetNextChunkValue(CChunkValue& chunkValue)
{
	constexpr size_t DefaultChunkLength = 10240;
	size_t ChunkLength = DefaultChunkLength;

	CString Chunk = priv->BodyText.Mid(priv->LastOffset);
	bool isLastChunk = false;

	if (Chunk.GetLength() <= ChunkLength)
	{
		ChunkLength = Chunk.GetLength();
		isLastChunk = true;
	}
	else
	{
		Chunk = Chunk.Left(ChunkLength);
		priv->LastOffset += ChunkLength;
	}

	chunkValue.SetTextValue(PKEY_Search_Contents, Chunk, CHUNK_TEXT);

	if (isLastChunk)
	{
		priv->EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_END_IMPORT);
		return FILTER_E_END_OF_CHUNKS;
	}
	else
	{
		return S_OK;
	}
}

HRESULT CWordPerfectFilter::FinalConstruct()
{
	this->priv = nullptr;
	return S_OK;
}

void CWordPerfectFilter::FinalRelease()
{
	if (priv != nullptr)
	{
		if (priv->Generator != nullptr) delete priv->Generator;
		delete priv;
	}
}
<commit_msg>Set the PKEY_Document_CharacterCount property as well<commit_after>#include "stdafx.h"
#include "CEventLog.h"
#include "CWordPerfectFilter.h"
#include "LogMessages.h"
#include <librevenge/librevenge.h>
#include <librevenge-generators/librevenge-generators.h>
#include <librevenge-stream/librevenge-stream.h>
#include <libwpd/libwpd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class CWordPerfectFilter::Private
{
public:
	librevenge::RVNGTextTextGenerator *Generator;
	bool CanParse = true;
	CEventLog EventLog = CEventLog(_T("WordPerfect Indexer"));
	size_t LastOffset = 0;
	CString BodyText;
	bool SentCharacterCount;
};

HRESULT CWordPerfectFilter::OnInit()
{
	librevenge::RVNGString BodyTextRVNG;
	if (priv == nullptr) priv = new CWordPerfectFilter::Private;
	if (priv->Generator != nullptr) delete priv->Generator;
	priv->Generator = new librevenge::RVNGTextTextGenerator(BodyTextRVNG);

	priv->EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_BEGIN_IMPORT);

	STATSTG statStg;
	ZeroMemory(&statStg, sizeof(statStg));
	HRESULT hr = m_pStream->Stat(&statStg, STATFLAG_NONAME);
	if (hr != S_OK)
	{
		CString str; str.Format(L"0x%08llX", hr);
		CAtlArray<CString> args; args.Add(str);

		priv->EventLog.ReportEvent(EVENTLOG_ERROR_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_GETISTREAMLENGTH_FAILURE, args);
		return E_UNEXPECTED;
	}

	size_t StreamLength = statStg.cbSize.QuadPart;
	unsigned char *Buffer = (unsigned char *)malloc(StreamLength * sizeof(unsigned char));
	hr = m_pStream->Read(Buffer, StreamLength * sizeof(unsigned char), nullptr);

	librevenge::RVNGStringStream RevengeStream(Buffer, StreamLength * sizeof(unsigned char));
	libwpd::WPDResult wpdError = libwpd::WPDocument::parse(&RevengeStream, priv->Generator, nullptr);

	if (wpdError != libwpd::WPD_OK)
	{
		priv->EventLog.ReportEvent(EVENTLOG_ERROR_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_WPD_DOC_CORRUPT);

		switch (wpdError)
		{
		case libwpd::WPD_FILE_ACCESS_ERROR:
			return STG_E_READFAULT;
		case libwpd::WPD_PARSE_ERROR:
		case libwpd::WPD_OLE_ERROR:
			return STG_E_DOCFILECORRUPT;
		case libwpd::WPD_UNSUPPORTED_ENCRYPTION_ERROR:
			return STG_E_ACCESSDENIED;
		default:
			return E_UNEXPECTED;
		}
	}

	priv->BodyText = CA2W(BodyTextRVNG.cstr(), CP_UTF8);
	priv->SentCharacterCount = false;
	priv->LastOffset = 0;
	free(Buffer);

	return S_OK;
}

HRESULT CWordPerfectFilter::GetNextChunkValue(CChunkValue& chunkValue)
{
	if (!priv->SentCharacterCount)
	{
		chunkValue.SetIntValue(PKEY_Document_CharacterCount, priv->BodyText.GetLength());
		priv->SentCharacterCount = true;
		return S_OK;
	}

	constexpr size_t DefaultChunkLength = 10240;
	size_t ChunkLength = DefaultChunkLength;

	CString Chunk = priv->BodyText.Mid(priv->LastOffset);
	bool isLastChunk = false;

	if (Chunk.GetLength() <= ChunkLength)
	{
		ChunkLength = Chunk.GetLength();
		isLastChunk = true;
	}
	else
	{
		Chunk = Chunk.Left(ChunkLength);
		priv->LastOffset += ChunkLength;
	}

	chunkValue.SetTextValue(PKEY_Search_Contents, Chunk, CHUNK_TEXT);

	if (isLastChunk)
	{
		priv->EventLog.ReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT_EXTRACTION_CATEGORY, MSG_END_IMPORT);
		return FILTER_E_END_OF_CHUNKS;
	}
	else
	{
		return S_OK;
	}
}

HRESULT CWordPerfectFilter::FinalConstruct()
{
	this->priv = nullptr;
	return S_OK;
}

void CWordPerfectFilter::FinalRelease()
{
	if (priv != nullptr)
	{
		if (priv->Generator != nullptr) delete priv->Generator;
		delete priv;
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/user_script_slave.h"

#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/histogram.h"
#include "base/logging.h"
#include "base/perftimer.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/renderer/extension_groups.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"

#include "grit/renderer_resources.h"

using WebKit::WebFrame;
using WebKit::WebString;

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";

// Sets up the chrome.extension module. This may be run multiple times per
// context, but the init method deletes itself after the first time.
static const char kInitExtension[] =
  "if (chrome.initExtension) chrome.initExtension('%s', true);";

int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) {
  typedef std::map<std::string, int> IsolatedWorldMap;

  static IsolatedWorldMap g_isolated_world_ids;
  static int g_next_isolated_world_id = 1;

  IsolatedWorldMap::iterator iter = g_isolated_world_ids.find(extension_id);
  if (iter != g_isolated_world_ids.end())
    return iter->second;

  int new_id = g_next_isolated_world_id;
  ++g_next_isolated_world_id;

  // This map will tend to pile up over time, but realistically, you're never
  // going to have enough extensions for it to matter.
  g_isolated_world_ids[extension_id] = new_id;
  return new_id;
}

UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      script_deleter_(&scripts_) {
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);
}

void UserScriptSlave::GetActiveExtensions(std::set<std::string>* extension_ids) {
  for (size_t i = 0; i < scripts_.size(); ++i) {
    DCHECK(!scripts_[i]->extension_id().empty());
    extension_ids->insert(scripts_[i]->extension_id());
  }
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory,
                                    bool only_inject_incognito) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  scripts_.reserve(num_scripts);
  for (size_t i = 0; i < num_scripts; ++i) {
    scripts_.push_back(new UserScript());
    UserScript* script = scripts_.back();
    script->Unpickle(pickle, &iter);

    if (only_inject_incognito && !script->is_incognito_enabled()) {
      // This script shouldn't run in an incognito tab.
      delete script;
      scripts_.pop_back();
      continue;
    }

    // Note that this is a pointer into shared memory. We don't own it. It gets
    // cleared up when the last renderer or browser process drops their
    // reference to the shared memory.
    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->js_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->css_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
  }

  return true;
}

// static
void UserScriptSlave::InsertInitExtensionCode(
    std::vector<WebScriptSource>* sources, const std::string& extension_id) {
  DCHECK(sources);
  sources->insert(sources->begin(),
                  WebScriptSource(WebString::fromUTF8(
                  StringPrintf(kInitExtension, extension_id.c_str()))));
}

bool UserScriptSlave::InjectScripts(WebFrame* frame,
                                    UserScript::RunLocation location) {
  GURL frame_url = GURL(frame->url());
  // Don't bother if this is not a URL we inject script into.
  if (!URLPattern::IsValidScheme(frame_url.scheme()))
    return true;

  // Don't inject user scripts into the gallery itself.  This prevents
  // a user script from removing the "report abuse" link, for example.
  if (frame_url.host() == GURL(extension_urls::kGalleryBrowsePrefix).host())
    return true;

  PerfTimer timer;
  int num_css = 0;
  int num_scripts = 0;

  for (size_t i = 0; i < scripts_.size(); ++i) {
    std::vector<WebScriptSource> sources;
    UserScript* script = scripts_[i];

    if (frame->parent() && !script->match_all_frames())
      continue;  // Only match subframes if the script declared it wanted to.

    if (!script->MatchesUrl(frame->url()))
      continue;  // This frame doesn't match the script url pattern, skip it.

    // CSS files are always injected on document start before js scripts.
    if (location == UserScript::DOCUMENT_START) {
      num_css += script->css_scripts().size();
      for (size_t j = 0; j < script->css_scripts().size(); ++j) {
        PerfTimer insert_timer;
        UserScript::File& file = script->css_scripts()[j];
        frame->insertStyleText(
            WebString::fromUTF8(file.GetContent().as_string()), WebString());
        UMA_HISTOGRAM_TIMES("Extensions.InjectCssTime", insert_timer.Elapsed());
      }
    }
    if (script->run_location() == location) {
      num_scripts += script->js_scripts().size();
      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
        UserScript::File &file = script->js_scripts()[j];
        std::string content = file.GetContent().as_string();

        // We add this dumb function wrapper for standalone user script to
        // emulate what Greasemonkey does.
        if (script->is_standalone() || script->emulate_greasemonkey()) {
          content.insert(0, kUserScriptHead);
          content += kUserScriptTail;
        }
        sources.push_back(
            WebScriptSource(WebString::fromUTF8(content), file.url()));
      }
    }

    if (!sources.empty()) {
      int isolated_world_id = 0;

      // Emulate Greasemonkey API for scripts that were converted to extensions
      // and "standalone" user scripts.
      if (script->is_standalone() || script->emulate_greasemonkey()) {
        sources.insert(sources.begin(),
            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
      }

      // Setup chrome.self to contain an Extension object with the correct
      // ID.
      if (!script->extension_id().empty()) {
        InsertInitExtensionCode(&sources, script->extension_id());
        isolated_world_id = GetIsolatedWorldId(script->extension_id());
      }

      PerfTimer exec_timer;
      frame->executeScriptInIsolatedWorld(
          isolated_world_id, &sources.front(), sources.size(),
          EXTENSION_GROUP_CONTENT_SCRIPTS);
      UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed());
    }
  }

  // Log debug info.
  if (location == UserScript::DOCUMENT_START) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount", num_css);
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount", num_scripts);
    if (num_css || num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time", timer.Elapsed());
  } else if (location == UserScript::DOCUMENT_END) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", num_scripts);
    if (num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", timer.Elapsed());
  } else if (location == UserScript::DOCUMENT_IDLE) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectIdle_ScriptCount", num_scripts);
    if (num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed());
  } else {
    NOTREACHED();
  }

  LOG(INFO) << "Injected " << num_scripts << " scripts and " << num_css <<
      "css files into " << frame->url().spec().data();
  return true;
}
<commit_msg>Fix a CHECK when opening an incognito tab with user scripts installed.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/user_script_slave.h"

#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/histogram.h"
#include "base/logging.h"
#include "base/perftimer.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/renderer/extension_groups.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"

#include "grit/renderer_resources.h"

using WebKit::WebFrame;
using WebKit::WebString;

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";

// Sets up the chrome.extension module. This may be run multiple times per
// context, but the init method deletes itself after the first time.
static const char kInitExtension[] =
  "if (chrome.initExtension) chrome.initExtension('%s', true);";

int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) {
  typedef std::map<std::string, int> IsolatedWorldMap;

  static IsolatedWorldMap g_isolated_world_ids;
  static int g_next_isolated_world_id = 1;

  IsolatedWorldMap::iterator iter = g_isolated_world_ids.find(extension_id);
  if (iter != g_isolated_world_ids.end())
    return iter->second;

  int new_id = g_next_isolated_world_id;
  ++g_next_isolated_world_id;

  // This map will tend to pile up over time, but realistically, you're never
  // going to have enough extensions for it to matter.
  g_isolated_world_ids[extension_id] = new_id;
  return new_id;
}

UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      script_deleter_(&scripts_) {
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);
}

void UserScriptSlave::GetActiveExtensions(std::set<std::string>* extension_ids) {
  for (size_t i = 0; i < scripts_.size(); ++i) {
    DCHECK(!scripts_[i]->extension_id().empty());
    extension_ids->insert(scripts_[i]->extension_id());
  }
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory,
                                    bool only_inject_incognito) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  scripts_.reserve(num_scripts);
  for (size_t i = 0; i < num_scripts; ++i) {
    scripts_.push_back(new UserScript());
    UserScript* script = scripts_.back();
    script->Unpickle(pickle, &iter);

    // Note that this is a pointer into shared memory. We don't own it. It gets
    // cleared up when the last renderer or browser process drops their
    // reference to the shared memory.
    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->js_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->css_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }

    if (only_inject_incognito && !script->is_incognito_enabled()) {
      // This script shouldn't run in an incognito tab.
      delete script;
      scripts_.pop_back();
    }
  }

  return true;
}

// static
void UserScriptSlave::InsertInitExtensionCode(
    std::vector<WebScriptSource>* sources, const std::string& extension_id) {
  DCHECK(sources);
  sources->insert(sources->begin(),
                  WebScriptSource(WebString::fromUTF8(
                  StringPrintf(kInitExtension, extension_id.c_str()))));
}

bool UserScriptSlave::InjectScripts(WebFrame* frame,
                                    UserScript::RunLocation location) {
  GURL frame_url = GURL(frame->url());
  // Don't bother if this is not a URL we inject script into.
  if (!URLPattern::IsValidScheme(frame_url.scheme()))
    return true;

  // Don't inject user scripts into the gallery itself.  This prevents
  // a user script from removing the "report abuse" link, for example.
  if (frame_url.host() == GURL(extension_urls::kGalleryBrowsePrefix).host())
    return true;

  PerfTimer timer;
  int num_css = 0;
  int num_scripts = 0;

  for (size_t i = 0; i < scripts_.size(); ++i) {
    std::vector<WebScriptSource> sources;
    UserScript* script = scripts_[i];

    if (frame->parent() && !script->match_all_frames())
      continue;  // Only match subframes if the script declared it wanted to.

    if (!script->MatchesUrl(frame->url()))
      continue;  // This frame doesn't match the script url pattern, skip it.

    // CSS files are always injected on document start before js scripts.
    if (location == UserScript::DOCUMENT_START) {
      num_css += script->css_scripts().size();
      for (size_t j = 0; j < script->css_scripts().size(); ++j) {
        PerfTimer insert_timer;
        UserScript::File& file = script->css_scripts()[j];
        frame->insertStyleText(
            WebString::fromUTF8(file.GetContent().as_string()), WebString());
        UMA_HISTOGRAM_TIMES("Extensions.InjectCssTime", insert_timer.Elapsed());
      }
    }
    if (script->run_location() == location) {
      num_scripts += script->js_scripts().size();
      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
        UserScript::File &file = script->js_scripts()[j];
        std::string content = file.GetContent().as_string();

        // We add this dumb function wrapper for standalone user script to
        // emulate what Greasemonkey does.
        if (script->is_standalone() || script->emulate_greasemonkey()) {
          content.insert(0, kUserScriptHead);
          content += kUserScriptTail;
        }
        sources.push_back(
            WebScriptSource(WebString::fromUTF8(content), file.url()));
      }
    }

    if (!sources.empty()) {
      int isolated_world_id = 0;

      // Emulate Greasemonkey API for scripts that were converted to extensions
      // and "standalone" user scripts.
      if (script->is_standalone() || script->emulate_greasemonkey()) {
        sources.insert(sources.begin(),
            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
      }

      // Setup chrome.self to contain an Extension object with the correct
      // ID.
      if (!script->extension_id().empty()) {
        InsertInitExtensionCode(&sources, script->extension_id());
        isolated_world_id = GetIsolatedWorldId(script->extension_id());
      }

      PerfTimer exec_timer;
      frame->executeScriptInIsolatedWorld(
          isolated_world_id, &sources.front(), sources.size(),
          EXTENSION_GROUP_CONTENT_SCRIPTS);
      UMA_HISTOGRAM_TIMES("Extensions.InjectScriptTime", exec_timer.Elapsed());
    }
  }

  // Log debug info.
  if (location == UserScript::DOCUMENT_START) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount", num_css);
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount", num_scripts);
    if (num_css || num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time", timer.Elapsed());
  } else if (location == UserScript::DOCUMENT_END) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", num_scripts);
    if (num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", timer.Elapsed());
  } else if (location == UserScript::DOCUMENT_IDLE) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectIdle_ScriptCount", num_scripts);
    if (num_scripts)
      UMA_HISTOGRAM_TIMES("Extensions.InjectIdle_Time", timer.Elapsed());
  } else {
    NOTREACHED();
  }

  LOG(INFO) << "Injected " << num_scripts << " scripts and " << num_css <<
      "css files into " << frame->url().spec().data();
  return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/user_script_slave.h"

#include "app/resource_bundle.h"
#include "base/histogram.h"
#include "base/logging.h"
#include "base/perftimer.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "chrome/renderer/extension_groups.h"
#include "googleurl/src/gurl.h"
#include "webkit/api/public/WebFrame.h"

#include "grit/renderer_resources.h"

using WebKit::WebFrame;
using WebKit::WebString;

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";

// Creates a convenient reference to a content script's parent extension.
// TODO(mpcomplete): self.onConnect is deprecated.  Remove it at 1.0.
// http://code.google.com/p/chromium/issues/detail?id=16356
static const char kInitExtension[] =
    "chrome.extension = new chrome.Extension('%s');"
    "chrome.self.onConnect = chrome.extension.onConnect;";

UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      script_deleter_(&scripts_),
      user_script_start_line_(0) {
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);

  // Count the number of lines that will be injected before the user script.
  base::StringPiece::size_type pos = 0;
  while ((pos = api_js_.find('\n', pos)) != base::StringPiece::npos) {
    user_script_start_line_++;
    pos++;
  }

  // NOTE: There is actually one extra line in the injected script because the
  // function header includes a newline as well. But WebKit expects the
  // numbering to be one-based, not zero-based, so actually *not* accounting for
  // this extra line ends us up with the right offset.
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  scripts_.reserve(num_scripts);
  for (size_t i = 0; i < num_scripts; ++i) {
    scripts_.push_back(new UserScript());
    UserScript* script = scripts_.back();
    script->Unpickle(pickle, &iter);

    // Note that this is a pointer into shared memory. We don't own it. It gets
    // cleared up when the last renderer or browser process drops their
    // reference to the shared memory.
    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->js_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->css_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
  }

  return true;
}

// static
void UserScriptSlave::InsertInitExtensionCode(
    std::vector<WebScriptSource>* sources, const std::string& extension_id) {
  DCHECK(sources);
  sources->insert(sources->begin(),
                  WebScriptSource(WebString::fromUTF8(
                  StringPrintf(kInitExtension, extension_id.c_str()))));
}

bool UserScriptSlave::InjectScripts(WebFrame* frame,
                                    UserScript::RunLocation location) {
  // Don't bother if this is not a URL we inject script into.
  if (!URLPattern::IsValidScheme(GURL(frame->url()).scheme()))
    return true;

  PerfTimer timer;
  int num_matched = 0;

  for (size_t i = 0; i < scripts_.size(); ++i) {
    std::vector<WebScriptSource> sources;
    UserScript* script = scripts_[i];
    if (!script->MatchesUrl(frame->url()))
      continue;  // This frame doesn't match the script url pattern, skip it.

    ++num_matched;
    // CSS files are always injected on document start before js scripts.
    if (location == UserScript::DOCUMENT_START) {
      for (size_t j = 0; j < script->css_scripts().size(); ++j) {
        UserScript::File& file = script->css_scripts()[j];
        frame->insertStyleText(
            WebString::fromUTF8(file.GetContent().as_string()), WebString());
      }
    }
    if (script->run_location() == location) {
      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
        UserScript::File &file = script->js_scripts()[j];
        std::string content = file.GetContent().as_string();

        // We add this dumb function wrapper for standalone user script to
        // emulate what Greasemonkey does.
        if (script->is_standalone()) {
          content.insert(0, kUserScriptHead);
          content += kUserScriptTail;
        }
        sources.push_back(
            WebScriptSource(WebString::fromUTF8(content), file.url()));
      }
    }

    if (!sources.empty()) {
      if (script->is_standalone()) {
        // For standalone scripts, we try to emulate the Greasemonkey API.
        sources.insert(sources.begin(),
            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
      } else {
        // Setup chrome.self to contain an Extension object with the correct
        // ID.
        InsertInitExtensionCode(&sources, script->extension_id());
      }

      frame->executeScriptInNewWorld(&sources.front(), sources.size(),
                                     EXTENSION_GROUP_CONTENT_SCRIPTS);
    }
  }

  // Log debug info.
  if (location == UserScript::DOCUMENT_START) {
    HISTOGRAM_COUNTS_100("UserScripts:DocStart:Count", num_matched);
    HISTOGRAM_TIMES("UserScripts:DocStart:Time", timer.Elapsed());
  } else {
    HISTOGRAM_COUNTS_100("UserScripts:DocEnd:Count", num_matched);
    HISTOGRAM_TIMES("UserScripts:DocEnd:Time", timer.Elapsed());
  }

  LOG(INFO) << "Injected " << num_matched << " user scripts into " <<
      frame->url().spec().data();
  return true;
}
<commit_msg>Turn extension script injection histograms into uma histograms.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/user_script_slave.h"

#include "app/resource_bundle.h"
#include "base/histogram.h"
#include "base/logging.h"
#include "base/perftimer.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "base/string_util.h"
#include "chrome/renderer/extension_groups.h"
#include "googleurl/src/gurl.h"
#include "webkit/api/public/WebFrame.h"

#include "grit/renderer_resources.h"

using WebKit::WebFrame;
using WebKit::WebString;

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";

// Creates a convenient reference to a content script's parent extension.
// TODO(mpcomplete): self.onConnect is deprecated.  Remove it at 1.0.
// http://code.google.com/p/chromium/issues/detail?id=16356
static const char kInitExtension[] =
    "chrome.extension = new chrome.Extension('%s');"
    "chrome.self.onConnect = chrome.extension.onConnect;";

UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      script_deleter_(&scripts_),
      user_script_start_line_(0) {
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);

  // Count the number of lines that will be injected before the user script.
  base::StringPiece::size_type pos = 0;
  while ((pos = api_js_.find('\n', pos)) != base::StringPiece::npos) {
    user_script_start_line_++;
    pos++;
  }

  // NOTE: There is actually one extra line in the injected script because the
  // function header includes a newline as well. But WebKit expects the
  // numbering to be one-based, not zero-based, so actually *not* accounting for
  // this extra line ends us up with the right offset.
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  scripts_.reserve(num_scripts);
  for (size_t i = 0; i < num_scripts; ++i) {
    scripts_.push_back(new UserScript());
    UserScript* script = scripts_.back();
    script->Unpickle(pickle, &iter);

    // Note that this is a pointer into shared memory. We don't own it. It gets
    // cleared up when the last renderer or browser process drops their
    // reference to the shared memory.
    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->js_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
      const char* body = NULL;
      int body_length = 0;
      CHECK(pickle.ReadData(&iter, &body, &body_length));
      script->css_scripts()[j].set_external_content(
          base::StringPiece(body, body_length));
    }
  }

  return true;
}

// static
void UserScriptSlave::InsertInitExtensionCode(
    std::vector<WebScriptSource>* sources, const std::string& extension_id) {
  DCHECK(sources);
  sources->insert(sources->begin(),
                  WebScriptSource(WebString::fromUTF8(
                  StringPrintf(kInitExtension, extension_id.c_str()))));
}

bool UserScriptSlave::InjectScripts(WebFrame* frame,
                                    UserScript::RunLocation location) {
  // Don't bother if this is not a URL we inject script into.
  if (!URLPattern::IsValidScheme(GURL(frame->url()).scheme()))
    return true;

  PerfTimer timer;
  int num_css = 0;
  int num_scripts = 0;

  for (size_t i = 0; i < scripts_.size(); ++i) {
    std::vector<WebScriptSource> sources;
    UserScript* script = scripts_[i];
    if (!script->MatchesUrl(frame->url()))
      continue;  // This frame doesn't match the script url pattern, skip it.

    // CSS files are always injected on document start before js scripts.
    if (location == UserScript::DOCUMENT_START) {
      num_css += script->css_scripts().size();
      for (size_t j = 0; j < script->css_scripts().size(); ++j) {
        UserScript::File& file = script->css_scripts()[j];
        frame->insertStyleText(
            WebString::fromUTF8(file.GetContent().as_string()), WebString());
      }
    }
    if (script->run_location() == location) {
      num_scripts += script->js_scripts().size();
      for (size_t j = 0; j < script->js_scripts().size(); ++j) {
        UserScript::File &file = script->js_scripts()[j];
        std::string content = file.GetContent().as_string();

        // We add this dumb function wrapper for standalone user script to
        // emulate what Greasemonkey does.
        if (script->is_standalone()) {
          content.insert(0, kUserScriptHead);
          content += kUserScriptTail;
        }
        sources.push_back(
            WebScriptSource(WebString::fromUTF8(content), file.url()));
      }
    }

    if (!sources.empty()) {
      if (script->is_standalone()) {
        // For standalone scripts, we try to emulate the Greasemonkey API.
        sources.insert(sources.begin(),
            WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
      } else {
        // Setup chrome.self to contain an Extension object with the correct
        // ID.
        InsertInitExtensionCode(&sources, script->extension_id());
      }

      frame->executeScriptInNewWorld(&sources.front(), sources.size(),
                                     EXTENSION_GROUP_CONTENT_SCRIPTS);
    }
  }

  // Log debug info.
  if (location == UserScript::DOCUMENT_START) {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_CssCount", num_css);
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectStart_ScriptCount", num_scripts);
    UMA_HISTOGRAM_TIMES("Extensions.InjectStart_Time", timer.Elapsed());
  } else {
    UMA_HISTOGRAM_COUNTS_100("Extensions.InjectEnd_ScriptCount", num_scripts);
    UMA_HISTOGRAM_TIMES("Extensions.InjectEnd_Time", timer.Elapsed());
  }

  LOG(INFO) << "Injected " << num_scripts << " scripts and " << num_css <<
      "css files into " << frame->url().spec().data();
  return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/service/service_ipc_server.h"

#include "chrome/common/service_messages.h"
#include "chrome/service/cloud_print/cloud_print_proxy.h"
#include "chrome/service/service_process.h"
#include "ipc/ipc_logging.h"

ServiceIPCServer::ServiceIPCServer(const IPC::ChannelHandle& channel_handle)
    : channel_handle_(channel_handle), client_connected_(false) {
}

bool ServiceIPCServer::Init() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::GetInstance()->SetIPCSender(this);
#endif
  sync_message_filter_ =
      new IPC::SyncMessageFilter(g_service_process->shutdown_event());
  CreateChannel();
  return true;
}

void ServiceIPCServer::CreateChannel() {
  channel_.reset(NULL); // Tear down the existing channel, if any.
  channel_.reset(new IPC::SyncChannel(channel_handle_,
      IPC::Channel::MODE_NAMED_SERVER, this,
      g_service_process->io_thread()->message_loop(), true,
      g_service_process->shutdown_event()));
  DCHECK(sync_message_filter_.get());
  channel_->AddFilter(sync_message_filter_.get());
}

ServiceIPCServer::~ServiceIPCServer() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::GetInstance()->SetIPCSender(NULL);
#endif

  channel_->RemoveFilter(sync_message_filter_.get());

  // The ChannelProxy object caches a pointer to the IPC thread, so need to
  // reset it as it's not guaranteed to outlive this object.
  // NOTE: this also has the side-effect of not closing the main IPC channel to
  // the browser process.  This is needed because this is the signal that the
  // browser uses to know that this process has died, so we need it to be alive
  // until this process is shut down, and the OS closes the handle
  // automatically.  We used to watch the object handle on Windows to do this,
  // but it wasn't possible to do so on POSIX.
  channel_->ClearIPCMessageLoop();
}

void ServiceIPCServer::OnChannelConnected(int32 peer_pid) {
  DCHECK(!client_connected_);
  client_connected_ = true;
}

void ServiceIPCServer::OnChannelError() {
  // When a client (typically a browser process) disconnects, the pipe is
  // closed and we get an OnChannelError. Since we want to keep servicing
  // client requests, we will recreate the channel.
  bool client_was_connected = client_connected_;
  client_connected_ = false;
  // TODO(sanjeevr): Instead of invoking the service process for such handlers,
  // define a Client interface that the ServiceProcess can implement.
  if (client_was_connected) {
    if (g_service_process->HandleClientDisconnect()) {
#if defined(OS_WIN)
      // On Windows, once an error on a named pipe occurs, the named pipe is no
      // longer valid and must be re-created. This is not the case on Mac or
      // Linux.
      CreateChannel();
#endif
    }
  } else {
    // If the client was never even connected we had an error connecting.
    if (!client_connected_) {
      LOG(ERROR) << "Unable to open service ipc channel "
                 << "named: " << channel_handle_.name;
    }
  }
}

bool ServiceIPCServer::Send(IPC::Message* msg) {
  if (!channel_.get()) {
    delete msg;
    return false;
  }

  return channel_->Send(msg);
}

bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxy,
                        OnEnableCloudPrintProxy)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxyWithTokens,
                        OnEnableCloudPrintProxyWithTokens)
    IPC_MESSAGE_HANDLER(ServiceMsg_DisableCloudPrintProxy,
                        OnDisableCloudPrintProxy)
    IPC_MESSAGE_HANDLER(ServiceMsg_IsCloudPrintProxyEnabled,
                        OnIsCloudPrintProxyEnabled)
#if defined(ENABLE_REMOTING)
    IPC_MESSAGE_HANDLER(ServiceMsg_SetRemotingHostCredentials,
                        OnSetRemotingHostCredentials)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableRemotingHost,
                        OnEnableRemotingHost)
    IPC_MESSAGE_HANDLER(ServiceMsg_DisableRemotingHost,
                        OnDisableRemotingHost)
    IPC_MESSAGE_HANDLER(ServiceMsg_GetRemotingHostInfo,
                        OnGetRemotingHostInfo)
#endif  // defined(ENABLE_REMOTING)
    IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown);
    IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ServiceIPCServer::OnEnableCloudPrintProxy(const std::string& lsid) {
  g_service_process->GetCloudPrintProxy()->EnableForUser(lsid);
}

void ServiceIPCServer::OnEnableCloudPrintProxyWithTokens(
    const std::string& cloud_print_token, const std::string& talk_token) {
  // TODO(sanjeevr): Implement this.
  NOTIMPLEMENTED();
}

void ServiceIPCServer::OnIsCloudPrintProxyEnabled() {
  std::string email;
  bool is_enabled = g_service_process->GetCloudPrintProxy()->IsEnabled(&email);
  channel_->Send(new ServiceHostMsg_CloudPrintProxy_IsEnabled(is_enabled,
                                                              email));
}

#if defined(ENABLE_REMOTING)
void ServiceIPCServer::OnSetRemotingHostCredentials(
    const std::string& login,
    const std::string& auth_token) {
  g_service_process->remoting_host_manager()->SetCredentials(
      login, auth_token);
}

void ServiceIPCServer::OnEnableRemotingHost() {
  g_service_process->remoting_host_manager()->Enable();
  SendRemotingHostInfo();
}

void ServiceIPCServer::OnDisableRemotingHost() {
  g_service_process->remoting_host_manager()->Disable();
  SendRemotingHostInfo();
}

void ServiceIPCServer::OnGetRemotingHostInfo() {
  SendRemotingHostInfo();
}

void ServiceIPCServer::SendRemotingHostInfo() {
  remoting::ChromotingHostInfo host_info;
  g_service_process->remoting_host_manager()->GetHostInfo(&host_info);
  channel_->Send(new ServiceHostMsg_RemotingHost_HostInfo(host_info));
}
#endif  // defined(ENABLE_REMOTING)

void ServiceIPCServer::OnDisableCloudPrintProxy() {
  g_service_process->GetCloudPrintProxy()->DisableForUser();
}

void ServiceIPCServer::OnShutdown() {
  g_service_process->Shutdown();
}

void ServiceIPCServer::OnUpdateAvailable() {
  g_service_process->SetUpdateAvailable();
}
<commit_msg>Mac/Linux proxy fix.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/service/service_ipc_server.h"

#include "chrome/common/service_messages.h"
#include "chrome/service/cloud_print/cloud_print_proxy.h"
#include "chrome/service/service_process.h"
#include "ipc/ipc_logging.h"

ServiceIPCServer::ServiceIPCServer(const IPC::ChannelHandle& channel_handle)
    : channel_handle_(channel_handle), client_connected_(false) {
}

bool ServiceIPCServer::Init() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::GetInstance()->SetIPCSender(this);
#endif
  sync_message_filter_ =
      new IPC::SyncMessageFilter(g_service_process->shutdown_event());
  CreateChannel();
  return true;
}

void ServiceIPCServer::CreateChannel() {
  channel_.reset(NULL); // Tear down the existing channel, if any.
  channel_.reset(new IPC::SyncChannel(channel_handle_,
      IPC::Channel::MODE_NAMED_SERVER, this,
      g_service_process->io_thread()->message_loop(), true,
      g_service_process->shutdown_event()));
  DCHECK(sync_message_filter_.get());
  channel_->AddFilter(sync_message_filter_.get());
}

ServiceIPCServer::~ServiceIPCServer() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  IPC::Logging::GetInstance()->SetIPCSender(NULL);
#endif

  channel_->RemoveFilter(sync_message_filter_.get());

  // The ChannelProxy object caches a pointer to the IPC thread, so need to
  // reset it as it's not guaranteed to outlive this object.
  // NOTE: this also has the side-effect of not closing the main IPC channel to
  // the browser process.  This is needed because this is the signal that the
  // browser uses to know that this process has died, so we need it to be alive
  // until this process is shut down, and the OS closes the handle
  // automatically.  We used to watch the object handle on Windows to do this,
  // but it wasn't possible to do so on POSIX.
  channel_->ClearIPCMessageLoop();
}

void ServiceIPCServer::OnChannelConnected(int32 peer_pid) {
  DCHECK(!client_connected_);
  client_connected_ = true;
}

void ServiceIPCServer::OnChannelError() {
  // When a client (typically a browser process) disconnects, the pipe is
  // closed and we get an OnChannelError. Since we want to keep servicing
  // client requests, we will recreate the channel.
  bool client_was_connected = client_connected_;
  client_connected_ = false;
  // TODO(sanjeevr): Instead of invoking the service process for such handlers,
  // define a Client interface that the ServiceProcess can implement.
  if (client_was_connected) {
    if (g_service_process->HandleClientDisconnect()) {
#if defined(OS_WIN)
      // On Windows, once an error on a named pipe occurs, the named pipe is no
      // longer valid and must be re-created. This is not the case on Mac or
      // Linux.
      CreateChannel();
#endif
    }
  } else {
    // If the client was never even connected we had an error connecting.
    if (!client_connected_) {
      LOG(ERROR) << "Unable to open service ipc channel "
                 << "named: " << channel_handle_.name;
    }
  }
}

bool ServiceIPCServer::Send(IPC::Message* msg) {
  if (!channel_.get()) {
    delete msg;
    return false;
  }

  return channel_->Send(msg);
}

bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  // When we get a message, always mark the client as connected. The
  // ChannelProxy::Context is only letting OnChannelConnected get called once,
  // so on the Mac and Linux, we never would set client_connected_ to true
  // again on subsequent connections.
  client_connected_ = true;
  IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxy,
                        OnEnableCloudPrintProxy)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxyWithTokens,
                        OnEnableCloudPrintProxyWithTokens)
    IPC_MESSAGE_HANDLER(ServiceMsg_DisableCloudPrintProxy,
                        OnDisableCloudPrintProxy)
    IPC_MESSAGE_HANDLER(ServiceMsg_IsCloudPrintProxyEnabled,
                        OnIsCloudPrintProxyEnabled)
#if defined(ENABLE_REMOTING)
    IPC_MESSAGE_HANDLER(ServiceMsg_SetRemotingHostCredentials,
                        OnSetRemotingHostCredentials)
    IPC_MESSAGE_HANDLER(ServiceMsg_EnableRemotingHost,
                        OnEnableRemotingHost)
    IPC_MESSAGE_HANDLER(ServiceMsg_DisableRemotingHost,
                        OnDisableRemotingHost)
    IPC_MESSAGE_HANDLER(ServiceMsg_GetRemotingHostInfo,
                        OnGetRemotingHostInfo)
#endif  // defined(ENABLE_REMOTING)
    IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown);
    IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable);
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ServiceIPCServer::OnEnableCloudPrintProxy(const std::string& lsid) {
  g_service_process->GetCloudPrintProxy()->EnableForUser(lsid);
}

void ServiceIPCServer::OnEnableCloudPrintProxyWithTokens(
    const std::string& cloud_print_token, const std::string& talk_token) {
  // TODO(sanjeevr): Implement this.
  NOTIMPLEMENTED();
}

void ServiceIPCServer::OnIsCloudPrintProxyEnabled() {
  std::string email;
  bool is_enabled = g_service_process->GetCloudPrintProxy()->IsEnabled(&email);
  channel_->Send(new ServiceHostMsg_CloudPrintProxy_IsEnabled(is_enabled,
                                                              email));
}

#if defined(ENABLE_REMOTING)
void ServiceIPCServer::OnSetRemotingHostCredentials(
    const std::string& login,
    const std::string& auth_token) {
  g_service_process->remoting_host_manager()->SetCredentials(
      login, auth_token);
}

void ServiceIPCServer::OnEnableRemotingHost() {
  g_service_process->remoting_host_manager()->Enable();
  SendRemotingHostInfo();
}

void ServiceIPCServer::OnDisableRemotingHost() {
  g_service_process->remoting_host_manager()->Disable();
  SendRemotingHostInfo();
}

void ServiceIPCServer::OnGetRemotingHostInfo() {
  SendRemotingHostInfo();
}

void ServiceIPCServer::SendRemotingHostInfo() {
  remoting::ChromotingHostInfo host_info;
  g_service_process->remoting_host_manager()->GetHostInfo(&host_info);
  channel_->Send(new ServiceHostMsg_RemotingHost_HostInfo(host_info));
}
#endif  // defined(ENABLE_REMOTING)

void ServiceIPCServer::OnDisableCloudPrintProxy() {
  g_service_process->GetCloudPrintProxy()->DisableForUser();
}

void ServiceIPCServer::OnShutdown() {
  g_service_process->Shutdown();
}

void ServiceIPCServer::OnUpdateAvailable() {
  g_service_process->SetUpdateAvailable();
}
<|endoftext|>


<commit_before>/*
 * avs2wav.cpp
 *  extract audio data as RIFF WAV format, from avs file
 *  Copyright (C) 2010 janus_wel<janus.wel.3@gmail.com>
 *  see LICENSE for redistributing, modifying, and so on.
 * */

#include "../avsutil.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <memory>
#include <string>
#include <stdexcept>

using namespace std;
using namespace avsutil;

// global object
// pout is abbr of progress out
// this stream is used in progress_cl()
ostream pout(cout.rdbuf());

// forward declarations
// typical one
void usage(ostream& out);
// callback function for IAudio::write()
void progress_cl(const unsigned __int64, const unsigned __int64);
// output audio informations
ostream& operator <<(ostream&, const AudioInfo&);

int main(const int argc, const char* argv[]) {
    if (argc < 2) {
        usage(cerr);
        cerr << "Specify <inputfile>." << endl;
        exit(1);
    }

    string avsfile(argv[1]);
    string wavfile(argv[1]);
    wavfile.append(".wav");

    const unsigned int header_width = 14;
    cout << left
         << setw(header_width) << "source:"      << avsfile << endl
         << setw(header_width) << "destination:" << wavfile << endl;

    try {
        auto_ptr<IAvs> avs(CreateAvsObj(avsfile.c_str()));
        auto_ptr<IAudio> audio(avs->audio());
        AudioInfo ai = audio->info();

        if (!ai.exists) {
            cerr << "no audio in the file: " << avsfile << endl;
            exit(1);
        }

        cout << ai;

        pout << right << fixed << setprecision(2);
        audio->progress_callback(progress_cl);
        ofstream fout(wavfile.c_str(), ios::binary | ios::trunc);
        fout << audio.get();

        cout << endl
             << "done." << endl;
    }
    catch (exception& ex) {
        cerr << endl << ex.what() << endl;
        exit(1);
    }

    return 0;
}

// definitions of functions
void usage(ostream& out) {
    out << "Usage: avs2wav <inputfile>" << endl;
}

void progress_cl(const unsigned __int64 processed, const unsigned __int64 max) {
    float percentage = (static_cast<float>(processed) / static_cast<float>(max)) * 100;
    pout << "\rprocessing... "
         << setw(10) << processed << "/" << max << " samples"
         << " (" << setw(6) << percentage << "%)";
}

ostream& operator <<(ostream& out, const AudioInfo& ai) {
    // constants
    static const unsigned int header_width = 18;

    // preparations
    string channels;
    switch (ai.channels) {
        case 1: channels = "mono";   break;
        case 2: channels = "stereo"; break;
        case 6: channels = "5.1ch";  break;
        default:
            stringstream ss;
            ss << dec << ai.channels;
            channels.assign(ss.str()).append("ch");
            break;
    }
    float sampling_rate = static_cast<float>(ai.sampling_rate) / 1000;

    // instantiate new ostream object and set streambuf of "out" to it
    // in order to save the formattings of "out"
    ostream o(out.rdbuf());
    o << left << setfill('.')
      << endl
      << setw(header_width) << "bit depth "     << ' ' << ai.bit_depth << "bit" << endl
      << setw(header_width) << "channels "      << ' ' << channels << endl
      << setw(header_width) << "sampling rate " << ' ' << sampling_rate << "kHz" << endl
      << setw(header_width) << "samples "       << ' ' << ai.samples << endl
      << endl;

    return out;
}
<commit_msg>Considering when redirected or connected without stdout<commit_after>/*
 * avs2wav.cpp
 *  extract audio data as RIFF WAV format, from avs file
 *  Copyright (C) 2010 janus_wel<janus.wel.3@gmail.com>
 *  see LICENSE for redistributing, modifying, and so on.
 * */

#include "../avsutil.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <memory>
#include <string>
#include <stdexcept>

#ifdef WIN32
#include <io.h>
#include <fcntl.h>
#else
#include <unistd.h>
#endif

using namespace std;
using namespace avsutil;

// global object
// progresss is abbr of "progress stream"
// this stream is used in progress_cl()
// streambuf is stdout fow now
ostream progresss(cout.rdbuf());

// forward declarations
// typical one
void usage(ostream& out);
// return true if redirected to file or connected to pipe
bool is_connected(void);
// set stdout to binary mode
void set_stdout_binary(void);
// callback function for IAudio::write()
void progress_cl(const unsigned __int64, const unsigned __int64);
// output audio informations
ostream& operator <<(ostream&, const AudioInfo&);

int main(const int argc, const char* argv[]) {
    // constants
    static const unsigned int header_width = 14;

    // check arguments
    if (argc < 2) {
        usage(cerr);
        cerr << "Specify <inputfile>." << endl;
        exit(1);
    }

    // input file
    string inputfile(argv[1]);

    try {
        auto_ptr<IAvs> avs(CreateAvsObj(inputfile.c_str()));
        auto_ptr<IAudio> audio(avs->audio());
        AudioInfo ai = audio->info();

        if (!ai.exists) {
            cerr << "no audio in the file: " << inputfile << endl;
            exit(1);
        }

        // preparations
        string outputfile;
        // output and information stream (to stdout for now)
        ostream outputs(cout.rdbuf());
        ostream infos(cout.rdbuf());
        // settings for stream
        progresss << right << fixed << setprecision(2);
        infos << left;
        // this is true if redirected to file or connected to pipe
        bool is_stdout = !is_connected();
        // settings for infos, outputs and progresss
        if (is_stdout) {
            // output to file
            outputfile.assign(argv[1]).append(".wav");
            // create filebuf and set it output stream
            filebuf* fbuf = new filebuf;
            fbuf->open(outputfile.c_str(), ios::out | ios::binary | ios::trunc);
            outputs.rdbuf(fbuf);
        }
        else {
            // redirected or connected pipe
            // output to stdout
            outputfile.assign("stdout");
            progresss.rdbuf(cerr.rdbuf());
            infos.rdbuf(cerr.rdbuf());
            set_stdout_binary();
        }

        infos
            << setw(header_width) << "source:"      << inputfile << endl
            << setw(header_width) << "destination:" << outputfile << endl
            << ai;

        audio->progress_callback(progress_cl);
        outputs << audio.get();

        infos
            << endl
            << "done." << endl
            << endl;
    }
    catch (exception& ex) {
        cerr << endl << ex.what() << endl;
        exit(1);
    }

    return 0;
}

// definitions of functions
void usage(ostream& out) {
    out << "Usage: avs2wav <inputfile> [| othercommands]" << endl;
}

bool is_connected(void) {
#ifdef WIN32
    return !_isatty(_fileno(stdout));
#else
    return !isatty(fileno(stdout));
#endif
}

void set_stdout_binary(void) {
#ifdef WIN32
    _setmode(_fileno(stdout), _O_BINARY);
#endif
}

void progress_cl(const unsigned __int64 processed, const unsigned __int64 max) {
    float percentage = (static_cast<float>(processed) / static_cast<float>(max)) * 100;
    progresss
        << "\rprocessing... "
        << setw(10) << processed << "/" << max << " samples"
        << " (" << setw(6) << percentage << "%)";
}

ostream& operator <<(ostream& out, const AudioInfo& ai) {
    // constants
    static const unsigned int header_width = 18;

    // preparations
    string channels;
    switch (ai.channels) {
        case 1: channels = "mono";   break;
        case 2: channels = "stereo"; break;
        case 6: channels = "5.1ch";  break;
        default:
            stringstream ss;
            ss << dec << ai.channels;
            channels.assign(ss.str()).append("ch");
            break;
    }
    float sampling_rate = static_cast<float>(ai.sampling_rate) / 1000;

    // instantiate new ostream object and set streambuf of "out" to it
    // in order to save the formattings of "out"
    ostream o(out.rdbuf());
    o << left << setfill('.')
        << endl
        << setw(header_width) << "bit depth "     << ' ' << ai.bit_depth << "bit" << endl
        << setw(header_width) << "channels "      << ' ' << channels << endl
        << setw(header_width) << "sampling rate " << ' ' << sampling_rate << "kHz" << endl
        << setw(header_width) << "samples "       << ' ' << ai.samples << endl
        << endl;

    return out;
}
<|endoftext|>


<commit_before>/*
* X509_DN
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/x509_dn.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/parsing.h>
#include <botan/internal/stl_util.h>
#include <botan/oids.h>

namespace Botan {

/*
* Create an empty X509_DN
*/
X509_DN::X509_DN()
   {
   }

/*
* Create an X509_DN
*/
X509_DN::X509_DN(const std::multimap<OID, std::string>& args)
   {
   std::multimap<OID, std::string>::const_iterator j;
   for(j = args.begin(); j != args.end(); ++j)
      add_attribute(j->first, j->second);
   }

/*
* Create an X509_DN
*/
X509_DN::X509_DN(const std::multimap<std::string, std::string>& args)
   {
   std::multimap<std::string, std::string>::const_iterator j;
   for(j = args.begin(); j != args.end(); ++j)
      add_attribute(OIDS::lookup(j->first), j->second);
   }

/*
* Add an attribute to a X509_DN
*/
void X509_DN::add_attribute(const std::string& type,
                            const std::string& str)
   {
   OID oid = OIDS::lookup(type);
   add_attribute(oid, str);
   }

/*
* Add an attribute to a X509_DN
*/
void X509_DN::add_attribute(const OID& oid, const std::string& str)
   {
   if(str == "")
      return;

   typedef std::multimap<OID, ASN1_String>::iterator rdn_iter;

   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);
   for(rdn_iter j = range.first; j != range.second; ++j)
      if(j->second.value() == str)
         return;

   multimap_insert(dn_info, oid, ASN1_String(str));
   dn_bits.clear();
   }

/*
* Get the attributes of this X509_DN
*/
std::multimap<OID, std::string> X509_DN::get_attributes() const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   std::multimap<OID, std::string> retval;
   for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
      multimap_insert(retval, j->first, j->second.value());
   return retval;
   }

/*
* Get the contents of this X.500 Name
*/
std::multimap<std::string, std::string> X509_DN::contents() const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   std::multimap<std::string, std::string> retval;
   for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
      multimap_insert(retval, OIDS::lookup(j->first), j->second.value());
   return retval;
   }

/*
* Get a single attribute type
*/
std::vector<std::string> X509_DN::get_attribute(const std::string& attr) const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   const OID oid = OIDS::lookup(deref_info_field(attr));
   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);

   std::vector<std::string> values;
   for(rdn_iter j = range.first; j != range.second; ++j)
      values.push_back(j->second.value());
   return values;
   }

/*
* Return the BER encoded data, if any
*/
MemoryVector<byte> X509_DN::get_bits() const
   {
   return dn_bits;
   }

/*
* Deref aliases in a subject/issuer info request
*/
std::string X509_DN::deref_info_field(const std::string& info)
   {
   if(info == "Name" || info == "CommonName") return "X520.CommonName";
   if(info == "SerialNumber")                 return "X520.SerialNumber";
   if(info == "Country")                      return "X520.Country";
   if(info == "Organization")                 return "X520.Organization";
   if(info == "Organizational Unit" || info == "OrgUnit")
      return "X520.OrganizationalUnit";
   if(info == "Locality")                     return "X520.Locality";
   if(info == "State" || info == "Province")  return "X520.State";
   if(info == "Email")                        return "RFC822";
   return info;
   }

/*
* Compare two X509_DNs for equality
*/
bool operator==(const X509_DN& dn1, const X509_DN& dn2)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   std::multimap<OID, std::string> attr1 = dn1.get_attributes();
   std::multimap<OID, std::string> attr2 = dn2.get_attributes();

   if(attr1.size() != attr2.size()) return false;

   rdn_iter p1 = attr1.begin();
   rdn_iter p2 = attr2.begin();

   while(true)
      {
      if(p1 == attr1.end() && p2 == attr2.end())
         break;
      if(p1 == attr1.end())      return false;
      if(p2 == attr2.end())      return false;
      if(p1->first != p2->first) return false;
      if(!x500_name_cmp(p1->second, p2->second))
         return false;
      ++p1;
      ++p2;
      }
   return true;
   }

/*
* Compare two X509_DNs for inequality
*/
bool operator!=(const X509_DN& dn1, const X509_DN& dn2)
   {
   return !(dn1 == dn2);
   }

/*
* Compare two X509_DNs
*/
bool operator<(const X509_DN& dn1, const X509_DN& dn2)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   std::multimap<OID, std::string> attr1 = dn1.get_attributes();
   std::multimap<OID, std::string> attr2 = dn2.get_attributes();

   if(attr1.size() < attr2.size()) return true;
   if(attr1.size() > attr2.size()) return false;

   for(rdn_iter p1 = attr1.begin(); p1 != attr1.end(); ++p1)
      {
      std::multimap<OID, std::string>::const_iterator p2;
      p2 = attr2.find(p1->first);
      if(p2 == attr2.end())       return false;
      if(p1->second > p2->second) return false;
      if(p1->second < p2->second) return true;
      }
   return false;
   }

namespace {

/*
* DER encode a RelativeDistinguishedName
*/
void do_ava(DER_Encoder& encoder,
            const std::multimap<OID, std::string>& dn_info,
            ASN1_Tag string_type, const std::string& oid_str,
            bool must_exist = false)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   const OID oid = OIDS::lookup(oid_str);
   const bool exists = (dn_info.find(oid) != dn_info.end());

   if(!exists && must_exist)
      throw Encoding_Error("X509_DN: No entry for " + oid_str);
   if(!exists) return;

   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);

   for(rdn_iter j = range.first; j != range.second; ++j)
      {
      encoder.start_cons(SET)
         .start_cons(SEQUENCE)
            .encode(oid)
            .encode(ASN1_String(j->second, string_type))
         .end_cons()
      .end_cons();
      }
   }

}

/*
* DER encode a DistinguishedName
*/
void X509_DN::encode_into(DER_Encoder& der) const
   {
   std::multimap<OID, std::string> dn_info = get_attributes();

   der.start_cons(SEQUENCE);

   if(!dn_bits.empty())
      der.raw_bytes(dn_bits);
   else
      {
      do_ava(der, dn_info, PRINTABLE_STRING, "X520.Country");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.State");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.Locality");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.Organization");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.OrganizationalUnit");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.CommonName");
      do_ava(der, dn_info, PRINTABLE_STRING, "X520.SerialNumber");
      }

   der.end_cons();
   }

/*
* Decode a BER encoded DistinguishedName
*/
void X509_DN::decode_from(BER_Decoder& source)
   {
   MemoryVector<byte> bits;

   source.start_cons(SEQUENCE)
      .raw_bytes(bits)
   .end_cons();

   BER_Decoder sequence(bits);

   while(sequence.more_items())
      {
      BER_Decoder rdn = sequence.start_cons(SET);

      while(rdn.more_items())
         {
         OID oid;
         ASN1_String str;

         rdn.start_cons(SEQUENCE)
            .decode(oid)
            .decode(str)
            .verify_end()
        .end_cons();

         add_attribute(oid, str.value());
         }
      }

   dn_info = bits;
   }

}
<commit_msg>Fix compile<commit_after>/*
* X509_DN
* (C) 1999-2007 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/x509_dn.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/parsing.h>
#include <botan/internal/stl_util.h>
#include <botan/oids.h>

namespace Botan {

/*
* Create an empty X509_DN
*/
X509_DN::X509_DN()
   {
   }

/*
* Create an X509_DN
*/
X509_DN::X509_DN(const std::multimap<OID, std::string>& args)
   {
   std::multimap<OID, std::string>::const_iterator j;
   for(j = args.begin(); j != args.end(); ++j)
      add_attribute(j->first, j->second);
   }

/*
* Create an X509_DN
*/
X509_DN::X509_DN(const std::multimap<std::string, std::string>& args)
   {
   std::multimap<std::string, std::string>::const_iterator j;
   for(j = args.begin(); j != args.end(); ++j)
      add_attribute(OIDS::lookup(j->first), j->second);
   }

/*
* Add an attribute to a X509_DN
*/
void X509_DN::add_attribute(const std::string& type,
                            const std::string& str)
   {
   OID oid = OIDS::lookup(type);
   add_attribute(oid, str);
   }

/*
* Add an attribute to a X509_DN
*/
void X509_DN::add_attribute(const OID& oid, const std::string& str)
   {
   if(str == "")
      return;

   typedef std::multimap<OID, ASN1_String>::iterator rdn_iter;

   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);
   for(rdn_iter j = range.first; j != range.second; ++j)
      if(j->second.value() == str)
         return;

   multimap_insert(dn_info, oid, ASN1_String(str));
   dn_bits.clear();
   }

/*
* Get the attributes of this X509_DN
*/
std::multimap<OID, std::string> X509_DN::get_attributes() const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   std::multimap<OID, std::string> retval;
   for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
      multimap_insert(retval, j->first, j->second.value());
   return retval;
   }

/*
* Get the contents of this X.500 Name
*/
std::multimap<std::string, std::string> X509_DN::contents() const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   std::multimap<std::string, std::string> retval;
   for(rdn_iter j = dn_info.begin(); j != dn_info.end(); ++j)
      multimap_insert(retval, OIDS::lookup(j->first), j->second.value());
   return retval;
   }

/*
* Get a single attribute type
*/
std::vector<std::string> X509_DN::get_attribute(const std::string& attr) const
   {
   typedef std::multimap<OID, ASN1_String>::const_iterator rdn_iter;

   const OID oid = OIDS::lookup(deref_info_field(attr));
   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);

   std::vector<std::string> values;
   for(rdn_iter j = range.first; j != range.second; ++j)
      values.push_back(j->second.value());
   return values;
   }

/*
* Return the BER encoded data, if any
*/
MemoryVector<byte> X509_DN::get_bits() const
   {
   return dn_bits;
   }

/*
* Deref aliases in a subject/issuer info request
*/
std::string X509_DN::deref_info_field(const std::string& info)
   {
   if(info == "Name" || info == "CommonName") return "X520.CommonName";
   if(info == "SerialNumber")                 return "X520.SerialNumber";
   if(info == "Country")                      return "X520.Country";
   if(info == "Organization")                 return "X520.Organization";
   if(info == "Organizational Unit" || info == "OrgUnit")
      return "X520.OrganizationalUnit";
   if(info == "Locality")                     return "X520.Locality";
   if(info == "State" || info == "Province")  return "X520.State";
   if(info == "Email")                        return "RFC822";
   return info;
   }

/*
* Compare two X509_DNs for equality
*/
bool operator==(const X509_DN& dn1, const X509_DN& dn2)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   std::multimap<OID, std::string> attr1 = dn1.get_attributes();
   std::multimap<OID, std::string> attr2 = dn2.get_attributes();

   if(attr1.size() != attr2.size()) return false;

   rdn_iter p1 = attr1.begin();
   rdn_iter p2 = attr2.begin();

   while(true)
      {
      if(p1 == attr1.end() && p2 == attr2.end())
         break;
      if(p1 == attr1.end())      return false;
      if(p2 == attr2.end())      return false;
      if(p1->first != p2->first) return false;
      if(!x500_name_cmp(p1->second, p2->second))
         return false;
      ++p1;
      ++p2;
      }
   return true;
   }

/*
* Compare two X509_DNs for inequality
*/
bool operator!=(const X509_DN& dn1, const X509_DN& dn2)
   {
   return !(dn1 == dn2);
   }

/*
* Compare two X509_DNs
*/
bool operator<(const X509_DN& dn1, const X509_DN& dn2)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   std::multimap<OID, std::string> attr1 = dn1.get_attributes();
   std::multimap<OID, std::string> attr2 = dn2.get_attributes();

   if(attr1.size() < attr2.size()) return true;
   if(attr1.size() > attr2.size()) return false;

   for(rdn_iter p1 = attr1.begin(); p1 != attr1.end(); ++p1)
      {
      std::multimap<OID, std::string>::const_iterator p2;
      p2 = attr2.find(p1->first);
      if(p2 == attr2.end())       return false;
      if(p1->second > p2->second) return false;
      if(p1->second < p2->second) return true;
      }
   return false;
   }

namespace {

/*
* DER encode a RelativeDistinguishedName
*/
void do_ava(DER_Encoder& encoder,
            const std::multimap<OID, std::string>& dn_info,
            ASN1_Tag string_type, const std::string& oid_str,
            bool must_exist = false)
   {
   typedef std::multimap<OID, std::string>::const_iterator rdn_iter;

   const OID oid = OIDS::lookup(oid_str);
   const bool exists = (dn_info.find(oid) != dn_info.end());

   if(!exists && must_exist)
      throw Encoding_Error("X509_DN: No entry for " + oid_str);
   if(!exists) return;

   std::pair<rdn_iter, rdn_iter> range = dn_info.equal_range(oid);

   for(rdn_iter j = range.first; j != range.second; ++j)
      {
      encoder.start_cons(SET)
         .start_cons(SEQUENCE)
            .encode(oid)
            .encode(ASN1_String(j->second, string_type))
         .end_cons()
      .end_cons();
      }
   }

}

/*
* DER encode a DistinguishedName
*/
void X509_DN::encode_into(DER_Encoder& der) const
   {
   std::multimap<OID, std::string> dn_info = get_attributes();

   der.start_cons(SEQUENCE);

   if(!dn_bits.empty())
      der.raw_bytes(dn_bits);
   else
      {
      do_ava(der, dn_info, PRINTABLE_STRING, "X520.Country");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.State");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.Locality");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.Organization");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.OrganizationalUnit");
      do_ava(der, dn_info, DIRECTORY_STRING, "X520.CommonName");
      do_ava(der, dn_info, PRINTABLE_STRING, "X520.SerialNumber");
      }

   der.end_cons();
   }

/*
* Decode a BER encoded DistinguishedName
*/
void X509_DN::decode_from(BER_Decoder& source)
   {
   MemoryVector<byte> bits;

   source.start_cons(SEQUENCE)
      .raw_bytes(bits)
   .end_cons();

   BER_Decoder sequence(bits);

   while(sequence.more_items())
      {
      BER_Decoder rdn = sequence.start_cons(SET);

      while(rdn.more_items())
         {
         OID oid;
         ASN1_String str;

         rdn.start_cons(SEQUENCE)
            .decode(oid)
            .decode(str)
            .verify_end()
        .end_cons();

         add_attribute(oid, str.value());
         }
      }

   dn_bits = bits;
   }

}
<|endoftext|>


<commit_before>#include <iostream>
#include <getopt.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <signal.h>
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>

#include "Fasta.h"

#include "LeftAlign.h"

#ifdef VERBOSE_DEBUG
#define DEBUG(msg) \
    if (debug) { cerr << msg; }
#else
#define DEBUG(msg)
#endif

using namespace std;

void printUsage(char** argv) {
    cerr << "usage: [BAM data stream] | " << argv[0] << " [options]" << endl
         << endl
         << "Left-aligns and merges the insertions and deletions in all alignments in stdin." << endl
         << "Iterates until each alignment is stable through a left-realignment step." << endl
         << endl
         << "arguments:" << endl
         << "      -f --fasta-reference FILE   FASTA reference file to use for realignment (required)" << endl
         << "      -d --debug             Print debugging information about realignment process" << endl
         << "      -s --suppress-output   Don't write BAM output stream (for debugging)" << endl
         << "      -m --max-iterations N  Iterate the left-realignment no more than this many times" << endl
         << "      -c --compressed        Write compressed BAM on stdout, default is uncompressed" << endl;
}

int main(int argc, char** argv) {

    int c;

    FastaReference reference;
    bool has_ref = false;
    bool suppress_output = false;
    bool debug = false;
    bool isuncompressed = true;

    int maxiterations = 50;

    if (argc < 2) {
        printUsage(argv);
        exit(1);
    }

    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"debug", no_argument, 0, 'd'},
            {"fasta-reference", required_argument, 0, 'f'},
            {"max-iterations", required_argument, 0, 'm'},
            {"suppress-output", no_argument, 0, 's'},
            {"compressed", no_argument, 0, 'c'},
            {0, 0, 0, 0}
        };

        int option_index = 0;

        c = getopt_long (argc, argv, "hdcsf:m:",
                         long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;

        switch (c) {

            case 'f':
                reference.open(optarg); // will exit on open failure
                has_ref = true;
                break;

            case 'm':
                maxiterations = atoi(optarg);
                break;

            case 'd':
                debug = true;
                break;

            case 's':
                suppress_output = true;
                break;

            case 'c':
                isuncompressed = false;
                break;

            case 'h':
                printUsage(argv);
                exit(0);
                break;

            case '?':
                printUsage(argv);
                exit(1);
                break;

              default:
                abort();
                break;
        }
    }

    if (!has_ref) {
        cerr << "no FASTA reference provided, cannot realign" << endl;
        exit(1);
    }

    BAMSINGLEREADER reader;
    if (!reader.Open(STDIN)) {
        cerr << "could not open stdin for reading" << endl;
        exit(1);
    }

#ifdef HAVE_BAMTOOLS

    BamWriter writer;

    if (isuncompressed) {
        writer.SetCompressionMode(BamWriter::Uncompressed);
    }

    if (!suppress_output && !writer.Open("stdout", reader.GetHeaderText(), reader.GetReferenceData())) {
        cerr << "could not open stdout for writing" << endl;
        exit(1);
    }
#else

    SeqLib::BamWriter writer(isuncompressed ? SeqLib::SAM : SeqLib::BAM);
    SeqLib::BamHeader hdr = reader.Header();
    if (hdr.isEmpty()) {
      cerr << "could not open header for input" << endl;
      exit(1);
    }
    writer.SetHeader(hdr);

    if (!suppress_output && !writer.Open("-")) {
        cerr << "could not open stdout for writing" << endl;
        exit(1);
    }
#endif

    // store the names of all the reference sequences in the BAM file
    map<int, string> referenceIDToName;
    REFVEC referenceSequences = reader.GETREFDATA;
    int i = 0;
    for (REFVEC::iterator r = referenceSequences.begin(); r != referenceSequences.end(); ++r) {
        referenceIDToName[i] = r->REFNAME;
        ++i;
    }

    BAMALIGN alignment;

    while (GETNEXT(reader, alignment)) {

            DEBUG("---------------------------   read    --------------------------" << endl);
            DEBUG("| " << referenceIDToName[alignment.REFID] << ":" << alignment.POSITION << endl);
            DEBUG("| " << alignment.QNAME << ":" << alignment.ENDPOSITION << endl);
            DEBUG("| " << alignment.QNAME << ":" << (alignment.ISMAPPED ? " mapped" : " unmapped") << endl);
            DEBUG("| " << alignment.QNAME << ":" << " cigar data size: " << alignment.GETCIGAR.size() << endl);
            DEBUG("--------------------------- realigned --------------------------" << endl);

            // skip unmapped alignments, as they cannot be left-realigned without CIGAR data
            if (alignment.ISMAPPED) {

                int endpos = alignment.ENDPOSITION;
                int length = endpos - alignment.POSITION + 1;
                if (alignment.POSITION >= 0 && length > 0) {
                    if (!stablyLeftAlign(alignment,
                                reference.getSubSequence(
                                    referenceIDToName[alignment.REFID],
                                    alignment.POSITION,
                                    length),
                                maxiterations, debug)) {
                        cerr << "unstable realignment of " << alignment.QNAME
                             << " at " << referenceIDToName[alignment.REFID] << ":" << alignment.POSITION << endl
                             << alignment.QUERYBASES << endl;
                    }
                }

            }

            DEBUG("----------------------------------------------------------------" << endl);
            DEBUG(endl);

        if (!suppress_output)
	  WRITEALIGNMENT(writer, alignment);

    }

    reader.Close();
    if (!suppress_output)
        writer.Close();

    return 0;
}
<commit_msg>Fixed issue #346 regarding missing BAM header in bamleftalign<commit_after>#include <iostream>
#include <getopt.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <signal.h>
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>

#include "Fasta.h"

#include "LeftAlign.h"

#ifdef VERBOSE_DEBUG
#define DEBUG(msg) \
    if (debug) { cerr << msg; }
#else
#define DEBUG(msg)
#endif

using namespace std;

void printUsage(char** argv) {
    cerr << "usage: [BAM data stream] | " << argv[0] << " [options]" << endl
         << endl
         << "Left-aligns and merges the insertions and deletions in all alignments in stdin." << endl
         << "Iterates until each alignment is stable through a left-realignment step." << endl
         << endl
         << "arguments:" << endl
         << "      -f --fasta-reference FILE   FASTA reference file to use for realignment (required)" << endl
         << "      -d --debug             Print debugging information about realignment process" << endl
         << "      -s --suppress-output   Don't write BAM output stream (for debugging)" << endl
         << "      -m --max-iterations N  Iterate the left-realignment no more than this many times" << endl
         << "      -c --compressed        Write compressed BAM on stdout, default is uncompressed" << endl;
}

int main(int argc, char** argv) {

    int c;

    FastaReference reference;
    bool has_ref = false;
    bool suppress_output = false;
    bool debug = false;
    bool isuncompressed = true;

    int maxiterations = 50;

    if (argc < 2) {
        printUsage(argv);
        exit(1);
    }

    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"debug", no_argument, 0, 'd'},
            {"fasta-reference", required_argument, 0, 'f'},
            {"max-iterations", required_argument, 0, 'm'},
            {"suppress-output", no_argument, 0, 's'},
            {"compressed", no_argument, 0, 'c'},
            {0, 0, 0, 0}
        };

        int option_index = 0;

        c = getopt_long (argc, argv, "hdcsf:m:",
                         long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;

        switch (c) {

            case 'f':
                reference.open(optarg); // will exit on open failure
                has_ref = true;
                break;

            case 'm':
                maxiterations = atoi(optarg);
                break;

            case 'd':
                debug = true;
                break;

            case 's':
                suppress_output = true;
                break;

            case 'c':
                isuncompressed = false;
                break;

            case 'h':
                printUsage(argv);
                exit(0);
                break;

            case '?':
                printUsage(argv);
                exit(1);
                break;

              default:
                abort();
                break;
        }
    }

    if (!has_ref) {
        cerr << "no FASTA reference provided, cannot realign" << endl;
        exit(1);
    }

    BAMSINGLEREADER reader;
    if (!reader.Open(STDIN)) {
        cerr << "could not open stdin for reading" << endl;
        exit(1);
    }

#ifdef HAVE_BAMTOOLS

    BamWriter writer;

    if (isuncompressed) {
        writer.SetCompressionMode(BamWriter::Uncompressed);
    }

    if (!suppress_output && !writer.Open("stdout", reader.GetHeaderText(), reader.GetReferenceData())) {
        cerr << "could not open stdout for writing" << endl;
        exit(1);
    }
#else

    SeqLib::BamWriter writer(isuncompressed ? SeqLib::SAM : SeqLib::BAM);
    SeqLib::BamHeader hdr = reader.Header();
    if (hdr.isEmpty()) {
      cerr << "could not open header for input" << endl;
      exit(1);
    }
    writer.SetHeader(hdr);

    if (!suppress_output && !writer.Open("-")) {
        cerr << "could not open stdout for writing" << endl;
        exit(1);
    }
    writer.WriteHeader();
#endif

    // store the names of all the reference sequences in the BAM file
    map<int, string> referenceIDToName;
    REFVEC referenceSequences = reader.GETREFDATA;
    int i = 0;
    for (REFVEC::iterator r = referenceSequences.begin(); r != referenceSequences.end(); ++r) {
        referenceIDToName[i] = r->REFNAME;
        ++i;
    }

    BAMALIGN alignment;

    while (GETNEXT(reader, alignment)) {

            DEBUG("---------------------------   read    --------------------------" << endl);
            DEBUG("| " << referenceIDToName[alignment.REFID] << ":" << alignment.POSITION << endl);
            DEBUG("| " << alignment.QNAME << ":" << alignment.ENDPOSITION << endl);
            DEBUG("| " << alignment.QNAME << ":" << (alignment.ISMAPPED ? " mapped" : " unmapped") << endl);
            DEBUG("| " << alignment.QNAME << ":" << " cigar data size: " << alignment.GETCIGAR.size() << endl);
            DEBUG("--------------------------- realigned --------------------------" << endl);

            // skip unmapped alignments, as they cannot be left-realigned without CIGAR data
            if (alignment.ISMAPPED) {

                int endpos = alignment.ENDPOSITION;
                int length = endpos - alignment.POSITION + 1;
                if (alignment.POSITION >= 0 && length > 0) {
                    if (!stablyLeftAlign(alignment,
                                reference.getSubSequence(
                                    referenceIDToName[alignment.REFID],
                                    alignment.POSITION,
                                    length),
                                maxiterations, debug)) {
                        cerr << "unstable realignment of " << alignment.QNAME
                             << " at " << referenceIDToName[alignment.REFID] << ":" << alignment.POSITION << endl
                             << alignment.QUERYBASES << endl;
                    }
                }

            }

            DEBUG("----------------------------------------------------------------" << endl);
            DEBUG(endl);

        if (!suppress_output)
	  WRITEALIGNMENT(writer, alignment);

    }

    reader.Close();
    if (!suppress_output)
        writer.Close();

    return 0;
}
<|endoftext|>