strCoding.cpp 4.44 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
xiongziliang committed
3 4 5
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
xiongziliang committed
6 7 8
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
xzl committed
9 10 11
 */

#include <string.h>
xiongzilaing committed
12
#include "strCoding.h"
xzl committed
13

14 15 16 17
#if defined(_WIN32)
#include <windows.h> 
#endif//defined(_WIN32)

xiongziliang committed
18
namespace mediakit {
xzl committed
19

20
//////////////////////////通用///////////////////////
xiongziliang committed
21
void UTF8ToUnicode(wchar_t* pOut, const char *pText)
22
{
23 24 25 26
    char* uchar = (char *)pOut;
    uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
    uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
    return;
27
}
xiongziliang committed
28
void UnicodeToUTF8(char* pOut, const wchar_t* pText)
29
{
30 31 32 33 34 35
    // 注意 WCHAR高低字的顺序,低字节在前,高字节在后 
    const char* pchar = (const char *)pText;
    pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
    pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
    pOut[2] = (0x80 | (pchar[0] & 0x3F));
    return;
36 37 38 39
}

char CharToInt(char ch) 
{
40 41 42 43
    if (ch >= '0' && ch <= '9')return (char)(ch - '0');
    if (ch >= 'a' && ch <= 'f')return (char)(ch - 'a' + 10);
    if (ch >= 'A' && ch <= 'F')return (char)(ch - 'A' + 10);
    return -1;
xzl committed
44
}
45 46
char StrToBin(const char *str) 
{
47 48 49 50 51 52
    char tempWord[2];
    char chn;
    tempWord[0] = CharToInt(str[0]); //make the B to 11 -- 00001011 
    tempWord[1] = CharToInt(str[1]); //make the 0 to 0 -- 00000000 
    chn = (tempWord[0] << 4) | tempWord[1]; //to change the BO to 10110000 
    return chn;
xzl committed
53
}
54

xiongziliang committed
55
string strCoding::UrlEncode(const string &str) {
56
    string out;
xiongziliang committed
57
    size_t len = str.size();
58
    for (size_t i = 0; i < len; ++i) {
xiongziliang committed
59
        char ch = str[i];
60
        if (isalnum((uint8_t)ch)) {
xiongziliang committed
61
            out.push_back(ch);
62 63 64
        }else {
            char buf[4];
            sprintf(buf, "%%%X%X", (uint8_t)ch >> 4,(uint8_t)ch & 0x0F);
xiongziliang committed
65
            out.append(buf);
66 67 68
        }
    }
    return out;
xzl committed
69
}
xiongziliang committed
70
string strCoding::UrlDecode(const string &str) {
71 72 73 74 75 76 77
    string output = "";
    char tmp[2];
    int i = 0, len = str.length();
    while (i < len) {
        if (str[i] == '%') {
            if(i > len - 3){
                //防止内存溢出
xiongziliang committed
78
                break;
79 80 81 82 83 84 85 86 87 88 89 90 91 92
            }
            tmp[0] = str[i + 1];
            tmp[1] = str[i + 2];
            output += StrToBin(tmp);
            i = i + 3;
        } else if (str[i] == '+') {
            output += ' ';
            i++;
        } else {
            output += str[i];
            i++;
        }
    }
    return output;
xzl committed
93 94
}

95 96 97 98 99

///////////////////////////////windows专用///////////////////////////////////
#if defined(_WIN32)
void UnicodeToGB2312(char* pOut, wchar_t uData)
{
100
    WideCharToMultiByte(CP_ACP, NULL, &uData, 1, pOut, sizeof(wchar_t), NULL, NULL);
101 102 103
}
void Gb2312ToUnicode(wchar_t* pOut, const char *gbBuffer)
{
104
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, gbBuffer, 2, pOut, 1);
105 106 107
}

string strCoding::UTF8ToGB2312(const string &str) {
108 109 110 111 112
    auto len = str.size();
    auto pText = str.data();
    char Ctemp[4] = {0};
    char *pOut = new char[len + 1];
    memset(pOut, 0, len + 1);
113

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    int i = 0, j = 0;
    while (i < len)
    {
        if (pText[i] >= 0)
        {
            pOut[j++] = pText[i++];
        }
        else
        {
            wchar_t Wtemp;
            UTF8ToUnicode(&Wtemp, pText + i);
            UnicodeToGB2312(Ctemp, Wtemp);
            pOut[j] = Ctemp[0];
            pOut[j + 1] = Ctemp[1];
            i += 3;
            j += 2;
        }
    }
    string ret = pOut;
    delete[] pOut;
    return ret;
135 136 137
}

string strCoding::GB2312ToUTF8(const string &str) {
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    auto len = str.size();
    auto pText = str.data();
    char buf[4] = { 0 };
    int nLength = len * 3;
    char* pOut = new char[nLength];
    memset(pOut, 0, nLength);
    int i = 0, j = 0;
    while (i < len)
    {
        //如果是英文直接复制就可以   
        if (*(pText + i) >= 0)
        {
            pOut[j++] = pText[i++];
        }
        else
        {
            wchar_t pbuffer;
            Gb2312ToUnicode(&pbuffer, pText + i);
            UnicodeToUTF8(buf, &pbuffer);
            pOut[j] = buf[0];
            pOut[j + 1] = buf[1];
            pOut[j + 2] = buf[2];
            j += 3;
            i += 2;
        }
    }   
    string ret = pOut;
    delete[] pOut;
    return ret;
167 168 169 170 171 172
}
#endif//defined(_WIN32)




xiongziliang committed
173
} /* namespace mediakit */