Source

nsis64 / Source / utf.cpp

Full commit
gol...@212acab6-… 205abbe 



















































































/*
 * utf.cpp
 * 
 * This file is a part of NSIS.
 * 
 * Copyright (C) 2011 Anders Kjersem
 * 
 * Licensed under the zlib/libpng license (the "License");
 * you may not use this file except in compliance with the License.
 * 
 * Licence details can be found in the file COPYING.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty.
 *
 */

#include "utf.h"

// BUGBUG: We might want to use MB_ERR_INVALID_CHARS but it is not supported
// on < WinXP or in our current POSIX implementation.
static const int UTF8MBTWCFLAGS  = 0;


#define ExeHeadWStrFree free
static EXEHEADWCHAR_T* ExeHeadWStrAlloc(UINT cch) 
{
  EXEHEADWCHAR_T* s = (EXEHEADWCHAR_T*) malloc(cch*sizeof(EXEHEADWCHAR_T));
#if 0
  // TODO: We should add POSIX versions of  G/SetLastError
  // if we want to tell _why_ UTF8ToExeHeadTStr failed...
  if (!s) SetLastError(ERROR_OUTOFMEMORY);
#endif
  return s;
}

#ifdef _UNICODE
#else // !_UNICODE

EXEHEADTCHAR_T* UTF8ToExeHeadTStrDup(LPCSTR StrU8,UINT Codepage) 
{
  int cchW = MultiByteToWideChar(CP_UTF8,UTF8MBTWCFLAGS,StrU8,-1,NULL,0);
  if (!cchW) return NULL;
  WCHAR *bufWStr = (WCHAR*) ExeHeadWStrAlloc(cchW);
  if (!bufWStr) return NULL;
  EXEHEADTCHAR_T *outstr = NULL;
  if (MultiByteToWideChar(CP_UTF8,UTF8MBTWCFLAGS,StrU8,-1,bufWStr,cchW))
  {
    int cbA = WideCharToMultiByte(Codepage,0,bufWStr,cchW,NULL,0,NULL,NULL);
    if (cbA && (outstr = ExeHeadTStrAlloc(cbA)))
    {
      if (!WideCharToMultiByte(Codepage,0,bufWStr,cchW,outstr,cbA,NULL,NULL))
      {
        free(outstr);
        outstr = NULL;
      }
    }
  }
  ExeHeadWStrFree(bufWStr);
  return outstr;
}

#endif // ?_UNICODE


bool IsUTF8BOM(FILE*fstrm) 
{
  // ungetc is only guaranteed to support 1 pushback, 
  // lets hope no ASCII file starts with 0xEF and is not a BOM!
  const int c = fgetc(fstrm);
  if (EOF == c) return false;
  if (0xef == c)
  {
    const int c2 = fgetc(fstrm);
    if (0xbb == c2)
    {
      const int c3 = fgetc(fstrm);
      if (0xbf == c3) return true;
      ungetc(c3,fstrm);
    }
    ungetc(c2,fstrm);
  }
  ungetc(c,fstrm);
  return false;
}