<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "AudioSource.h"
#include "AudioEngine.h"

#include <string>
#include <algorithm>

using namespace std;

namespace avg {

AudioSource::AudioSource(AudioMsgQueue& msgQ, AudioMsgQueue& statusQ, int sampleRate)
    : m_MsgQ(msgQ),
      m_StatusQ(statusQ),
      m_SampleRate(sampleRate),
      m_bPaused(false),
      m_bSeeking(false),
      m_Volume(1.0),
      m_LastVolume(1.0)
{
}

AudioSource::~AudioSource()
{
}

void AudioSource::pause()
{
    m_bPaused = true;
}

void AudioSource::play()
{
    m_bPaused = false;
}

void AudioSource::notifySeek()
{
    while (m_bSeeking) {
        processNextMsg(true);
    }
    m_bSeeking = true;
}

void AudioSource::setVolume(float volume)
{
    m_Volume = volume;
}

void AudioSource::fillAudioBuffer(AudioBufferPtr pBuffer)
{
    bool bContinue = true;
    while (bContinue && m_bSeeking) {
        bContinue = processNextMsg(false);
    }
    if (!m_bPaused) {
        unsigned char* pDest = (unsigned char *)(pBuffer->getData());
        int framesLeftToFill = pBuffer->getNumFrames();
        AudioMsgPtr pMsg;
        while (framesLeftToFill > 0) {
            int framesLeftInBuffer = 0;
            if (m_pInputAudioBuffer) {
                framesLeftInBuffer = m_pInputAudioBuffer->getNumFrames()
                        - m_CurInputAudioPos;
            }
            while (framesLeftInBuffer > 0 && framesLeftToFill > 0) {
                int framesToCopy = min(framesLeftToFill, framesLeftInBuffer);
    //            cerr << "framesToCopy: " << framesToCopy << endl;
                char * pInputPos = (char*)m_pInputAudioBuffer->getData() +
                        m_CurInputAudioPos*pBuffer->getFrameSize();
                int bytesToCopy = framesToCopy*pBuffer->getFrameSize();
                memcpy(pDest, pInputPos, bytesToCopy);
                m_CurInputAudioPos += framesToCopy;
                framesLeftToFill -= framesToCopy;
                framesLeftInBuffer -= framesToCopy;
                pDest += bytesToCopy;

                m_LastTime += framesToCopy/m_SampleRate;
    //            cerr << "  " << m_LastTime << endl;
            }
            if (framesLeftToFill != 0) {
                bool bContinue = processNextMsg(false);
                if (!bContinue) {
                    framesLeftToFill = 0;
                }
            }
        }
        pBuffer->volumize(m_LastVolume, m_Volume);
        m_LastVolume = m_Volume;

        AudioMsgPtr pStatusMsg(new AudioMsg);
        pStatusMsg->setAudioTime(m_LastTime);
        m_StatusQ.push(pStatusMsg);
    }
}

bool AudioSource::processNextMsg(bool bWait)
{
    AudioMsgPtr pMsg = m_MsgQ.pop(bWait);
    if (pMsg) {
        switch (pMsg->getType()) {
            case AudioMsg::AUDIO:
                m_pInputAudioBuffer = pMsg->getAudioBuffer();
                m_CurInputAudioPos = 0;
                m_LastTime = pMsg->getAudioTime();
//                cerr << "  New buffer: " << m_LastTime << endl;
                return true;
            case AudioMsg::END_OF_FILE: {
//                cerr << "        AudioSource: EOF" << endl;
                AudioMsgPtr pStatusMsg(new AudioMsg);
                pStatusMsg->setEOF();
                m_StatusQ.push(pStatusMsg);
                return false;
            }
            case AudioMsg::SEEK_DONE: {
//                cerr << "        AudioSource: SEEK_DONE" << endl;
                m_bSeeking = false;
                m_pInputAudioBuffer = AudioBufferPtr();
                m_LastTime = pMsg->getSeekTime();
                AudioMsgPtr pStatusMsg(new AudioMsg);
                pStatusMsg->setSeekDone(-1, m_LastTime);
                m_StatusQ.push(pStatusMsg);
                return true;
            }
            default:
                AVG_ASSERT(false);
                return false;
        }
    } else {
        //                cerr << "no pop" << endl;
        return false;
    }
}

}
<commit_msg>video branch: Fixed hang on seek/EOF with audio.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2011 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "AudioSource.h"
#include "AudioEngine.h"

#include <string>
#include <algorithm>

using namespace std;

namespace avg {

AudioSource::AudioSource(AudioMsgQueue& msgQ, AudioMsgQueue& statusQ, int sampleRate)
    : m_MsgQ(msgQ),
      m_StatusQ(statusQ),
      m_SampleRate(sampleRate),
      m_bPaused(false),
      m_bSeeking(false),
      m_Volume(1.0),
      m_LastVolume(1.0)
{
}

AudioSource::~AudioSource()
{
}

void AudioSource::pause()
{
    m_bPaused = true;
}

void AudioSource::play()
{
    m_bPaused = false;
}

void AudioSource::notifySeek()
{
    while (m_bSeeking) {
        processNextMsg(true);
    }
    m_bSeeking = true;
}

void AudioSource::setVolume(float volume)
{
    m_Volume = volume;
}

void AudioSource::fillAudioBuffer(AudioBufferPtr pBuffer)
{
    bool bContinue = true;
    while (bContinue && m_bSeeking) {
        bContinue = processNextMsg(false);
    }
    if (!m_bPaused) {
        unsigned char* pDest = (unsigned char *)(pBuffer->getData());
        int framesLeftToFill = pBuffer->getNumFrames();
        AudioMsgPtr pMsg;
        while (framesLeftToFill > 0) {
            int framesLeftInBuffer = 0;
            if (m_pInputAudioBuffer) {
                framesLeftInBuffer = m_pInputAudioBuffer->getNumFrames()
                        - m_CurInputAudioPos;
            }
            while (framesLeftInBuffer > 0 && framesLeftToFill > 0) {
                int framesToCopy = min(framesLeftToFill, framesLeftInBuffer);
    //            cerr << "framesToCopy: " << framesToCopy << endl;
                char * pInputPos = (char*)m_pInputAudioBuffer->getData() +
                        m_CurInputAudioPos*pBuffer->getFrameSize();
                int bytesToCopy = framesToCopy*pBuffer->getFrameSize();
                memcpy(pDest, pInputPos, bytesToCopy);
                m_CurInputAudioPos += framesToCopy;
                framesLeftToFill -= framesToCopy;
                framesLeftInBuffer -= framesToCopy;
                pDest += bytesToCopy;

                m_LastTime += framesToCopy/m_SampleRate;
    //            cerr << "  " << m_LastTime << endl;
            }
            if (framesLeftToFill != 0) {
                bool bContinue = processNextMsg(false);
                if (!bContinue) {
                    framesLeftToFill = 0;
                }
            }
        }
        pBuffer->volumize(m_LastVolume, m_Volume);
        m_LastVolume = m_Volume;

        AudioMsgPtr pStatusMsg(new AudioMsg);
        pStatusMsg->setAudioTime(m_LastTime);
        m_StatusQ.push(pStatusMsg);
    }
}

bool AudioSource::processNextMsg(bool bWait)
{
    AudioMsgPtr pMsg = m_MsgQ.pop(bWait);
    if (pMsg) {
        switch (pMsg->getType()) {
            case AudioMsg::AUDIO:
                m_pInputAudioBuffer = pMsg->getAudioBuffer();
                m_CurInputAudioPos = 0;
                m_LastTime = pMsg->getAudioTime();
//                cerr << "  New buffer: " << m_LastTime << endl;
                return true;
            case AudioMsg::END_OF_FILE: {
//                cerr << "        AudioSource: EOF" << endl;
                m_bSeeking = false;
                AudioMsgPtr pStatusMsg(new AudioMsg);
                pStatusMsg->setEOF();
                m_StatusQ.push(pStatusMsg);
                return false;
            }
            case AudioMsg::SEEK_DONE: {
//                cerr << "        AudioSource: SEEK_DONE" << endl;
                m_bSeeking = false;
                m_pInputAudioBuffer = AudioBufferPtr();
                m_LastTime = pMsg->getSeekTime();
                AudioMsgPtr pStatusMsg(new AudioMsg);
                pStatusMsg->setSeekDone(-1, m_LastTime);
                m_StatusQ.push(pStatusMsg);
                return true;
            }
            default:
                AVG_ASSERT(false);
                return false;
        }
    } else {
        //                cerr << "no pop" << endl;
        return false;
    }
}

}
<|endoftext|>


<commit_before>#include <node/node_buffer.h>
#include "Artwork.h"
#include "async_macros.h"

using namespace node;
using namespace v8;

namespace node_iTunes {

static Persistent<String> ARTWORK_CLASS_SYMBOL;

void free_artwork_data_callback(char *data, void *hint);

void Artwork::Init(v8::Handle<Object> target) {
  HandleScope scope;

  // String Constants
  ARTWORK_CLASS_SYMBOL = NODE_PSYMBOL("Artwork");

  Local<FunctionTemplate> t = FunctionTemplate::New(New);
  artwork_constructor_template = Persistent<FunctionTemplate>::New(t);
  artwork_constructor_template->Inherit(item_constructor_template);
  artwork_constructor_template->SetClassName(ARTWORK_CLASS_SYMBOL);
  t->InstanceTemplate()->SetInternalFieldCount(1);

  NODE_SET_PROTOTYPE_METHOD(t, "data", Data);

  target->Set(ARTWORK_CLASS_SYMBOL, artwork_constructor_template->GetFunction());
}

// JavaScript Constructor /////////////////////////////////////////////////////
  v8::Handle<Value> Artwork::New(const Arguments& args) {
  HandleScope scope;

  Artwork* p = new Artwork();
  p->Wrap(args.This());
  return args.This();
}

// Data ///////////////////////////////////////////////////////////////////////
v8::Handle<Value> Artwork::Data(const Arguments& args) {
  HandleScope scope;
  INIT(Artwork);
  if (HAS_CALLBACK_ARG) {
    GET_CALLBACK;
  }
  BEGIN_ASYNC(EIO_Data, EIO_AfterData);
}

// Gets the TIFF data representation by default.
// TODO: Add support for specifying format and compression level.
//   See here: http://borkware.com/quickies/one?topic=NSImage
int Artwork::EIO_Data(eio_req *req) {
  INIT_EIO_FUNC;
  iTunesArtwork *item = (iTunesArtwork *)ar->itemRef;
  NSImage *image = [item data];
  NSData *data = [image TIFFRepresentation];
  [data retain];
  ar->result = (void *)[data bytes];
  req->result = [data length];
  FINISH_EIO_FUNC;
}

int Artwork::EIO_AfterData(eio_req *req) {
  INIT_AFTER_FUNC;
  // TODO: Error handling
  argv[0] = Null();
  // Create the buffer.
  // http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon
  Buffer *slowBuffer = Buffer::New((char *)ar->result, req->result, free_artwork_data_callback, NULL);
  Local<Object> globalObj = Context::GetCurrent()->Global();
  Local<Function> bufferConstructor  = Local<Function>::Cast(globalObj->Get(String::New("Buffer")));
  v8::Handle<Value> constructorArgs[3] = { slowBuffer->handle_, Integer::New(req->result), Integer::New(0) };
  Local<Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);
  argv[1] = actualBuffer;
  FINISH_AFTER_FUNC;
}

void free_artwork_data_callback(char *data, void *hint) {
  NSLog(@"free_artwork_data_callback called, probably leaking memory!!!");
}

} // namespace node_iTunes
<commit_msg>Fix memory leak when the Artwork data Buffer is attempted to be garbage collected.<commit_after>#include <node/node_buffer.h>
#include "Artwork.h"
#include "async_macros.h"

using namespace node;
using namespace v8;

namespace node_iTunes {

static Persistent<String> ARTWORK_CLASS_SYMBOL;

void free_artwork_data_callback(char *data, void *hint);

void Artwork::Init(v8::Handle<Object> target) {
  HandleScope scope;

  // String Constants
  ARTWORK_CLASS_SYMBOL = NODE_PSYMBOL("Artwork");

  Local<FunctionTemplate> t = FunctionTemplate::New(New);
  artwork_constructor_template = Persistent<FunctionTemplate>::New(t);
  artwork_constructor_template->Inherit(item_constructor_template);
  artwork_constructor_template->SetClassName(ARTWORK_CLASS_SYMBOL);
  t->InstanceTemplate()->SetInternalFieldCount(1);

  NODE_SET_PROTOTYPE_METHOD(t, "data", Data);

  target->Set(ARTWORK_CLASS_SYMBOL, artwork_constructor_template->GetFunction());
}

// JavaScript Constructor /////////////////////////////////////////////////////
  v8::Handle<Value> Artwork::New(const Arguments& args) {
  HandleScope scope;

  Artwork* p = new Artwork();
  p->Wrap(args.This());
  return args.This();
}

// Data ///////////////////////////////////////////////////////////////////////
v8::Handle<Value> Artwork::Data(const Arguments& args) {
  HandleScope scope;
  INIT(Artwork);
  if (HAS_CALLBACK_ARG) {
    GET_CALLBACK;
  }
  BEGIN_ASYNC(EIO_Data, EIO_AfterData);
}

// Gets the TIFF data representation by default.
// TODO: Add support for specifying format and compression level.
//   See here: http://borkware.com/quickies/one?topic=NSImage
int Artwork::EIO_Data(eio_req *req) {
  INIT_EIO_FUNC;
  iTunesArtwork *item = (iTunesArtwork *)ar->itemRef;
  NSImage *image = [item data];
  NSData *data = [image TIFFRepresentation];
  [data retain];
  ar->result = data;
  req->result = [data length];
  FINISH_EIO_FUNC;
}

int Artwork::EIO_AfterData(eio_req *req) {
  INIT_AFTER_FUNC;
  // TODO: Error handling
  argv[0] = Null();
  // Create the buffer.
  // http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon
  Buffer *slowBuffer = Buffer::New((char *)[(NSData *)ar->result bytes], req->result, free_artwork_data_callback, ar->result);
  Local<Object> globalObj = Context::GetCurrent()->Global();
  Local<Function> bufferConstructor  = Local<Function>::Cast(globalObj->Get(String::New("Buffer")));
  v8::Handle<Value> constructorArgs[3] = { slowBuffer->handle_, Integer::New(req->result), Integer::New(0) };
  Local<Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);
  argv[1] = actualBuffer;
  FINISH_AFTER_FUNC;
}

void free_artwork_data_callback(char *data, void *hint) {
  [(NSData *)hint release];
}

} // namespace node_iTunes
<|endoftext|>


<commit_before>// Copyright 2013 The Flutter 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 "handle_exception.h"

#include <fuchsia/feedback/cpp/fidl.h>
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/syslog/global.h>
#include <lib/zx/vmo.h>
#include <sys/types.h>
#include <zircon/status.h>

#include <string>

#include "third_party/tonic/converter/dart_converter.h"

#include "logging.h"

namespace {
static bool SetStackTrace(const std::string& data,
                          fuchsia::feedback::RuntimeCrashReport* report) {
  uint64_t num_bytes = data.size();
  zx::vmo vmo;

  if (zx::vmo::create(num_bytes, 0u, &vmo) < 0) {
    return false;
  }

  if (num_bytes > 0) {
    if (vmo.write(data.data(), 0, num_bytes) < 0) {
      return false;
    }
  }

  fuchsia::mem::Buffer buffer;
  buffer.vmo = std::move(vmo);
  buffer.size = num_bytes;
  report->set_exception_stack_trace(std::move(buffer));

  return true;
}

fuchsia::feedback::CrashReport BuildCrashReport(
    const std::string& component_url,
    const std::string& error,
    const std::string& stack_trace) {
  // The runtime type has already been pre-pended to the error message so we
  // expect the format to be '$RuntimeType: $Message'.
  std::string error_type;
  std::string error_message;
  const size_t delimiter_pos = error.find_first_of(':');
  if (delimiter_pos == std::string::npos) {
    FX_LOGF(ERROR, LOG_TAG,
            "error parsing Dart exception: expected format '$RuntimeType: "
            "$Message', got '%s'",
            error.c_str());
    // We still need to specify a type, otherwise the stack trace does not
    // show up in the crash server UI.
    error_type = "UnknownError";
    error_message = error;
  } else {
    error_type = error.substr(0, delimiter_pos);
    error_message =
        error.substr(delimiter_pos + 2 /*to get rid of the leading ': '*/);
  }

  // Truncate error message to the maximum length allowed for the crash_reporter
  // FIDL call
  error_message = error_message.substr(
      0, fuchsia::feedback::MAX_EXCEPTION_MESSAGE_LENGTH - 1);

  fuchsia::feedback::RuntimeCrashReport dart_report;
  dart_report.set_exception_type(error_type);
  dart_report.set_exception_message(error_message);
  if (!SetStackTrace(stack_trace, &dart_report)) {
    FX_LOG(ERROR, LOG_TAG, "Failed to convert Dart stack trace to VMO");
  }

  fuchsia::feedback::SpecificCrashReport specific_report;
  specific_report.set_dart(std::move(dart_report));
  fuchsia::feedback::CrashReport report;
  report.set_program_name(component_url);
  report.set_specific_report(std::move(specific_report));
  return report;
}

}  // namespace

namespace dart_utils {

void HandleIfException(std::shared_ptr<::sys::ServiceDirectory> services,
                       const std::string& component_url,
                       Dart_Handle result) {
  if (!Dart_IsError(result) || !Dart_ErrorHasException(result)) {
    return;
  }

  const std::string error =
      tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetException(result)));
  const std::string stack_trace =
      tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetStackTrace(result)));

  return HandleException(services, component_url, error, stack_trace);
}

void HandleException(std::shared_ptr<::sys::ServiceDirectory> services,
                     const std::string& component_url,
                     const std::string& error,
                     const std::string& stack_trace) {
  fuchsia::feedback::CrashReport crash_report =
      BuildCrashReport(component_url, error, stack_trace);

  fuchsia::feedback::CrashReporterPtr crash_reporter =
      services->Connect<fuchsia::feedback::CrashReporter>();
  crash_reporter->File(
      std::move(crash_report),
      [](fuchsia::feedback::CrashReporter_File_Result result) {
        if (result.is_err()) {
          FX_LOGF(ERROR, LOG_TAG, "Failed to report Dart exception: %d (%s)",
                  result.err(), zx_status_get_string(result.err()));
        }
      });
}

}  // namespace dart_utils
<commit_msg>Fuchsia: filed crash reports are marked as non-fatal (#24980)<commit_after>// Copyright 2013 The Flutter 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 "handle_exception.h"

#include <fuchsia/feedback/cpp/fidl.h>
#include <fuchsia/mem/cpp/fidl.h>
#include <lib/syslog/global.h>
#include <lib/zx/vmo.h>
#include <sys/types.h>
#include <zircon/status.h>

#include <string>

#include "third_party/tonic/converter/dart_converter.h"

#include "logging.h"

namespace {
static bool SetStackTrace(const std::string& data,
                          fuchsia::feedback::RuntimeCrashReport* report) {
  uint64_t num_bytes = data.size();
  zx::vmo vmo;

  if (zx::vmo::create(num_bytes, 0u, &vmo) < 0) {
    return false;
  }

  if (num_bytes > 0) {
    if (vmo.write(data.data(), 0, num_bytes) < 0) {
      return false;
    }
  }

  fuchsia::mem::Buffer buffer;
  buffer.vmo = std::move(vmo);
  buffer.size = num_bytes;
  report->set_exception_stack_trace(std::move(buffer));

  return true;
}

fuchsia::feedback::CrashReport BuildCrashReport(
    const std::string& component_url,
    const std::string& error,
    const std::string& stack_trace) {
  // The runtime type has already been pre-pended to the error message so we
  // expect the format to be '$RuntimeType: $Message'.
  std::string error_type;
  std::string error_message;
  const size_t delimiter_pos = error.find_first_of(':');
  if (delimiter_pos == std::string::npos) {
    FX_LOGF(ERROR, LOG_TAG,
            "error parsing Dart exception: expected format '$RuntimeType: "
            "$Message', got '%s'",
            error.c_str());
    // We still need to specify a type, otherwise the stack trace does not
    // show up in the crash server UI.
    error_type = "UnknownError";
    error_message = error;
  } else {
    error_type = error.substr(0, delimiter_pos);
    error_message =
        error.substr(delimiter_pos + 2 /*to get rid of the leading ': '*/);
  }

  // Truncate error message to the maximum length allowed for the crash_reporter
  // FIDL call
  error_message = error_message.substr(
      0, fuchsia::feedback::MAX_EXCEPTION_MESSAGE_LENGTH - 1);

  fuchsia::feedback::RuntimeCrashReport dart_report;
  dart_report.set_exception_type(error_type);
  dart_report.set_exception_message(error_message);
  if (!SetStackTrace(stack_trace, &dart_report)) {
    FX_LOG(ERROR, LOG_TAG, "Failed to convert Dart stack trace to VMO");
  }

  fuchsia::feedback::SpecificCrashReport specific_report;
  specific_report.set_dart(std::move(dart_report));
  fuchsia::feedback::CrashReport report;
  report.set_program_name(component_url);
  report.set_specific_report(std::move(specific_report));
  report.set_is_fatal(false);
  return report;
}

}  // namespace

namespace dart_utils {

void HandleIfException(std::shared_ptr<::sys::ServiceDirectory> services,
                       const std::string& component_url,
                       Dart_Handle result) {
  if (!Dart_IsError(result) || !Dart_ErrorHasException(result)) {
    return;
  }

  const std::string error =
      tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetException(result)));
  const std::string stack_trace =
      tonic::StdStringFromDart(Dart_ToString(Dart_ErrorGetStackTrace(result)));

  return HandleException(services, component_url, error, stack_trace);
}

void HandleException(std::shared_ptr<::sys::ServiceDirectory> services,
                     const std::string& component_url,
                     const std::string& error,
                     const std::string& stack_trace) {
  fuchsia::feedback::CrashReport crash_report =
      BuildCrashReport(component_url, error, stack_trace);

  fuchsia::feedback::CrashReporterPtr crash_reporter =
      services->Connect<fuchsia::feedback::CrashReporter>();
  crash_reporter->File(
      std::move(crash_report),
      [](fuchsia::feedback::CrashReporter_File_Result result) {
        if (result.is_err()) {
          FX_LOGF(ERROR, LOG_TAG, "Failed to report Dart exception: %d (%s)",
                  result.err(), zx_status_get_string(result.err()));
        }
      });
}

}  // namespace dart_utils
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "base/file_path.h"
#include "base/file_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/ui/ui_layout_test.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_util.h"

static const char* kRootFiles[] = {
  "clear.html",
//  "complex-keys.html",  // Output too big for a cookie.  crbug.com/33472
//  "complex-values.html",  // crbug.com/33472
  "quota.html",
  "remove-item.html",
  "window-attributes-exist.html",
  NULL
};

static const char* kEventsFiles[] = {
//  "basic-body-attribute.html",  // crbug.com/33472
//  "basic.html",  // crbug.com/33472
//  "basic-setattribute.html",  // crbug.com/33472
  "case-sensitive.html",
  "documentURI.html",
  NULL
};

static const char* kStorageFiles[] = {
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "index-get-and-set.html",
  "simple-usage.html",
  "string-conversion.html",
//  "window-open.html", // TODO(jorlow): Fix
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources for most of the DOM Storage layout tests.
  // Add those to the list to be copied.
  void AddJSTestResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    const FilePath dir(FILE_PATH_LITERAL("layout_tests"));
    const FilePath file(FILE_PATH_LITERAL("clear_dom_storage.html"));
    GURL url = ui_test_utils::GetTestUrl(dir, file);
    ASSERT_TRUE(tab->SetCookie(url, ""));
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared",
                            TestTimeouts::action_max_timeout_ms());
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, kNoHttpPort);
      ++files;
    }
  }

  FilePath test_dir_;
};

#if defined(OS_WIN)
// http://crbug.com/101996
#define RootLayoutTests FLAKY_RootLayoutTests
#endif
TEST_F(DOMStorageTest, RootLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  RunTests(kRootFiles);
}

// Flakily fails on all platforms.  http://crbug.com/102641
TEST_F(DOMStorageTest, FLAKY_EventLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("events"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("resources"));
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("script-tests"));
  RunTests(kEventsFiles);
}

TEST_F(DOMStorageTest, LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

TEST_F(DOMStorageTest, SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

class DomStorageEmptyDatabaseTest : public UITest {
 protected:
  FilePath StorageDir() const {
    FilePath storage_dir = user_data_dir();
    storage_dir = storage_dir.AppendASCII("Default");
    storage_dir = storage_dir.AppendASCII("Local Storage");
    return storage_dir;
  }

  bool StorageDirIsEmpty() const {
    FilePath storage_dir = StorageDir();
    if (!file_util::DirectoryExists(storage_dir))
      return true;
    return file_util::IsDirectoryEmpty(storage_dir);
  }

  GURL TestUrl() const {
    FilePath test_dir = test_data_directory_;
    FilePath test_file = test_dir.AppendASCII("dom_storage_empty_db.html");
    return net::FilePathToFileURL(test_file);
  }
};

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterClear) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterGet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:get()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

// Flaky, see http://crbug.com/73776
TEST_F(DomStorageEmptyDatabaseTest, FLAKY_NonEmptyDirAfterSet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  QuitBrowser();
  EXPECT_FALSE(StorageDirIsEmpty());

  LaunchBrowserAndServer();
  NavigateToURL(TestUrl());
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}
<commit_msg>Mark two tests as fails, to unblock the commit queue.<commit_after>// Copyright (c) 2011 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 "base/file_path.h"
#include "base/file_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/ui/ui_layout_test.h"
#include "content/public/common/content_switches.h"
#include "net/base/net_util.h"

static const char* kRootFiles[] = {
  "clear.html",
//  "complex-keys.html",  // Output too big for a cookie.  crbug.com/33472
//  "complex-values.html",  // crbug.com/33472
  "quota.html",
  "remove-item.html",
  "window-attributes-exist.html",
  NULL
};

static const char* kEventsFiles[] = {
//  "basic-body-attribute.html",  // crbug.com/33472
//  "basic.html",  // crbug.com/33472
//  "basic-setattribute.html",  // crbug.com/33472
  "case-sensitive.html",
  "documentURI.html",
  NULL
};

static const char* kStorageFiles[] = {
  "delete-removal.html",
  "enumerate-storage.html",
  "enumerate-with-length-and-key.html",
  "index-get-and-set.html",
  "simple-usage.html",
  "string-conversion.html",
//  "window-open.html", // TODO(jorlow): Fix
  NULL
};

class DOMStorageTest : public UILayoutTest {
 protected:
  DOMStorageTest()
      : UILayoutTest(),
        test_dir_(FilePath().
                  AppendASCII("storage").AppendASCII("domstorage")) {
  }

  virtual ~DOMStorageTest() { }

  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking);
    UILayoutTest::SetUp();
  }

  // We require fast/js/resources for most of the DOM Storage layout tests.
  // Add those to the list to be copied.
  void AddJSTestResources() {
    // Add other paths our tests require.
    FilePath js_dir = FilePath().
                      AppendASCII("fast").AppendASCII("js");
    AddResourceForLayoutTest(js_dir, FilePath().AppendASCII("resources"));
  }

  // This is somewhat of a hack because we're running a real browser that
  // actually persists the LocalStorage state vs. DRT and TestShell which don't.
  // The correct fix is to fix the LayoutTests, but similar patches have been
  // rejected in the past.
  void ClearDOMStorage() {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    const FilePath dir(FILE_PATH_LITERAL("layout_tests"));
    const FilePath file(FILE_PATH_LITERAL("clear_dom_storage.html"));
    GURL url = ui_test_utils::GetTestUrl(dir, file);
    ASSERT_TRUE(tab->SetCookie(url, ""));
    ASSERT_TRUE(tab->NavigateToURL(url));

    WaitUntilCookieNonEmpty(tab.get(), url, "cleared",
                            TestTimeouts::action_max_timeout_ms());
  }

  // Runs each test in an array of strings until it hits a NULL.
  void RunTests(const char** files) {
    while (*files) {
      ClearDOMStorage();
      RunLayoutTest(*files, kNoHttpPort);
      ++files;
    }
  }

  FilePath test_dir_;
};

#if defined(OS_WIN)
// http://crbug.com/101996
#define RootLayoutTests FLAKY_RootLayoutTests
#endif
TEST_F(DOMStorageTest, RootLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath(), kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("script-tests"));
  RunTests(kRootFiles);
}

// Flakily fails on all platforms.  http://crbug.com/102641
TEST_F(DOMStorageTest, FLAKY_EventLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("events"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("resources"));
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("events").
                                      AppendASCII("script-tests"));
  RunTests(kEventsFiles);
}

#if defined(OS_LINUX)
// http://crbug.com/104872
#define MAYBE_LocalStorageLayoutTests FAILS_LocalStorageLayoutTests
#else
#define MAYBE_LocalStorageLayoutTests LocalStorageLayoutTests
#endif

TEST_F(DOMStorageTest, MAYBE_LocalStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("localstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

#if defined(OS_LINUX)
// http://crbug.com/104872
#define MAYBE_SessionStorageLayoutTests FAILS_SessionStorageLayoutTests
#else
#define MAYBE_SessionStorageLayoutTests SessionStorageLayoutTests
#endif

TEST_F(DOMStorageTest, MAYBE_SessionStorageLayoutTests) {
  InitializeForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage"),
                          kNoHttpPort);
  AddJSTestResources();
  AddResourceForLayoutTest(test_dir_, FilePath().AppendASCII("sessionstorage").
                                      AppendASCII("resources"));
  RunTests(kStorageFiles);
}

class DomStorageEmptyDatabaseTest : public UITest {
 protected:
  FilePath StorageDir() const {
    FilePath storage_dir = user_data_dir();
    storage_dir = storage_dir.AppendASCII("Default");
    storage_dir = storage_dir.AppendASCII("Local Storage");
    return storage_dir;
  }

  bool StorageDirIsEmpty() const {
    FilePath storage_dir = StorageDir();
    if (!file_util::DirectoryExists(storage_dir))
      return true;
    return file_util::IsDirectoryEmpty(storage_dir);
  }

  GURL TestUrl() const {
    FilePath test_dir = test_data_directory_;
    FilePath test_file = test_dir.AppendASCII("dom_storage_empty_db.html");
    return net::FilePathToFileURL(test_file);
  }
};

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterClear) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

TEST_F(DomStorageEmptyDatabaseTest, EmptyDirAfterGet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:get()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}

// Flaky, see http://crbug.com/73776
TEST_F(DomStorageEmptyDatabaseTest, FLAKY_NonEmptyDirAfterSet) {
  NavigateToURL(TestUrl());
  ASSERT_TRUE(StorageDirIsEmpty());

  NavigateToURL(GURL("javascript:set()"));
  QuitBrowser();
  EXPECT_FALSE(StorageDirIsEmpty());

  LaunchBrowserAndServer();
  NavigateToURL(TestUrl());
  NavigateToURL(GURL("javascript:clear()"));
  QuitBrowser();
  EXPECT_TRUE(StorageDirIsEmpty());
}
<|endoftext|>


<commit_before>// $Id: TGHtmlImage.cxx,v 1.1 2007/05/04 17:07:01 brun Exp $
// Author:  Valeriy Onuchin   03/05/2007

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**************************************************************************

    HTML widget for xclass. Based on tkhtml 1.28
    Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
    Copyright (C) 2002-2003 Hector Peraza.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

**************************************************************************/

// Routines used for processing <IMG> markup

#include <string.h>
#include <stdlib.h>

#include "TGHtml.h"
//#include <TGHtmlUri.h>
#include "TImage.h"
#include "TUrl.h"
#include "TSocket.h"
#include "TSystem.h"

//______________________________________________________________________________
TGHtmlImage::TGHtmlImage(TGHtml *h, const char *url, const char *width,
                       const char *height)
{
   // ctor.

   _html = h;
   zUrl = StrDup(url);
   zWidth = StrDup(width);
   zHeight = StrDup(height);
   image = NULL;
   pNext = NULL;
   pList = NULL;
   w = 0;
   h = 0;
   timer = NULL;
}

//______________________________________________________________________________
TGHtmlImage::~TGHtmlImage()
{
   //  dtor.

   delete [] zUrl;
   delete [] zWidth;
   delete [] zHeight;

   if (image) delete image;
   if (timer) delete timer;
}

//______________________________________________________________________________
int TGHtml::GetImageAlignment(TGHtmlElement *p)
{
   // Find the alignment for an image

   char *z;
   int i;
   int result;

   static struct {
      char *zName;
      int iValue;
   } aligns[] = {
      { "bottom",    IMAGE_ALIGN_Bottom    },
      { "baseline",  IMAGE_ALIGN_Bottom    },
      { "middle",    IMAGE_ALIGN_Middle    },
      { "top",       IMAGE_ALIGN_Top       },
      { "absbottom", IMAGE_ALIGN_AbsBottom },
      { "absmiddle", IMAGE_ALIGN_AbsMiddle },
      { "texttop",   IMAGE_ALIGN_TextTop   },
      { "left",      IMAGE_ALIGN_Left      },
      { "right",     IMAGE_ALIGN_Right     },
   };

   z = p->MarkupArg("align", 0);
   result = IMAGE_ALIGN_Bottom;
   if (z) {
      for (i = 0; i < int(sizeof(aligns) / sizeof(aligns[0])); i++) {
         if (strcasecmp(aligns[i].zName, z) == 0) {
            result = aligns[i].iValue;
            break;
         }
      }
   }
   return result;
}

//______________________________________________________________________________
void TGHtml::ImageChanged(TGHtmlImage *pImage, int newWidth, int newHeight)
{
   // This routine is called when an image changes. If the size of the
   // images changes, then we need to completely redo the layout. If
   // only the appearance changes, then this works like an expose event.
   //
   // pImage    - Pointer to an TGHtmlImage object
   // newWidth  - New width of the image
   // newHeight - New height of the image

   TGHtmlImageMarkup *pElem;

   if (pImage->w != newWidth || pImage->h != newHeight) {
      // We have to completely redo the layout after adjusting the size
      // of the images
      for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
         pElem->w = newWidth;
         pElem->h = newHeight;
      }
      flags |= RELAYOUT;
      pImage->w = newWidth;
      pImage->h = newHeight;
      RedrawEverything();
   } else {
#if 0
    for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
      pElem->redrawNeeded = 1;
    }
    flags |= REDRAW_IMAGES;
    ScheduleRedraw();
#else
      for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
         pElem->redrawNeeded = 1;
         DrawRegion(pElem->x, pElem->y - pElem->ascent, pElem->w, pElem->h);
      }
#endif
   }
}

//______________________________________________________________________________
TGHtmlImage *TGHtml::GetImage(TGHtmlImageMarkup *p)
{
   // Given an <IMG> markup, find or create an appropriate TGHtmlImage
   // object and return a pointer to that object. NULL might be returned.

   char *zWidth;
   char *zHeight;
   char *zSrc;
   TGHtmlImage *pImage;

   if (p->type != Html_IMG) { CANT_HAPPEN; return 0; }

   zSrc = p->MarkupArg("src", 0);
   if (zSrc == 0) return 0;

   zSrc = ResolveUri(zSrc);
   if (zSrc == 0) return 0;

   zWidth = p->MarkupArg("width", "");
   zHeight = p->MarkupArg("height", "");

   //p->w = atoi(zWidth);
   //p->h = atoi(zHeight);

   for (pImage = imageList; pImage; pImage = pImage->pNext) {
      if (strcmp(pImage->zUrl, zSrc) == 0
          &&  strcmp(pImage->zWidth, zWidth) == 0
          &&  strcmp(pImage->zHeight, zHeight) == 0) {
         delete [] zSrc;
         return pImage;
      }
   }

   TImage *img = LoadImage(zSrc, atoi(zWidth), atoi(zHeight));

   if (img) {
      pImage = new TGHtmlImage(this, zSrc, zWidth, zHeight);
      pImage->image = img;
    //if (img->IsAnimated()) {
    //  pImage->timer = new TTimer(this, img->GetAnimDelay());
    //}
      ImageChanged(pImage, img->GetWidth(), img->GetHeight());
      pImage->pNext = imageList;
      imageList = pImage;
   } else {
      pImage = 0;
   }

   delete [] zSrc;

   return pImage;
}

//______________________________________________________________________________
static TImage *ReadRemoteImage(const char *url)
{
   // Temporary function to read remote pictures

   TImage *image = 0;
   FILE *tmp;
   char *buf;
   TUrl fUrl(url);

   TString msg = "GET ";
   msg += fUrl.GetProtocol();
   msg += "://";
   msg += fUrl.GetHost();
   msg += ":";
   msg += fUrl.GetPort();
   msg += "/";
   msg += fUrl.GetFile();
   msg += "\r\n";

   TString uri(url);
   if (!uri.BeginsWith("http://") || uri.EndsWith(".html"))
      return 0;
   TSocket s(fUrl.GetHost(), fUrl.GetPort());
   if (!s.IsValid())
      return 0;
   if (s.SendRaw(msg.Data(), msg.Length()) == -1)
      return 0;
   Int_t size = 1024*1024;
   buf = (char *)calloc(size, sizeof(char));
   if (s.RecvRaw(buf, size) == -1) {
      free(buf);
      return 0;
   }
   TString pathtmp = Form("%s/%s",
      gSystem->TempDirectory(), gSystem->BaseName(url));
   tmp = fopen(pathtmp.Data(), "wb");
   fwrite(buf, sizeof(char), size, tmp);
   fclose(tmp);
   free(buf);
   image = TImage::Open(pathtmp.Data());
   if (!image->IsValid()) {
      delete image;
      image = 0;
   }
   gSystem->Unlink(pathtmp.Data());
   return image;
}

//______________________________________________________________________________
TImage *TGHtml::LoadImage(const char *url, int w, int h)
{
   // This is the default LoadImage() procedure. It just tries to load the
   // image from a file in the local filesystem.

   TImage *image = 0;

   //TGHtmlUri uri(url);

   TString uri(url);
   if (uri.BeginsWith("http://") && !uri.EndsWith(".html"))
      image = ReadRemoteImage(url);
   else
      image = TImage::Open(url);
   if (image) {
      if (!image->IsValid()) {
         delete image;
         image = 0;
         return 0;
      }
      if ((w > 0 && h > 0) && ((w != (int)image->GetWidth()) ||
          (h != (int)image->GetHeight()))) {
         image->Scale(w, h);
      }
   }
   return image;
}

//______________________________________________________________________________
char *TGHtml::GetPctWidth(TGHtmlElement *p, char *opt, char *ret)
{
   // Return the height and width, converting to percent if required

   int n, m, val;
   char *tz, *z;
   TGHtmlElement *pElem = p;

   z = pElem->MarkupArg(opt, "");
   if (!strchr(z, '%')) return z;
   if (!sscanf(z, "%d", &n)) return z;
   if (n < 0 || n > 100) return z;
   if (opt[0] == 'h') {
      val = fCanvas->GetHeight() * 100;
   } else {
      val = fCanvas->GetWidth() * 100;
   }
   if (!inTd) {
      sprintf(ret, "%d", val / n);
   } else {
      while (pElem && pElem->type != Html_TD) pElem = pElem->pPrev;
      if (!pElem) return z;
      tz = pElem->MarkupArg(opt, 0);
      if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
         sprintf(ret, "%d", m * 100 / n);
         return ret;
      }
      pElem = ((TGHtmlCell *)pElem)->pTable;
      if (!pElem) return z;
      tz = pElem->MarkupArg(opt, 0);
      if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
         sprintf(ret, "%d", m * 100 / n);
         return ret;
      }
      return z;
   }
   return ret;
}

//______________________________________________________________________________
int TGHtml::GetImageAt(int x, int y)
{
   // This routine searchs for an image beneath the coordinates x,y
   // and returns the token number of the the image, or -1 if no
   // image found.

   TGHtmlBlock *pBlock;
   TGHtmlElement *pElem;
   //int n;

   for (pBlock = firstBlock; pBlock; pBlock = pBlock->bNext) {
      if (pBlock->top > y || pBlock->bottom < y ||
          pBlock->left > x || pBlock->right < x) {
         continue;
      }
      for (pElem = pBlock->pNext; pElem; pElem = pElem->pNext) {
         if (pBlock->bNext && pElem == pBlock->bNext->pNext) break;
         if (pElem->type == Html_IMG) {
            return TokenNumber(pElem);
         }
      }
   }

   return -1;
}
<commit_msg>From Bertrand: Add a protection on temp file being NULL<commit_after>// $Id: TGHtmlImage.cxx,v 1.2 2007/05/07 15:28:48 brun Exp $
// Author:  Valeriy Onuchin   03/05/2007

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/**************************************************************************

    HTML widget for xclass. Based on tkhtml 1.28
    Copyright (C) 1997-2000 D. Richard Hipp <drh@acm.org>
    Copyright (C) 2002-2003 Hector Peraza.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

**************************************************************************/

// Routines used for processing <IMG> markup

#include <string.h>
#include <stdlib.h>

#include "TGHtml.h"
//#include <TGHtmlUri.h>
#include "TImage.h"
#include "TUrl.h"
#include "TSocket.h"
#include "TSystem.h"

//______________________________________________________________________________
TGHtmlImage::TGHtmlImage(TGHtml *h, const char *url, const char *width,
                       const char *height)
{
   // ctor.

   _html = h;
   zUrl = StrDup(url);
   zWidth = StrDup(width);
   zHeight = StrDup(height);
   image = NULL;
   pNext = NULL;
   pList = NULL;
   w = 0;
   h = 0;
   timer = NULL;
}

//______________________________________________________________________________
TGHtmlImage::~TGHtmlImage()
{
   //  dtor.

   delete [] zUrl;
   delete [] zWidth;
   delete [] zHeight;

   if (image) delete image;
   if (timer) delete timer;
}

//______________________________________________________________________________
int TGHtml::GetImageAlignment(TGHtmlElement *p)
{
   // Find the alignment for an image

   char *z;
   int i;
   int result;

   static struct {
      char *zName;
      int iValue;
   } aligns[] = {
      { "bottom",    IMAGE_ALIGN_Bottom    },
      { "baseline",  IMAGE_ALIGN_Bottom    },
      { "middle",    IMAGE_ALIGN_Middle    },
      { "top",       IMAGE_ALIGN_Top       },
      { "absbottom", IMAGE_ALIGN_AbsBottom },
      { "absmiddle", IMAGE_ALIGN_AbsMiddle },
      { "texttop",   IMAGE_ALIGN_TextTop   },
      { "left",      IMAGE_ALIGN_Left      },
      { "right",     IMAGE_ALIGN_Right     },
   };

   z = p->MarkupArg("align", 0);
   result = IMAGE_ALIGN_Bottom;
   if (z) {
      for (i = 0; i < int(sizeof(aligns) / sizeof(aligns[0])); i++) {
         if (strcasecmp(aligns[i].zName, z) == 0) {
            result = aligns[i].iValue;
            break;
         }
      }
   }
   return result;
}

//______________________________________________________________________________
void TGHtml::ImageChanged(TGHtmlImage *pImage, int newWidth, int newHeight)
{
   // This routine is called when an image changes. If the size of the
   // images changes, then we need to completely redo the layout. If
   // only the appearance changes, then this works like an expose event.
   //
   // pImage    - Pointer to an TGHtmlImage object
   // newWidth  - New width of the image
   // newHeight - New height of the image

   TGHtmlImageMarkup *pElem;

   if (pImage->w != newWidth || pImage->h != newHeight) {
      // We have to completely redo the layout after adjusting the size
      // of the images
      for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
         pElem->w = newWidth;
         pElem->h = newHeight;
      }
      flags |= RELAYOUT;
      pImage->w = newWidth;
      pImage->h = newHeight;
      RedrawEverything();
   } else {
#if 0
    for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
      pElem->redrawNeeded = 1;
    }
    flags |= REDRAW_IMAGES;
    ScheduleRedraw();
#else
      for (pElem = pImage->pList; pElem; pElem = pElem->iNext) {
         pElem->redrawNeeded = 1;
         DrawRegion(pElem->x, pElem->y - pElem->ascent, pElem->w, pElem->h);
      }
#endif
   }
}

//______________________________________________________________________________
TGHtmlImage *TGHtml::GetImage(TGHtmlImageMarkup *p)
{
   // Given an <IMG> markup, find or create an appropriate TGHtmlImage
   // object and return a pointer to that object. NULL might be returned.

   char *zWidth;
   char *zHeight;
   char *zSrc;
   TGHtmlImage *pImage;

   if (p->type != Html_IMG) { CANT_HAPPEN; return 0; }

   zSrc = p->MarkupArg("src", 0);
   if (zSrc == 0) return 0;

   zSrc = ResolveUri(zSrc);
   if (zSrc == 0) return 0;

   zWidth = p->MarkupArg("width", "");
   zHeight = p->MarkupArg("height", "");

   //p->w = atoi(zWidth);
   //p->h = atoi(zHeight);

   for (pImage = imageList; pImage; pImage = pImage->pNext) {
      if (strcmp(pImage->zUrl, zSrc) == 0
          &&  strcmp(pImage->zWidth, zWidth) == 0
          &&  strcmp(pImage->zHeight, zHeight) == 0) {
         delete [] zSrc;
         return pImage;
      }
   }

   TImage *img = LoadImage(zSrc, atoi(zWidth), atoi(zHeight));

   if (img) {
      pImage = new TGHtmlImage(this, zSrc, zWidth, zHeight);
      pImage->image = img;
    //if (img->IsAnimated()) {
    //  pImage->timer = new TTimer(this, img->GetAnimDelay());
    //}
      ImageChanged(pImage, img->GetWidth(), img->GetHeight());
      pImage->pNext = imageList;
      imageList = pImage;
   } else {
      pImage = 0;
   }

   delete [] zSrc;

   return pImage;
}

//______________________________________________________________________________
static TImage *ReadRemoteImage(const char *url)
{
   // Temporary function to read remote pictures

   TImage *image = 0;
   FILE *tmp;
   char *buf;
   TUrl fUrl(url);

   TString msg = "GET ";
   msg += fUrl.GetProtocol();
   msg += "://";
   msg += fUrl.GetHost();
   msg += ":";
   msg += fUrl.GetPort();
   msg += "/";
   msg += fUrl.GetFile();
   msg += "\r\n";

   TString uri(url);
   if (!uri.BeginsWith("http://") || uri.EndsWith(".html"))
      return 0;
   TSocket s(fUrl.GetHost(), fUrl.GetPort());
   if (!s.IsValid())
      return 0;
   if (s.SendRaw(msg.Data(), msg.Length()) == -1)
      return 0;
   Int_t size = 1024*1024;
   buf = (char *)calloc(size, sizeof(char));
   if (s.RecvRaw(buf, size) == -1) {
      free(buf);
      return 0;
   }
   TString pathtmp = Form("%s/%s",
      gSystem->TempDirectory(), gSystem->BaseName(url));
   tmp = fopen(pathtmp.Data(), "wb");
   if (!tmp) {
      free(buf);
      return 0;
   }
   fwrite(buf, sizeof(char), size, tmp);
   fclose(tmp);
   free(buf);
   image = TImage::Open(pathtmp.Data());
   if (!image->IsValid()) {
      delete image;
      image = 0;
   }
   gSystem->Unlink(pathtmp.Data());
   return image;
}

//______________________________________________________________________________
TImage *TGHtml::LoadImage(const char *url, int w, int h)
{
   // This is the default LoadImage() procedure. It just tries to load the
   // image from a file in the local filesystem.

   TImage *image = 0;

   //TGHtmlUri uri(url);

   TString uri(url);
   if (uri.BeginsWith("http://") && !uri.EndsWith(".html"))
      image = ReadRemoteImage(url);
   else
      image = TImage::Open(url);
   if (image) {
      if (!image->IsValid()) {
         delete image;
         image = 0;
         return 0;
      }
      if ((w > 0 && h > 0) && ((w != (int)image->GetWidth()) ||
          (h != (int)image->GetHeight()))) {
         image->Scale(w, h);
      }
   }
   return image;
}

//______________________________________________________________________________
char *TGHtml::GetPctWidth(TGHtmlElement *p, char *opt, char *ret)
{
   // Return the height and width, converting to percent if required

   int n, m, val;
   char *tz, *z;
   TGHtmlElement *pElem = p;

   z = pElem->MarkupArg(opt, "");
   if (!strchr(z, '%')) return z;
   if (!sscanf(z, "%d", &n)) return z;
   if (n < 0 || n > 100) return z;
   if (opt[0] == 'h') {
      val = fCanvas->GetHeight() * 100;
   } else {
      val = fCanvas->GetWidth() * 100;
   }
   if (!inTd) {
      sprintf(ret, "%d", val / n);
   } else {
      while (pElem && pElem->type != Html_TD) pElem = pElem->pPrev;
      if (!pElem) return z;
      tz = pElem->MarkupArg(opt, 0);
      if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
         sprintf(ret, "%d", m * 100 / n);
         return ret;
      }
      pElem = ((TGHtmlCell *)pElem)->pTable;
      if (!pElem) return z;
      tz = pElem->MarkupArg(opt, 0);
      if (tz && !strchr(tz, '%') && sscanf(tz, "%d", &m)) {
         sprintf(ret, "%d", m * 100 / n);
         return ret;
      }
      return z;
   }
   return ret;
}

//______________________________________________________________________________
int TGHtml::GetImageAt(int x, int y)
{
   // This routine searchs for an image beneath the coordinates x,y
   // and returns the token number of the the image, or -1 if no
   // image found.

   TGHtmlBlock *pBlock;
   TGHtmlElement *pElem;
   //int n;

   for (pBlock = firstBlock; pBlock; pBlock = pBlock->bNext) {
      if (pBlock->top > y || pBlock->bottom < y ||
          pBlock->left > x || pBlock->right < x) {
         continue;
      }
      for (pElem = pBlock->pNext; pElem; pElem = pElem->pNext) {
         if (pBlock->bNext && pElem == pBlock->bNext->pNext) break;
         if (pElem->type == Html_IMG) {
            return TokenNumber(pElem);
         }
      }
   }

   return -1;
}
<|endoftext|>


<commit_before>#include "WPILib.h"

class Asimov: public IterativeRobot
{
public:
	Asimov() {}

private:
	// Init
	void RobotInit() override
	{

	}

	// Disabled
	void DisabledInit() override
	{
	}

	void DisabledPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Teleop
	void TeleopInit() override
	{

	}

	void TeleopPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Autonomous
	void AutonomousInit() override
	{

	}

	void AutonomousPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Test
	void TestInit() override
	{

	}

	void TestPeriodic() override
	{

	}
};

START_ROBOT_CLASS(Asimov)

<commit_msg>iunno<commit_after>#include "WPILib.h"

#include "Subsystems/Intake.h"
#include "Subsystems/Shooter.h"

class Asimov: public IterativeRobot
{
private:
	subsystems::Intake intake_;
	Joystick gamepad_;

public:
	Asimov(): gamepad_(2) {}

private:
	// Init
	void RobotInit() override
	{
		intake_.Initialize();
	}

	// Disabled
	void DisabledInit() override
	{
	}

	void DisabledPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Teleop
	void TeleopInit() override
	{

	}

	void TeleopPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Autonomous
	void AutonomousInit() override
	{

	}

	void AutonomousPeriodic() override
	{
		Scheduler::GetInstance()->Run();
	}

	// Test
	void TestInit() override
	{
		intake_.SetMode(subsystems::Intake::Mode_t::VBUS);
	}

	void TestPeriodic() override
	{
		if(gamepad_.GetRawButton(1))
		{
			intake_.TakeBall(true);
		}
		else if(gamepad_.GetRawButton(2))
		{
			intake_.TakeBall(false);
		}
		else if(gamepad_.GetRawButton(3))
		{
			intake_.OutakeBall();
		}
		else
		{
			intake_.SetSpeed(gamepad_.GetRawAxis(0));
		}

	}
};

START_ROBOT_CLASS(Asimov)

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPointSet.h"
#include "otbImage.h"
#include "otbPointSetFileReader.h"
#include "itkBSplineScatteredDataPointSetToImageFilter.h"
#include "otbImageFileWriter.h"

// 1   5 12

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

  if(argc!=3)
  {
    std::cout << argv[0] <<" <input_lidar_filename> <output_image_filename>"
	      << " <output_resolution> <upper_left_corner_latitude>"
              << " <size_x> <sizee_y> <number_of_stream_divisions>"
	      << std::endl;

    return EXIT_FAILURE;
  }

  typedef double RealType;
  typedef itk::Vector<RealType, 1> VectorType;
  typedef itk::PointSet <VectorType, 2> PointSetType;
  typedef otb::PointSetFileReader<PointSetType> PointSetFileReaderType;
  PointSetFileReaderType::Pointer reader = PointSetFileReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();

  typedef double PixelType;
  typedef otb::Image<PixelType, 2> ImageType;

  typedef itk::Image<VectorType, 2> VectorImageType;

  double resolution = atof(argv[3]);
  int splineOrder = atoi(argv[4]);
  int level = atoi(argv[5]);

  ImageType::IndexType start;
  start[0] =  0;
  start[1] =  0;

  ImageType::SizeType  size;
  size[0]  = static_cast<long int >(
         ceil((reader->GetMaxX()-reader->GetMinX()+1)/resolution));
  size[1]  = static_cast<long int >(
         ceil((reader->GetMaxY()-reader->GetMinY()+1)/resolution));

  ImageType::PointType origin;
  origin[0] = 0;//minX;
  origin[1] = 0;//maxY;

  ImageType::SpacingType spacing;
  spacing[0] = resolution;
  spacing[1] = -resolution;

   typedef itk::BSplineScatteredDataPointSetToImageFilter
      <PointSetType, VectorImageType> FilterType;

  FilterType::Pointer filter = FilterType::New();

  filter->SetSplineOrder( splineOrder );
  FilterType::ArrayType ncps;
  ncps.Fill( 6 );
  filter->SetNumberOfControlPoints( ncps );
  filter->SetNumberOfLevels( level );

  // Define the parametric domain.
  filter->SetOrigin( origin );
  filter->SetSpacing( spacing );
  filter->SetSize( size );

  filter->SetInput( reader->GetOutput() );

  filter->Update();

    // Write the output to an image.
  typedef otb::Image<RealType, 2> RealImageType;
  RealImageType::Pointer image = RealImageType::New();
  ImageType::RegionType region;
  region.SetSize( size );
  region.SetIndex( start );
  image->SetRegions( region );
  image->Allocate();
  itk::ImageRegionIteratorWithIndex<RealImageType>
      Itt( image, image->GetLargestPossibleRegion() );

  for ( Itt.GoToBegin(); !Itt.IsAtEnd(); ++Itt )
  {
    Itt.Set( filter->GetOutput()->GetPixel( Itt.GetIndex() )[0] );
  }

  typedef otb::ImageFileWriter<ImageType> WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( image );
  writer->SetFileName( argv[2] );
  writer->Update();

  return EXIT_SUCCESS;

}

<commit_msg>ENH: Adding lidar to image example<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPointSet.h"
#include "otbImage.h"
#include "otbPointSetFileReader.h"
#include "itkBSplineScatteredDataPointSetToImageFilter.h"
#include "otbImageFileWriter.h"

// 1   5 12

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

  if(argc!=6)
  {
    std::cout << argv[0] <<" <input_lidar_filename> <output_image_filename>"
	      << " <output_resolution> <spline_order>"
              << " <number_of_level>"
	      << std::endl;
    return EXIT_FAILURE;
  }

  typedef double RealType;
  typedef itk::Vector<RealType, 1> VectorType;
  typedef itk::PointSet <VectorType, 2> PointSetType;
  typedef otb::PointSetFileReader<PointSetType> PointSetFileReaderType;
  PointSetFileReaderType::Pointer reader = PointSetFileReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();

  typedef double PixelType;
  typedef otb::Image<PixelType, 2> ImageType;

  typedef itk::Image<VectorType, 2> VectorImageType;

  double resolution = atof(argv[3]);
  int splineOrder = atoi(argv[4]);
  int level = atoi(argv[5]);

  ImageType::IndexType start;
  start[0] =  0;
  start[1] =  0;

//   std::cout << std::setprecision(15);
//   std::cout << reader->GetMinX() << std::endl;
//   std::cout << reader->GetMaxX() << std::endl;
//   std::cout << reader->GetMinY() << std::endl;
//   std::cout << reader->GetMaxY() << std::endl;

  ImageType::SizeType  size;
  size[0]  = static_cast<long int >(
         ceil((reader->GetMaxX()-reader->GetMinX()+1)/resolution))+1;
  size[1]  = static_cast<long int >(
         ceil((reader->GetMaxY()-reader->GetMinY()+1)/resolution))+1;

  ImageType::PointType origin;
  origin[0] = reader->GetMinX();//minX;
  origin[1] = reader->GetMaxY();//maxY;

  ImageType::SpacingType spacing;
  spacing[0] = resolution;
  spacing[1] = -resolution;

//   std::cout << "Size: " << size << std::endl;
//   std::cout << "Origin: " << origin << std::endl;
//   std::cout << "Spacing: " << spacing << std::endl;

   typedef itk::BSplineScatteredDataPointSetToImageFilter
      <PointSetType, VectorImageType> FilterType;

  FilterType::Pointer filter = FilterType::New();

  filter->SetSplineOrder( splineOrder );
  FilterType::ArrayType ncps;
  ncps.Fill( 6 );
  filter->SetNumberOfControlPoints( ncps );
  filter->SetNumberOfLevels( level );

  // Define the parametric domain.
  filter->SetOrigin( origin );
  filter->SetSpacing( spacing );
  filter->SetSize( size );

  filter->SetInput( reader->GetOutput() );

  filter->Update();

    // Write the output to an image.
  typedef otb::Image<RealType, 2> RealImageType;
  RealImageType::Pointer image = RealImageType::New();
  ImageType::RegionType region;
  region.SetSize( size );
  region.SetIndex( start );
  image->SetRegions( region );
  image->Allocate();
  itk::ImageRegionIteratorWithIndex<RealImageType>
      Itt( image, image->GetLargestPossibleRegion() );

  for ( Itt.GoToBegin(); !Itt.IsAtEnd(); ++Itt )
  {
    Itt.Set( filter->GetOutput()->GetPixel( Itt.GetIndex() )[0] );
  }

  typedef otb::ImageFileWriter<ImageType> WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( image );
  writer->SetFileName( argv[2] );
  writer->Update();

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
////////////////////////////////////////////////////////////////////////////////

#include "BasicBlocks.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"

using namespace arangodb::aql;

using Json = arangodb::basics::Json;

void SingletonBlock::buildWhitelist() {
  if (!_whitelistBuilt) {
    auto en = static_cast<SingletonNode const*>(getPlanNode());
    auto const& registerPlan = en->getRegisterPlan()->varInfo;
    std::unordered_set<Variable const*> const& varsUsedLater = en->getVarsUsedLater();

    for (auto const& it : varsUsedLater) {
      auto it2 = registerPlan.find(it->id);

      if (it2 != registerPlan.end()) {
        _whitelist.emplace((*it2).second.registerId);
      }
    }
  }
  _whitelistBuilt = true;
}

/// @brief initializeCursor, store a copy of the register values coming from
/// above
int SingletonBlock::initializeCursor(AqlItemBlock* items, size_t pos) {
  DEBUG_BEGIN_BLOCK();
  // Create a deep copy of the register values given to us:
  deleteInputVariables();

  if (items != nullptr) {
    // build a whitelist with all the registers that we will copy from above
    buildWhitelist();
    deleteInputVariables();
    TRI_ASSERT(_whitelistBuilt);
    _inputRegisterValues = items->slice(pos, _whitelist);
  }

  _done = false;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

/// @brief shutdown the singleton block
int SingletonBlock::shutdown(int errorCode) {
  int res = ExecutionBlock::shutdown(errorCode);

  deleteInputVariables();

  return res;
}

int SingletonBlock::getOrSkipSome(size_t,  // atLeast,
                                  size_t atMost, bool skipping,
                                  AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_done) {
    return TRI_ERROR_NO_ERROR;
  }

  if (!skipping) {
    result = new AqlItemBlock(
        1, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]);

    try {
      if (_inputRegisterValues != nullptr) {
        buildWhitelist();
        TRI_ASSERT(_whitelistBuilt);

        skipped++;
        for (RegisterId reg = 0; reg < _inputRegisterValues->getNrRegs();
             ++reg) {
          if (_whitelist.find(reg) == _whitelist.end()) {
            continue;
          }
          TRI_IF_FAILURE("SingletonBlock::getOrSkipSome") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          AqlValue a = _inputRegisterValues->getValue(0, reg);
          if (a.isEmpty()) {
            continue;
          }
          _inputRegisterValues->steal(a);

          try {
            TRI_IF_FAILURE("SingletonBlock::getOrSkipSomeSet") {
              THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
            }

            result->setValue(0, reg, a);
          } catch (...) {
            a.destroy();
            throw;
          }
          _inputRegisterValues->eraseValue(0, reg);
        }
      }
    } catch (...) {
      delete result;
      result = nullptr;
      throw;
    }
  } else {
    if (_inputRegisterValues != nullptr) {
      skipped++;
    }
  }

  _done = true;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

FilterBlock::FilterBlock(ExecutionEngine* engine, FilterNode const* en)
    : ExecutionBlock(engine, en), _inReg(ExecutionNode::MaxRegisterId) {
  auto it = en->getRegisterPlan()->varInfo.find(en->_inVariable->id);
  TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
  _inReg = it->second.registerId;
  TRI_ASSERT(_inReg < ExecutionNode::MaxRegisterId);
}

FilterBlock::~FilterBlock() {}

/// @brief internal function to get another block
bool FilterBlock::getBlock(size_t atLeast, size_t atMost) {
  DEBUG_BEGIN_BLOCK();
  while (true) {  // will be left by break or return
    if (!ExecutionBlock::getBlock(atLeast, atMost)) {
      return false;
    }

    if (_buffer.size() > 1) {
      break;  // Already have a current block
    }

    // Now decide about these docs:
    AqlItemBlock* cur = _buffer.front();

    _chosen.clear();
    _chosen.reserve(cur->size());
    for (size_t i = 0; i < cur->size(); ++i) {
      if (takeItem(cur, i)) {
        TRI_IF_FAILURE("FilterBlock::getBlock") {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
        }

        _chosen.emplace_back(i);
      }
    }

    _engine->_stats.filtered += (cur->size() - _chosen.size());

    if (!_chosen.empty()) {
      break;  // OK, there are some docs in the result
    }

    _buffer.pop_front();  // Block was useless, just try again
    delete cur;           // free this block

    throwIfKilled();  // check if we were aborted
  }

  return true;
  DEBUG_END_BLOCK();
}

int FilterBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
                               AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_done) {
    return TRI_ERROR_NO_ERROR;
  }

  // if _buffer.size() is > 0 then _pos is valid
  std::vector<AqlItemBlock*> collector;

  try {
    while (skipped < atLeast) {
      if (_buffer.empty()) {
        if (!getBlock(atLeast - skipped, atMost - skipped)) {
          _done = true;
          break;
        }
        _pos = 0;
      }

      // If we get here, then _buffer.size() > 0 and _pos points to a
      // valid place in it.
      AqlItemBlock* cur = _buffer.front();
      if (_chosen.size() - _pos + skipped > atMost) {
        // The current block of chosen ones is too large for atMost:
        if (!skipping) {
          std::unique_ptr<AqlItemBlock> more(
              cur->slice(_chosen, _pos, _pos + (atMost - skipped)));

          TRI_IF_FAILURE("FilterBlock::getOrSkipSome1") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          collector.emplace_back(more.get());
          more.release();
        }
        _pos += atMost - skipped;
        skipped = atMost;
      } else if (_pos > 0 || _chosen.size() < cur->size()) {
        // The current block fits into our result, but it is already
        // half-eaten or needs to be copied anyway:
        if (!skipping) {
          std::unique_ptr<AqlItemBlock> more(
              cur->steal(_chosen, _pos, _chosen.size()));

          TRI_IF_FAILURE("FilterBlock::getOrSkipSome2") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          collector.emplace_back(more.get());
          more.release();
        }
        skipped += _chosen.size() - _pos;
        delete cur;
        _buffer.pop_front();
        _chosen.clear();
        _pos = 0;
      } else {
        // The current block fits into our result and is fresh and
        // takes them all, so we can just hand it on:
        skipped += cur->size();
        if (!skipping) {
          // if any of the following statements throw, then cur is not lost,
          // as it is still contained in _buffer
          TRI_IF_FAILURE("FilterBlock::getOrSkipSome3") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }
          collector.emplace_back(cur);
        } else {
          delete cur;
        }
        _buffer.pop_front();
        _chosen.clear();
        _pos = 0;
      }
    }
  } catch (...) {
    for (auto& c : collector) {
      delete c;
    }
    throw;
  }

  if (!skipping) {
    if (collector.size() == 1) {
      result = collector[0];
    } else if (collector.size() > 1) {
      try {
        TRI_IF_FAILURE("FilterBlock::getOrSkipSomeConcatenate") {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
        }
        result = AqlItemBlock::concatenate(collector);
      } catch (...) {
        for (auto& x : collector) {
          delete x;
        }
        throw;
      }
      for (auto& x : collector) {
        delete x;
      }
    }
  }
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

bool FilterBlock::hasMore() {
  DEBUG_BEGIN_BLOCK();
  if (_done) {
    return false;
  }

  if (_buffer.empty()) {
    // QUESTION: Is this sensible? Asking whether there is more might
    // trigger an expensive fetching operation, even if later on only
    // a single document is needed due to a LIMIT...
    // However, how should we know this here?
    if (!getBlock(DefaultBatchSize(), DefaultBatchSize())) {
      _done = true;
      return false;
    }
    _pos = 0;
  }

  TRI_ASSERT(!_buffer.empty());

  // Here, _buffer.size() is > 0 and _pos points to a valid place
  // in it.

  return true;
  DEBUG_END_BLOCK();
}

int LimitBlock::initializeCursor(AqlItemBlock* items, size_t pos) {
  DEBUG_BEGIN_BLOCK();
  int res = ExecutionBlock::initializeCursor(items, pos);
  if (res != TRI_ERROR_NO_ERROR) {
    return res;
  }
  _state = 0;
  _count = 0;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

int LimitBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
                              AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_state == 2) {
    return TRI_ERROR_NO_ERROR;
  }

  if (_state == 0) {
    if (_fullCount) {
      // properly initialize fullcount value, which has a default of -1
      if (_engine->_stats.fullCount == -1) {
        _engine->_stats.fullCount = 0;
      }
    }

    if (_offset > 0) {
      size_t numActuallySkipped = 0;
      ExecutionBlock::_dependencies[0]->skip(_offset, numActuallySkipped);
      if (_fullCount) {
        _engine->_stats.fullCount += static_cast<int64_t>(numActuallySkipped);
      }
    }
    _state = 1;
    _count = 0;
    if (_limit == 0 && !_fullCount) {
      // quick exit for limit == 0
      _state = 2;
      return TRI_ERROR_NO_ERROR;
    }
  }

  // If we get to here, _state == 1 and _count < _limit
  if (_limit > 0) {
    if (atMost > _limit - _count) {
      atMost = _limit - _count;
      if (atLeast > atMost) {
        atLeast = atMost;
      }
    }

    ExecutionBlock::getOrSkipSome(atLeast, atMost, skipping, result, skipped);

    if (skipped == 0) {
      return TRI_ERROR_NO_ERROR;
    }

    _count += skipped;
    if (_fullCount) {
      _engine->_stats.fullCount += static_cast<int64_t>(skipped);
    }
  }

  if (_count >= _limit) {
    _state = 2;

    if (_fullCount) {
      // if fullCount is set, we must fetch all elements from the
      // dependency. we'll use the default batch size for this
      atLeast = DefaultBatchSize();
      atMost = DefaultBatchSize();

      // suck out all data from the dependencies
      while (true) {
        skipped = 0;
        AqlItemBlock* ignore = nullptr;
        ExecutionBlock::getOrSkipSome(atLeast, atMost, skipping, ignore,
                                      skipped);

        if (ignore != nullptr) {
          _engine->_stats.fullCount += static_cast<int64_t>(ignore->size());
          delete ignore;
        }

        if (skipped == 0) {
          break;
        }
      }
    }
  }

  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

AqlItemBlock* ReturnBlock::getSome(size_t atLeast, size_t atMost) {
  DEBUG_BEGIN_BLOCK();
  std::unique_ptr<AqlItemBlock> res(
      ExecutionBlock::getSomeWithoutRegisterClearout(atLeast, atMost));

  if (res.get() == nullptr) {
    return nullptr;
  }

  if (_returnInheritedResults) {
    return res.release();
  }

  size_t const n = res->size();

  // Let's steal the actual result and throw away the vars:
  auto ep = static_cast<ReturnNode const*>(getPlanNode());
  auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
  TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
  RegisterId const registerId = it->second.registerId;

  auto stripped = std::make_unique<AqlItemBlock>(n, 1);

  for (size_t i = 0; i < n; i++) {
    auto a = res->getValueReference(i, registerId);

    if (!a.isEmpty()) {
      if (a.requiresDestruction()) {
        res->steal(a);

        try {
          TRI_IF_FAILURE("ReturnBlock::getSome") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          stripped->setValue(i, 0, a);
        } catch (...) {
          a.destroy();
          throw;
        }
        // If the following does not go well, we do not care, since
        // the value is already stolen and installed in stripped
        res->eraseValue(i, registerId);
      } else {
        stripped->setValue(i, 0, a);
      }
    }
  }

  delete res.get();
  res.release();

  return stripped.release();
  DEBUG_END_BLOCK();
}

/// @brief make the return block return the results inherited from above,
/// without creating new blocks
/// returns the id of the register the final result can be found in
RegisterId ReturnBlock::returnInheritedResults() {
  DEBUG_BEGIN_BLOCK();
  _returnInheritedResults = true;

  auto ep = static_cast<ReturnNode const*>(getPlanNode());
  auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
  TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());

  return it->second.registerId;
  DEBUG_END_BLOCK();
}

/// @brief initializeCursor, only call base
int NoResultsBlock::initializeCursor(AqlItemBlock*, size_t) {
  DEBUG_BEGIN_BLOCK();
  _done = true;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

int NoResultsBlock::getOrSkipSome(size_t,  // atLeast
                                  size_t,  // atMost
                                  bool,    // skipping
                                  AqlItemBlock*& result, size_t& skipped) {
  TRI_ASSERT(result == nullptr && skipped == 0);
  return TRI_ERROR_NO_ERROR;
}
<commit_msg>silenced cppcheck warning<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
////////////////////////////////////////////////////////////////////////////////

#include "BasicBlocks.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"

using namespace arangodb::aql;

using Json = arangodb::basics::Json;

void SingletonBlock::buildWhitelist() {
  if (!_whitelistBuilt) {
    auto en = static_cast<SingletonNode const*>(getPlanNode());
    auto const& registerPlan = en->getRegisterPlan()->varInfo;
    std::unordered_set<Variable const*> const& varsUsedLater = en->getVarsUsedLater();

    for (auto const& it : varsUsedLater) {
      auto it2 = registerPlan.find(it->id);

      if (it2 != registerPlan.end()) {
        _whitelist.emplace((*it2).second.registerId);
      }
    }
  }
  _whitelistBuilt = true;
}

/// @brief initializeCursor, store a copy of the register values coming from
/// above
int SingletonBlock::initializeCursor(AqlItemBlock* items, size_t pos) {
  DEBUG_BEGIN_BLOCK();
  // Create a deep copy of the register values given to us:
  deleteInputVariables();

  if (items != nullptr) {
    // build a whitelist with all the registers that we will copy from above
    buildWhitelist();
    deleteInputVariables();
    TRI_ASSERT(_whitelistBuilt);
    _inputRegisterValues = items->slice(pos, _whitelist);
  }

  _done = false;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

/// @brief shutdown the singleton block
int SingletonBlock::shutdown(int errorCode) {
  int res = ExecutionBlock::shutdown(errorCode);

  deleteInputVariables();

  return res;
}

int SingletonBlock::getOrSkipSome(size_t,  // atLeast,
                                  size_t atMost, bool skipping,
                                  AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_done) {
    return TRI_ERROR_NO_ERROR;
  }

  if (!skipping) {
    result = new AqlItemBlock(
        1, getPlanNode()->getRegisterPlan()->nrRegs[getPlanNode()->getDepth()]);

    try {
      if (_inputRegisterValues != nullptr) {
        buildWhitelist();
        TRI_ASSERT(_whitelistBuilt);

        skipped++;
        for (RegisterId reg = 0; reg < _inputRegisterValues->getNrRegs();
             ++reg) {
          if (_whitelist.find(reg) == _whitelist.end()) {
            continue;
          }
          TRI_IF_FAILURE("SingletonBlock::getOrSkipSome") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          AqlValue a = _inputRegisterValues->getValue(0, reg);
          if (a.isEmpty()) {
            continue;
          }
          _inputRegisterValues->steal(a);

          try {
            TRI_IF_FAILURE("SingletonBlock::getOrSkipSomeSet") {
              THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
            }

            result->setValue(0, reg, a);
          } catch (...) {
            a.destroy();
            throw;
          }
          _inputRegisterValues->eraseValue(0, reg);
        }
      }
    } catch (...) {
      delete result;
      result = nullptr;
      throw;
    }
  } else {
    if (_inputRegisterValues != nullptr) {
      skipped++;
    }
  }

  _done = true;
  return TRI_ERROR_NO_ERROR;

  // cppcheck-suppress style
  DEBUG_END_BLOCK();
}

FilterBlock::FilterBlock(ExecutionEngine* engine, FilterNode const* en)
    : ExecutionBlock(engine, en), _inReg(ExecutionNode::MaxRegisterId) {
  auto it = en->getRegisterPlan()->varInfo.find(en->_inVariable->id);
  TRI_ASSERT(it != en->getRegisterPlan()->varInfo.end());
  _inReg = it->second.registerId;
  TRI_ASSERT(_inReg < ExecutionNode::MaxRegisterId);
}

FilterBlock::~FilterBlock() {}

/// @brief internal function to get another block
bool FilterBlock::getBlock(size_t atLeast, size_t atMost) {
  DEBUG_BEGIN_BLOCK();
  while (true) {  // will be left by break or return
    if (!ExecutionBlock::getBlock(atLeast, atMost)) {
      return false;
    }

    if (_buffer.size() > 1) {
      break;  // Already have a current block
    }

    // Now decide about these docs:
    AqlItemBlock* cur = _buffer.front();

    _chosen.clear();
    _chosen.reserve(cur->size());
    for (size_t i = 0; i < cur->size(); ++i) {
      if (takeItem(cur, i)) {
        TRI_IF_FAILURE("FilterBlock::getBlock") {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
        }

        _chosen.emplace_back(i);
      }
    }

    _engine->_stats.filtered += (cur->size() - _chosen.size());

    if (!_chosen.empty()) {
      break;  // OK, there are some docs in the result
    }

    _buffer.pop_front();  // Block was useless, just try again
    delete cur;           // free this block

    throwIfKilled();  // check if we were aborted
  }

  return true;
  DEBUG_END_BLOCK();
}

int FilterBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
                               AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_done) {
    return TRI_ERROR_NO_ERROR;
  }

  // if _buffer.size() is > 0 then _pos is valid
  std::vector<AqlItemBlock*> collector;

  try {
    while (skipped < atLeast) {
      if (_buffer.empty()) {
        if (!getBlock(atLeast - skipped, atMost - skipped)) {
          _done = true;
          break;
        }
        _pos = 0;
      }

      // If we get here, then _buffer.size() > 0 and _pos points to a
      // valid place in it.
      AqlItemBlock* cur = _buffer.front();
      if (_chosen.size() - _pos + skipped > atMost) {
        // The current block of chosen ones is too large for atMost:
        if (!skipping) {
          std::unique_ptr<AqlItemBlock> more(
              cur->slice(_chosen, _pos, _pos + (atMost - skipped)));

          TRI_IF_FAILURE("FilterBlock::getOrSkipSome1") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          collector.emplace_back(more.get());
          more.release();
        }
        _pos += atMost - skipped;
        skipped = atMost;
      } else if (_pos > 0 || _chosen.size() < cur->size()) {
        // The current block fits into our result, but it is already
        // half-eaten or needs to be copied anyway:
        if (!skipping) {
          std::unique_ptr<AqlItemBlock> more(
              cur->steal(_chosen, _pos, _chosen.size()));

          TRI_IF_FAILURE("FilterBlock::getOrSkipSome2") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          collector.emplace_back(more.get());
          more.release();
        }
        skipped += _chosen.size() - _pos;
        delete cur;
        _buffer.pop_front();
        _chosen.clear();
        _pos = 0;
      } else {
        // The current block fits into our result and is fresh and
        // takes them all, so we can just hand it on:
        skipped += cur->size();
        if (!skipping) {
          // if any of the following statements throw, then cur is not lost,
          // as it is still contained in _buffer
          TRI_IF_FAILURE("FilterBlock::getOrSkipSome3") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }
          collector.emplace_back(cur);
        } else {
          delete cur;
        }
        _buffer.pop_front();
        _chosen.clear();
        _pos = 0;
      }
    }
  } catch (...) {
    for (auto& c : collector) {
      delete c;
    }
    throw;
  }

  if (!skipping) {
    if (collector.size() == 1) {
      result = collector[0];
    } else if (collector.size() > 1) {
      try {
        TRI_IF_FAILURE("FilterBlock::getOrSkipSomeConcatenate") {
          THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
        }
        result = AqlItemBlock::concatenate(collector);
      } catch (...) {
        for (auto& x : collector) {
          delete x;
        }
        throw;
      }
      for (auto& x : collector) {
        delete x;
      }
    }
  }
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

bool FilterBlock::hasMore() {
  DEBUG_BEGIN_BLOCK();
  if (_done) {
    return false;
  }

  if (_buffer.empty()) {
    // QUESTION: Is this sensible? Asking whether there is more might
    // trigger an expensive fetching operation, even if later on only
    // a single document is needed due to a LIMIT...
    // However, how should we know this here?
    if (!getBlock(DefaultBatchSize(), DefaultBatchSize())) {
      _done = true;
      return false;
    }
    _pos = 0;
  }

  TRI_ASSERT(!_buffer.empty());

  // Here, _buffer.size() is > 0 and _pos points to a valid place
  // in it.

  return true;
  DEBUG_END_BLOCK();
}

int LimitBlock::initializeCursor(AqlItemBlock* items, size_t pos) {
  DEBUG_BEGIN_BLOCK();
  int res = ExecutionBlock::initializeCursor(items, pos);
  if (res != TRI_ERROR_NO_ERROR) {
    return res;
  }
  _state = 0;
  _count = 0;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

int LimitBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
                              AqlItemBlock*& result, size_t& skipped) {
  DEBUG_BEGIN_BLOCK();
  TRI_ASSERT(result == nullptr && skipped == 0);

  if (_state == 2) {
    return TRI_ERROR_NO_ERROR;
  }

  if (_state == 0) {
    if (_fullCount) {
      // properly initialize fullcount value, which has a default of -1
      if (_engine->_stats.fullCount == -1) {
        _engine->_stats.fullCount = 0;
      }
    }

    if (_offset > 0) {
      size_t numActuallySkipped = 0;
      ExecutionBlock::_dependencies[0]->skip(_offset, numActuallySkipped);
      if (_fullCount) {
        _engine->_stats.fullCount += static_cast<int64_t>(numActuallySkipped);
      }
    }
    _state = 1;
    _count = 0;
    if (_limit == 0 && !_fullCount) {
      // quick exit for limit == 0
      _state = 2;
      return TRI_ERROR_NO_ERROR;
    }
  }

  // If we get to here, _state == 1 and _count < _limit
  if (_limit > 0) {
    if (atMost > _limit - _count) {
      atMost = _limit - _count;
      if (atLeast > atMost) {
        atLeast = atMost;
      }
    }

    ExecutionBlock::getOrSkipSome(atLeast, atMost, skipping, result, skipped);

    if (skipped == 0) {
      return TRI_ERROR_NO_ERROR;
    }

    _count += skipped;
    if (_fullCount) {
      _engine->_stats.fullCount += static_cast<int64_t>(skipped);
    }
  }

  if (_count >= _limit) {
    _state = 2;

    if (_fullCount) {
      // if fullCount is set, we must fetch all elements from the
      // dependency. we'll use the default batch size for this
      atLeast = DefaultBatchSize();
      atMost = DefaultBatchSize();

      // suck out all data from the dependencies
      while (true) {
        skipped = 0;
        AqlItemBlock* ignore = nullptr;
        ExecutionBlock::getOrSkipSome(atLeast, atMost, skipping, ignore,
                                      skipped);

        if (ignore != nullptr) {
          _engine->_stats.fullCount += static_cast<int64_t>(ignore->size());
          delete ignore;
        }

        if (skipped == 0) {
          break;
        }
      }
    }
  }

  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

AqlItemBlock* ReturnBlock::getSome(size_t atLeast, size_t atMost) {
  DEBUG_BEGIN_BLOCK();
  std::unique_ptr<AqlItemBlock> res(
      ExecutionBlock::getSomeWithoutRegisterClearout(atLeast, atMost));

  if (res.get() == nullptr) {
    return nullptr;
  }

  if (_returnInheritedResults) {
    return res.release();
  }

  size_t const n = res->size();

  // Let's steal the actual result and throw away the vars:
  auto ep = static_cast<ReturnNode const*>(getPlanNode());
  auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
  TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());
  RegisterId const registerId = it->second.registerId;

  auto stripped = std::make_unique<AqlItemBlock>(n, 1);

  for (size_t i = 0; i < n; i++) {
    auto a = res->getValueReference(i, registerId);

    if (!a.isEmpty()) {
      if (a.requiresDestruction()) {
        res->steal(a);

        try {
          TRI_IF_FAILURE("ReturnBlock::getSome") {
            THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
          }

          stripped->setValue(i, 0, a);
        } catch (...) {
          a.destroy();
          throw;
        }
        // If the following does not go well, we do not care, since
        // the value is already stolen and installed in stripped
        res->eraseValue(i, registerId);
      } else {
        stripped->setValue(i, 0, a);
      }
    }
  }

  delete res.get();
  res.release();

  return stripped.release();
  DEBUG_END_BLOCK();
}

/// @brief make the return block return the results inherited from above,
/// without creating new blocks
/// returns the id of the register the final result can be found in
RegisterId ReturnBlock::returnInheritedResults() {
  DEBUG_BEGIN_BLOCK();
  _returnInheritedResults = true;

  auto ep = static_cast<ReturnNode const*>(getPlanNode());
  auto it = ep->getRegisterPlan()->varInfo.find(ep->_inVariable->id);
  TRI_ASSERT(it != ep->getRegisterPlan()->varInfo.end());

  return it->second.registerId;
  DEBUG_END_BLOCK();
}

/// @brief initializeCursor, only call base
int NoResultsBlock::initializeCursor(AqlItemBlock*, size_t) {
  DEBUG_BEGIN_BLOCK();
  _done = true;
  return TRI_ERROR_NO_ERROR;
  DEBUG_END_BLOCK();
}

int NoResultsBlock::getOrSkipSome(size_t,  // atLeast
                                  size_t,  // atMost
                                  bool,    // skipping
                                  AqlItemBlock*& result, size_t& skipped) {
  TRI_ASSERT(result == nullptr && skipped == 0);
  return TRI_ERROR_NO_ERROR;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include "fixel/index_remapper.h"

namespace MR
{
  namespace Fixel
  {

    constexpr index_type IndexRemapper::invalid;

    IndexRemapper::IndexRemapper (const index_type num_fixels)
    {
      external2internal.resize (num_fixels);
      internal2external.resize (num_fixels);
      for (index_type f = 0; f != num_fixels; ++f)
        external2internal[f] = internal2external[f] = f;
      mapping_is_default = true;
    }

    IndexRemapper::IndexRemapper (Image<bool> fixel_mask)
    {
      external2internal.resize (fixel_mask.size (0));
      index_type counter = 0;
      for (fixel_mask.index(0) = 0; fixel_mask.index(0) != fixel_mask.size(0); ++fixel_mask.index(0))
        external2internal[fixel_mask.index(0)] = fixel_mask.value() ? counter++ : invalid;
  #ifdef NDEBUG
      internal2external.resize (counter);
  #else
      internal2external.assign (counter, invalid);
  #endif
      for (index_type e = 0; e != fixel_mask.size(0); ++e) {
        if (external2internal[e] >= 0)
          internal2external[external2internal[e]] = e;
      }
  #ifndef NDEBUG
      for (index_type i = 0; i != counter; ++i)
        assert (internal2external[i] != invalid);
  #endif
      mapping_is_default = false;
    }

  }
}
<commit_msg>fixelcfestats: Fix segfault with use of -mask option<commit_after>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include "fixel/index_remapper.h"

namespace MR
{
  namespace Fixel
  {

    constexpr index_type IndexRemapper::invalid;

    IndexRemapper::IndexRemapper (const index_type num_fixels)
    {
      external2internal.resize (num_fixels);
      internal2external.resize (num_fixels);
      for (index_type f = 0; f != num_fixels; ++f)
        external2internal[f] = internal2external[f] = f;
      mapping_is_default = true;
    }

    IndexRemapper::IndexRemapper (Image<bool> fixel_mask)
    {
      external2internal.resize (fixel_mask.size (0));
      index_type counter = 0;
      for (fixel_mask.index(0) = 0; fixel_mask.index(0) != fixel_mask.size(0); ++fixel_mask.index(0))
        external2internal[fixel_mask.index(0)] = fixel_mask.value() ? counter++ : invalid;
  #ifdef NDEBUG
      internal2external.resize (counter);
  #else
      internal2external.assign (counter, invalid);
  #endif
      for (index_type e = 0; e != fixel_mask.size(0); ++e) {
        if (external2internal[e] != invalid)
          internal2external[external2internal[e]] = e;
      }
  #ifndef NDEBUG
      for (index_type i = 0; i != counter; ++i)
        assert (internal2external[i] != invalid);
  #endif
      mapping_is_default = false;
    }

  }
}
<|endoftext|>