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

#include "base/profiler.h"
#include "base/string_util.h"

#if defined(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/google/profiler.h"
#endif

// When actually using quantify, uncomment the following line.
// #define QUANTIFY

#ifdef QUANTIFY
// this #define is used to prevent people from directly using pure.h
// instead of profiler.h
#define PURIFY_PRIVATE_INCLUDE
#include "base/third_party/purify/pure.h"
#endif // QUANTIFY

namespace base {

void Profiler::StartRecording() {
#ifdef QUANTIFY
  QuantifyStartRecordingData();
#elif defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerStart("chrome-profile");
#endif
}

void Profiler::StopRecording() {
#ifdef QUANTIFY
  QuantifyStopRecordingData();
#elif defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerStop();
#endif
}

void Profiler::Flush() {
#if defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerFlush();
#endif
}

void Profiler::ClearData() {
#ifdef QUANTIFY
  QuantifyClearData();
#endif
}

void Profiler::SetThreadName(const char *name) {
#ifdef QUANTIFY
  // make a copy since the Quantify function takes a char*, not const char*
  char buffer[512];
  base::snprintf(buffer, sizeof(buffer)-1, "%s", name);
  QuantifySetThreadName(buffer);
#endif
}

}  // namespace base
<commit_msg>Add a defined(OS_LINUX) guard for the include of tcmalloc's profiler.h<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/profiler.h"
#include "base/string_util.h"

#if defined(USE_TCMALLOC) && defined(OS_LINUX)
#include "third_party/tcmalloc/chromium/src/google/profiler.h"
#endif

// When actually using quantify, uncomment the following line.
// #define QUANTIFY

#ifdef QUANTIFY
// this #define is used to prevent people from directly using pure.h
// instead of profiler.h
#define PURIFY_PRIVATE_INCLUDE
#include "base/third_party/purify/pure.h"
#endif // QUANTIFY

namespace base {

void Profiler::StartRecording() {
#ifdef QUANTIFY
  QuantifyStartRecordingData();
#elif defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerStart("chrome-profile");
#endif
}

void Profiler::StopRecording() {
#ifdef QUANTIFY
  QuantifyStopRecordingData();
#elif defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerStop();
#endif
}

void Profiler::Flush() {
#if defined(USE_TCMALLOC) && defined(OS_LINUX)
  ProfilerFlush();
#endif
}

void Profiler::ClearData() {
#ifdef QUANTIFY
  QuantifyClearData();
#endif
}

void Profiler::SetThreadName(const char *name) {
#ifdef QUANTIFY
  // make a copy since the Quantify function takes a char*, not const char*
  char buffer[512];
  base::snprintf(buffer, sizeof(buffer)-1, "%s", name);
  QuantifySetThreadName(buffer);
#endif
}

}  // namespace base
<|endoftext|>


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

#include "base/win_util.h"

#include <sddl.h>

#include "base/logging.h"
#include "base/registry.h"
#include "base/scoped_handle.h"
#include "base/string_util.h"

namespace win_util {

#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \
    offsetof(struct_name, member) + \
    (sizeof static_cast<struct_name*>(NULL)->member)
#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
    SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)

void GetNonClientMetrics(NONCLIENTMETRICS* metrics) {
  DCHECK(metrics);

  static const UINT SIZEOF_NONCLIENTMETRICS =
      (GetWinVersion() == WINVERSION_VISTA) ?
      sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
  metrics->cbSize = SIZEOF_NONCLIENTMETRICS;
  const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                                              SIZEOF_NONCLIENTMETRICS, metrics,
                                              0);
  DCHECK(success);
}

WinVersion GetWinVersion() {
  static bool checked_version = false;
  static WinVersion win_version = WINVERSION_PRE_2000;
  if (!checked_version) {
    OSVERSIONINFO version_info;
    version_info.dwOSVersionInfoSize = sizeof version_info;
    GetVersionEx(&version_info);
    if (version_info.dwMajorVersion == 5) {
      switch (version_info.dwMinorVersion) {
        case 0:
          win_version = WINVERSION_2000;
          break;
        case 1:
          win_version = WINVERSION_XP;
          break;
        case 2:
        default:
          win_version = WINVERSION_SERVER_2003;
          break;
      }
    } else if (version_info.dwMajorVersion >= 6) {
      win_version = WINVERSION_VISTA;
    }
    checked_version = true;
  }
  return win_version;
}

void GetServicePackLevel(int* major, int* minor) {
  DCHECK(major && minor);
  static bool checked_version = false;
  static int service_pack_major = -1;
  static int service_pack_minor = -1;
  if (!checked_version) {
    OSVERSIONINFOEX version_info = {0};
    version_info.dwOSVersionInfoSize = sizeof(version_info);
    GetVersionEx(reinterpret_cast<OSVERSIONINFOW*>(&version_info));
    service_pack_major = version_info.wServicePackMajor;
    service_pack_minor = version_info.wServicePackMinor;
    checked_version = true;
  }

  *major = service_pack_major;
  *minor = service_pack_minor;
}

bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
                             ACCESS_MASK access) {
  PSECURITY_DESCRIPTOR descriptor = NULL;
  PACL old_dacl = NULL;
  PACL new_dacl = NULL;

  if (ERROR_SUCCESS != GetSecurityInfo(handle, SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL,
            &descriptor))
    return false;

  BYTE sid[SECURITY_MAX_SID_SIZE] = {0};
  DWORD size_sid = SECURITY_MAX_SID_SIZE;

  if (known_sid == WinSelfSid) {
    // We hijack WinSelfSid when we want to add the current user instead of
    // a known sid.
    HANDLE token = NULL;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
      LocalFree(descriptor);
      return false;
    }

    DWORD size = sizeof(TOKEN_USER) + size_sid;
    TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
    scoped_ptr<TOKEN_USER> token_user_ptr(token_user);
    BOOL ret = GetTokenInformation(token, TokenUser, token_user, size, &size);

    CloseHandle(token);

    if (!ret) {
      LocalFree(descriptor);
      return false;
    }
    memcpy(sid, token_user->User.Sid, size_sid);
  } else {
    if (!CreateWellKnownSid(known_sid , NULL, sid, &size_sid)) {
      LocalFree(descriptor);
      return false;
    }
  }

  EXPLICIT_ACCESS new_access = {0};
  new_access.grfAccessMode = GRANT_ACCESS;
  new_access.grfAccessPermissions = access;
  new_access.grfInheritance = NO_INHERITANCE;

  new_access.Trustee.pMultipleTrustee = NULL;
  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(&sid);

  if (ERROR_SUCCESS != SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl)) {
    LocalFree(descriptor);
    return false;
  }

  DWORD result = SetSecurityInfo(handle, SE_KERNEL_OBJECT,
                                 DACL_SECURITY_INFORMATION, NULL, NULL,
                                 new_dacl, NULL);

  LocalFree(new_dacl);
  LocalFree(descriptor);

  if (ERROR_SUCCESS != result)
    return false;

  return true;
}

bool GetUserSidString(std::wstring* user_sid) {
  // Get the current token.
  HANDLE token = NULL;
  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
    return false;
  ScopedHandle token_scoped(token);

  DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
  scoped_ptr<TOKEN_USER> user(reinterpret_cast<TOKEN_USER*>(new BYTE[size]));

  if (!::GetTokenInformation(token, TokenUser, user.get(), size, &size))
    return false;

  if (!user->User.Sid)
    return false;

  // Convert the data to a string.
  wchar_t* sid_string;
  if (!::ConvertSidToStringSid(user->User.Sid, &sid_string))
    return false;

  *user_sid = sid_string;

  ::LocalFree(sid_string);

  return true;
}

bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor) {
  // Get the current token.
  HANDLE token = NULL;
  if (!OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
    return false;
  ScopedHandle token_scoped(token);

  // Get the size of the TokenGroups structure.
  DWORD size = 0;
  BOOL result = GetTokenInformation(token, TokenGroups, NULL,  0, &size);
  if (result != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    return false;

  // Get the data.
  scoped_ptr<TOKEN_GROUPS> token_groups;
  token_groups.reset(reinterpret_cast<TOKEN_GROUPS*>(new char[size]));

  if (!GetTokenInformation(token, TokenGroups, token_groups.get(), size, &size))
    return false;

  // Look for the logon sid.
  SID* logon_sid = NULL;
  for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
    if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) {
        logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid);
        break;
    }
  }

  if (!logon_sid)
    return false;

  // Convert the data to a string.
  wchar_t* sid_string;
  if (!ConvertSidToStringSid(logon_sid, &sid_string))
    return false;

  static const wchar_t dacl_format[] = L"D:(A;OICI;GA;;;%ls)";
  wchar_t dacl[SECURITY_MAX_SID_SIZE + arraysize(dacl_format) + 1] = {0};
  wsprintf(dacl, dacl_format, sid_string);

  LocalFree(sid_string);

  // Convert the string to a security descriptor
  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
      dacl,
      SDDL_REVISION_1,
      reinterpret_cast<PSECURITY_DESCRIPTOR*>(security_descriptor),
      NULL)) {
    return false;
  }

  return true;
}

#pragma warning(push)
#pragma warning(disable:4312 4244)
WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) {
  // The reason we don't return the SetwindowLongPtr() value is that it returns
  // the orignal window procedure and not the current one. I don't know if it is
  // a bug or an intended feature.
  WNDPROC oldwindow_proc =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
  SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc));
  return oldwindow_proc;
}

void* SetWindowUserData(HWND hwnd, void* user_data) {
  return
      reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA,
          reinterpret_cast<LONG_PTR>(user_data)));
}

void* GetWindowUserData(HWND hwnd) {
  return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}

// Maps to the WNDPROC for a window that was active before the subclass was
// installed.
static const wchar_t* const kHandlerKey = L"__ORIGINAL_MESSAGE_HANDLER__";

bool Subclass(HWND window, WNDPROC subclass_proc) {
  WNDPROC original_handler =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
  if (original_handler != subclass_proc) {
    win_util::SetWindowProc(window, subclass_proc);
    SetProp(window, kHandlerKey, original_handler);
    return true;
  }
  return false;
}

bool Unsubclass(HWND window, WNDPROC subclass_proc) {
  WNDPROC current_handler =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
  if (current_handler == subclass_proc) {
    HANDLE original_handler = GetProp(window, kHandlerKey);
    if (original_handler) {
      RemoveProp(window, kHandlerKey);
      win_util::SetWindowProc(window,
                              reinterpret_cast<WNDPROC>(original_handler));
      return true;
    }
  }
  return false;
}

WNDPROC GetSuperclassWNDPROC(HWND window) {
  return reinterpret_cast<WNDPROC>(GetProp(window, kHandlerKey));
}

#pragma warning(pop)

bool IsShiftPressed() {
  return (::GetKeyState(VK_SHIFT) & 0x80) == 0x80;
}

bool IsCtrlPressed() {
  return (::GetKeyState(VK_CONTROL) & 0x80) == 0x80;
}

bool IsAltPressed() {
  return (::GetKeyState(VK_MENU) & 0x80) == 0x80;
}

std::wstring GetClassName(HWND window) {
  // GetClassNameW will return a truncated result (properly null terminated) if
  // the given buffer is not large enough.  So, it is not possible to determine
  // that we got the entire class name if the result is exactly equal to the
  // size of the buffer minus one.
  DWORD buffer_size = MAX_PATH;
  while (true) {
    std::wstring output;
    DWORD size_ret =
        GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size);
    if (size_ret == 0)
      break;
    if (size_ret < (buffer_size - 1)) {
      output.resize(size_ret);
      return output;
    }
    buffer_size *= 2;
  }
  return std::wstring();  // error
}

bool UserAccountControlIsEnabled() {
  RegKey key(HKEY_LOCAL_MACHINE,
      L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
  DWORD uac_enabled;
  if (!key.ReadValueDW(L"EnableLUA", &uac_enabled))
    return true;
  return (uac_enabled == 1);
}

std::wstring FormatMessage(unsigned messageid) {
  wchar_t* string_buffer = NULL;
  unsigned string_length = ::FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageid, 0,
      reinterpret_cast<wchar_t *>(&string_buffer), 0, NULL);

  std::wstring formatted_string;
  if (string_buffer) {
    formatted_string = string_buffer;
    LocalFree(reinterpret_cast<HLOCAL>(string_buffer));
  } else {
    // The formating failed. simply convert the message value into a string.
    SStringPrintf(&formatted_string, L"message number %d", messageid);
  }
  return formatted_string;
}

std::wstring FormatLastWin32Error() {
  return FormatMessage(GetLastError());
}

}  // namespace win_util

#ifdef _MSC_VER
//
// If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1.
//
extern char VisualStudio2005ServicePack1Detection[10];
COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*),
               VS2005SP1Detect);
//
// Chrome requires at least Service Pack 1 for Visual Studio 2005.
//
#endif  // _MSC_VER

#ifndef COPY_FILE_COPY_SYMLINK
#error You must install the Windows 2008 or Vista Software Development Kit and \
set it as your default include path to build this library. You can grab it by \
searching for "download windows sdk 2008" in your favorite web search engine.  \
Also make sure you register the SDK with Visual Studio, by selecting \
"Integrate Windows SDK with Visual Studio 2005" from the Windows SDK \
menu (see Start - All Programs - Microsoft Windows SDK - \
Visual Studio Registration).
#endif
<commit_msg>More fun with detecting UAC. Reports in the field indicate that some computers have EnableLUA set to 2, which Vista treats as UAC 'on' but since our check checks for uac == 1 we think UAC is 'off'.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/win_util.h"

#include <sddl.h>

#include "base/logging.h"
#include "base/registry.h"
#include "base/scoped_handle.h"
#include "base/string_util.h"

namespace win_util {

#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \
    offsetof(struct_name, member) + \
    (sizeof static_cast<struct_name*>(NULL)->member)
#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
    SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)

void GetNonClientMetrics(NONCLIENTMETRICS* metrics) {
  DCHECK(metrics);

  static const UINT SIZEOF_NONCLIENTMETRICS =
      (GetWinVersion() == WINVERSION_VISTA) ?
      sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
  metrics->cbSize = SIZEOF_NONCLIENTMETRICS;
  const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                                              SIZEOF_NONCLIENTMETRICS, metrics,
                                              0);
  DCHECK(success);
}

WinVersion GetWinVersion() {
  static bool checked_version = false;
  static WinVersion win_version = WINVERSION_PRE_2000;
  if (!checked_version) {
    OSVERSIONINFO version_info;
    version_info.dwOSVersionInfoSize = sizeof version_info;
    GetVersionEx(&version_info);
    if (version_info.dwMajorVersion == 5) {
      switch (version_info.dwMinorVersion) {
        case 0:
          win_version = WINVERSION_2000;
          break;
        case 1:
          win_version = WINVERSION_XP;
          break;
        case 2:
        default:
          win_version = WINVERSION_SERVER_2003;
          break;
      }
    } else if (version_info.dwMajorVersion >= 6) {
      win_version = WINVERSION_VISTA;
    }
    checked_version = true;
  }
  return win_version;
}

void GetServicePackLevel(int* major, int* minor) {
  DCHECK(major && minor);
  static bool checked_version = false;
  static int service_pack_major = -1;
  static int service_pack_minor = -1;
  if (!checked_version) {
    OSVERSIONINFOEX version_info = {0};
    version_info.dwOSVersionInfoSize = sizeof(version_info);
    GetVersionEx(reinterpret_cast<OSVERSIONINFOW*>(&version_info));
    service_pack_major = version_info.wServicePackMajor;
    service_pack_minor = version_info.wServicePackMinor;
    checked_version = true;
  }

  *major = service_pack_major;
  *minor = service_pack_minor;
}

bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
                             ACCESS_MASK access) {
  PSECURITY_DESCRIPTOR descriptor = NULL;
  PACL old_dacl = NULL;
  PACL new_dacl = NULL;

  if (ERROR_SUCCESS != GetSecurityInfo(handle, SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL,
            &descriptor))
    return false;

  BYTE sid[SECURITY_MAX_SID_SIZE] = {0};
  DWORD size_sid = SECURITY_MAX_SID_SIZE;

  if (known_sid == WinSelfSid) {
    // We hijack WinSelfSid when we want to add the current user instead of
    // a known sid.
    HANDLE token = NULL;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
      LocalFree(descriptor);
      return false;
    }

    DWORD size = sizeof(TOKEN_USER) + size_sid;
    TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
    scoped_ptr<TOKEN_USER> token_user_ptr(token_user);
    BOOL ret = GetTokenInformation(token, TokenUser, token_user, size, &size);

    CloseHandle(token);

    if (!ret) {
      LocalFree(descriptor);
      return false;
    }
    memcpy(sid, token_user->User.Sid, size_sid);
  } else {
    if (!CreateWellKnownSid(known_sid , NULL, sid, &size_sid)) {
      LocalFree(descriptor);
      return false;
    }
  }

  EXPLICIT_ACCESS new_access = {0};
  new_access.grfAccessMode = GRANT_ACCESS;
  new_access.grfAccessPermissions = access;
  new_access.grfInheritance = NO_INHERITANCE;

  new_access.Trustee.pMultipleTrustee = NULL;
  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(&sid);

  if (ERROR_SUCCESS != SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl)) {
    LocalFree(descriptor);
    return false;
  }

  DWORD result = SetSecurityInfo(handle, SE_KERNEL_OBJECT,
                                 DACL_SECURITY_INFORMATION, NULL, NULL,
                                 new_dacl, NULL);

  LocalFree(new_dacl);
  LocalFree(descriptor);

  if (ERROR_SUCCESS != result)
    return false;

  return true;
}

bool GetUserSidString(std::wstring* user_sid) {
  // Get the current token.
  HANDLE token = NULL;
  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
    return false;
  ScopedHandle token_scoped(token);

  DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
  scoped_ptr<TOKEN_USER> user(reinterpret_cast<TOKEN_USER*>(new BYTE[size]));

  if (!::GetTokenInformation(token, TokenUser, user.get(), size, &size))
    return false;

  if (!user->User.Sid)
    return false;

  // Convert the data to a string.
  wchar_t* sid_string;
  if (!::ConvertSidToStringSid(user->User.Sid, &sid_string))
    return false;

  *user_sid = sid_string;

  ::LocalFree(sid_string);

  return true;
}

bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor) {
  // Get the current token.
  HANDLE token = NULL;
  if (!OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
    return false;
  ScopedHandle token_scoped(token);

  // Get the size of the TokenGroups structure.
  DWORD size = 0;
  BOOL result = GetTokenInformation(token, TokenGroups, NULL,  0, &size);
  if (result != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    return false;

  // Get the data.
  scoped_ptr<TOKEN_GROUPS> token_groups;
  token_groups.reset(reinterpret_cast<TOKEN_GROUPS*>(new char[size]));

  if (!GetTokenInformation(token, TokenGroups, token_groups.get(), size, &size))
    return false;

  // Look for the logon sid.
  SID* logon_sid = NULL;
  for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
    if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) {
        logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid);
        break;
    }
  }

  if (!logon_sid)
    return false;

  // Convert the data to a string.
  wchar_t* sid_string;
  if (!ConvertSidToStringSid(logon_sid, &sid_string))
    return false;

  static const wchar_t dacl_format[] = L"D:(A;OICI;GA;;;%ls)";
  wchar_t dacl[SECURITY_MAX_SID_SIZE + arraysize(dacl_format) + 1] = {0};
  wsprintf(dacl, dacl_format, sid_string);

  LocalFree(sid_string);

  // Convert the string to a security descriptor
  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
      dacl,
      SDDL_REVISION_1,
      reinterpret_cast<PSECURITY_DESCRIPTOR*>(security_descriptor),
      NULL)) {
    return false;
  }

  return true;
}

#pragma warning(push)
#pragma warning(disable:4312 4244)
WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) {
  // The reason we don't return the SetwindowLongPtr() value is that it returns
  // the orignal window procedure and not the current one. I don't know if it is
  // a bug or an intended feature.
  WNDPROC oldwindow_proc =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
  SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc));
  return oldwindow_proc;
}

void* SetWindowUserData(HWND hwnd, void* user_data) {
  return
      reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA,
          reinterpret_cast<LONG_PTR>(user_data)));
}

void* GetWindowUserData(HWND hwnd) {
  return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}

// Maps to the WNDPROC for a window that was active before the subclass was
// installed.
static const wchar_t* const kHandlerKey = L"__ORIGINAL_MESSAGE_HANDLER__";

bool Subclass(HWND window, WNDPROC subclass_proc) {
  WNDPROC original_handler =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
  if (original_handler != subclass_proc) {
    win_util::SetWindowProc(window, subclass_proc);
    SetProp(window, kHandlerKey, original_handler);
    return true;
  }
  return false;
}

bool Unsubclass(HWND window, WNDPROC subclass_proc) {
  WNDPROC current_handler =
      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
  if (current_handler == subclass_proc) {
    HANDLE original_handler = GetProp(window, kHandlerKey);
    if (original_handler) {
      RemoveProp(window, kHandlerKey);
      win_util::SetWindowProc(window,
                              reinterpret_cast<WNDPROC>(original_handler));
      return true;
    }
  }
  return false;
}

WNDPROC GetSuperclassWNDPROC(HWND window) {
  return reinterpret_cast<WNDPROC>(GetProp(window, kHandlerKey));
}

#pragma warning(pop)

bool IsShiftPressed() {
  return (::GetKeyState(VK_SHIFT) & 0x80) == 0x80;
}

bool IsCtrlPressed() {
  return (::GetKeyState(VK_CONTROL) & 0x80) == 0x80;
}

bool IsAltPressed() {
  return (::GetKeyState(VK_MENU) & 0x80) == 0x80;
}

std::wstring GetClassName(HWND window) {
  // GetClassNameW will return a truncated result (properly null terminated) if
  // the given buffer is not large enough.  So, it is not possible to determine
  // that we got the entire class name if the result is exactly equal to the
  // size of the buffer minus one.
  DWORD buffer_size = MAX_PATH;
  while (true) {
    std::wstring output;
    DWORD size_ret =
        GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size);
    if (size_ret == 0)
      break;
    if (size_ret < (buffer_size - 1)) {
      output.resize(size_ret);
      return output;
    }
    buffer_size *= 2;
  }
  return std::wstring();  // error
}

bool UserAccountControlIsEnabled() {
  RegKey key(HKEY_LOCAL_MACHINE,
      L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
  DWORD uac_enabled;
  if (!key.ReadValueDW(L"EnableLUA", &uac_enabled))
    return true;
  // Users can set the EnableLUA value to something arbitrary, like 2, which
  // Vista will treat as UAC enabled, so we make sure it is not set to 0.
  return (uac_enabled != 0);
}

std::wstring FormatMessage(unsigned messageid) {
  wchar_t* string_buffer = NULL;
  unsigned string_length = ::FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageid, 0,
      reinterpret_cast<wchar_t *>(&string_buffer), 0, NULL);

  std::wstring formatted_string;
  if (string_buffer) {
    formatted_string = string_buffer;
    LocalFree(reinterpret_cast<HLOCAL>(string_buffer));
  } else {
    // The formating failed. simply convert the message value into a string.
    SStringPrintf(&formatted_string, L"message number %d", messageid);
  }
  return formatted_string;
}

std::wstring FormatLastWin32Error() {
  return FormatMessage(GetLastError());
}

}  // namespace win_util

#ifdef _MSC_VER
//
// If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1.
//
extern char VisualStudio2005ServicePack1Detection[10];
COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*),
               VS2005SP1Detect);
//
// Chrome requires at least Service Pack 1 for Visual Studio 2005.
//
#endif  // _MSC_VER

#ifndef COPY_FILE_COPY_SYMLINK
#error You must install the Windows 2008 or Vista Software Development Kit and \
set it as your default include path to build this library. You can grab it by \
searching for "download windows sdk 2008" in your favorite web search engine.  \
Also make sure you register the SDK with Visual Studio, by selecting \
"Integrate Windows SDK with Visual Studio 2005" from the Windows SDK \
menu (see Start - All Programs - Microsoft Windows SDK - \
Visual Studio Registration).
#endif
<|endoftext|>


<commit_before>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <google/protobuf/compiler/cpp/cpp_map_field.h>

#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

bool IsProto3Field(const FieldDescriptor* field_descriptor) {
  const FileDescriptor* file_descriptor = field_descriptor->file();
  return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
}

void SetMessageVariables(const FieldDescriptor* descriptor,
                         std::map<std::string, std::string>* variables,
                         const Options& options) {
  SetCommonFieldVariables(descriptor, variables, options);
  (*variables)["type"] = ClassName(descriptor->message_type(), false);
  (*variables)["full_name"] = descriptor->full_name();

  const FieldDescriptor* key =
      descriptor->message_type()->FindFieldByName("key");
  const FieldDescriptor* val =
      descriptor->message_type()->FindFieldByName("value");
  (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
  switch (val->cpp_type()) {
    case FieldDescriptor::CPPTYPE_MESSAGE:
      (*variables)["val_cpp"] = FieldMessageTypeName(val, options);
      break;
    case FieldDescriptor::CPPTYPE_ENUM:
      (*variables)["val_cpp"] = ClassName(val->enum_type(), true);
      break;
    default:
      (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
  }
  (*variables)["key_wire_type"] =
      "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
  (*variables)["val_wire_type"] =
      "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
  (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
  (*variables)["number"] = StrCat(descriptor->number());
  (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));

  if (HasDescriptorMethods(descriptor->file(), options)) {
    (*variables)["lite"] = "";
  } else {
    (*variables)["lite"] = "Lite";
  }
}

MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
                                     const Options& options)
    : FieldGenerator(descriptor, options) {
  SetMessageVariables(descriptor, &variables_, options);
}

MapFieldGenerator::~MapFieldGenerator() {}

void MapFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "::$proto_ns$::internal::MapField$lite$<\n"
      "    $map_classname$,\n"
      "    $key_cpp$, $val_cpp$,\n"
      "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
      "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
      "$name$_;\n");
}

void MapFieldGenerator::GenerateAccessorDeclarations(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "private:\n"
      "const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "    ${1$_internal_$name$$}$() const;\n"
      "::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "    ${1$_internal_mutable_$name$$}$();\n"
      "public:\n"
      "$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "    ${1$$name$$}$() const;\n"
      "$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "    ${1$mutable_$name$$}$();\n",
      descriptor_);
}

void MapFieldGenerator::GenerateInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "$classname$::_internal_$name$() const {\n"
      "  return $name$_.GetMap();\n"
      "}\n"
      "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "$classname$::$name$() const {\n"
      "$annotate_accessor$"
      "  // @@protoc_insertion_point(field_map:$full_name$)\n"
      "  return _internal_$name$();\n"
      "}\n"
      "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "$classname$::_internal_mutable_$name$() {\n"
      "  return $name$_.MutableMap();\n"
      "}\n"
      "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "$classname$::mutable_$name$() {\n"
      "$annotate_accessor$"
      "  // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
      "  return _internal_mutable_$name$();\n"
      "}\n");
}

void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.Clear();\n");
}

void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.MergeFrom(from.$name$_);\n");
}

void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.InternalSwap(&other->$name$_);\n");
}

void MapFieldGenerator::GenerateCopyConstructorCode(
    io::Printer* printer) const {
  GenerateConstructorCode(printer);
  GenerateMergingCode(printer);
}

static void GenerateSerializationLoop(const Formatter& format, bool string_key,
                                      bool string_value,
                                      bool is_deterministic) {
  std::string ptr;
  if (is_deterministic) {
    format("for (size_type i = 0; i < n; i++) {\n");
    ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
                     : "items[static_cast<ptrdiff_t>(i)].second";
  } else {
    format(
        "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
        "    it = this->_internal_$name$().begin();\n"
        "    it != this->_internal_$name$().end(); ++it) {\n");
    ptr = "it";
  }
  format.Indent();

  format(
      "target = $map_classname$::Funcs::InternalSerialize($number$, "
      "$1$->first, $1$->second, target, stream);\n",
      ptr);

  if (string_key || string_value) {
    // ptr is either an actual pointer or an iterator, either way we can
    // create a pointer by taking the address after de-referencing it.
    format("Utf8Check::Check(&(*$1$));\n", ptr);
  }

  format.Outdent();
  format("}\n");
}

void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("if (!this->_internal_$name$().empty()) {\n");
  format.Indent();
  const FieldDescriptor* key_field =
      descriptor_->message_type()->FindFieldByName("key");
  const FieldDescriptor* value_field =
      descriptor_->message_type()->FindFieldByName("value");
  const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
  const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;

  format(
      "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
      "    ConstPtr;\n");
  if (string_key) {
    format(
        "typedef ConstPtr SortItem;\n"
        "typedef ::$proto_ns$::internal::"
        "CompareByDerefFirst<SortItem> Less;\n");
  } else {
    format(
        "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
        "SortItem;\n"
        "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
        "Less;\n");
  }
  bool utf8_check = string_key || string_value;
  if (utf8_check) {
    format(
        "struct Utf8Check {\n"
        "  static void Check(ConstPtr p) {\n");
    format.Indent();
    format.Indent();
    if (string_key) {
      GenerateUtf8CheckCodeForString(
          key_field, options_, false,
          "p->first.data(), static_cast<int>(p->first.length()),\n", format);
    }
    if (string_value) {
      GenerateUtf8CheckCodeForString(
          value_field, options_, false,
          "p->second.data(), static_cast<int>(p->second.length()),\n", format);
    }
    format.Outdent();
    format.Outdent();
    format(
        "  }\n"
        "};\n");
  }

  format(
      "\n"
      "if (stream->IsSerializationDeterministic() &&\n"
      "    this->_internal_$name$().size() > 1) {\n"
      "  ::std::unique_ptr<SortItem[]> items(\n"
      "      new SortItem[this->_internal_$name$().size()]);\n"
      "  typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
      "size_type;\n"
      "  size_type n = 0;\n"
      "  for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
      "      it = this->_internal_$name$().begin();\n"
      "      it != this->_internal_$name$().end(); ++it, ++n) {\n"
      "    items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
      "  }\n"
      "  ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
  format.Indent();
  GenerateSerializationLoop(format, string_key, string_value, true);
  format.Outdent();
  format("} else {\n");
  format.Indent();
  GenerateSerializationLoop(format, string_key, string_value, false);
  format.Outdent();
  format("}\n");
  format.Outdent();
  format("}\n");
}

void MapFieldGenerator::GenerateByteSize(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "total_size += $tag_size$ *\n"
      "    "
      "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
      "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
      "    it = this->_internal_$name$().begin();\n"
      "    it != this->_internal_$name$().end(); ++it) {\n"
      "  total_size += $map_classname$::Funcs::ByteSizeLong(it->first, "
      "it->second);\n"
      "}\n");
}

void MapFieldGenerator::GenerateConstinitInitializer(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    format("$name$_(::$proto_ns$::internal::ConstantInitialized{})");
  } else {
    format("$name$_()");
  }
}

}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<commit_msg>Fix -Wunused-parameter in map<string, int> fields (fixes #8494) (#8500)<commit_after>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <google/protobuf/compiler/cpp/cpp_map_field.h>

#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

bool IsProto3Field(const FieldDescriptor* field_descriptor) {
  const FileDescriptor* file_descriptor = field_descriptor->file();
  return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
}

void SetMessageVariables(const FieldDescriptor* descriptor,
                         std::map<std::string, std::string>* variables,
                         const Options& options) {
  SetCommonFieldVariables(descriptor, variables, options);
  (*variables)["type"] = ClassName(descriptor->message_type(), false);
  (*variables)["full_name"] = descriptor->full_name();

  const FieldDescriptor* key =
      descriptor->message_type()->FindFieldByName("key");
  const FieldDescriptor* val =
      descriptor->message_type()->FindFieldByName("value");
  (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
  switch (val->cpp_type()) {
    case FieldDescriptor::CPPTYPE_MESSAGE:
      (*variables)["val_cpp"] = FieldMessageTypeName(val, options);
      break;
    case FieldDescriptor::CPPTYPE_ENUM:
      (*variables)["val_cpp"] = ClassName(val->enum_type(), true);
      break;
    default:
      (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
  }
  (*variables)["key_wire_type"] =
      "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
  (*variables)["val_wire_type"] =
      "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
  (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
  (*variables)["number"] = StrCat(descriptor->number());
  (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));

  if (HasDescriptorMethods(descriptor->file(), options)) {
    (*variables)["lite"] = "";
  } else {
    (*variables)["lite"] = "Lite";
  }
}

MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
                                     const Options& options)
    : FieldGenerator(descriptor, options) {
  SetMessageVariables(descriptor, &variables_, options);
}

MapFieldGenerator::~MapFieldGenerator() {}

void MapFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "::$proto_ns$::internal::MapField$lite$<\n"
      "    $map_classname$,\n"
      "    $key_cpp$, $val_cpp$,\n"
      "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
      "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
      "$name$_;\n");
}

void MapFieldGenerator::GenerateAccessorDeclarations(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "private:\n"
      "const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "    ${1$_internal_$name$$}$() const;\n"
      "::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "    ${1$_internal_mutable_$name$$}$();\n"
      "public:\n"
      "$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "    ${1$$name$$}$() const;\n"
      "$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "    ${1$mutable_$name$$}$();\n",
      descriptor_);
}

void MapFieldGenerator::GenerateInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "$classname$::_internal_$name$() const {\n"
      "  return $name$_.GetMap();\n"
      "}\n"
      "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
      "$classname$::$name$() const {\n"
      "$annotate_accessor$"
      "  // @@protoc_insertion_point(field_map:$full_name$)\n"
      "  return _internal_$name$();\n"
      "}\n"
      "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "$classname$::_internal_mutable_$name$() {\n"
      "  return $name$_.MutableMap();\n"
      "}\n"
      "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
      "$classname$::mutable_$name$() {\n"
      "$annotate_accessor$"
      "  // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
      "  return _internal_mutable_$name$();\n"
      "}\n");
}

void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.Clear();\n");
}

void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.MergeFrom(from.$name$_);\n");
}

void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.InternalSwap(&other->$name$_);\n");
}

void MapFieldGenerator::GenerateCopyConstructorCode(
    io::Printer* printer) const {
  GenerateConstructorCode(printer);
  GenerateMergingCode(printer);
}

static void GenerateSerializationLoop(const Formatter& format, bool string_key,
                                      bool string_value,
                                      bool is_deterministic) {
  std::string ptr;
  if (is_deterministic) {
    format("for (size_type i = 0; i < n; i++) {\n");
    ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
                     : "items[static_cast<ptrdiff_t>(i)].second";
  } else {
    format(
        "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
        "    it = this->_internal_$name$().begin();\n"
        "    it != this->_internal_$name$().end(); ++it) {\n");
    ptr = "it";
  }
  format.Indent();

  format(
      "target = $map_classname$::Funcs::InternalSerialize($number$, "
      "$1$->first, $1$->second, target, stream);\n",
      ptr);

  if (string_key || string_value) {
    // ptr is either an actual pointer or an iterator, either way we can
    // create a pointer by taking the address after de-referencing it.
    format("Utf8Check::Check(&(*$1$));\n", ptr);
  }

  format.Outdent();
  format("}\n");
}

void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("if (!this->_internal_$name$().empty()) {\n");
  format.Indent();
  const FieldDescriptor* key_field =
      descriptor_->message_type()->FindFieldByName("key");
  const FieldDescriptor* value_field =
      descriptor_->message_type()->FindFieldByName("value");
  const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
  const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;

  format(
      "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
      "    ConstPtr;\n");
  if (string_key) {
    format(
        "typedef ConstPtr SortItem;\n"
        "typedef ::$proto_ns$::internal::"
        "CompareByDerefFirst<SortItem> Less;\n");
  } else {
    format(
        "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
        "SortItem;\n"
        "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
        "Less;\n");
  }
  bool utf8_check = string_key || string_value;
  if (utf8_check) {
    format(
        "struct Utf8Check {\n"
        "  static void Check(ConstPtr p) {\n"
        // p may be unused when GetUtf8CheckMode evaluates to kNone,
        // thus disabling the validation.
        "    (void)p;\n");
    format.Indent();
    format.Indent();
    if (string_key) {
      GenerateUtf8CheckCodeForString(
          key_field, options_, false,
          "p->first.data(), static_cast<int>(p->first.length()),\n", format);
    }
    if (string_value) {
      GenerateUtf8CheckCodeForString(
          value_field, options_, false,
          "p->second.data(), static_cast<int>(p->second.length()),\n", format);
    }
    format.Outdent();
    format.Outdent();
    format(
        "  }\n"
        "};\n");
  }

  format(
      "\n"
      "if (stream->IsSerializationDeterministic() &&\n"
      "    this->_internal_$name$().size() > 1) {\n"
      "  ::std::unique_ptr<SortItem[]> items(\n"
      "      new SortItem[this->_internal_$name$().size()]);\n"
      "  typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
      "size_type;\n"
      "  size_type n = 0;\n"
      "  for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
      "      it = this->_internal_$name$().begin();\n"
      "      it != this->_internal_$name$().end(); ++it, ++n) {\n"
      "    items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
      "  }\n"
      "  ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
  format.Indent();
  GenerateSerializationLoop(format, string_key, string_value, true);
  format.Outdent();
  format("} else {\n");
  format.Indent();
  GenerateSerializationLoop(format, string_key, string_value, false);
  format.Outdent();
  format("}\n");
  format.Outdent();
  format("}\n");
}

void MapFieldGenerator::GenerateByteSize(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "total_size += $tag_size$ *\n"
      "    "
      "::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
      "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
      "    it = this->_internal_$name$().begin();\n"
      "    it != this->_internal_$name$().end(); ++it) {\n"
      "  total_size += $map_classname$::Funcs::ByteSizeLong(it->first, "
      "it->second);\n"
      "}\n");
}

void MapFieldGenerator::GenerateConstinitInitializer(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    format("$name$_(::$proto_ns$::internal::ConstantInitialized{})");
  } else {
    format("$name$_()");
  }
}

}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stx/protobuf/msg.h>
#include <stx/json/json.h>
#include <zbase/WebUIServlet.h>
#include <zbase/WebUIModuleConfig.pb.h>
#include <zbase/HTTPAuth.h>
#include <zbase/buildconfig.h>

namespace zbase {

WebUIServlet::WebUIServlet(
    AnalyticsAuth* auth) :
    auth_(auth) {}

void WebUIServlet::handleHTTPRequest(
    http::HTTPRequest* request,
    http::HTTPResponse* response) {
  URI uri(request->uri());
  try {
    handle(request, response);
  } catch (const StandardException& e) {
    logError("zbase", e, "error while handling HTTP request");
    response->setStatus(http::kStatusInternalServerError);
    response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(Assets::getAsset("zbase/webui/500.html"));
  }
}

void WebUIServlet::handle(
    http::HTTPRequest* request,
    http::HTTPResponse* response) {
  URI uri(request->uri());

  auto session = HTTPAuth::authenticateRequest(*request, auth_);

  static const String kAssetsPathPrefix = "/a/_/a/";
  if (StringUtil::beginsWith(uri.path(), kAssetsPathPrefix)) {
    auto asset_path = uri.path().substr(kAssetsPathPrefix.size());

    // FIXME validate path

    //"css" => "text/css; charset=utf-8",
    //"png" => "image/png",
    //"html" => "text/html; charset=utf-8",
    //"js" => "application/javascript; charset=utf-8"
    response->setStatus(http::kStatusOK);
    //response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(loadFile("assets/" + asset_path)); // FIXME
    return;
  }

  static const String kConfigPath = "/a/_/c";
  if (uri.path() == kConfigPath) {
    Buffer buf;
    json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));

    renderConfig(request, session, &json);

    response->setStatus(http::kStatusOK);
    response->addHeader("Content-Type", "application/json; charset=utf-8");
    response->addBody(buf);
    return;
  }

  static const String kModulesPathPrefix = "/a/_/m/";
  if (StringUtil::beginsWith(uri.path(), kModulesPathPrefix)) {
    auto module_name = uri.path().substr(kModulesPathPrefix.size());

    // FIXME cache module config
    auto module_cfg = msg::parseText<WebUIModuleConfig>(
        loadFile(StringUtil::format("$0/MANIFEST", module_name)));

    if (session.isEmpty() && !module_cfg.is_public()) {
      response->setStatus(http::kStatusForbidden);
      response->addHeader("Content-Type", "text/html; charset=utf-8");
      response->addBody(Assets::getAsset("zbase/webui/403.html"));
      return;
    }

    String module_html;

    for (const auto& file : module_cfg.html_file()) {
      module_html +=
          loadFile(StringUtil::format("$0/$1", module_name, file));
    }

    for (const auto& file : module_cfg.css_file()) {
      module_html += StringUtil::format(
        "<style type='text/css'>$0</style>",
        loadFile(StringUtil::format("$0/$1", module_name, file)));
    }

    for (const auto& file : module_cfg.js_file()) {
      module_html += StringUtil::format(
        "<script type='text/javascript'>$0</script>",
        loadFile(StringUtil::format("$0/$1", module_name, file)));
    }

    module_html += StringUtil::format(
        "<script type='text/javascript'>ZBase.moduleReady('$0');</script>",
        module_name);

    response->setStatus(http::kStatusOK);
    response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(module_html);
    return;
  }

  Buffer app_config;
  json::JSONOutputStream app_config_json(
      BufferOutputStream::fromBuffer(&app_config));
  renderConfig(request, session, &app_config_json);

  auto app_html = loadFile("app.html");
  StringUtil::replaceAll(&app_html, "{{app_css}}", loadFile("app.css"));
  StringUtil::replaceAll(&app_html, "{{app_js}}", loadFile("app.js"));
  StringUtil::replaceAll(&app_html, "{{config_json}}", app_config.toString());

  response->setStatus(http::kStatusOK);
  response->addHeader("Content-Type", "text/html; charset=utf-8");
  response->addBody(app_html);
}

String WebUIServlet::loadFile(const String& filename) {
  return Assets::getAsset("zbase/webui/" + filename);
}

void WebUIServlet::renderConfig(
    http::HTTPRequest* request,
    const Option<AnalyticsSession>& session,
    json::JSONOutputStream* json) {
  auto app_cfg = msg::parseText<WebUIAppConfig>(loadFile("MANIFEST"));

  json->beginObject();

  // routes
  json->addObjectEntry("routes");
  json->beginArray();

  size_t nroute = 0;
  for (const auto& route : app_cfg.route()) {
    if (!route.is_public() && session.isEmpty()) {
      continue;
    }

    Vector<String> modules(
        route.require_module().begin(),
        route.require_module().end());

    if (++nroute > 1) {
      json->addComma();
    }

    json->beginObject();

    json->addObjectEntry("view");
    json->addString(route.view());

    if (route.has_path_prefix()) {
      json->addComma();
      json->addObjectEntry("path_prefix");
      json->addString(route.path_prefix());
    }

    if (route.has_path_match()) {
      json->addComma();
      json->addObjectEntry("path_match");
      json->addString(route.path_match());
    }

    json->addComma();
    json->addObjectEntry("modules");
    json::toJSON(modules, json);

    json->endObject();
  }

  json->endArray();

  // current user
  if (!session.isEmpty()) {
    json->addComma();
    json->addObjectEntry("current_user");
    json->beginObject();

    json->addObjectEntry("userid");
    json->addString(session.get().userid());
    json->addComma();

    json->addObjectEntry("namespace");
    json->addString(session.get().customer());

    json->endObject();
  }

  // default route
  json->addComma();
  json->addObjectEntry("default_route");
  json->addString(session.isEmpty() ? "/a/login" : "/a/");
  json->addComma();

  json->addObjectEntry("zbase_domain");
  json->addString(getDomain(*request));
  json->addComma();

  json->addObjectEntry("zbase_build_id");
  json->addString(ZBASE_BUILD_ID);

  json->endObject();
}

}
<commit_msg>hacky documentation backend<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stx/protobuf/msg.h>
#include <stx/json/json.h>
#include <zbase/WebUIServlet.h>
#include <zbase/WebUIModuleConfig.pb.h>
#include <zbase/HTTPAuth.h>
#include <zbase/buildconfig.h>

namespace zbase {

WebUIServlet::WebUIServlet(
    AnalyticsAuth* auth) :
    auth_(auth) {}

void WebUIServlet::handleHTTPRequest(
    http::HTTPRequest* request,
    http::HTTPResponse* response) {
  URI uri(request->uri());
  try {
    handle(request, response);
  } catch (const StandardException& e) {
    logError("zbase", e, "error while handling HTTP request");
    response->setStatus(http::kStatusInternalServerError);
    response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(Assets::getAsset("zbase/webui/500.html"));
  }
}

void WebUIServlet::handle(
    http::HTTPRequest* request,
    http::HTTPResponse* response) {
  URI uri(request->uri());

  auto session = HTTPAuth::authenticateRequest(*request, auth_);

  static const String kAssetsPathPrefix = "/a/_/a/";
  if (StringUtil::beginsWith(uri.path(), kAssetsPathPrefix)) {
    auto asset_path = uri.path().substr(kAssetsPathPrefix.size());

    // FIXME validate path

    //"css" => "text/css; charset=utf-8",
    //"png" => "image/png",
    //"html" => "text/html; charset=utf-8",
    //"js" => "application/javascript; charset=utf-8"
    response->setStatus(http::kStatusOK);
    //response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(loadFile("assets/" + asset_path)); // FIXME
    return;
  }

  static const String kConfigPath = "/a/_/c";
  if (uri.path() == kConfigPath) {
    Buffer buf;
    json::JSONOutputStream json(BufferOutputStream::fromBuffer(&buf));

    renderConfig(request, session, &json);

    response->setStatus(http::kStatusOK);
    response->addHeader("Content-Type", "application/json; charset=utf-8");
    response->addBody(buf);
    return;
  }

  static const String kDocumentationPathPrefix = "/a/_/d/";
  if (StringUtil::beginsWith(uri.path(), kDocumentationPathPrefix)) {
    auto asset_path = uri.path().substr(kDocumentationPathPrefix.size());

    // FIXME validate path
    response->setStatus(http::kStatusOK);
    //response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(Assets::getAsset("zbase/docs/" + asset_path)); // FIXME
    return;
  }

  static const String kModulesPathPrefix = "/a/_/m/";
  if (StringUtil::beginsWith(uri.path(), kModulesPathPrefix)) {
    auto module_name = uri.path().substr(kModulesPathPrefix.size());

    // FIXME cache module config
    auto module_cfg = msg::parseText<WebUIModuleConfig>(
        loadFile(StringUtil::format("$0/MANIFEST", module_name)));

    if (session.isEmpty() && !module_cfg.is_public()) {
      response->setStatus(http::kStatusForbidden);
      response->addHeader("Content-Type", "text/html; charset=utf-8");
      response->addBody(Assets::getAsset("zbase/webui/403.html"));
      return;
    }

    String module_html;

    for (const auto& file : module_cfg.html_file()) {
      module_html +=
          loadFile(StringUtil::format("$0/$1", module_name, file));
    }

    for (const auto& file : module_cfg.css_file()) {
      module_html += StringUtil::format(
        "<style type='text/css'>$0</style>",
        loadFile(StringUtil::format("$0/$1", module_name, file)));
    }

    for (const auto& file : module_cfg.js_file()) {
      module_html += StringUtil::format(
        "<script type='text/javascript'>$0</script>",
        loadFile(StringUtil::format("$0/$1", module_name, file)));
    }

    module_html += StringUtil::format(
        "<script type='text/javascript'>ZBase.moduleReady('$0');</script>",
        module_name);

    response->setStatus(http::kStatusOK);
    response->addHeader("Content-Type", "text/html; charset=utf-8");
    response->addBody(module_html);
    return;
  }

  Buffer app_config;
  json::JSONOutputStream app_config_json(
      BufferOutputStream::fromBuffer(&app_config));
  renderConfig(request, session, &app_config_json);

  auto app_html = loadFile("app.html");
  StringUtil::replaceAll(&app_html, "{{app_css}}", loadFile("app.css"));
  StringUtil::replaceAll(&app_html, "{{app_js}}", loadFile("app.js"));
  StringUtil::replaceAll(&app_html, "{{config_json}}", app_config.toString());

  response->setStatus(http::kStatusOK);
  response->addHeader("Content-Type", "text/html; charset=utf-8");
  response->addBody(app_html);
}

String WebUIServlet::loadFile(const String& filename) {
  return Assets::getAsset("zbase/webui/" + filename);
}

void WebUIServlet::renderConfig(
    http::HTTPRequest* request,
    const Option<AnalyticsSession>& session,
    json::JSONOutputStream* json) {
  auto app_cfg = msg::parseText<WebUIAppConfig>(loadFile("MANIFEST"));

  json->beginObject();

  // routes
  json->addObjectEntry("routes");
  json->beginArray();

  size_t nroute = 0;
  for (const auto& route : app_cfg.route()) {
    if (!route.is_public() && session.isEmpty()) {
      continue;
    }

    Vector<String> modules(
        route.require_module().begin(),
        route.require_module().end());

    if (++nroute > 1) {
      json->addComma();
    }

    json->beginObject();

    json->addObjectEntry("view");
    json->addString(route.view());

    if (route.has_path_prefix()) {
      json->addComma();
      json->addObjectEntry("path_prefix");
      json->addString(route.path_prefix());
    }

    if (route.has_path_match()) {
      json->addComma();
      json->addObjectEntry("path_match");
      json->addString(route.path_match());
    }

    json->addComma();
    json->addObjectEntry("modules");
    json::toJSON(modules, json);

    json->endObject();
  }

  json->endArray();

  // current user
  if (!session.isEmpty()) {
    json->addComma();
    json->addObjectEntry("current_user");
    json->beginObject();

    json->addObjectEntry("userid");
    json->addString(session.get().userid());
    json->addComma();

    json->addObjectEntry("namespace");
    json->addString(session.get().customer());

    json->endObject();
  }

  // default route
  json->addComma();
  json->addObjectEntry("default_route");
  json->addString(session.isEmpty() ? "/a/login" : "/a/");
  json->addComma();

  json->addObjectEntry("zbase_domain");
  json->addString(getDomain(*request));
  json->addComma();

  json->addObjectEntry("zbase_build_id");
  json->addString(ZBASE_BUILD_ID);

  json->endObject();
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2015 Jake Petroules.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "visualstudioversioninfo.h"
#include <tools/qbsassert.h>
#include <QtCore/qdebug.h>
#include <QtCore/qglobal.h>

namespace qbs {
namespace Internal {

VisualStudioVersionInfo::VisualStudioVersionInfo()
{
}

VisualStudioVersionInfo::VisualStudioVersionInfo(const Version &version)
    : m_version(version)
{
    QBS_CHECK(version.minorVersion() == 0 || version == Version(7, 1));
}

Set<VisualStudioVersionInfo> VisualStudioVersionInfo::knownVersions()
{
    Set<VisualStudioVersionInfo> known;
    known << Version(14) << Version(12) << Version(11)
          << Version(10) << Version(9) << Version(8)
          << Version(7, 1) << Version(7) << Version(6);
    return known;
}

bool VisualStudioVersionInfo::operator<(const VisualStudioVersionInfo &other) const
{
    return m_version < other.m_version;
}

bool VisualStudioVersionInfo::operator==(const VisualStudioVersionInfo &other) const
{
    return m_version == other.m_version;
}

bool VisualStudioVersionInfo::usesMsBuild() const
{
    return m_version.majorVersion() >= 10;
}

bool VisualStudioVersionInfo::usesVcBuild() const
{
    return m_version.majorVersion() <= 9;
}

bool VisualStudioVersionInfo::usesSolutions() const
{
    return m_version.majorVersion() >= 7;
}

Version VisualStudioVersionInfo::version() const
{
    return m_version;
}

int VisualStudioVersionInfo::marketingVersion() const
{
    switch (m_version.majorVersion()) {
    case 6:
        return 6;
    case 7:
        switch (m_version.minorVersion()) {
        case 0:
            return 2002;
        case 1:
            return 2003;
        default:
            Q_UNREACHABLE();
        }
        break;
    case 8:
        return 2005;
    case 9:
        return 2008;
    case 10:
        return 2010;
    case 11:
        return 2012;
    case 12:
        return 2013;
    case 14:
        return 2015;
    case 15:
        return 2017;
    default:
        qWarning() << QStringLiteral("unrecognized Visual Studio version: ")
                   << m_version.toString();
        return 0;
    }
}

QString VisualStudioVersionInfo::solutionVersion() const
{
    // Visual Studio 2012 finally stabilized the solution version
    if (m_version >= Version(11))
        return QStringLiteral("12.00");

    if (m_version >= Version(8))
        return QStringLiteral("%1.00").arg(m_version.majorVersion() + 1);

    if (m_version >= Version(7, 1))
        return QStringLiteral("8.00");

    if (m_version >= Version(7))
        return QStringLiteral("7.00");

    // these versions do not use solution files
    // Visual Studio 6 uses .dsw files which are format version 6.00 but these are different
    Q_ASSERT(!usesSolutions());
    Q_UNREACHABLE();
}

QString VisualStudioVersionInfo::toolsVersion() const
{
    // "https://msdn.microsoft.com/en-us/library/bb383796.aspx"
    // Starting in Visual Studio 2013, the MSBuild Toolset version is the same as the Visual Studio
    // version number"... again
    if (m_version >= Version(12))
        return QStringLiteral("%1.0").arg(m_version.majorVersion());

    if (m_version >= Version(10))
        return QStringLiteral("4.0");

    // pre-MSBuild
    return QStringLiteral("%1,00").arg(m_version.majorVersion());
}

QString VisualStudioVersionInfo::platformToolsetVersion() const
{
    return QStringLiteral("v%1").arg(m_version.majorVersion() * 10);
}

quint32 qHash(const VisualStudioVersionInfo &info)
{
    return qHash(info.version().toString());
}

} // namespace Internal
} // namespace qbs
<commit_msg>Recognize Visual Studio 2017<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2015 Jake Petroules.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "visualstudioversioninfo.h"
#include <tools/qbsassert.h>
#include <QtCore/qdebug.h>
#include <QtCore/qglobal.h>

namespace qbs {
namespace Internal {

VisualStudioVersionInfo::VisualStudioVersionInfo()
{
}

VisualStudioVersionInfo::VisualStudioVersionInfo(const Version &version)
    : m_version(version)
{
    QBS_CHECK(version.minorVersion() == 0 || version == Version(7, 1));
}

Set<VisualStudioVersionInfo> VisualStudioVersionInfo::knownVersions()
{
    Set<VisualStudioVersionInfo> known;
    known << Version(15) << Version(14) << Version(12) << Version(11)
          << Version(10) << Version(9) << Version(8)
          << Version(7, 1) << Version(7) << Version(6);
    return known;
}

bool VisualStudioVersionInfo::operator<(const VisualStudioVersionInfo &other) const
{
    return m_version < other.m_version;
}

bool VisualStudioVersionInfo::operator==(const VisualStudioVersionInfo &other) const
{
    return m_version == other.m_version;
}

bool VisualStudioVersionInfo::usesMsBuild() const
{
    return m_version.majorVersion() >= 10;
}

bool VisualStudioVersionInfo::usesVcBuild() const
{
    return m_version.majorVersion() <= 9;
}

bool VisualStudioVersionInfo::usesSolutions() const
{
    return m_version.majorVersion() >= 7;
}

Version VisualStudioVersionInfo::version() const
{
    return m_version;
}

int VisualStudioVersionInfo::marketingVersion() const
{
    switch (m_version.majorVersion()) {
    case 6:
        return 6;
    case 7:
        switch (m_version.minorVersion()) {
        case 0:
            return 2002;
        case 1:
            return 2003;
        default:
            Q_UNREACHABLE();
        }
        break;
    case 8:
        return 2005;
    case 9:
        return 2008;
    case 10:
        return 2010;
    case 11:
        return 2012;
    case 12:
        return 2013;
    case 14:
        return 2015;
    case 15:
        return 2017;
    default:
        qWarning() << QStringLiteral("unrecognized Visual Studio version: ")
                   << m_version.toString();
        return 0;
    }
}

QString VisualStudioVersionInfo::solutionVersion() const
{
    // Visual Studio 2012 finally stabilized the solution version
    if (m_version >= Version(11))
        return QStringLiteral("12.00");

    if (m_version >= Version(8))
        return QStringLiteral("%1.00").arg(m_version.majorVersion() + 1);

    if (m_version >= Version(7, 1))
        return QStringLiteral("8.00");

    if (m_version >= Version(7))
        return QStringLiteral("7.00");

    // these versions do not use solution files
    // Visual Studio 6 uses .dsw files which are format version 6.00 but these are different
    Q_ASSERT(!usesSolutions());
    Q_UNREACHABLE();
}

QString VisualStudioVersionInfo::toolsVersion() const
{
    // "https://msdn.microsoft.com/en-us/library/bb383796.aspx"
    // Starting in Visual Studio 2013, the MSBuild Toolset version is the same as the Visual Studio
    // version number"... again
    if (m_version >= Version(12))
        return QStringLiteral("%1.0").arg(m_version.majorVersion());

    if (m_version >= Version(10))
        return QStringLiteral("4.0");

    // pre-MSBuild
    return QStringLiteral("%1,00").arg(m_version.majorVersion());
}

QString VisualStudioVersionInfo::platformToolsetVersion() const
{
    return QStringLiteral("v%1").arg(m_version.majorVersion() * 10);
}

quint32 qHash(const VisualStudioVersionInfo &info)
{
    return qHash(info.version().toString());
}

} // namespace Internal
} // namespace qbs
<|endoftext|>


<commit_before>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   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 "exactannovaluesearch.h"

#include <google/btree.h>                // for btree_iterator
#include <google/btree_map.h>            // for btree_map
#include <boost/container/flat_map.hpp>  // for flat_multimap
#include <boost/container/vector.hpp>    // for vec_iterator, operator!=
#include <cstdint>                       // for uint32_t, int64_t
#include "annis/db.h"                    // for DB
#include "annis/stringstorage.h"         // for StringStorage
#include "annis/annostorage.h"           // for AnnoStorage
#include "annis/types.h"                 // for Annotation, AnnotationKey

using namespace annis;
using namespace std;

ExactAnnoValueSearch::ExactAnnoValueSearch(const DB &db, const string &annoNamspace, const string &annoName, const string &annoValue)
  :db(db),validAnnotationInitialized(false), debugDescription(annoNamspace + ":" + annoName + "=\"" + annoValue + "\"")
{
  std::pair<bool, uint32_t> nameID = db.strings.findID(annoName);
  std::pair<bool, uint32_t> namspaceID = db.strings.findID(annoNamspace);
  std::pair<bool, uint32_t> valueID = db.strings.findID(annoValue);

  if(nameID.first && namspaceID.first && valueID.first)
  {
    Annotation key;
    key.name = nameID.second;
    key.ns = namspaceID.second;
    key.val = valueID.second;

    searchRanges.push_back(Range(db.nodeAnnos.inverseAnnotations.equal_range(key)));
    it = searchRanges.begin()->first;
  }
  currentRange = searchRanges.begin();
}

ExactAnnoValueSearch::ExactAnnoValueSearch(const DB &db, const std::string &annoName, const std::string &annoValue)
  :db(db), validAnnotationInitialized(false), debugDescription(annoName + "=\"" + annoValue + "\"")
{
  std::pair<bool, uint32_t> nameID = db.strings.findID(annoName);
  std::pair<bool, uint32_t> valueID = db.strings.findID(annoValue);

  if(nameID.first && valueID.first)
  {
    auto keysLower = db.nodeAnnos.annoKeys.lower_bound({nameID.second, 0});
    auto keysUpper = db.nodeAnnos.annoKeys.upper_bound({nameID.second, uintmax});
    for(auto itKey = keysLower; itKey != keysUpper; itKey++)
    {
      searchRanges.push_back(Range(db.nodeAnnos.inverseAnnotations.equal_range(
      {itKey->first.name, itKey->first.ns, valueID.second})));
    }
  }
  currentRange = searchRanges.begin();

  if(currentRange != searchRanges.end())
  {
    it = currentRange->first;
  }
}

bool ExactAnnoValueSearch::next(Match& result)
{
  while(currentRange != searchRanges.end() && it != currentRange->second)
  {
    result.node = it->second; // node ID
    result.anno = it->first; // annotation itself

    it++;
    if(it == currentRange->second)
    {
      currentRange++;
      if(currentRange != searchRanges.end())
      {
        it = currentRange->first;
      }
    }

    if(getConstAnnoValue())
    {
      /*
       * When we replace the resulting annotation with a constant value it is possible that duplicates
       * can occur. Therfore we must check that each node is only included once as a result
       */
      if(uniqueResultFilter.find(result.node) == uniqueResultFilter.end())
      {
        uniqueResultFilter.insert(result.node);

        result.anno = *getConstAnnoValue();

        return true;
      }
    }
    else
    {
      return true;
    }
  }

  return false;

}

void ExactAnnoValueSearch::reset()
{
  uniqueResultFilter.clear();

  currentRange = searchRanges.begin();
  if(currentRange != searchRanges.end())
  {
    it = currentRange->first;
  }
}

void ExactAnnoValueSearch::initializeValidAnnotations()
{
  for(auto range : searchRanges)
  {
    for(ItType annoIt = range.first; annoIt != range.second; annoIt++)
    {
      validAnnotations.insert(annoIt->first);
    }
  }

  validAnnotationInitialized = true;
}

std::int64_t ExactAnnoValueSearch::guessMaxCount() const
{
  std::int64_t sum = 0;

  for(auto range : searchRanges)
  {
    if(range.first != range.second)
    {
      const Annotation& anno = range.first->first;

      if(anno.ns == db.getNamespaceStringID() && anno.name == db.getNodeNameStringID())
      {
        // we know that node names are typically unique
        sum += 1;
      }
      else
      {
        const std::string val = db.strings.str(anno.val);
        sum += db.nodeAnnos.guessMaxCount(anno.ns, anno.name, val, val);
      }
    }
  }

  return sum;
}

ExactAnnoValueSearch::~ExactAnnoValueSearch()
{

}

<commit_msg>Do not put invalid search ranges into the search range list.<commit_after>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   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 "exactannovaluesearch.h"

#include <google/btree.h>                // for btree_iterator
#include <google/btree_map.h>            // for btree_map
#include <boost/container/flat_map.hpp>  // for flat_multimap
#include <boost/container/vector.hpp>    // for vec_iterator, operator!=
#include <cstdint>                       // for uint32_t, int64_t
#include "annis/db.h"                    // for DB
#include "annis/stringstorage.h"         // for StringStorage
#include "annis/annostorage.h"           // for AnnoStorage
#include "annis/types.h"                 // for Annotation, AnnotationKey

using namespace annis;
using namespace std;

ExactAnnoValueSearch::ExactAnnoValueSearch(const DB &db, const string &annoNamspace, const string &annoName, const string &annoValue)
  :db(db),validAnnotationInitialized(false), debugDescription(annoNamspace + ":" + annoName + "=\"" + annoValue + "\"")
{
  std::pair<bool, uint32_t> nameID = db.strings.findID(annoName);
  std::pair<bool, uint32_t> namspaceID = db.strings.findID(annoNamspace);
  std::pair<bool, uint32_t> valueID = db.strings.findID(annoValue);

  if(nameID.first && namspaceID.first && valueID.first)
  {
    Annotation key;
    key.name = nameID.second;
    key.ns = namspaceID.second;
    key.val = valueID.second;

    searchRanges.push_back(Range(db.nodeAnnos.inverseAnnotations.equal_range(key)));
    it = searchRanges.begin()->first;
  }
  currentRange = searchRanges.begin();
}

ExactAnnoValueSearch::ExactAnnoValueSearch(const DB &db, const std::string &annoName, const std::string &annoValue)
  :db(db), validAnnotationInitialized(false), debugDescription(annoName + "=\"" + annoValue + "\"")
{
  std::pair<bool, uint32_t> nameID = db.strings.findID(annoName);
  std::pair<bool, uint32_t> valueID = db.strings.findID(annoValue);

  if(nameID.first && valueID.first)
  {
    auto keysLower = db.nodeAnnos.annoKeys.lower_bound({nameID.second, 0});
    auto keysUpper = db.nodeAnnos.annoKeys.upper_bound({nameID.second, uintmax});
    for(auto itKey = keysLower; itKey != keysUpper; itKey++)
    {
      Range r = db.nodeAnnos.inverseAnnotations.equal_range(
        {itKey->first.name, itKey->first.ns, valueID.second});

      // only remember ranges that actually have valid iterator pairs
      if(r.first != r.second)
      {
        searchRanges.push_back(std::move(r));
      }
    }
  }
  currentRange = searchRanges.begin();

  if(currentRange != searchRanges.end())
  {
    it = currentRange->first;
  }
}

bool ExactAnnoValueSearch::next(Match& result)
{
  while(currentRange != searchRanges.end() && it != currentRange->second)
  {
    result.node = it->second; // node ID
    result.anno = it->first; // annotation itself

    it++;
    if(it == currentRange->second)
    {
      currentRange++;
      if(currentRange != searchRanges.end())
      {
        it = currentRange->first;
      }
    }

    if(getConstAnnoValue())
    {
      /*
       * When we replace the resulting annotation with a constant value it is possible that duplicates
       * can occur. Therfore we must check that each node is only included once as a result
       */
      if(uniqueResultFilter.find(result.node) == uniqueResultFilter.end())
      {
        uniqueResultFilter.insert(result.node);

        result.anno = *getConstAnnoValue();

        return true;
      }
    }
    else
    {
      return true;
    }
  }

  return false;

}

void ExactAnnoValueSearch::reset()
{
  uniqueResultFilter.clear();

  currentRange = searchRanges.begin();
  if(currentRange != searchRanges.end())
  {
    it = currentRange->first;
  }
}

void ExactAnnoValueSearch::initializeValidAnnotations()
{
  for(auto range : searchRanges)
  {
    for(ItType annoIt = range.first; annoIt != range.second; annoIt++)
    {
      validAnnotations.insert(annoIt->first);
    }
  }

  validAnnotationInitialized = true;
}

std::int64_t ExactAnnoValueSearch::guessMaxCount() const
{
  std::int64_t sum = 0;

  for(auto range : searchRanges)
  {
    if(range.first != range.second)
    {
      const Annotation& anno = range.first->first;

      if(anno.ns == db.getNamespaceStringID() && anno.name == db.getNodeNameStringID())
      {
        // we know that node names are typically unique
        sum += 1;
      }
      else
      {
        const std::string val = db.strings.str(anno.val);
        sum += db.nodeAnnos.guessMaxCount(anno.ns, anno.name, val, val);
      }
    }
  }

  return sum;
}

ExactAnnoValueSearch::~ExactAnnoValueSearch()
{

}

<|endoftext|>