utils.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 2,314 行 · 第 1/5 页

CPP
2,314
字号
 * Parse the given date, in different formats, see header for details.
 */
DATE getDATEFromString(const wchar_t *date, const wchar_t *hour) {
    DATE ret = 0;
    if (isDateForAllDayEventFormat(date)) {
        const wchar_t *type = TEXT("START");
        if(hour && wcscmp(hour, TEXT("2359")) == 0) {
            type = TEXT("END");
        }
        systemTimeToDoubleBirthFormat(date, &ret, type);
    } else {
        systemTimeToDouble(date, &ret, hour);
    }
    return ret;
}


/*
* The method returns the file name from the complete path.
*
* @param path     : the complete path
* @param filename : the filename retrieved form path
*/

void getFileName(const wchar_t* path, wchar_t* filename) {
    wchar_t* p;

    p = wcsrchr(path, L'\\');

    if (p == NULL) {
        wcscpy(filename, path);
        return;
    }

    wcscpy(filename, p+1);
}

/*
* The method converts the path separator "\" with "@".
* Used for favorites items to permit to sync files and directory with a filesystem sync source.
* "\" char is not permitted in file name on windows machine
* This conversion happens on send items to server
*
* @param filename : the file name retrieved to be modified
*/

void convertAtSlash(wchar_t* filename) {

    int position = 0;
    std::wstring s;
    s.append(filename);

    position = s.find(_T("@"));
    while (position != std::string::npos) {
        s.replace(position,1,_T(""));
        s.insert(position, _T("\\"));
        position = s.find(_T("@"));
    }

    wsprintf(filename, s.data());
}

/*
* The method converts the separator "@" with "\".
* Used for favorites items to permit to sync files and directory with a filesystem sync source.
* "\" char is not permitted in file name on windows machine
* This conversion happens on returned items from server
*
* @param filename : the file name retrieved to be modified
*/

void convertSlashAt(wchar_t* filename) {

    int position = 0;
    std::wstring s;
    s.append((wchar_t*)filename);

    // search for \;
    position = s.find(_T("\\"));
    while (position != std::string::npos) {
        s.replace(position,1,_T(""));
        s.insert(position, _T("@"));
        position = s.find(_T("\\"));
    }
    wsprintf(filename, s.data());
}

/*
* The method get the complete path name starting from path + filename.
*
* @param path     : the path and filename
* @param dirname  : the returned path name without the dir
*/
void getDirName(const wchar_t* path, wchar_t* dirname) {

    std::wstring s;
    int position = 0;

    s.append((wchar_t*) path);
    position = s.rfind(_T('\\'));

    if (position == std::wstring::npos) {
        wsprintf(dirname, path);
        return;
    }

    wstring ret = s.substr(0, position);
    if (ret == TEXT("")) {
        ret = TEXT("\\");
    }
    wsprintf(dirname, ret.c_str());   
    
    // s.replace(position, s.length() - position, _T(""));
    // getFileName(s.data(), dirname);
}

/*
* return the length for the base64 array starting from length of the original array
*/
int lengthForB64(int len) {

    int modules = 0;
    int ret     = 0;

    modules = len % 3;
    if (modules == 0) {
        ret = 4 * (len / 3);

    } else {
        ret = 4 * ((len/3) + 1);

    }
    return ret;


}

/*
* encode in base 64 starting from char* that was trasnformed into utf8
*/
wchar_t* encodeBase64UTF8(wchar_t* toEncode) {

    if (toEncode == NULL)
        return NULL;

    char*    b64 = NULL;
    TransformationInfo info;
    char* tmp = toMultibyte(toEncode);

    DataTransformer* dtb64 = DataTransformerFactory::getEncoder("b64");

    if (dtb64 == NULL) {
        return NULL;
    }
    info.size = strlen(tmp);

    b64 = dtb64->transform((char*)tmp, info);

    wchar_t* ret = toWideChar(b64);

    /*
    char* tmp = toMultibyte(toEncode);
    int len = (wcslen(toEncode)/3+1)<<2;
    char* b64tmp = new char[len];
        memset(b64tmp, 0, len);
    int retLen = b64_encode(b64tmp, tmp, len);

    wchar_t* ret = toWideChar(b64tmp);
    */
    if (tmp)
        delete [] tmp;

    if (b64)
        delete [] b64;

    if (dtb64)
        delete dtb64;

    return ret;
}

/*
* decoding from b64 and trasforming decoding from UTF8.
* used for contact, calendar, task
*/
wchar_t* decodeBase64WUTF8(wchar_t* toDecode) {

    wchar_t* ret = NULL;
    char*    tmp = NULL;
    int      len = 0;
    char* decodedData = NULL;

    if (toDecode == NULL)
        return NULL;

    tmp = toMultibyte(toDecode);
    TransformationInfo info;
    DataTransformer* dt = DataTransformerFactory::getDecoder("b64");

    if (dt == NULL) {
        return NULL;
    }

    decodedData = dt->transform(tmp, info);

    if (decodedData) {
        tmp[info.size] = 0;
    }

    ret = toWideChar(tmp);

    if (tmp) {
        delete [] tmp;
    }

    return ret;

}


char* decodeBase64WUTF8(wchar_t* toDecode, int* myLen) {

    wchar_t* ret = NULL;
    char*    tmp = NULL;
    int      len = 0;

    if (toDecode == NULL)
        return NULL;

    tmp = toMultibyte(toDecode);

    len = b64_decode(tmp, tmp);
    *myLen = len;
    tmp[len] = 0;
    return tmp;
}


/*
* This function gets a unique file name in the current directory based on the parameter filename.
* It checks in the specified dir if fileName exists. If none it return the same file name.
* If one already exists it return a file name like - file (1) - according to the
* rules applied by windows for PPC
*
* @param fileName : the file name that can be modified if the same file already exists
*/

void getUniqueFileName(wchar_t* fileName) {

    LOG.debug("uniqueFileBegin");
    BOOL exists = FALSE;
    FILE* f = NULL;
    int i = 1;

    f = _wfopen(fileName, TEXT("r"));

    if (f == NULL) {
        return;
    }

    fflush(f);
    fclose(f);

    wchar_t path [DIM_LOCAL_TEMP];
    wchar_t file [DIM_LOCAL_TEMP];
    wsprintf(path, fileName);

    getFileName(fileName, file); // file contains file name

    getDirName(fileName, path); // path

    wchar_t* p = NULL;

    std::wstring s;
    int position = 0;
    s.append((wchar_t*)file);
    position = s.find(PWI_EXTENSION);
    if (position != std::wstring::npos) {
        file[position] = 0;
    }

    do {
        wchar_t localFile[DIM_LOCAL_TEMP];
        wstring complete = appendToPath((wchar_t*)path, file);
        wsprintf(localFile, TEXT("%s (%i)%s"), complete.c_str(), i, PWI_EXTENSION);
        //wsprintf(localFile, TEXT("%s%s%s (%i)%s") , path, TEXT("\\"), file, i, PWI_EXTENSION);

        f = _wfopen(localFile, TEXT("r"));

        if (f == NULL) {
            wsprintf(fileName, localFile);
            break;
        }
        fflush(f);
        fclose(f);

        i++;
    } while(1);
    LOG.debug("uniqueFileEnd");
}



//void UTCToLocalTime(SYSTEMTIME &sysTime)
//{
//     FILETIME LocalFileTime, SystemFileTime;
//     SystemTimeToFileTime(&sysTime, &SystemFileTime);
//     FileTimeToLocalFileTime(&SystemFileTime, &LocalFileTime);
//     FileTimeToSystemTime(&LocalFileTime, &sysTime);
//}

void localTimeToUTC(SYSTEMTIME &sysTime)
{
     FILETIME LocalFileTime, SystemFileTime;
     SystemTimeToFileTime(&sysTime, &LocalFileTime);
     LocalFileTimeToFileTime(&LocalFileTime, &SystemFileTime);
     FileTimeToSystemTime(&SystemFileTime, &sysTime);

     /*LPTIME_ZONE_INFORMATION lpTimeZoneInformation;
     GetTimeZoneInformation(lpTimeZoneInformation);*/

}

void SafeGetTimeZoneInformation(TIME_ZONE_INFORMATION *ptzi) {

   ZeroMemory(ptzi, sizeof(TIME_ZONE_INFORMATION));

   // Ask the OS for the standard/daylight rules for the current time zone.
   if ((GetTimeZoneInformation(ptzi) == 0xFFFFFFFF) ||
       (ptzi->StandardDate.wMonth > 12) || (ptzi->DaylightDate.wMonth > 12))
   {
      // If the OS fails us, we default to the United States' rules.
      ZeroMemory(ptzi, sizeof(TIME_ZONE_INFORMATION));
      ptzi->StandardDate.wMonth =  10;  // October
      ptzi->StandardDate.wDay   =   5;  // Last Sunday (DOW == 0)
      ptzi->StandardDate.wHour  =   2;  // At 2:00 AM
      ptzi->DaylightBias        = -60;  // One hour difference
      ptzi->DaylightDate.wMonth =   4;  // April
      ptzi->DaylightDate.wDay   =   1;  // First Sunday (DOW == 0)
      ptzi->DaylightDate.wHour  =   2;  // At 2:00 AM
   }
}


time_t GetTransitionTimeT(TIME_ZONE_INFORMATION *ptzi, int year, BOOL fStartDST) {

   // We only handle years within the range that time_t supports.  We need to
   // handle the very end of 1969 since the local time could be up to 13 hours
   // into the previous year.  In this case, our code will actually return a
   // negative value, but it will be compared to another negative value and is
   // handled correctly.  The same goes for the 13 hours past a the max time_t
   // value of 0x7FFFFFFF (in the year 2038).  Again, these values are handled
   // correctly as well.

   if ((year < 1969) || (year > 2038)) {
      return (time_t)0;
   }

   SYSTEMTIME *pst = fStartDST ? &ptzi->DaylightDate : &ptzi->StandardDate;

   // WORD wYear          Year (0000 == 0)
   // WORD wMonth         Month (January == 1)
   // WORD wDayOfWeek     Day of week (Sunday == 0)
   // WORD wDay           Month day (1 - 31)
   // WORD wHour          Hour (0 - 23)
   // WORD wMinute        Minute (0 - 59)
   // WORD wSecond        Second (0 - 59)
   // WORD wMilliseconds  Milliseconds (0 - 999)

   // Compute the number of days since 1/1/1970 to the beginning of this year.
   long daysToYear = ((year - 1970) * 365) // Tally up previous years.
                   + ((year - 1969) >> 2); // Add few extra for the leap years.

   // Compute the number of days since the beginning of this year to the
   // beginning of the month.  We will add to this value to get the actual
   // year day.
   long yearDay = IS_LEAP_YEAR(year) ? M2LYD[pst->wMonth - 1] :
                                       M2YD [pst->wMonth - 1];

   // Check for day-in-month format.
   if (pst->wYear == 0) {

      // Compute the week day for the first day of the month (Sunday == 0).
      long monthDOW = (daysToYear + yearDay + BASE_DOW) % 7;

      // Add the day offset of the transition day to the year day.
      if (monthDOW < pst->wDayOfWeek) {
         yearDay += (pst->wDayOfWeek - monthDOW) + (pst->wDay - 1) * 7;
      } else {
         yearDay += (pst->wDayOfWeek - monthDOW) + pst->wDay * 7;
      }

      // It is possible that we overshot the month, especially if pst->wDay
      // is 5 (which means the last instance of the day in the month). Check
      // if the year-day has exceeded the month and adjust accordingly.
      if ((pst->wDay == 5) &&
          (yearDay >= (IS_LEAP_YEAR(year) ? M2LYD[pst->wMonth] :
                                            M2YD [pst->wMonth])))
      {
         yearDay -= 7;
      }

   // If not day-in-month format, then we assume an absolute date.
   } else {

      // Simply add the month day to the current year day.
      yearDay += pst->wDay - 1;
   }

   // Tally up all our days, hours, minutes, and seconds since 1970.
   long seconds = ((SECONDS_IN_A_DAY * (daysToYear + yearDay)) +
                   (3600L * (long)pst->wHour) +
                   (60L * (long)pst->wMinute) +
                   (long)pst->wSecond);

   // If we are checking for the end of DST, then we need to add the DST bias
   // since we are in DST when we chack this time stamp.
   if (!fStartDST) {
      seconds += ptzi->DaylightBias * 60L;
   }

   return (time_t)seconds;
}


BOOL IsDST(TIME_ZONE_INFORMATION *ptzi, time_t localTime) {

   // If either of the months is 0, then this usually means that the time zone
   // does not use DST.
   if ((ptzi->StandardDate.wMonth == 0) || (ptzi->DaylightDate.wMonth == 0)) {
      return FALSE;
   }

   // time_t   is a 32-bit value for the seconds since January 1, 1970
   // FILETIME is a 64-bit value for the number of 100-nanosecond intervals
   //          since January 1, 1601

   // Compute the FILETIME for the given local time.
   DWORDLONG dwl = ((DWORDLONG)116444736000000000 +
                   ((DWORDLONG)localTime * (DWORDLONG)10000000));
   FILETIME ft = *(FILETIME*)&dwl;

   // Convert the FILETIME to a SYSTEMTIME.
   SYSTEMTIME st;
   ZeroMemory(&st, sizeof(st));
   FileTimeToSystemTime(&ft, &st);

   // Get our start and end daylight savings times.
   time_t timeStart = GetTransitionTimeT(ptzi, (int)st.wYear, TRUE);
   time_t timeEnd   = GetTransitionTimeT(ptzi, (int)st.wYear, FALSE);

   // Check what hemisphere we are in.
   if (timeStart < timeEnd) {

      // Northern hemisphere ordering.
      return ((localTime >= timeStart) && (localTime < timeEnd));

   } else if (timeStart > timeEnd) {

      // Southern hemisphere ordering.
      return ((localTime < timeEnd) || (localTime >= timeStart));
   }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?