int CTortoiseGitBlameData::GetEncode(int *bomoffset)
{
	int encoding = 0;
	BYTE_VECTOR rawAll;
	for (const auto& rawBytes : m_RawLines)
		rawAll.append(rawBytes.data(), rawBytes.size());
	encoding = GetEncode(rawAll.data(), static_cast<int>(rawAll.size()), bomoffset);
	return encoding;
}
int CTortoiseGitBlameData::GetEncode(int *bomoffset)
{
	int encoding = 0;
	BYTE_VECTOR rawAll;
	for (auto it = m_RawLines.begin(), it_end = m_RawLines.end(); it != it_end; ++it)
	{
		rawAll.append(&(*it)[0], it->size());
	}
	encoding = GetEncode(&rawAll[0], (int)rawAll.size(), bomoffset);
	return encoding;
}
int CTortoiseGitBlameData::GetEncode(int *bomoffset)
{
	int encoding = 0;
	BYTE_VECTOR rawAll;
	for (const auto& rawBytes : m_RawLines)
	{
		rawAll.append(&rawBytes[0], rawBytes.size());
	}
	encoding = GetEncode(&rawAll[0], (int)rawAll.size(), bomoffset);
	return encoding;
}
int CTortoiseGitBlameData::UpdateEncoding(int encode)
{
	int encoding = encode;
	int bomoffset = 0;
	if (encoding==0)
	{
		BYTE_VECTOR all;
		for (auto it = m_RawLines.begin(); it != m_RawLines.end(); ++it)
		{
			if (!it->empty())
				all.append(&(*it)[0], it->size());
		}
		encoding = GetEncode(&all[0], (int)all.size(), &bomoffset);
	}

	if (encoding != m_encode)
	{
		m_encode = encoding;

		m_Utf8Lines.resize(m_RawLines.size());
		for (size_t i_Lines = 0; i_Lines < m_RawLines.size(); ++i_Lines)
		{
			const BYTE_VECTOR& rawLine = m_RawLines[i_Lines];

			int bomoffset = 0;
			CStringA lineUtf8;
			lineUtf8.Empty();

			if (!rawLine.empty())
			{
				if (encoding == 1201)
				{
					CString line;
					int size = (int)((rawLine.size() - bomoffset)/2);
					TCHAR *buffer = line.GetBuffer(size);
					memcpy(buffer, &rawLine[bomoffset], sizeof(TCHAR)*size);
					// swap the bytes to little-endian order to get proper strings in wchar_t format
					wchar_t * pSwapBuf = buffer;
					for (int i = 0; i < size; ++i)
					{
						*pSwapBuf = WideCharSwap2(*pSwapBuf);
						++pSwapBuf;
					}
					line.ReleaseBuffer();

					lineUtf8 = CUnicodeUtils::GetUTF8(line);
				}
				else if (encoding == 1200)
				{
					CString line;
					// the first bomoffset is 2, after that it's 1 (see issue #920)
					// also: don't set bomoffset if called from Encodings menu (i.e. start == 42 and bomoffset == 0); bomoffset gets only set if autodetected
					if (bomoffset == 0 && i_Lines != 0)
					{
						bomoffset = 1;
					}
					int size = (int)((rawLine.size() - bomoffset)/2);
					TCHAR *buffer = line.GetBuffer(size);
					memcpy(buffer, &rawLine[bomoffset], sizeof(TCHAR) * size);
					line.ReleaseBuffer();

					lineUtf8 = CUnicodeUtils::GetUTF8(line);
				}
				else if (encoding == CP_UTF8)
					lineUtf8 = CStringA((LPCSTR)&rawLine[bomoffset], (int)(rawLine.size() - bomoffset));
				else
				{
					CString line = CUnicodeUtils::GetUnicode(CStringA((LPCSTR)&rawLine[bomoffset], (int)(rawLine.size() - bomoffset)), encoding);
					lineUtf8 = CUnicodeUtils::GetUTF8(line);
				}
			}

			m_Utf8Lines[i_Lines] = lineUtf8;
			bomoffset = 0;
		}
	}
	return encoding;
}