125 строки
3.6 KiB
C++
125 строки
3.6 KiB
C++
//===-- WinAdapter.cpp - Windows Adapter for other platforms ----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "assert.h"
|
|
#include "dxc/Support/WinFunctions.h"
|
|
#include "dxc/Support/WinIncludes.h"
|
|
#ifndef _WIN32
|
|
|
|
#include "dxc/Support/Unicode.h"
|
|
|
|
//===--------------------------- CAllocator -------------------------------===//
|
|
|
|
void *CAllocator::Reallocate(void *p, size_t nBytes) throw() {
|
|
return realloc(p, nBytes);
|
|
}
|
|
void *CAllocator::Allocate(size_t nBytes) throw() { return malloc(nBytes); }
|
|
void CAllocator::Free(void *p) throw() { free(p); }
|
|
|
|
//===--------------------------- BSTR Allocation --------------------------===//
|
|
|
|
void SysFreeString(BSTR bstrString) {
|
|
if (bstrString)
|
|
free((void *)((uintptr_t)bstrString - sizeof(uint32_t)));
|
|
}
|
|
|
|
// Allocate string with length prefix
|
|
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/bstr
|
|
BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui) {
|
|
uint32_t *blobOut =
|
|
(uint32_t *)malloc(sizeof(uint32_t) + (ui + 1) * sizeof(OLECHAR));
|
|
|
|
if (!blobOut)
|
|
return nullptr;
|
|
|
|
// Size in bytes without trailing NULL character
|
|
blobOut[0] = ui * sizeof(OLECHAR);
|
|
|
|
BSTR strOut = (BSTR)&blobOut[1];
|
|
|
|
if (strIn)
|
|
memcpy(strOut, strIn, blobOut[0]);
|
|
|
|
// Write trailing NULL character:
|
|
strOut[ui] = 0;
|
|
|
|
return strOut;
|
|
}
|
|
//===--------------------------- BSTR Length ------------------------------===//
|
|
unsigned int SysStringLen(const BSTR bstrString) {
|
|
if (!bstrString)
|
|
return 0;
|
|
|
|
uint32_t *blobIn = (uint32_t *)((uintptr_t)bstrString - sizeof(uint32_t));
|
|
|
|
return blobIn[0] / sizeof(OLECHAR);
|
|
}
|
|
//===---------------------- Char converstion ------------------------------===//
|
|
|
|
const char *CPToLocale(uint32_t CodePage) {
|
|
#ifdef __APPLE__
|
|
static const char *utf8 = "en_US.UTF-8";
|
|
static const char *iso88591 = "en_US.ISO8859-1";
|
|
#else
|
|
static const char *utf8 = "en_US.utf8";
|
|
static const char *iso88591 = "en_US.iso88591";
|
|
#endif
|
|
if (CodePage == CP_UTF8) {
|
|
return utf8;
|
|
} else if (CodePage == CP_ACP) {
|
|
// Experimentation suggests that ACP is expected to be ISO-8859-1
|
|
return iso88591;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//===--------------------------- CHandle -------------------------------===//
|
|
|
|
CHandle::CHandle(HANDLE h) { m_h = h; }
|
|
CHandle::~CHandle() { CloseHandle(m_h); }
|
|
CHandle::operator HANDLE() const throw() { return m_h; }
|
|
|
|
// CComBSTR
|
|
CComBSTR::CComBSTR(int nSize, LPCWSTR sz) {
|
|
if (nSize < 0) {
|
|
throw std::invalid_argument("CComBSTR must have size >= 0");
|
|
}
|
|
|
|
if (nSize == 0) {
|
|
m_str = NULL;
|
|
} else {
|
|
m_str = SysAllocStringLen(sz, nSize);
|
|
if (!*this) {
|
|
std::runtime_error("out of memory");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CComBSTR::operator==(const CComBSTR &bstrSrc) const throw() {
|
|
return wcscmp(m_str, bstrSrc.m_str) == 0;
|
|
}
|
|
|
|
//===--------------------------- WArgV -------------------------------===//
|
|
WArgV::WArgV(int argc, const char **argv)
|
|
: WStringVector(argc), WCharPtrVector(argc) {
|
|
for (int i = 0; i < argc; ++i) {
|
|
std::string S(argv[i]);
|
|
const int wideLength = ::MultiByteToWideChar(
|
|
CP_UTF8, MB_ERR_INVALID_CHARS, S.data(), S.size(), nullptr, 0);
|
|
assert(wideLength > 0 &&
|
|
"else it should have failed during size calculation");
|
|
WStringVector[i].resize(wideLength);
|
|
::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, S.data(), S.size(),
|
|
&(WStringVector[i])[0], WStringVector[i].size());
|
|
WCharPtrVector[i] = WStringVector[i].data();
|
|
}
|
|
}
|
|
|
|
#endif
|