text:
// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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.

#include "client/crashpad_client.h"

#include <windows.h>

// Must be after windows.h.
#include <versionhelpers.h>

#include <signal.h>
#include <stdint.h>
#include <string.h>

#include <memory>

#include "base/atomicops.h"
#include "base/logging.h"
#include "base/scoped_generic.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "util/file/file_io.h"
#include "util/misc/capture_context.h"
#include "util/misc/from_pointer_cast.h"
#include "util/misc/random_string.h"
#include "util/win/address_types.h"
#include "util/win/command_line.h"
#include "util/win/context_wrappers.h"
#include "util/win/critical_section_with_debug_info.h"
#include "util/win/get_function.h"
#include "util/win/handle.h"
#include "util/win/initial_client_data.h"
#include "util/win/loader_lock.h"
#include "util/win/nt_internals.h"
#include "util/win/ntstatus_logging.h"
#include "util/win/process_info.h"
#include "util/win/registration_protocol_win.h"
#include "util/win/safe_terminate_process.h"
#include "util/win/scoped_process_suspend.h"
#include "util/win/termination_codes.h"
#include "util/win/xp_compat.h"

namespace crashpad {

namespace {

// This handle is never closed. This is used to signal to the server that a dump
// should be taken in the event of a crash.
HANDLE g_signal_exception = INVALID_HANDLE_VALUE;

// Where we store the exception information that the crash handler reads.
ExceptionInformation g_crash_exception_information;

// These handles are never closed. g_signal_non_crash_dump is used to signal to
// the server to take a dump (not due to an exception), and the server will
// signal g_non_crash_dump_done when the dump is completed.
HANDLE g_signal_non_crash_dump = INVALID_HANDLE_VALUE;
HANDLE g_non_crash_dump_done = INVALID_HANDLE_VALUE;

// Guards multiple simultaneous calls to DumpWithoutCrash(). This is leaked.
base::Lock* g_non_crash_dump_lock;

// Where we store a pointer to the context information when taking a non-crash
// dump.
ExceptionInformation g_non_crash_exception_information;

enum class StartupState : int {
  kNotReady = 0,  // This must be value 0 because it is the initial value of a
                  // global AtomicWord.
  kSucceeded = 1,  // The CreateProcess() for the handler succeeded.
  kFailed = 2,  // The handler failed to start.
};

// This is a tri-state of type StartupState. It starts at 0 == kNotReady, and
// when the handler is known to have started successfully, or failed to start
// the value will be updated. The unhandled exception filter will not proceed
// until one of those two cases happens.
base::subtle::AtomicWord g_handler_startup_state;

// A CRITICAL_SECTION initialized with
// RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO to force it to be allocated with a
// valid .DebugInfo field. The address of this critical section is given to the
// handler. All critical sections with debug info are linked in a doubly-linked
// list, so this allows the handler to capture all of them.
CRITICAL_SECTION g_critical_section_with_debug_info;

void SetHandlerStartupState(StartupState state) {
  DCHECK(state == StartupState::kSucceeded || state == StartupState::kFailed);
  base::subtle::Release_Store(&g_handler_startup_state,
                              static_cast<base::subtle::AtomicWord>(state));
}

StartupState BlockUntilHandlerStartedOrFailed() {
  // Wait until we know the handler has either succeeded or failed to start.
  base::subtle::AtomicWord startup_state;
  while (
      (startup_state = base::subtle::Acquire_Load(&g_handler_startup_state)) ==
      static_cast<int>(StartupState::kNotReady)) {
    Sleep(1);
  }

  return static_cast<StartupState>(startup_state);
}

#if defined(ADDRESS_SANITIZER)
extern "C" LONG __asan_unhandled_exception_filter(EXCEPTION_POINTERS* info);
#endif

LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
#if defined(ADDRESS_SANITIZER)
  // In ASan builds, delegate to the ASan exception filter.
  LONG status = __asan_unhandled_exception_filter(exception_pointers);
  if (status != EXCEPTION_CONTINUE_SEARCH)
    return status;
#endif

  if (BlockUntilHandlerStartedOrFailed() == StartupState::kFailed) {
    // If we know for certain that the handler has failed to start, then abort
    // here, rather than trying to signal to a handler that will never arrive,
    // and then sleeping unnecessarily.
    LOG(ERROR) << "crash server failed to launch, self-terminating";
    SafeTerminateProcess(GetCurrentProcess(), kTerminationCodeCrashNoDump);
    return EXCEPTION_CONTINUE_SEARCH;
  }

  // Otherwise, we know the handler startup has succeeded, and we can continue.

  // Tracks whether a thread has already entered UnhandledExceptionHandler.
  static base::subtle::AtomicWord have_crashed;

  // This is a per-process handler. While this handler is being invoked, other
  // threads are still executing as usual, so multiple threads could enter at
  // the same time. Because we're in a crashing state, we shouldn't be doing
  // anything that might cause allocations, call into kernel mode, etc. So, we
  // don't want to take a critical section here to avoid simultaneous access to
  // the global exception pointers in ExceptionInformation. Because the crash
  // handler will record all threads, it's fine to simply have the second and
  // subsequent entrants block here. They will soon be suspended by the crash
  // handler, and then the entire process will be terminated below. This means
  // that we won't save the exception pointers from the second and further
  // crashes, but contention here is very unlikely, and we'll still have a stack
  // that's blocked at this location.
  if (base::subtle::Barrier_AtomicIncrement(&have_crashed, 1) > 1) {
    SleepEx(INFINITE, false);
  }

  // Otherwise, we're the first thread, so record the exception pointer and
  // signal the crash handler.
  g_crash_exception_information.thread_id = GetCurrentThreadId();
  g_crash_exception_information.exception_pointers =
      FromPointerCast<WinVMAddress>(exception_pointers);

  // Now signal the crash server, which will take a dump and then terminate us
  // when it's complete.
  SetEvent(g_signal_exception);

  // Time to wait for the handler to create a dump.
  constexpr DWORD kMillisecondsUntilTerminate = 60 * 1000;

  // Sleep for a while to allow it to process us. Eventually, we terminate
  // ourselves in case the crash server is gone, so that we don't leave zombies
  // around. This would ideally never happen.
  Sleep(kMillisecondsUntilTerminate);

  LOG(ERROR) << "crash server did not respond, self-terminating";

  SafeTerminateProcess(GetCurrentProcess(), kTerminationCodeCrashNoDump);

  return EXCEPTION_CONTINUE_SEARCH;
}

void HandleAbortSignal(int signum) {
  DCHECK_EQ(signum, SIGABRT);

  CONTEXT context;
  CaptureContext(&context);

  EXCEPTION_RECORD record = {};
  record.ExceptionCode = STATUS_FATAL_APP_EXIT;
  record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
  record.ExceptionAddress = ProgramCounterFromCONTEXT(&context);

  EXCEPTION_POINTERS exception_pointers;
  exception_pointers.ContextRecord = &context;
  exception_pointers.ExceptionRecord = &record;

  UnhandledExceptionHandler(&exception_pointers);
}

std::wstring FormatArgumentString(const std::string& name,
                                  const std::wstring& value) {
  return std::wstring(L"--") + base::UTF8ToWide(name) + L"=" + value;
}

struct ScopedProcThreadAttributeListTraits {
  static PPROC_THREAD_ATTRIBUTE_LIST InvalidValue() { return nullptr; }

  static void Free(PPROC_THREAD_ATTRIBUTE_LIST proc_thread_attribute_list) {
    // This is able to use GET_FUNCTION_REQUIRED() instead of GET_FUNCTION()
    // because it will only be called if InitializeProcThreadAttributeList() and
    // UpdateProcThreadAttribute() are present.
    static const auto delete_proc_thread_attribute_list =
        GET_FUNCTION_REQUIRED(L"kernel32.dll", ::DeleteProcThreadAttributeList);
    delete_proc_thread_attribute_list(proc_thread_attribute_list);
  }
};

using ScopedProcThreadAttributeList =
    base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST,
                        ScopedProcThreadAttributeListTraits>;

bool IsInheritableHandle(HANDLE handle) {
  if (!handle || handle == INVALID_HANDLE_VALUE)
    return false;

  // File handles (FILE_TYPE_DISK) and pipe handles (FILE_TYPE_PIPE) are known
  // to be inheritable. Console handles (FILE_TYPE_CHAR) are not inheritable via
  // PROC_THREAD_ATTRIBUTE_HANDLE_LIST. See
  // https://crashpad.chromium.org/bug/77.
  DWORD handle_type = GetFileType(handle);
  return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE;
}

// Adds |handle| to |handle_list| if it appears valid, and is not already in
// |handle_list|.
//
// Invalid handles (including INVALID_HANDLE_VALUE and null handles) cannot be
// added to a PPROC_THREAD_ATTRIBUTE_LIST's PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
// If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with
// ERROR_INVALID_PARAMETER. If a null handle appears, the child process will
// silently not inherit any handles.
//
// Use this function to add handles with uncertain validities.
void AddHandleToListIfValidAndInheritable(std::vector<HANDLE>* handle_list,
                                          HANDLE handle) {
  // There doesn't seem to be any documentation of this, but if there's a handle
  // duplicated in this list, CreateProcess() fails with
  // ERROR_INVALID_PARAMETER.
  if (IsInheritableHandle(handle) &&
      std::find(handle_list->begin(), handle_list->end(), handle) ==
          handle_list->end()) {
    handle_list->push_back(handle);
  }
}

void AddUint32(std::vector<unsigned char>* data_vector, uint32_t data) {
  data_vector->push_back(static_cast<unsigned char>(data & 0xff));
  data_vector->push_back(static_cast<unsigned char>((data & 0xff00) >> 8));
  data_vector->push_back(static_cast<unsigned char>((data & 0xff0000) >> 16));
  data_vector->push_back(static_cast<unsigned char>((data & 0xff000000) >> 24));
}

void AddUint64(std::vector<unsigned char>* data_vector, uint64_t data) {
  AddUint32(data_vector, static_cast<uint32_t>(data & 0xffffffffULL));
  AddUint32(data_vector,
            static_cast<uint32_t>((data & 0xffffffff00000000ULL) >> 32));
}

//! \brief Creates a randomized pipe name to listen for client registrations
//!     on and returns its name.
//!
//! \param[out] pipe_name The pipe name that will be listened on.
//! \param[out] pipe_handle The first pipe instance corresponding for the pipe.
void CreatePipe(std::wstring* pipe_name, ScopedFileHANDLE* pipe_instance) {
  int tries = 5;
  std::string pipe_name_base = base::StringPrintf(
#if defined(WINDOWS_UWP)
      "\\\\.\\pipe\\LOCAL\\crashpad_%lu_",
#else
      "\\\\.\\pipe\\crashpad_%lu_",
#endif
      GetCurrentProcessId());
  do {
    *pipe_name = base::UTF8ToWide(pipe_name_base + RandomString());

    pipe_instance->reset(CreateNamedPipeInstance(*pipe_name, true));

    // CreateNamedPipe() is documented as setting the error to
    // ERROR_ACCESS_DENIED if FILE_FLAG_FIRST_PIPE_INSTANCE is specified and the
    // pipe name is already in use. However it may set the error to other codes
    // such as ERROR_PIPE_BUSY (if the pipe already exists and has reached its
    // maximum instance count) or ERROR_INVALID_PARAMETER (if the pipe already
    // exists and its attributes differ from those specified to
    // CreateNamedPipe()). Some of these errors may be ambiguous: for example,
    // ERROR_INVALID_PARAMETER may also occur if CreateNamedPipe() is called
    // incorrectly even in the absence of an existing pipe by the same name.
    // Rather than chasing down all of the possible errors that might indicate
    // that a pipe name is already in use, retry up to a few times on any error.
  } while (!pipe_instance->is_valid() && --tries);

  PCHECK(pipe_instance->is_valid()) << "CreateNamedPipe";
}

struct BackgroundHandlerStartThreadData {
  BackgroundHandlerStartThreadData(
      const base::FilePath& handler,
      const base::FilePath& database,
      const base::FilePath& metrics_dir,
      const std::string& url,
      const std::map<std::string, std::string>& annotations,
      const std::vector<std::string>& arguments,
      const std::vector<base::FilePath>& attachments,
      const std::wstring& ipc_pipe,
      ScopedFileHANDLE ipc_pipe_handle)
      : handler(handler),
        database(database),
        metrics_dir(metrics_dir),
        url(url),
        annotations(annotations),
        arguments(arguments),
        attachments(attachments),
        ipc_pipe(ipc_pipe),
        ipc_pipe_handle(std::move(ipc_pipe_handle)) {}

  base::FilePath handler;
  base::FilePath database;
  base::FilePath metrics_dir;
  std::string url;
  std::map<std::string, std::string> annotations;
  std::vector<std::string> arguments;
  std::vector<base::FilePath> attachments;
  std::wstring ipc_pipe;
  ScopedFileHANDLE ipc_pipe_handle;
};

// Ensures that SetHandlerStartupState() is called on scope exit. Assumes
// failure, and on success, SetSuccessful() should be called.
class ScopedCallSetHandlerStartupState {
 public:
  ScopedCallSetHandlerStartupState() : successful_(false) {}

  ScopedCallSetHandlerStartupState(const ScopedCallSetHandlerStartupState&) =
      delete;
  ScopedCallSetHandlerStartupState& operator=(
      const ScopedCallSetHandlerStartupState&) = delete;

  ~ScopedCallSetHandlerStartupState() {
    SetHandlerStartupState(successful_ ? StartupState::kSucceeded
                                       : StartupState::kFailed);
  }

  void SetSuccessful() { successful_ = true; }

 private:
  bool successful_;
};

bool StartHandlerProcess(
    std::unique_ptr<BackgroundHandlerStartThreadData> data) {
  CHECK(!IsThreadInLoaderLock());

  ScopedCallSetHandlerStartupState scoped_startup_state_caller;

  std::wstring command_line;
  AppendCommandLineArgument(data->handler.value(), &command_line);
  for (const std::string& argument : data->arguments) {
    AppendCommandLineArgument(base::UTF8ToWide(argument), &command_line);
  }
  if (!data->database.value().empty()) {
    AppendCommandLineArgument(
        FormatArgumentString("database", data->database.value()),
        &command_line);
  }
  if (!data->metrics_dir.value().empty()) {
    AppendCommandLineArgument(
        FormatArgumentString("metrics-dir", data->metrics_dir.value()),
        &command_line);
  }
  if (!data->url.empty()) {
    AppendCommandLineArgument(
        FormatArgumentString("url", base::UTF8ToWide(data->url)),
        &command_line);
  }
  for (const auto& kv : data->annotations) {
    AppendCommandLineArgument(
        FormatArgumentString("annotation",
                             base::UTF8ToWide(kv.first + '=' + kv.second)),
        &command_line);
  }
  for (const base::FilePath& attachment : data->attachments) {
    AppendCommandLineArgument(
        FormatArgumentString("attachment", attachment.value()),
        &command_line);
  }

  ScopedKernelHANDLE this_process(
      OpenProcess(kXPProcessAllAccess, true, GetCurrentProcessId()));
  if (!this_process.is_valid()) {
    PLOG(ERROR) << "OpenProcess";
    return false;
  }

  InitialClientData initial_client_data(
      g_signal_exception,
      g_signal_non_crash_dump,
      g_non_crash_dump_done,
      data->ipc_pipe_handle.get(),
      this_process.get(),
      FromPointerCast<WinVMAddress>(&g_crash_exception_information),
      FromPointerCast<WinVMAddress>(&g_non_crash_exception_information),
      FromPointerCast<WinVMAddress>(&g_critical_section_with_debug_info));
  AppendCommandLineArgument(
      base::UTF8ToWide(std::string("--initial-client-data=") +
                       initial_client_data.StringRepresentation()),
      &command_line);

  BOOL rv;
  DWORD creation_flags;
  STARTUPINFOEX startup_info = {};
  startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
  startup_info.StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  startup_info.StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  startup_info.StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);

  std::vector<HANDLE> handle_list;
  std::unique_ptr<uint8_t[]> proc_thread_attribute_list_storage;
  ScopedProcThreadAttributeList proc_thread_attribute_list_owner;

  static const auto initialize_proc_thread_attribute_list =
      GET_FUNCTION(L"kernel32.dll", ::InitializeProcThreadAttributeList);
  static const auto update_proc_thread_attribute =
      initialize_proc_thread_attribute_list
          ? GET_FUNCTION(L"kernel32.dll", ::UpdateProcThreadAttribute)
          : nullptr;
  if (!initialize_proc_thread_attribute_list || !update_proc_thread_attribute) {
    // The OS doesn't allow handle inheritance to be restricted, so the handler
    // will inherit every inheritable handle.
    creation_flags = 0;
    startup_info.StartupInfo.cb = sizeof(startup_info.StartupInfo);
  } else {
    // Restrict handle inheritance to just those needed in the handler.

    creation_flags = EXTENDED_STARTUPINFO_PRESENT;
    startup_info.StartupInfo.cb = sizeof(startup_info);
    SIZE_T size;
    rv = initialize_proc_thread_attribute_list(nullptr, 1, 0, &size);
    if (rv) {
      LOG(ERROR) << "InitializeProcThreadAttributeList (size) succeeded, "
                    "expected failure";
      return false;
    } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      PLOG(ERROR) << "InitializeProcThreadAttributeList (size)";
      return false;
    }

    proc_thread_attribute_list_storage.reset(new uint8_t[size]);
    startup_info.lpAttributeList =
        reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(
            proc_thread_attribute_list_storage.get());
    rv = initialize_proc_thread_attribute_list(
        startup_info.lpAttributeList, 1, 0, &size);
    if (!rv) {
      PLOG(ERROR) << "InitializeProcThreadAttributeList";
      return false;
    }
    proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList);

    handle_list.reserve(8);
    handle_list.push_back(g_signal_exception);
    handle_list.push_back(g_signal_non_crash_dump);
    handle_list.push_back(g_non_crash_dump_done);
    handle_list.push_back(data->ipc_pipe_handle.get());
    handle_list.push_back(this_process.get());
    AddHandleToListIfValidAndInheritable(&handle_list,
                                         startup_info.StartupInfo.hStdInput);
    AddHandleToListIfValidAndInheritable(&handle_list,
                                         startup_info.StartupInfo.hStdOutput);
    AddHandleToListIfValidAndInheritable(&handle_list,
                                         startup_info.StartupInfo.hStdError);
    rv = update_proc_thread_attribute(
        startup_info.lpAttributeList,
        0,
        PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
        &handle_list[0],
        handle_list.size() * sizeof(handle_list[0]),
        nullptr,
        nullptr);
    if (!rv) {
      PLOG(ERROR) << "UpdateProcThreadAttribute";
      return false;
    }
  }

  // If the embedded crashpad handler is being started via an entry point in a
  // DLL (the handler executable is rundll32.exe), then don't pass
  // the application name to CreateProcess as this appears to generate an
  // invalid command line where the first argument needed by rundll32 is not in
  // the correct format as required in:
  // https://support.microsoft.com/en-ca/help/164787/info-windows-rundll-and-rundll32-interface
  const base::WStringPiece kRunDll32Exe(L"rundll32.exe");
  bool is_embedded_in_dll = false;
  if (data->handler.value().size() >= kRunDll32Exe.size() &&
      _wcsicmp(data->handler.value()
                   .substr(data->handler.value().size() - kRunDll32Exe.size())
                   .c_str(),
               kRunDll32Exe.data()) == 0) {
    is_embedded_in_dll = true;
  }

  PROCESS_INFORMATION process_info;
  rv = CreateProcess(
      is_embedded_in_dll ? nullptr : data->handler.value().c_str(),
      &command_line[0],
      nullptr,
      nullptr,
      true,
      creation_flags,
      nullptr,
      nullptr,
      &startup_info.StartupInfo,
      &process_info);
  if (!rv) {
    PLOG(ERROR) << "CreateProcess";
    return false;
  }

  rv = CloseHandle(process_info.hThread);
  PLOG_IF(WARNING, !rv) << "CloseHandle thread";

  rv = CloseHandle(process_info.hProcess);
  PLOG_IF(WARNING, !rv) << "CloseHandle process";

  // It is important to close our side of the pipe here before confirming that
  // we can communicate with the server. By doing so, the only remaining copy of
  // the server side of the pipe belongs to the exception handler process we
  // just spawned. Otherwise, the pipe will continue to exist indefinitely, so
  // the connection loop will not detect that it will never be serviced.
  data->ipc_pipe_handle.reset();

  // Confirm that the server is waiting for connections before continuing.
  ClientToServerMessage message = {};
  message.type = ClientToServerMessage::kPing;
  ServerToClientMessage response = {};
  if (!SendToCrashHandlerServer(data->ipc_pipe, message, &response)) {
    return false;
  }

  scoped_startup_state_caller.SetSuccessful();
  return true;
}

DWORD WINAPI BackgroundHandlerStartThreadProc(void* data) {
  std::unique_ptr<BackgroundHandlerStartThreadData> data_as_ptr(
      reinterpret_cast<BackgroundHandlerStartThreadData*>(data));
  return StartHandlerProcess(std::move(data_as_ptr)) ? 0 : 1;
}

void CommonInProcessInitialization() {
  // We create this dummy CRITICAL_SECTION with the
  // RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO flag set to have an entry point
  // into the doubly-linked list of RTL_CRITICAL_SECTION_DEBUG objects. This
  // allows us to walk the list at crash time to gather data for !locks. A
  // debugger would instead inspect ntdll!RtlCriticalSectionList to get the head
  // of the list. But that is not an exported symbol, so on an arbitrary client
  // machine, we don't have a way of getting that pointer.
  InitializeCriticalSectionWithDebugInfoIfPossible(
      &g_critical_section_with_debug_info);

  g_non_crash_dump_lock = new base::Lock();
}

void RegisterHandlers() {
  SetUnhandledExceptionFilter(&UnhandledExceptionHandler);

  // The Windows CRT's signal.h lists:
  // - SIGINT
  // - SIGILL
  // - SIGFPE
  // - SIGSEGV
  // - SIGTERM
  // - SIGBREAK
  // - SIGABRT
  // SIGILL and SIGTERM are documented as not being generated. SIGBREAK and
  // SIGINT are for Ctrl-Break and Ctrl-C, and aren't something for which
  // capturing a dump is warranted. SIGFPE and SIGSEGV are captured as regular
  // exceptions through the unhandled exception filter. This leaves SIGABRT. In
  // the standard CRT, abort() is implemented as a synchronous call to the
  // SIGABRT signal handler if installed, but after doing so, the unhandled
  // exception filter is not triggered (it instead __fastfail()s). So, register
  // to handle SIGABRT to catch abort() calls, as client code might use this and
  // expect it to cause a crash dump. This will only work when the abort()
  // that's called in client code is the same (or has the same behavior) as the
  // one in use here.
  void (*rv)(int) = signal(SIGABRT, HandleAbortSignal);
  DCHECK_NE(rv, SIG_ERR);
}

}  // namespace

CrashpadClient::CrashpadClient() : ipc_pipe_(), handler_start_thread_() {}

CrashpadClient::~CrashpadClient() {}

bool CrashpadClient::StartHandler(
    const base::FilePath& handler,
    const base::FilePath& database,
    const base::FilePath& metrics_dir,
    const std::string& url,
    const std::map<std::string, std::string>& annotations,
    const std::vector<std::string>& arguments,
    bool restartable,
    bool asynchronous_start,
    const std::vector<base::FilePath>& attachments) {
  DCHECK(ipc_pipe_.empty());

  // Both the pipe and the signalling events have to be created on the main
  // thread (not the spawning thread) so that they're valid after we return from
  // this function.
  ScopedFileHANDLE ipc_pipe_handle;
  CreatePipe(&ipc_pipe_, &ipc_pipe_handle);

  SECURITY_ATTRIBUTES security_attributes = {0};
  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  security_attributes.bInheritHandle = true;

  g_signal_exception =
      CreateEvent(&security_attributes, false /* auto reset */, false, nullptr);
  g_signal_non_crash_dump =
      CreateEvent(&security_attributes, false /* auto reset */, false, nullptr);
  g_non_crash_dump_done =
      CreateEvent(&security_attributes, false /* auto reset */, false, nullptr);

  CommonInProcessInitialization();

  RegisterHandlers();

  auto data = new BackgroundHandlerStartThreadData(handler,
                                                   database,
                                                   metrics_dir,
                                                   url,
                                                   annotations,
                                                   arguments,
                                                   attachments,
                                                   ipc_pipe_,
                                                   std::move(ipc_pipe_handle));

  if (asynchronous_start) {
    // It is important that the current thread not be synchronized with the
    // thread that is created here. StartHandler() needs to be callable inside a
    // DllMain(). In that case, the background thread will not start until the
    // current DllMain() completes, which would cause deadlock if it was waited
    // upon.
    handler_start_thread_.reset(CreateThread(nullptr,
                                             0,
                                             &BackgroundHandlerStartThreadProc,
                                             reinterpret_cast<void*>(data),
                                             0,
                                             nullptr));
    if (!handler_start_thread_.is_valid()) {
      PLOG(ERROR) << "CreateThread";
      SetHandlerStartupState(StartupState::kFailed);
      return false;
    }

    // In asynchronous mode, we can't report on the overall success or failure
    // of initialization at this point.
    return true;
  } else {
    return StartHandlerProcess(
        std::unique_ptr<BackgroundHandlerStartThreadData>(data));
  }
}

bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) {
  DCHECK(ipc_pipe_.empty());
  DCHECK(!ipc_pipe.empty());

  ipc_pipe_ = ipc_pipe;

  DCHECK(!ipc_pipe_.empty());
  DCHECK_EQ(g_signal_exception, INVALID_HANDLE_VALUE);
  DCHECK_EQ(g_signal_non_crash_dump, INVALID_HANDLE_VALUE);
  DCHECK_EQ(g_non_crash_dump_done, INVALID_HANDLE_VALUE);
  DCHECK(!g_critical_section_with_debug_info.DebugInfo);
  DCHECK(!g_non_crash_dump_lock);

  ClientToServerMessage message;
  memset(&message, 0, sizeof(message));
  message.type = ClientToServerMessage::kRegister;
  message.registration.version = RegistrationRequest::kMessageVersion;
  message.registration.client_process_id = GetCurrentProcessId();
  message.registration.crash_exception_information =
      FromPointerCast<WinVMAddress>(&g_crash_exception_information);
  message.registration.non_crash_exception_information =
      FromPointerCast<WinVMAddress>(&g_non_crash_exception_information);

  CommonInProcessInitialization();

  message.registration.critical_section_address =
      FromPointerCast<WinVMAddress>(&g_critical_section_with_debug_info);

  ServerToClientMessage response = {};

  if (!SendToCrashHandlerServer(ipc_pipe_, message, &response)) {
    return false;
  }

  SetHandlerStartupState(StartupState::kSucceeded);

  RegisterHandlers();

  // The server returns these already duplicated to be valid in this process.
  g_signal_exception =
      IntToHandle(response.registration.request_crash_dump_event);
  g_signal_non_crash_dump =
      IntToHandle(response.registration.request_non_crash_dump_event);
  g_non_crash_dump_done =
      IntToHandle(response.registration.non_crash_dump_completed_event);

  return true;
}

std::wstring CrashpadClient::GetHandlerIPCPipe() const {
  DCHECK(!ipc_pipe_.empty());
  return ipc_pipe_;
}

bool CrashpadClient::WaitForHandlerStart(unsigned int timeout_ms) {
  DCHECK(handler_start_thread_.is_valid());
  DWORD result = WaitForSingleObject(handler_start_thread_.get(), timeout_ms);
  if (result == WAIT_TIMEOUT) {
    LOG(ERROR) << "WaitForSingleObject timed out";
    return false;
  } else if (result == WAIT_ABANDONED) {
    LOG(ERROR) << "WaitForSingleObject abandoned";
    return false;
  } else if (result != WAIT_OBJECT_0) {
    PLOG(ERROR) << "WaitForSingleObject";
    return false;
  }

  DWORD exit_code;
  if (!GetExitCodeThread(handler_start_thread_.get(), &exit_code)) {
    PLOG(ERROR) << "GetExitCodeThread";
    return false;
  }

  handler_start_thread_.reset();
  return exit_code == 0;
}

// static
void CrashpadClient::DumpWithoutCrash(const CONTEXT& context) {
  if (g_signal_non_crash_dump == INVALID_HANDLE_VALUE ||
      g_non_crash_dump_done == INVALID_HANDLE_VALUE) {
    LOG(ERROR) << "not connected";
    return;
  }

  if (BlockUntilHandlerStartedOrFailed() == StartupState::kFailed) {
    // If we know for certain that the handler has failed to start, then abort
    // here, as we would otherwise wait indefinitely for the
    // g_non_crash_dump_done event that would never be signalled.
    LOG(ERROR) << "crash server failed to launch, no dump captured";
    return;
  }

  // In the non-crashing case, we aren't concerned about avoiding calls into
  // Win32 APIs, so just use regular locking here in case of multiple threads
  // calling this function. If a crash occurs while we're in here, the worst
  // that can happen is that the server captures a partial dump for this path
  // because another thread's crash processing finished and the process was
  // terminated before this thread's non-crash processing could be completed.
  base::AutoLock lock(*g_non_crash_dump_lock);

  // Create a fake EXCEPTION_POINTERS to give the handler something to work
  // with.
  EXCEPTION_POINTERS exception_pointers = {};

  // This is logically const, but EXCEPTION_POINTERS does not declare it as
  // const, so we have to cast that away from the argument.
  exception_pointers.ContextRecord = const_cast<CONTEXT*>(&context);

  // We include a fake exception and use a code of '0x517a7ed' (something like
  // "simulated") so that it's relatively obvious in windbg that it's not
  // actually an exception. Most values in
  // https://msdn.microsoft.com/library/aa363082.aspx have some of the top
  // nibble set, so we make sure to pick a value that doesn't, so as to be
  // unlikely to conflict.
  constexpr uint32_t kSimulatedExceptionCode = 0x517a7ed;
  EXCEPTION_RECORD record = {};
  record.ExceptionCode = kSimulatedExceptionCode;
  record.ExceptionAddress = ProgramCounterFromCONTEXT(&context);

  exception_pointers.ExceptionRecord = &record;

  g_non_crash_exception_information.thread_id = GetCurrentThreadId();
  g_non_crash_exception_information.exception_pointers =
      FromPointerCast<WinVMAddress>(&exception_pointers);

  bool set_event_result = !!SetEvent(g_signal_non_crash_dump);
  PLOG_IF(ERROR, !set_event_result) << "SetEvent";

  DWORD wfso_result = WaitForSingleObject(g_non_crash_dump_done, INFINITE);
  PLOG_IF(ERROR, wfso_result != WAIT_OBJECT_0) << "WaitForSingleObject";
}

// static
void CrashpadClient::DumpAndCrash(EXCEPTION_POINTERS* exception_pointers) {
  if (g_signal_exception == INVALID_HANDLE_VALUE) {
    LOG(ERROR) << "not connected";
    SafeTerminateProcess(GetCurrentProcess(),
                         kTerminationCodeNotConnectedToHandler);
    return;
  }

  // We don't need to check for handler startup here, as
  // UnhandledExceptionHandler() necessarily does that.

  UnhandledExceptionHandler(exception_pointers);
}

// static
bool CrashpadClient::DumpAndCrashTargetProcess(HANDLE process,
                                               HANDLE blame_thread,
                                               DWORD exception_code) {
  if (!IsWindowsVistaOrGreater()) {
    LOG(ERROR) << "unavailable before Vista";
    return false;
  }

  // Confirm that our bitness is the same as the process we're crashing.
  ProcessInfo process_info;
  if (!process_info.Initialize(process)) {
    LOG(ERROR) << "ProcessInfo::Initialize";
    return false;
  }
#if defined(ARCH_CPU_64_BITS)
  if (!process_info.Is64Bit()) {
    LOG(ERROR) << "DumpAndCrashTargetProcess currently not supported x64->x86";
    return false;
  }
#endif  // ARCH_CPU_64_BITS

  ScopedProcessSuspend suspend(process);

  // If no thread handle was provided, or the thread has already exited, we pass
  // 0 to the handler, which indicates no fake exception record to be created.
  DWORD thread_id = 0;
  if (blame_thread) {
    // Now that we've suspended the process, if our thread hasn't exited, we
    // know we're relatively safe to pass the thread id through.
    if (WaitForSingleObject(blame_thread, 0) == WAIT_TIMEOUT) {
      static const auto get_thread_id =
          GET_FUNCTION_REQUIRED(L"kernel32.dll", ::GetThreadId);
      thread_id = get_thread_id(blame_thread);
    }
  }

  constexpr size_t kInjectBufferSize = 4 * 1024;
  WinVMAddress inject_memory =
      FromPointerCast<WinVMAddress>(VirtualAllocEx(process,
                                                   nullptr,
                                                   kInjectBufferSize,
                                                   MEM_RESERVE | MEM_COMMIT,
                                                   PAGE_READWRITE));
  if (!inject_memory) {
    PLOG(ERROR) << "VirtualAllocEx";
    return false;
  }

  // Because we're the same bitness as our target, we can rely kernel32 being
  // loaded at the same address in our process as the target, and just look up
  // its address here.
  WinVMAddress raise_exception_address =
      FromPointerCast<WinVMAddress>(&RaiseException);

  WinVMAddress code_entry_point = 0;
  std::vector<unsigned char> data_to_write;
  if (process_info.Is64Bit()) {
    // Data written is first, the data for the 4th argument (lpArguments) to
    // RaiseException(). A two element array:
    //
    // DWORD64: thread_id
    // DWORD64: exception_code
    //
    // Following that, code which sets the arguments to RaiseException() and
    // then calls it:
    //
    // mov r9, <data_array_address>
    // mov r8d, 2  ; nNumberOfArguments
    // mov edx, 1  ; dwExceptionFlags = EXCEPTION_NONCONTINUABLE
    // mov ecx, 0xcca11ed  ; dwExceptionCode, interpreted specially by the
    //                     ;                  handler.
    // jmp <address_of_RaiseException>
    //
    // Note that the first three arguments to RaiseException() are DWORDs even
    // on x64, so only the 4th argument (a pointer) is a full-width register.
    //
    // We also don't need to set up a stack or use call, since the only
    // registers modified are volatile ones, and we can just jmp straight to
    // RaiseException().

    // The data array.
    AddUint64(&data_to_write, thread_id);
    AddUint64(&data_to_write, exception_code);

    // The thread entry point.
    code_entry_point = inject_memory + data_to_write.size();

    // r9 = pointer to data.
    data_to_write.push_back(0x49);
    data_to_write.push_back(0xb9);
    AddUint64(&data_to_write, inject_memory);

    // r8d = 2 for nNumberOfArguments.
    data_to_write.push_back(0x41);
    data_to_write.push_back(0xb8);
    AddUint32(&data_to_write, 2);

    // edx = 1 for dwExceptionFlags.
    data_to_write.push_back(0xba);
    AddUint32(&data_to_write, 1);

    // ecx = kTriggeredExceptionCode for dwExceptionCode.
    data_to_write.push_back(0xb9);
    AddUint32(&data_to_write, kTriggeredExceptionCode);

    // jmp to RaiseException() via rax.
    data_to_write.push_back(0x48);  // mov rax, imm.
    data_to_write.push_back(0xb8);
    AddUint64(&data_to_write, raise_exception_address);
    data_to_write.push_back(0xff);  // jmp rax.
    data_to_write.push_back(0xe0);
  } else {
    // Data written is first, the data for the 4th argument (lpArguments) to
    // RaiseException(). A two element array:
    //
    // DWORD: thread_id
    // DWORD: exception_code
    //
    // Following that, code which pushes our arguments to RaiseException() and
    // then calls it:
    //
    // push <data_array_address>
    // push 2  ; nNumberOfArguments
    // push 1  ; dwExceptionFlags = EXCEPTION_NONCONTINUABLE
    // push 0xcca11ed  ; dwExceptionCode, interpreted specially by the handler.
    // call <address_of_RaiseException>
    // ud2  ; Generate invalid opcode to make sure we still crash if we return
    //      ; for some reason.
    //
    // No need to clean up the stack, as RaiseException() is __stdcall.

    // The data array.
    AddUint32(&data_to_write, thread_id);
    AddUint32(&data_to_write, exception_code);

    // The thread entry point.
    code_entry_point = inject_memory + data_to_write.size();

    // Push data address.
    data_to_write.push_back(0x68);
    AddUint32(&data_to_write, static_cast<uint32_t>(inject_memory));

    // Push 2 for nNumberOfArguments.
    data_to_write.push_back(0x6a);
    data_to_write.push_back(2);

    // Push 1 for dwExceptionCode.
    data_to_write.push_back(0x6a);
    data_to_write.push_back(1);

    // Push dwExceptionFlags.
    data_to_write.push_back(0x68);
    AddUint32(&data_to_write, kTriggeredExceptionCode);

    // Relative call to RaiseException().
    int64_t relative_address_to_raise_exception =
        raise_exception_address - (inject_memory + data_to_write.size() + 5);
    data_to_write.push_back(0xe8);
    AddUint32(&data_to_write,
              static_cast<uint32_t>(relative_address_to_raise_exception));

    // ud2.
    data_to_write.push_back(0x0f);
    data_to_write.push_back(0x0b);
  }

  DCHECK_LT(data_to_write.size(), kInjectBufferSize);

  SIZE_T bytes_written;
  if (!WriteProcessMemory(process,
                          reinterpret_cast<void*>(inject_memory),
                          data_to_write.data(),
                          data_to_write.size(),
                          &bytes_written)) {
    PLOG(ERROR) << "WriteProcessMemory";
    return false;
  }

  if (bytes_written != data_to_write.size()) {
    LOG(ERROR) << "WriteProcessMemory unexpected number of bytes";
    return false;
  }

  if (!FlushInstructionCache(
          process, reinterpret_cast<void*>(inject_memory), bytes_written)) {
    PLOG(ERROR) << "FlushInstructionCache";
    return false;
  }

  DWORD old_protect;
  if (!VirtualProtectEx(process,
                        reinterpret_cast<void*>(inject_memory),
                        kInjectBufferSize,
                        PAGE_EXECUTE_READ,
                        &old_protect)) {
    PLOG(ERROR) << "VirtualProtectEx";
    return false;
  }

  // Cause an exception in the target process by creating a thread which calls
  // RaiseException with our arguments above. Note that we cannot get away with
  // using DebugBreakProcess() (nothing happens unless a debugger is attached)
  // and we cannot get away with CreateRemoteThread() because it doesn't work if
  // the target is hung waiting for the loader lock. We use NtCreateThreadEx()
  // with the SKIP_THREAD_ATTACH flag, which skips various notifications,
  // letting this cause an exception, even when the target is stuck in the
  // loader lock.
  HANDLE injected_thread;

  // This is what DebugBreakProcess() uses.
  constexpr size_t kStackSize = 0x4000;

  NTSTATUS status = NtCreateThreadEx(&injected_thread,
                                     STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
                                     nullptr,
                                     process,
                                     reinterpret_cast<void*>(code_entry_point),
                                     nullptr,
                                     THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH,
                                     0,
                                     kStackSize,
                                     0,
                                     nullptr);
  if (!NT_SUCCESS(status)) {
    NTSTATUS_LOG(ERROR, status) << "NtCreateThreadEx";
    return false;
  }

  // The injected thread raises an exception and ultimately results in process
  // termination. The suspension must be made aware that the process may be
  // terminating, otherwise it'll log an extraneous error.
  suspend.TolerateTermination();

  bool result = true;
  if (WaitForSingleObject(injected_thread, 60 * 1000) != WAIT_OBJECT_0) {
    PLOG(ERROR) << "WaitForSingleObject";
    result = false;
  }

  status = NtClose(injected_thread);
  if (!NT_SUCCESS(status)) {
    NTSTATUS_LOG(ERROR, status) << "NtClose";
    result = false;
  }

  return result;
}

}  // namespace crashpad


text:
$:.unshift(File.expand_path('../../lib', __FILE__))
$:.unshift(File.expand_path('../../../aws-sdk-core/features', __FILE__))
$:.unshift(File.expand_path('../../../aws-sdk-core/lib', __FILE__))
$:.unshift(File.expand_path('../../../aws-sigv4/lib', __FILE__))

require 'features_helper'
require 'aws-sdk-mediaconvert'

Aws::MediaConvert::Client.add_plugin(ApiCallTracker)

redpajama_set_name: RedPajamaGithub


text:
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>basic_waitable_timer::async_wait</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../../index.html" title="Asio">
<link rel="up" href="../basic_waitable_timer.html" title="basic_waitable_timer">
<link rel="prev" href="../basic_waitable_timer.html" title="basic_waitable_timer">
<link rel="next" href="basic_waitable_timer.html" title="basic_waitable_timer::basic_waitable_timer">

basic_waitable_timer::async_wait

Start an asynchronous wait on the timer.

template<
    typename WaitHandler>
void-or-deduced async_wait(
    WaitHandler handler);

          This function may be used to initiate an asynchronous wait against the
          timer. It always returns immediately.

          For each call to async_wait(), the supplied handler will be called
          exactly once. The handler will be called when:

              The timer has expired.

              The timer was cancelled, in which case the handler is passed the error
              code asio::error::operation_aborted.

          Parameters

handler

                The handler to be called when the timer expires. Copies will be made
                of the handler as required. The function signature of the handler
                must be:

void handler(
  const asio::error_code& error // Result of operation.
);

                Regardless of whether the asynchronous operation completes immediately
                or not, the handler will not be invoked from within this function.
                Invocation of the handler will be performed in a manner equivalent
                to using asio::io_service::post().

Copyright © 2003-2015 Christopher M.
      Kohlhoff

        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)


text:
<readable><title>2908466042_bf07cb52c7</title><content>
Two blond dogs fight in a living room .
two brown dogs playing around with each other in a house .
Two dogs bite each others faces inside of a house .
Two dogs biting at each other .
Two dogs play rough with each other indoors .
</content></readable>


text:
package org.apache.calcite.prepare;

import org.apache.calcite.adapter.java.JavaTypeFactory;
import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.CalciteSystemProperty;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.ConventionTraitDef;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCostFactory;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptTable.ViewExpander;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.RelTraitDef;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.plan.volcano.VolcanoPlanner;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelRoot;
import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexExecutor;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.util.SqlOperatorTables;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql2rel.RelDecorrelator;
import org.apache.calcite.sql2rel.SqlRexConvertletTable;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Planner;
import org.apache.calcite.tools.Program;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.ValidationException;
import org.apache.calcite.util.Pair;

import com.google.common.collect.ImmutableList;

import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.io.Reader;
import java.util.List;

import static java.util.Objects.requireNonNull;

/** Implementation of {@link org.apache.calcite.tools.Planner}. */
public class PlannerImpl implements Planner, ViewExpander {
  private final SqlOperatorTable operatorTable;
  private final ImmutableList<Program> programs;
  private final @Nullable RelOptCostFactory costFactory;
  private final Context context;
  private final CalciteConnectionConfig connectionConfig;
  private final RelDataTypeSystem typeSystem;

  /** Holds the trait definitions to be registered with planner. May be null. */
  private final @Nullable ImmutableList<RelTraitDef> traitDefs;

  private final SqlParser.Config parserConfig;
  private final SqlValidator.Config sqlValidatorConfig;
  private final SqlToRelConverter.Config sqlToRelConverterConfig;
  private final SqlRexConvertletTable convertletTable;

  private State state;

  // set in STATE_1_RESET
  @SuppressWarnings("unused")
  private boolean open;

  // set in STATE_2_READY
  private @Nullable SchemaPlus defaultSchema;
  private @Nullable JavaTypeFactory typeFactory;
  private @Nullable RelOptPlanner planner;
  private @Nullable RexExecutor executor;

  // set in STATE_4_VALIDATE
  private @Nullable SqlValidator validator;
  private @Nullable SqlNode validatedSqlNode;

  /** Creates a planner. Not a public API; call
   * {@link org.apache.calcite.tools.Frameworks#getPlanner} instead. */
  @SuppressWarnings("method.invocation.invalid")
  public PlannerImpl(FrameworkConfig config) {
    this.costFactory = config.getCostFactory();
    this.defaultSchema = config.getDefaultSchema();
    this.operatorTable = config.getOperatorTable();
    this.programs = config.getPrograms();
    this.parserConfig = config.getParserConfig();
    this.sqlValidatorConfig = config.getSqlValidatorConfig();
    this.sqlToRelConverterConfig = config.getSqlToRelConverterConfig();
    this.state = State.STATE_0_CLOSED;
    this.traitDefs = config.getTraitDefs();
    this.convertletTable = config.getConvertletTable();
    this.executor = config.getExecutor();
    this.context = config.getContext();
    this.connectionConfig = connConfig(context, parserConfig);
    this.typeSystem = config.getTypeSystem();
    reset();
  }

  /** Gets a user-defined config and appends default connection values. */
  private static CalciteConnectionConfig connConfig(Context context,
      SqlParser.Config parserConfig) {
    CalciteConnectionConfigImpl config =
        context.maybeUnwrap(CalciteConnectionConfigImpl.class)
            .orElse(CalciteConnectionConfig.DEFAULT);
    if (!config.isSet(CalciteConnectionProperty.CASE_SENSITIVE)) {
      config = config.set(CalciteConnectionProperty.CASE_SENSITIVE,
          String.valueOf(parserConfig.caseSensitive()));
    }
    if (!config.isSet(CalciteConnectionProperty.CONFORMANCE)) {
      config = config.set(CalciteConnectionProperty.CONFORMANCE,
          String.valueOf(parserConfig.conformance()));
    }
    return config;
  }

  /** Makes sure that the state is at least the given state. */
  private void ensure(State state) {
    if (state == this.state) {
      return;
    }
    if (state.ordinal() < this.state.ordinal()) {
      throw new IllegalArgumentException("cannot move to " + state + " from "
          + this.state);
    }
    state.from(this);
  }

  @Override public RelTraitSet getEmptyTraitSet() {
    return requireNonNull(planner, "planner").emptyTraitSet();
  }

  @Override public void close() {
    open = false;
    typeFactory = null;
    state = State.STATE_0_CLOSED;
  }

  @Override public void reset() {
    ensure(State.STATE_0_CLOSED);
    open = true;
    state = State.STATE_1_RESET;
  }

  private void ready() {
    switch (state) {
    case STATE_0_CLOSED:
      reset();
      break;
    default:
      break;
    }
    ensure(State.STATE_1_RESET);

    typeFactory = new JavaTypeFactoryImpl(typeSystem);
    RelOptPlanner planner = this.planner = new VolcanoPlanner(costFactory, context);
    RelOptUtil.registerDefaultRules(planner,
        connectionConfig.materializationsEnabled(),
        Hook.ENABLE_BINDABLE.get(false));
    planner.setExecutor(executor);

    state = State.STATE_2_READY;

    // If user specify own traitDef, instead of default default trait,
    // register the trait def specified in traitDefs.
    if (this.traitDefs == null) {
      planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
      if (CalciteSystemProperty.ENABLE_COLLATION_TRAIT.value()) {
        planner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
      }
    } else {
      for (RelTraitDef def : this.traitDefs) {
        planner.addRelTraitDef(def);
      }
    }
  }

  @Override public SqlNode parse(final Reader reader) throws SqlParseException {
    switch (state) {
    case STATE_0_CLOSED:
    case STATE_1_RESET:
      ready();
      break;
    default:
      break;
    }
    ensure(State.STATE_2_READY);
    SqlParser parser = SqlParser.create(reader, parserConfig);
    SqlNode sqlNode = parser.parseStmt();
    state = State.STATE_3_PARSED;
    return sqlNode;
  }

  @EnsuresNonNull("validator")
  @Override public SqlNode validate(SqlNode sqlNode) throws ValidationException {
    ensure(State.STATE_3_PARSED);
    this.validator = createSqlValidator(createCatalogReader());
    try {
      validatedSqlNode = validator.validate(sqlNode);
    } catch (RuntimeException e) {
      throw new ValidationException(e);
    }
    state = State.STATE_4_VALIDATED;
    return validatedSqlNode;
  }

  @Override public Pair<SqlNode, RelDataType> validateAndGetType(SqlNode sqlNode)
      throws ValidationException {
    final SqlNode validatedNode = this.validate(sqlNode);
    final RelDataType type =
        this.validator.getValidatedNodeType(validatedNode);
    return Pair.of(validatedNode, type);
  }

  @SuppressWarnings("deprecation")
  @Override public final RelNode convert(SqlNode sql) {
    return rel(sql).rel;
  }

  @Override public RelRoot rel(SqlNode sql) {
    ensure(State.STATE_4_VALIDATED);
    SqlNode validatedSqlNode = requireNonNull(this.validatedSqlNode,
        "validatedSqlNode is null. Need to call #validate() first");
    final RexBuilder rexBuilder = createRexBuilder();
    final RelOptCluster cluster = RelOptCluster.create(
        requireNonNull(planner, "planner"),
        rexBuilder);
    final SqlToRelConverter.Config config =
        sqlToRelConverterConfig.withTrimUnusedFields(false);
    final SqlToRelConverter sqlToRelConverter =
        new SqlToRelConverter(this, validator,
            createCatalogReader(), cluster, convertletTable, config);
    RelRoot root =
        sqlToRelConverter.convertQuery(validatedSqlNode, false, true);
    root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true));
    final RelBuilder relBuilder =
        config.getRelBuilderFactory().create(cluster, null);
    root = root.withRel(
        RelDecorrelator.decorrelateQuery(root.rel, relBuilder));
    state = State.STATE_5_CONVERTED;
    return root;
  }

  // CHECKSTYLE: IGNORE 2
  /** @deprecated Now {@link PlannerImpl} implements {@link ViewExpander}
   * directly. */
  @Deprecated // to be removed before 2.0
  public class ViewExpanderImpl implements ViewExpander {
    ViewExpanderImpl() {
    }

    @Override public RelRoot expandView(RelDataType rowType, String queryString,
        List<String> schemaPath, @Nullable List<String> viewPath) {
      return PlannerImpl.this.expandView(rowType, queryString, schemaPath,
          viewPath);
    }
  }

  @Override public RelRoot expandView(RelDataType rowType, String queryString,
      List<String> schemaPath, @Nullable List<String> viewPath) {
    RelOptPlanner planner = this.planner;
    if (planner == null) {
      ready();
      planner = requireNonNull(this.planner, "planner");
    }
    SqlParser parser = SqlParser.create(queryString, parserConfig);
    SqlNode sqlNode;
    try {
      sqlNode = parser.parseQuery();
    } catch (SqlParseException e) {
      throw new RuntimeException("parse failed", e);
    }

    final CalciteCatalogReader catalogReader =
        createCatalogReader().withSchemaPath(schemaPath);
    final SqlValidator validator = createSqlValidator(catalogReader);

    final RexBuilder rexBuilder = createRexBuilder();
    final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder);
    final SqlToRelConverter.Config config =
        sqlToRelConverterConfig.withTrimUnusedFields(false);
    final SqlToRelConverter sqlToRelConverter =
        new SqlToRelConverter(this, validator,
            catalogReader, cluster, convertletTable, config);

    final RelRoot root =
        sqlToRelConverter.convertQuery(sqlNode, true, false);
    final RelRoot root2 =
        root.withRel(sqlToRelConverter.flattenTypes(root.rel, true));
    final RelBuilder relBuilder =
        config.getRelBuilderFactory().create(cluster, null);
    return root2.withRel(
        RelDecorrelator.decorrelateQuery(root.rel, relBuilder));
  }

  // CalciteCatalogReader is stateless; no need to store one
  private CalciteCatalogReader createCatalogReader() {
    SchemaPlus defaultSchema = requireNonNull(this.defaultSchema, "defaultSchema");
    final SchemaPlus rootSchema = rootSchema(defaultSchema);

    return new CalciteCatalogReader(
        CalciteSchema.from(rootSchema),
        CalciteSchema.from(defaultSchema).path(null),
        getTypeFactory(), connectionConfig);
  }

  private SqlValidator createSqlValidator(CalciteCatalogReader catalogReader) {
    final SqlOperatorTable opTab =
        SqlOperatorTables.chain(operatorTable, catalogReader);
    return new CalciteSqlValidator(opTab,
        catalogReader,
        getTypeFactory(),
        sqlValidatorConfig
            .withDefaultNullCollation(connectionConfig.defaultNullCollation())
            .withLenientOperatorLookup(connectionConfig.lenientOperatorLookup())
            .withSqlConformance(connectionConfig.conformance())
            .withIdentifierExpansion(true));
  }

  private static SchemaPlus rootSchema(SchemaPlus schema) {
    for (;;) {
      SchemaPlus parentSchema = schema.getParentSchema();
      if (parentSchema == null) {
        return schema;
      }
      schema = parentSchema;
    }
  }

  // RexBuilder is stateless; no need to store one
  private RexBuilder createRexBuilder() {
    return new RexBuilder(getTypeFactory());
  }

  @Override public JavaTypeFactory getTypeFactory() {
    return requireNonNull(typeFactory, "typeFactory");
  }

  @Override public RelNode transform(int ruleSetIndex, RelTraitSet requiredOutputTraits,
      RelNode rel) {
    ensure(State.STATE_5_CONVERTED);
    rel.getCluster().setMetadataProvider(
        new CachingRelMetadataProvider(
            requireNonNull(rel.getCluster().getMetadataProvider(), "metadataProvider"),
            rel.getCluster().getPlanner()));
    Program program = programs.get(ruleSetIndex);
    return program.run(requireNonNull(planner, "planner"),
        rel, requiredOutputTraits, ImmutableList.of(),
        ImmutableList.of());
  }

  /** Stage of a statement in the query-preparation lifecycle. */
  private enum State {
    STATE_0_CLOSED {
      @Override void from(PlannerImpl planner) {
        planner.close();
      }
    },
    STATE_1_RESET {
      @Override void from(PlannerImpl planner) {
        planner.ensure(STATE_0_CLOSED);
        planner.reset();
      }
    },
    STATE_2_READY {
      @Override void from(PlannerImpl planner) {
        STATE_1_RESET.from(planner);
        planner.ready();
      }
    },
    STATE_3_PARSED,
    STATE_4_VALIDATED,
    STATE_5_CONVERTED;

    /** Moves planner's state to this state. This must be a higher state. */
    void from(PlannerImpl planner) {
      throw new IllegalArgumentException("cannot move from " + planner.state
          + " to " + this);
    }
  }
}


text:
module Fog
  module Compute
    class Brightbox
      class Real
        # Get full details of the interface.
        #
        # @param [String] identifier Unique reference to identify the resource
        #
        # @return [Hash] if successful Hash version of JSON object
        #
        # @see https://api.gb1.brightbox.com/1.0/#interface_get_interface
        #
        def get_interface(identifier)
          return nil if identifier.nil? || identifier == ""
          wrapped_request("get", "/1.0/interfaces/#{identifier}", [200])
        end
      end
    end
  end
end


text:
//import org.apache.metamodel.schema.Schema;
//import org.apache.metamodel.schema.Table;
// https://github.com/apache/metamodel/blob/b0cfe3aed447769f752743ac1753ebed90adaad2/core/src/main/java/org/apache/metamodel/query/builder/InitFromBuilder.java

using org.apache.metamodel.schema;

namespace org.apache.metamodel.query.builder
{
    /**
     * The initial interface used when building a query. A query starts by stating
     * the FROM clause.
     */
    public interface InitFromBuilder
    {
        TableFromBuilder from(Table table);
        TableFromBuilder from(Schema schema, string tableName);
        TableFromBuilder from(string schemaName, string tableName);
        TableFromBuilder from(string tableName);
    } // InitFromBuilder class
} // org.apache.metamodel.query.builder namespace


text:
/* global define */
define([
    'marionette',
    'marked',

    '../../app',

    'tpl!templates/topology/item.html'
], function(Marionette, marked, app, template) {

    var Item = Marionette.LayoutView.extend({
        template: template,

        className: 'item item-topology',

        options: {
            link: true
        },

        behaviors: {
            TimeSince: {}
        },

        modelEvents: {
            'change': 'render'
        },

        templateHelpers: function() {
            return {
                showLink: this.getOption('link')
            };
        },

        serializeData: function() {
            var attrs = this.model.toJSON();

            attrs.url = app.router.reverse('topology.index', attrs);

            if (!attrs.label) {
                attrs.label = '(Unamed)';
            }

            if (attrs.description) {
                attrs.description = marked(attrs.description);
            }

            attrs.urls = {
                entities: app.router.reverse('topology.entities', attrs),
                links: app.router.reverse('topology.links', attrs)
            };

            return attrs;
        }
    });

    return {
        Item: Item
    };

});


text:
module VmCloudHelper::TextualSummary
  include TextualMixins::TextualAdvancedSettings
  include TextualMixins::TextualDescription
  include TextualMixins::TextualDrift
  include TextualMixins::TextualFilesystems
  include TextualMixins::TextualGroupTags
  include TextualMixins::TextualInitProcesses
  include TextualMixins::TextualName
  include TextualMixins::TextualOsInfo
  include TextualMixins::TextualPatches
  include TextualMixins::TextualPowerState
  include TextualMixins::TextualRegion
  include TextualMixins::TextualScanHistory
  # TODO: Determine if DoNav + url_for + :title is the right way to do links, or should it be link_to with :title

  #
  # Groups
  #

  def textual_group_properties
    %i(name region server description ipaddress mac_address custom_1 container preemptible tools_status load_balancer_health_check_state osinfo architecture advanced_settings resources guid virtualization_type root_device_type ems_ref)
  end

  def textual_group_security
    %i(users groups patches key_pairs)
  end

  def textual_group_configuration
    %i(guest_applications init_processes win32_services kernel_drivers filesystem_drivers filesystems registry_items)
  end

  def textual_group_diagnostics
    %i(processes event_logs)
  end

  def textual_group_vmsafe
    %i(vmsafe_enable vmsafe_agent_address vmsafe_agent_port vmsafe_fail_open vmsafe_immutable_vm vmsafe_timeout)
  end

  def textual_group_miq_custom_attributes
    textual_miq_custom_attributes
  end

  def textual_group_ems_custom_attributes
    textual_ems_custom_attributes
  end

  def textual_group_power_management
    %i(power_state boot_time state_changed_on)
  end

  #
  # Items
  #
  def textual_server
    @record.miq_server && "#{@record.miq_server.name} [#{@record.miq_server.id}]"
  end

  def textual_ipaddress
    return nil if @record.template?
    ips = @record.ipaddresses
    {:label => n_("IP Address", "IP Addresses", ips.size), :value => ips.join(", ")}
  end

  def textual_mac_address
    return nil if @record.template?
    macs = @record.mac_addresses
    {:label => n_("MAC Address", "MAC Addresses", macs.size), :value => macs.join(", ")}
  end

  def textual_custom_1
    return nil if @record.custom_1.blank?
    {:label => _("Custom Identifier"), :value => @record.custom_1}
  end

  def textual_preemptible
    preemptible = @record.try(:preemptible?)
    return nil if preemptible.nil?

    {
      :label => _("Preemptible"),
      :value => (preemptible ? _("Yes; VM will run at most 24 hours.") : _("No"))
    }
  end

  def textual_tools_status
    {:label => _("Platform Tools"), :value => (@record.tools_status.nil? ? _("N/A") : @record.tools_status)}
  end

  def textual_architecture
    bitness = @record.hardware.try!(:bitness)
    return nil if bitness.blank?
    {:label => _("Architecture"), :value => "#{bitness} bit"}
  end

  def textual_resources
    return nil if @record.template?
    {:label => _("Resources"), :value => _("Available"), :title => _("Show resources of this VM"), :explorer => true,
      :link => url_for(:action => 'show', :id => @record, :display => 'resources_info')}
  end

  def textual_guid
    {:label => _("Management Engine GUID"), :value => @record.guid}
  end

  def textual_users
    num = @record.number_of(:users)
    h = {:label => _("Users"), :image => "user", :value => num}
    if num > 0
      h[:title] = n_("Show the User defined on this VM", "Show the Users defined on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:action => 'users', :id => @record, :db => controller.controller_name)
    end
    h
  end

  def textual_groups
    num = @record.number_of(:groups)
    h = {:label => _("Groups"), :image => "group", :value => num}
    if num > 0
      h[:title] = n_("Show the Group defined on this VM", "Show the Groups defined on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:action => 'groups', :id => @record, :db => controller.controller_name)
    end
    h
  end

  def textual_key_pairs
    return nil if @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    h = {:label => _("Key Pairs")}
    key_pairs = @record.key_pairs
    h[:value] = key_pairs.blank? ? _("N/A") : key_pairs.collect(&:name).join(", ")
    h
  end

  def textual_guest_applications
    os = @record.os_image_name.downcase
    return nil if os == "unknown"
    num = @record.number_of(:guest_applications)
    label = (os =~ /linux/) ? n_("Package", "Packages", num) : n_("Application", "Applications", num)
    h = {:label => label, :image => "guest_application", :value => num}
    if num > 0
      h[:title] = ("Show the %{label} installed on this VM") % {:label => label}
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'guest_applications', :id => @record)
    end
    h
  end

  def textual_win32_services
    os = @record.os_image_name.downcase
    return nil if os == "unknown" || os =~ /linux/
    num = @record.number_of(:win32_services)
    h = {:label => _("Win32 Services"), :image => "win32service", :value => num}
    if num > 0
      h[:title] = n_("Show the Win32 Service installed on this VM",
                     "Show the Win32 Services installed on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'win32_services', :id => @record)
    end
    h
  end

  def textual_kernel_drivers
    os = @record.os_image_name.downcase
    return nil if os == "unknown" || os =~ /linux/
    num = @record.number_of(:kernel_drivers)
    # TODO: Why is this image different than graphical?
    h = {:label => _("Kernel Drivers"), :image => "gears", :value => num}
    if num > 0
      h[:title] = n_("Show the Kernel Driver installed on this VM",
                     "Show the Kernel Drivers installed on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'kernel_drivers', :id => @record)
    end
    h
  end

  def textual_filesystem_drivers
    os = @record.os_image_name.downcase
    return nil if os == "unknown" || os =~ /linux/
    num = @record.number_of(:filesystem_drivers)
    # TODO: Why is this image different than graphical?
    h = {:label => _("File System Drivers"), :image => "gears", :value => num}
    if num > 0
      h[:title] = n_("Show the File System Driver installed on this VM" ,
                    "Show the File System Drivers installed on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'filesystem_drivers', :id => @record)
    end
    h
  end

  def textual_registry_items
    os = @record.os_image_name.downcase
    return nil if os == "unknown" || os =~ /linux/
    num = @record.number_of(:registry_items)
    # TODO: Why is this label different from the link title text?
    h = {:label => _("Registry Entries"), :image => "registry_item", :value => num}
    if num > 0
      h[:title] = n_("Show the Registry Item installed on this VM", "Show the Registry Items installed on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'registry_items', :id => @record)
    end
    h
  end

  def textual_processes
    return nil if @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    h = {:label => _("Running Processes"), :image => "processes"}
    date = last_date(:processes)
    if date.nil?
      h[:value] = _("Not Available")
    else
      # TODO: Why does this date differ in style from the compliance one?
      h[:value] = _("From %{time} Ago") % {:time => time_ago_in_words(date.in_time_zone(Time.zone)).titleize}
      h[:title] = _("Show Running Processes on this VM")
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'processes', :id => @record)
    end
    h
  end

  def textual_event_logs
    return nil if @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    num = @record.operating_system.nil? ? 0 : @record.operating_system.number_of(:event_logs)
    h = {:label => _("Event Logs"), :image => "event_logs", :value => (num == 0 ? _("Not Available") : _("Available"))}
    if num > 0
      h[:title] = n_("Show Event Log on this VM", "Show Event Logs on this VM", num)
      h[:explorer] = true
      h[:link]  = url_for(:controller => controller.controller_name, :action => 'event_logs', :id => @record)
    end
    h
  end

  def textual_vmsafe_enable
    return nil if @record.vmsafe_enable || @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    {:label => _("Enable"), :value => "false"}
  end

  def textual_vmsafe_agent_address
    return nil unless @record.vmsafe_enable
    {:label => _("Agent Address"), :value => @record.vmsafe_agent_address}
  end

  def textual_vmsafe_agent_port
    return nil unless @record.vmsafe_enable
    {:label => _("Agent Port"), :value => @record.vmsafe_agent_port}
  end

  def textual_vmsafe_fail_open
    return nil unless @record.vmsafe_enable
    {:label => _("Fail Open"), :value => @record.vmsafe_fail_open}
  end

  def textual_vmsafe_immutable_vm
    return nil unless @record.vmsafe_enable
    {:label => _("Immutable VM"), :value => @record.vmsafe_immutable_vm}
  end

  def textual_vmsafe_timeout
    return nil unless @record.vmsafe_enable
    {:label => _("Timeout (ms)"), :value => @record.vmsafe_timeout_ms}
  end

  def textual_miq_custom_attributes
    attrs = @record.miq_custom_attributes
    return nil if attrs.blank?
    attrs.collect { |a| {:label => a.name, :value => a.value} }
  end

  def textual_ems_custom_attributes
    attrs = @record.ems_custom_attributes
    return nil if attrs.blank?
    attrs.collect { |a| {:label => a.name, :value => a.value} }
  end

  def textual_compliance_history
    super(:title    => _("Show Compliance History of this VM (Last 10 Checks)"),
          :explorer => true)
  end

  def textual_boot_time
    return nil if @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    date = @record.boot_time
    {:label => _("Last Boot Time"), :value => (date.nil? ? _("N/A") : format_timezone(date))}
  end

  def textual_state_changed_on
    return nil if @record.kind_of?(ManageIQ::Providers::CloudManager::Template)
    date = @record.state_changed_on
    {:label => _("State Changed On"), :value => (date.nil? ? _("N/A") : format_timezone(date))}
  end

  def textual_virtualization_type
    v_type = @record.hardware.try!(:virtualization_type)
    return nil if v_type.blank?
    {:label => _("Virtualization Type"), :value => v_type.to_s}
  end

  def textual_root_device_type
    rd_type = @record.hardware.try!(:root_device_type)
    return nil if rd_type.blank?
    {:label => _("Root Device Type"), :value => rd_type.to_s}
  end

  def textual_ems_ref
    return nil if @record.ems_ref.blank?
    {:label => _("ID within Provider"), :value => @record.ems_ref}
  end
end


text:
@interface QNFile ()

@property (nonatomic, readonly) NSString *filepath;

@property (nonatomic) NSData *data;

@property (readonly)  int64_t fileSize;

@property (readonly)  int64_t fileModifyTime;

@property (nonatomic) NSFileHandle *file;

@end

@implementation QNFile

- (instancetype)init:(NSString *)path
               error:(NSError *__autoreleasing *)error {
	if (self = [super init]) {
		_filepath = path;
		NSError *error2 = nil;
		NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error2];
		if (error2 != nil) {
			if (error != nil) {
				*error = error2;
			}
			return self;
		}
		NSNumber *fileSizeNumber = fileAttr[NSFileSize];
		_fileSize = [fileSizeNumber intValue];
		NSDate *modifyTime = fileAttr[NSFileModificationDate];
		int64_t t = 0;
		if (modifyTime != nil) {
			t = [modifyTime timeIntervalSince1970];
		}
		_fileModifyTime = t;
		NSFileHandle *f = nil;
		NSData *d = nil;
		//[NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error] 不能用在大于 200M的文件上,改用filehandle
		// 参见 https://issues.apache.org/jira/browse/CB-5790
		if (_fileSize > 32*1024*1024) {
			f = [NSFileHandle fileHandleForReadingAtPath:path];
			if (f == nil) {
				if (error != nil) {
					*error =[[NSError alloc] initWithDomain:path code:kQNFileError userInfo:nil];
				}
				return self;
			}
		}else{
			d = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:&error2];
			if (error2 != nil) {
				if (error != nil) {
					*error = error2;
				}
				return self;
			}
		}
		_file = f;
		_data = d;
	}

	return self;
}

- (NSData *)read:(long)offset
            size:(long)size {
	if (_data != nil) {
		return [_data subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
	}
	[_file seekToFileOffset:offset];
	return [_file readDataOfLength:size];
}

- (NSData *)readAll {
	return [self read:0 size:(long)_fileSize];
}

- (void)close {
	if (_file != nil) {
		[_file closeFile];
	}
}

-(NSString *)path {
	return _filepath;
}

- (int64_t)modifyTime {
	return _fileModifyTime;
}

- (int64_t)size {
	return _fileSize;
}

@end


text:
using System.Linq;
using Entities = Thinktecture.IdentityServer.Repositories.Sql;

namespace Thinktecture.IdentityServer.Repositories.Sql
{
    public class ConfigurationRepository : IConfigurationRepository
    {
        public virtual bool SupportsWriteAccess
        {
            get { return true; }
        }

        public virtual Models.Configuration.GlobalConfiguration Global
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.GlobalConfiguration.First<Entities.Configuration.GlobalConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.GlobalConfiguration.First<Entities.Configuration.GlobalConfiguration>();
                    entities.GlobalConfiguration.Remove(entity);

                    entities.GlobalConfiguration.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.DiagnosticsConfiguration Diagnostics
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.Diagnostics.First<Entities.Configuration.DiagnosticsConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.Diagnostics.First<Entities.Configuration.DiagnosticsConfiguration>();
                    entities.Diagnostics.Remove(entity);

                    entities.Diagnostics.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.KeyMaterialConfiguration Keys
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.Keys.FirstOrDefault<Entities.Configuration.KeyMaterialConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.Keys.FirstOrDefault<Entities.Configuration.KeyMaterialConfiguration>();

                    if (entity != null)
                    {
                        entities.Keys.Remove(entity);
                    }

                    entities.Keys.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.WSFederationConfiguration WSFederation
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.WSFederation.First<Entities.Configuration.WSFederationConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.WSFederation.First<Entities.Configuration.WSFederationConfiguration>();
                    entities.WSFederation.Remove(entity);

                    entities.WSFederation.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.FederationMetadataConfiguration FederationMetadata
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.FederationMetadata.First<Entities.Configuration.FederationMetadataConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.FederationMetadata.First<Entities.Configuration.FederationMetadataConfiguration>();
                    entities.FederationMetadata.Remove(entity);

                    entities.FederationMetadata.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.WSTrustConfiguration WSTrust
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.WSTrust.First<Entities.Configuration.WSTrustConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.WSTrust.First<Entities.Configuration.WSTrustConfiguration>();
                    entities.WSTrust.Remove(entity);

                    entities.WSTrust.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.OAuth2Configuration OAuth2
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.OAuth2.First<Entities.Configuration.OAuth2Configuration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.OAuth2.First<Entities.Configuration.OAuth2Configuration>();
                    entities.OAuth2.Remove(entity);

                    entities.OAuth2.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public virtual Models.Configuration.SimpleHttpConfiguration SimpleHttp
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.SimpleHttp.First<Entities.Configuration.SimpleHttpConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.SimpleHttp.First<Entities.Configuration.SimpleHttpConfiguration>();
                    entities.SimpleHttp.Remove(entity);

                    entities.SimpleHttp.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        // todo: wire up with DB
        public Models.Configuration.AdfsIntegrationConfiguration AdfsIntegration
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.AdfsIntegration.First<Entities.Configuration.AdfsIntegrationConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.AdfsIntegration.First<Entities.Configuration.AdfsIntegrationConfiguration>();
                    entities.AdfsIntegration.Remove(entity);

                    entities.AdfsIntegration.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }

        public Models.Configuration.OpenIdConnectConfiguration OpenIdConnect
        {
            get
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.OpenIdConnect.First<Entities.Configuration.OpenIdConnectConfiguration>();
                    return entity.ToDomainModel();
                }
            }
            set
            {
                using (var entities = IdentityServerConfigurationContext.Get())
                {
                    var entity = entities.OpenIdConnect.First<Entities.Configuration.OpenIdConnectConfiguration>();
                    entities.OpenIdConnect.Remove(entity);

                    entities.OpenIdConnect.Add(value.ToEntity());
                    entities.SaveChanges();
                }
            }
        }
    }
}


text:
package au.com.ogsoft.yahaml4j;

public class ParsePoint {

    public int lineNumber;
    public int characterNumber;
    public String currentLine;

    public ParsePoint(Integer lineNumber, Integer characterNumber, String currentLine) {
        this.lineNumber = lineNumber;
        this.characterNumber = characterNumber;
        this.currentLine = currentLine;
    }
}


text:
import { Box, Flex, Separator, Theme } from "@artsy/palette"
import { WorksForYou_query } from "__generated__/WorksForYou_query.graphql"
import Spinner from "lib/Components/Spinner"
import { ZeroState } from "lib/Components/States/ZeroState"
import Notification from "lib/Components/WorksForYou/Notification"
import colors from "lib/data/colors"
import { PAGE_SIZE } from "lib/data/constants"
import { get } from "lib/utils/get"
import { isCloseToBottom } from "lib/utils/isCloseToBottom"
import React from "react"
import {
  FlatList,
  NativeModules,
  RefreshControl,
  ScrollView,
  StyleSheet,
  TextStyle,
  View,
  ViewStyle,
} from "react-native"
import { createPaginationContainer, graphql, RelayPaginationProp } from "react-relay"
import Events from "../NativeModules/Events"

interface Props {
  relay: RelayPaginationProp
  query: WorksForYou_query
}

interface State {
  isRefreshing: boolean
  loadingContent: boolean
}

export class WorksForYou extends React.Component<Props, State> {
  currentScrollOffset?: number = 0

  constructor(props: Props) {
    super(props)

    this.state = {
      isRefreshing: false,
      loadingContent: false,
    }
  }

  componentDidMount() {
    // Update read status in gravity
    NativeModules.ARTemporaryAPIModule.markNotificationsRead(error => {
      if (error) {
        console.warn(error)
      } else {
        Events.postEvent({
          name: "Notifications read",
          source_screen: "works for you page",
        })
      }
    })
  }

  fetchNextPage = () => {
    if (!this.props.relay.hasMore() || this.props.relay.isLoading()) {
      return
    }
    this.setState({ loadingContent: true }, () => {
      this.props.relay.loadMore(PAGE_SIZE, error => {
        if (error) {
          // FIXME: Handle error
          console.error("WorksForYou.tsx", error.message)
        }

        this.setState({ loadingContent: false })
      })
    })
  }

  handleRefresh = () => {
    this.setState({ isRefreshing: true })
    this.props.relay.refetchConnection(PAGE_SIZE, error => {
      if (error) {
        // FIXME: Handle error
        console.error("WorksForYou.tsx #handleRefresh", error.message)
      }
      this.setState({ isRefreshing: false })
    })
  }

  render() {
    const notifications = get(this.props, props => props.query.me.followsAndSaves.notifications.edges)
    const hasNotifications = notifications.length

    /* If showing the empty state, the ScrollView should have a {flex: 1} style so it can expand to fit the screen.
       otherwise, it should not use any flex growth.
    */
    return (
      <ScrollView
        contentContainerStyle={hasNotifications ? {} : styles.container}
        onScroll={isCloseToBottom(this.fetchNextPage)}
        scrollEventThrottle={100}
        refreshControl={<RefreshControl refreshing={this.state.isRefreshing} onRefresh={this.handleRefresh} />}
      >
        <View style={{ flex: 1 }}>{hasNotifications ? this.renderNotifications() : this.renderEmptyState()}</View>
      </ScrollView>
    )
  }

  renderNotifications() {
    const { loadingContent } = this.state
    const notifications = get(this.props, props => props.query.me.followsAndSaves.notifications.edges)

    return (
      <Theme>
        <FlatList
          data={notifications}
          keyExtractor={item => item.node.id}
          scrollEnabled={false}
          renderItem={data => {
            return <Notification notification={data.item.node} />
          }}
          ItemSeparatorComponent={() => (
            <Box px={2}>
              <Separator />
            </Box>
          )}
          ListFooterComponent={() => (
            <>
              {loadingContent && (
                <Box p={2} style={{ height: 50 }}>
                  <Flex style={{ flex: 1 }} flexDirection="row" justifyContent="center">
                    <Spinner />
                  </Flex>
                </Box>
              )}
            </>
          )}
        />
      </Theme>
    )
  }

  renderEmptyState() {
    return (
      <ZeroState
        title="You haven't followed any artists yet."
        subtitle="Follow artists to see new works that have been added to Artsy"
      />
    )
  }
}

interface Styles {
  container: ViewStyle
  title: TextStyle
  separator: ViewStyle
}

const styles = StyleSheet.create<Styles>({
  container: {
    flex: 1,
  },
  title: {
    marginTop: 20,
    fontSize: 20,
  },
  separator: {
    height: 1,
    backgroundColor: colors["gray-regular"],
  },
})

const WorksForYouContainer = createPaginationContainer(
  WorksForYou,
  {
    query: graphql`
      fragment WorksForYou_query on Query
        @argumentDefinitions(
          count: { type: "Int", defaultValue: 10 }
          cursor: { type: "String" }
          sort: { type: "ArtworkSorts" }
        ) {
        me {
          followsAndSaves {
            notifications: bundledArtworksByArtistConnection(sort: PUBLISHED_AT_DESC, first: $count, after: $cursor)
              @connection(key: "WorksForYou_notifications") {
              pageInfo {
                hasNextPage
                endCursor
              }
              edges {
                node {
                  id
                  ...Notification_notification
                }
              }
            }
          }
        }
      }
    `,
  },
  {
    direction: "forward",
    getConnectionFromProps(props) {
      return props.query.me.followsAndSaves.notifications
    },
    getFragmentVariables(prevVars, totalCount) {
      return {
        ...prevVars,
        count: totalCount,
      }
    },
    getVariables(_props, { count, cursor }, fragmentVariables) {
      return {
        // in most cases, for variables other than connection filters like
        // `first`, `after`, etc. you may want to use the previous values.
        ...fragmentVariables,
        count,
        cursor,
      }
    },
    query: graphql`
      query WorksForYouQuery($count: Int!, $cursor: String) {
        ...WorksForYou_query @arguments(count: $count, cursor: $cursor)
      }
    `,
  }
)

export default WorksForYouContainer


text:
lua-path
========

path string manipulation

## Installation

```sh
luarocks install --from=http://mah0x211.github.io/rocks/ path
```

## Functions

### path = normalize( str, str[, ...] )

returns a normalized path string.

**Parameters**

- path: path components.

**Returns**

1. path: normalized absolute path string.

### path = dirname( path )

return a directory portion of path string.

**Parameters**

- path: path string.

**Returns**

1. path: directory portion of path string.
2. errstr: dependent on a system.

### path = basename( path )

return a filename or directory portion of path string.

**Parameters**

- path: path string.

**Returns**

1. path: filename or directory portion of path string.
2. errstr: dependent on a system.

### ext = extname( path )

return a extension of the path string.

**Parameters**

- path: path string.

**Returns**

1. path: extension of the path string.

### path, errstr = exists( path )

returns the canonicalized absolute pathname.

**Parameters**

- path: path string.

**Returns**

1. path: returns the canonicalized absolute pathname or nil on error or not exists.
2. errstr: dependent on a system.

### info, errstr = stat( path [, followSymlink [,  openfd]] )

return a information about the file pointed to by specified path.

**Parameters**

- path: path string.
- followSymlink: follow symbolic links (default: true).
- openfd: open a file descriptor (default: false).

**Returns**

1. info: info table (same as struct stat without st_ prefix), nil on error or not exists.
2. errstr: dependent on a system.

### path = tofile( path )

returns the absolute path if it is regular file.

**Parameters**

- path: path string.

**Returns**

1. path: absolute path string or nil on error or not exists.
2. errstr: dependent on a system.

### path = todir( path )

returns the absolute path if it is directory.

**Parameters**

- path: path string.

**Returns**

1. path: absolute path string or nil on error or not exists.
2. errstr: dependent on a system.

### bool = isfile( info.mode )

returns a true if it is regular file.

### bool = isdir( info.mode )

returns a true if it is directory.

### bool = ischr( info.mode )

returns a true if it is character device.

### bool = isblk( info.mode )

returns a true if it is block device.

### bool = isfifo( info.mode )

returns a true if it is FIFO special file, or a pipe.

### bool = islnk( info.mode )

returns a true if it is symbolic link.

### bool = issock( info.mode )

returns a true if it is socket.

### entries, errstr = readdir( path )

return entries of specified directory path.

**Parameters**

- path: directory path string.

**Returns**

1. entries: entries table, nil on error or not exists.
2. errstr: dependent on a system.


text:
<?php
// autogenerated file 30.09.2013 15:20
// $Id: $
// $Log: $
//
require_once 'EbatNs_FacetType.php';

/**
 * A compressed, representative title for the eBay URL.
 *
 * @link http://developer.ebay.com/DevZone/XML/docs/Reference/eBay/types/URLTypeCodeType.html
 *
 * @property string ViewItemURL
 * @property string ViewUserURL
 * @property string MyeBayURL
 * @property string MyeBayBiddingURL
 * @property string MyeBayNotWonURL
 * @property string MyeBayWonURL
 * @property string MyeBayWatchingURL
 * @property string eBayStoreURL
 * @property string SmallLogoURL
 * @property string MediumLogoURL
 * @property string LargeLogoURL
 * @property string CustomCode
 */
class URLTypeCodeType extends EbatNs_FacetType
{
	const CodeType_ViewItemURL = 'ViewItemURL';
	const CodeType_ViewUserURL = 'ViewUserURL';
	const CodeType_MyeBayURL = 'MyeBayURL';
	const CodeType_MyeBayBiddingURL = 'MyeBayBiddingURL';
	const CodeType_MyeBayNotWonURL = 'MyeBayNotWonURL';
	const CodeType_MyeBayWonURL = 'MyeBayWonURL';
	const CodeType_MyeBayWatchingURL = 'MyeBayWatchingURL';
	const CodeType_eBayStoreURL = 'eBayStoreURL';
	const CodeType_SmallLogoURL = 'SmallLogoURL';
	const CodeType_MediumLogoURL = 'MediumLogoURL';
	const CodeType_LargeLogoURL = 'LargeLogoURL';
	const CodeType_CustomCode = 'CustomCode';

	/**
	 * @return
	 */
	function __construct()
	{
		parent::__construct('URLTypeCodeType', 'urn:ebay:apis:eBLBaseComponents');

	}
}

$Facet_URLTypeCodeType = new URLTypeCodeType();

?>


text:
NAMESPACE_BEGIN(CryptoPP)

typedef DES_EDE2 Default_BlockCipher;
typedef SHA DefaultHashModule;
typedef HMAC<DefaultHashModule> DefaultMAC;

//! Password-Based Encryptor using DES-EDE2
class DefaultEncryptor : public ProxyFilter
{
public:
	DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment = NULL);
	DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);

protected:
	void FirstPut(const byte *);
	void LastPut(const byte *inString, size_t length);

private:
	SecByteBlock m_passphrase;
	CBC_Mode<Default_BlockCipher>::Encryption m_cipher;
};

//! Password-Based Decryptor using DES-EDE2
class DefaultDecryptor : public ProxyFilter
{
public:
	DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
	DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);

	class Err : public Exception
	{
	public:
		Err(const std::string &s)
			: Exception(DATA_INTEGRITY_CHECK_FAILED, s) {}
	};
	class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}};

	enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD};
	State CurrentState() const {return m_state;}

protected:
	void FirstPut(const byte *inString);
	void LastPut(const byte *inString, size_t length);

	State m_state;

private:
	void CheckKey(const byte *salt, const byte *keyCheck);

	SecByteBlock m_passphrase;
	CBC_Mode<Default_BlockCipher>::Decryption m_cipher;
	member_ptr<FilterWithBufferedInput> m_decryptor;
	bool m_throwException;
};

//! Password-Based Encryptor using DES-EDE2 and HMAC/SHA-1
class DefaultEncryptorWithMAC : public ProxyFilter
{
public:
	DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL);
	DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);

protected:
	void FirstPut(const byte *inString) {}
	void LastPut(const byte *inString, size_t length);

private:
	member_ptr<DefaultMAC> m_mac;
};

//! Password-Based Decryptor using DES-EDE2 and HMAC/SHA-1
class DefaultDecryptorWithMAC : public ProxyFilter
{
public:
	class MACBadErr : public DefaultDecryptor::Err {public: MACBadErr() : DefaultDecryptor::Err("DefaultDecryptorWithMAC: MAC check failed") {}};

	DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
	DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);

	DefaultDecryptor::State CurrentState() const;
	bool CheckLastMAC() const;

protected:
	void FirstPut(const byte *inString) {}
	void LastPut(const byte *inString, size_t length);

private:
	member_ptr<DefaultMAC> m_mac;
	HashVerifier *m_hashVerifier;
	bool m_throwException;
};

NAMESPACE_END

#endif