首页
社区
课程
招聘
[旧帖] [求助][求助]请大家指点下,这段c++代码优化的思路 0.00雪花
发表于: 2013-7-29 12:38 1307

[旧帖] [求助][求助]请大家指点下,这段c++代码优化的思路 0.00雪花

2013-7-29 12:38
1307
这段代码是生成json的代码,我想请高手给个优化的思路
#ifndef _BMLIB_BMJSON_H
#define _BMLIB_BMJSON_H

#include "BMStrUtils.h"
namespace BMLib
{	
	class BMJson
	{
		public:
			static string& AddJsonField(string& str,const char* pszKey,const char* pszValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";
				str += "\"";
				str += pszValue;
				str += "\"";

				return str;
			}
			
			static string& AddJsonObjectField(string& str,const char* pszKey,const char* pszValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";				
				str += pszValue;
				
				return str;
			}

			static string& AddJsonField(string& str,const char* pszKey,int nValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%d",nValue);
				str += strValue;	
				
				return str;
			}
			static string & AddJsonField(string &str,const char * pszKey,char cValue,int iType = 0)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				if(iType == 0)
				{
					BMStrUtils::Format(strValue,"%d",cValue);
				}
				else{
					BMStrUtils::Format(strValue,"%c",cValue);
				}
				str += strValue;	

				return str;
			}
			static string & AddJsonField(string &str,const char * pszKey,unsigned char cValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%d",cValue);
				str += strValue;	

				return str;
			}

			static string & AddJsonField(string &str,const char * pszKey,short sValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%d",sValue);
				str += strValue;	

				return str;
			}
			static string & AddJsonField(string &str,const char * pszKey,unsigned int iValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%u",iValue);
				str += strValue;	

				return str;
			}
			static string& AddJsonField(string& str,const char* pszKey,float fValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%f",fValue);
				str += strValue;	
				
				return str;
			}
			//2012-6-22
			static string& AddJsonField(string& str,const char* pszKey,long long llValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%ld",llValue);
				str += strValue;	

				return str;
			}
			static string& AddJsonField(string& str,const char* pszKey,long lValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%ld",lValue);
				str += strValue;	

				return str;
			}

			static string& AddJsonField(string& str,const char* pszKey,bool bValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += ",\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				if(bValue)
					str += "true";	
				else
					str += "false";

				return str;
			}

			static string& AddJsonFirstField(string& str,const char* pszKey,const char* pszValue)
			{
				if(str == "")
					str += "\"";	
				else
					str += "\"";
				str += pszKey ;
				str += "\"";
				str += ":";
				str += "\"";
				str += pszValue;
				str += "\"";

				return str;
			}
			
			static string& AddJsonFirstObjectField(string& str,const char* pszKey,const char* pszValue)
			{
				str += "\"";
				str += pszKey ;
				str += "\"";
				str += ":";				
				str += pszValue;
				
				return str;
			}

			static string& AddJsonFirstField(string& str,const char* pszKey,int nValue)
			{
				str += "\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%d",nValue);
				str += strValue;
				
				return str;
			}

			static string& AddJsonFirstField(string& str,const char* pszKey,float fValue)
			{
				str += "\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				string strValue;
				BMStrUtils::Format(strValue,"%f",fValue);
				str += strValue;
				
				return str;
			}
			

			static string& AddJsonFirstField(string& str,const char* pszKey,bool bValue)
			{
				str += "\"";
				str += pszKey ;
				str += "\"";
				str += ":";		
				if(bValue)
					str += "true";	
				else
					str += "false";

				return str;
			}
			

			static string& AddJsonObject(string& str,const char* pszJson)
			{
				if(str == "")
					str += "{";
				else
					str += ",{";
				str += pszJson;
				str += "}";

				return str;
			}

			static string& AddJsonArray(string& str,const char* pszJson)
			{
				str += "[";
				str += pszJson;
				str += "]";

				return str;
			}

	};
}
#endif

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 9
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

#ifndef __BMLIB_STRUTILS_H__
#define __BMLIB_STRUTILS_H__

#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <stdarg.h>

using namespace std;
namespace BMLib
{

	class BMStrUtils
	{
		public:	
		/**
		* 格式化字符串\n
		* 根据参数pszFormat字符串来转换并格式化数据,然后将结果复制到参数str所指的字符串中,直到出现字符串结束'\0'为止
		* @return 返回格式化后字符串的长度
		*/
			static int Format(std::string& str, const char* pszFormat, ...)
			{
				va_list argList;
				va_start(argList, pszFormat);
				int iMaxLen = vsnprintf(NULL, 0, pszFormat, argList);
				va_end(argList);

				if (iMaxLen <= 0)
				{
					return iMaxLen;
				}

				iMaxLen++;

				char* pszBuf = (char *)malloc(iMaxLen+10);
				if (pszBuf != NULL)
				{
					memset(pszBuf,0,iMaxLen+10);
					va_list argListSave ;
					va_start(argListSave, pszFormat);
					iMaxLen = vsnprintf(pszBuf, iMaxLen, pszFormat, argListSave);
					va_end(argListSave);

					str = pszBuf;
					free(pszBuf);
					pszBuf = NULL;
				}
				/* 2012-7-18
				++iMaxLen;

				char* pszBuf = new char[iMaxLen];
				if (!pszBuf)
				{
					return -1;
				}

				va_list argListSave ;
				va_start(argListSave, pszFormat);
				iMaxLen = vsnprintf(pszBuf, iMaxLen, pszFormat, argListSave);
				va_end(argListSave);

				str.assign(pszBuf, iMaxLen);
				delete[] pszBuf;
				*/
				
				return iMaxLen;
			}

			/**
			* 格式化字符串\n
			* 根据参数pszFormat字符串来转换并格式化数据,然后将结果复制到参数str所指的字符串中,直到出现字符串结束'\0'为止
			* @return 返回格式化后字符串的长度
			*/
			static std::string& MakeUpper(std::string& str)
			{
				transform(str.begin(), str.end(), str.begin(),
						static_cast<int(*)(int)> (toupper));
				return str;
			}


			/**
			* 转为大写
			*/
			static std::string& MakeLower(std::string& str)
			{
				transform(str.begin(), str.end(), str.begin(),
						static_cast<int(*)(int)> (tolower));
				return str;
			}


			/**
			 *转为小写
			 */
			static int CompareNoCase(const std::string& str1,
					const std::string& str2)
			{
				return strcasecmp(str1.c_str(), str2.c_str());
			}


			/**
			 *字符串比较,不区分大小写
			 */
			static int NCompareCase(const std::string& str1,
					const std::string& str2, unsigned int n)
			{
				return strncmp(str1.c_str(), str2.c_str(), n);
			}


			/**
			 *比较前count个字符
			 */
			static int NCompareNoCase(const std::string& str1,
					const std::string& str2, unsigned int n)
			{
				return strncasecmp(str1.c_str(), str2.c_str(), n);
			}


			/**
			* 字符替换
			* @return 返回被替换的次数
			 */
			static int Replace(std::string& str, char chOld, char chNew)
			{
				if (chOld == chNew)
				{
					return 0;
				}

				int iCount = 0;
				for (unsigned int i = 0; i < str.length(); ++i)
				{
					if (str[i] == chOld)
					{
						str[i] = chNew;
						++iCount;
					}
				}

				return iCount;
			}


			/**
			* 字符串替换
			* @return 返回被替换的次数
			*/
			static int Replace(std::string& str, const char* pszOld,
					const char* pszNew)
			{
				if (pszOld == pszNew)
				{
					return 0;
				}

				const size_t iOldLen = strlen(pszOld);
				const size_t iNewLen = strlen(pszNew);

				int iCount = 0;
				size_t iIndex = str.find(pszOld, 0);
				while (iIndex != std::string::npos)
				{
					str.erase(iIndex, iOldLen);
					str.insert(iIndex, pszNew);
					iIndex = str.find(pszOld, iIndex + iNewLen);
					++iCount;
				}

				return iCount;
			}


			/**
			* 删除字符串中的某字符
			* @return 返回删除的次数
			*/
			static int Remove(std::string& str, char ch)
			{
				int iCount = 0;
				size_t iIndex = str.find(ch);
				while (iIndex != std::string::npos)
				{
					str.erase(iIndex, 1);
					iIndex = str.find(ch);
					++iCount;
				}

				return iCount;
			}


			/**
			* 删除字符串中的某些字符\n
			* 如果是想删除子串,用Replace
			* @return 返回删除的次数
			*/
			static int Remove(std::string& str, const char* pszTrim)
			{
				int iCount = 0;
				size_t iIndex = str.find_first_of(pszTrim);
				while (iIndex != std::string::npos)
				{
					str.erase(iIndex, 1);
					iIndex = str.find_first_of(pszTrim);
					++iCount;
				}

				return iCount;
			}


			/**
			* 删除字符串中某些字符外的字符
			* @return 返回删除的次数
			*/
			static int RemoveNot(std::string& str, const char* pszTrim)
			{
				int iCount = 0;
				size_t iIndex = str.find_first_not_of(pszTrim);
				while (iIndex != std::string::npos)
				{
					str.erase(iIndex, 1);
					iIndex = str.find_first_not_of(pszTrim);
					++iCount;
				}

				return iCount;
			}


			/**
			* 删除字符串左边中的某些字符
			*/
			static std::string& TrimLeft(std::string& str, const char* pszTrim)
			{
				size_t iIndex = str.find_first_not_of(pszTrim);
				if (iIndex != std::string::npos)
				{
					str.erase(0, iIndex);
				}

				return str;
			}


			/**
			* 删除字符串右边中的某些字符
			*/
			static std::string& TrimRight(std::string& str, const char* pszTrim)
			{
				size_t iIndex = str.find_last_not_of(pszTrim);
				if ((++iIndex) != str.length())
				{
					str.erase(iIndex, str.length() - iIndex);
				}

				return str;
			}

			static std::string& Trim(std::string& str, const char* pszTrim)
			{
				TrimLeft(str, pszTrim);
				TrimRight(str, pszTrim);
				return str;
			}


			/**
			* Url编码
			*/
			static std::string& UrlEncode(const std::string& strSrc,
					std::string& strDst, bool bEncodeMutilBytes = false)
			{
				return UrlEncode(strSrc.c_str(), strDst, bEncodeMutilBytes);
			}

			static std::string& UrlEncode(const char* pszSrc,
					std::string& strDst, bool bEncodeMutilBytes = false)
			{
				const size_t iLen = strlen(pszSrc);

				strDst = "";
				strDst.reserve(iLen * 3);

				unsigned char uch;
				char sz[8];
				for (size_t i = 0; i < iLen; ++i)
				{
					uch = (unsigned char) pszSrc[i];
					if (bEncodeMutilBytes && (uch > 0x7F))
					{
						snprintf(sz, sizeof(sz), "%%%02X", uch);
						strDst += sz;
					}
					else
					{
						switch (uch)
						{
							case '&':
								strDst += "%26";
								break;
							case '=':
								strDst += "%3D";
								break;
							case '%':
								strDst += "%25";
								break;
							case '+':
								strDst += "%2B";
								break;
							case '?':
								strDst += "%3F";
								break;
							case ' ':
								strDst += "+";
								break;
							case '\n':
								strDst += "%0A";
								break;
							case '\r':
								strDst += "%0D";
								break;
							case '\t':
								strDst += "%09";
								break;
							case ':':
								strDst += "%3A";
								break;
							case '/':
								strDst += "%2F";
								break;
							default:
								strDst += uch;
								break;
						}
					}
				}

				return strDst;
			}


			/**
			* 引号编码.
			* 如果一个字符串需要安全的放到引号中,用这种编码方式.
			* 实现方法就是按C++的字符串转义来处理
			*/
			static std::string& QuotEncode(const std::string& strSrc,
					std::string& strDst)
			{
				return QuotEncode(strSrc.c_str(), strDst);
			}

			static std::string& QuotEncode(const char* pszSrc,
					std::string& strDst)
			{
				const size_t iLen = strlen(pszSrc);

				strDst = "";
				strDst.reserve(iLen * 2);

				unsigned char uch;
				bool bMutilBytes = false;
				for (size_t i = 0; i < iLen; ++i)
				{
					uch = (unsigned char) pszSrc[i];
					if (uch > 0x7F || bMutilBytes)
					{
						bMutilBytes = !bMutilBytes;
						strDst += uch;
					}
					else
					{
						switch (uch)
						{
							case '\n':
								strDst += "\\n";
								break;
							case '\t':
								strDst += "\\t";
								break;
							case '\v':
								strDst += "\\v";
								break;
							case '\b':
								strDst += "\\b";
								break;
							case '\r':
								strDst += "\\r";
								break;
							case '\f':
								strDst += "\\f";
								break;
							case '\a':
								strDst += "\\a";
								break;
							case '\\':
								strDst += "\\\\";
								break;
							case '\?':
								strDst += "\\\?";
								break;
							case '\'':
								strDst += "\\\'";
								break;
							case '\"':
								strDst += "\\\"";
								break;
							default:
								strDst += uch;
								break;
						}
					}
				}

				return strDst;
			}


			/**
			* 把0-9,A-F这样的十六进制字符转为相应的十进制
			*/
			static int HexToInt(char ch)
			{
				if (ch >= '0' && ch <= '9')
				{
					return ch - '0';
				}
				else if (ch >= 'a' && ch <= 'f')
				{
					return ch - 'a' + 10;
				}
				else if (ch >= 'A' && ch <= 'F')
				{
					return ch - 'A' + 10;
				}
				else
				{
					return 0;
				}
			}


			/**
			* Url解码
			*/
			static bool UrlDecode(const std::string& strSrc,
					std::string& strDst)
			{
				return UrlDecode(strSrc.c_str(), strDst);
			}

			static bool UrlDecode(const char* pszSrc, std::string& strDst)
			{
				const size_t iLen = strlen(pszSrc);

				strDst = "";
				strDst.reserve(iLen);
				char ch;
				for (size_t i = 0; i < iLen;)
				{
					switch (pszSrc[i])
					{
						case '+':
							strDst += ' ';
							++i;
							break;

						case '%':
							if ((i + 2) >= iLen)
							{
								return false;
							}

							ch = (HexToInt(pszSrc[i + 1]) << 4) + HexToInt(
									pszSrc[i + 2]);
							strDst += ch;
							i += 3;
							break;

						default:
							strDst += pszSrc[i];
							++i;
							break;
					}
				}

				return true;
			}


			/**
			* Url解码,不推荐使用
			*/
			static bool UrlDecode(const char* pszSrc, char* pszDst)
			{
				std::string strDst;
				if (!UrlDecode(pszSrc, strDst))
				{
					return false;
				}

				strcpy(pszDst, strDst.c_str());
				return true;
			}


			/**
			* HTML编码
			*/
			static std::string& HtmlEncode(const std::string& strSrc,
					std::string& strDst)
			{
				return HtmlEncode(strSrc.c_str(), strDst);
			}

			static std::string& HtmlEncode(const char* pszSrc,
					std::string& strDst)
			{
				const size_t iLen = strlen(pszSrc);
				strDst = "";
				strDst.reserve(iLen * 3);

				unsigned char uch;
				bool bMutilBytes = false;
				for (size_t i = 0; i < iLen; ++i)
				{
					uch = (unsigned char) pszSrc[i];
					if (uch > 0x7F || bMutilBytes)
					{
						bMutilBytes = !bMutilBytes;
						strDst += uch;
					}
					else
					{
						switch (uch)
						{
							case '<':
								strDst += "<";
								break;
							case '>':
								strDst += ">";
								break;
							case '&':
								strDst += "&";
								break;
							case '"':
								strDst += """;
								break;
							case '$':
								strDst += "$";
								break;
							case '%':
								strDst += "%";
								break;
							default:
								strDst += uch;
								break;
						}
					}
				}

				return strDst;
			}


			/**
			* 分割字符串的相关操作
			* 把字符串分割成多个字符串,可以有多个分割符
			* 注意:这种方式会忽略重复的分割符
			*/
			static void Split(const std::string& strBuf,
					const std::string& strDel,
					std::vector<std::string>& aryStringList)
			{
				size_t pos1 = 0, pos2 = 0;
				while (true)
				{
					pos1 = strBuf.find_first_not_of(strDel, pos2);
					if (pos1 == std::string::npos)
					{
						break;
					}

					pos2 = strBuf.find_first_of(strDel, pos1);
					if (pos2 == std::string::npos)
					{
						aryStringList.push_back(strBuf.substr(pos1));
						break;
					}
					else
					{
						aryStringList.push_back(
								strBuf.substr(pos1, pos2 - pos1));
					}
				}
			}

			static void Split(const std::string& strBuf,
				const std::string& strDel,
				int aryIntList[],int iarySize)
			{
				size_t pos1 = 0, pos2 = 0;
				int size=0;
				string strbuff;
				while (true)
				{
					pos1 = strBuf.find_first_not_of(strDel, pos2);
					if (pos1 == std::string::npos)
					{
						break;
					}

					pos2 = strBuf.find_first_of(strDel, pos1);
					if (pos2 == std::string::npos)
					{
						strbuff =strBuf.substr(pos1);
						if (size < iarySize)
						{
							aryIntList[size] =atoi(strbuff.c_str());
							size ++;
						}						
						break;
					}
					else
					{
						strbuff =strBuf.substr(pos1, pos2 - pos1);
						if (size < iarySize)
						{
							aryIntList[size] =atoi(strbuff.c_str());
							size ++;
						}
					}
				}
			}


			/**
			* 分割字符串的相关操作
			* 把字符串分割成多个字符串,分隔符唯一
			* 注意:这种方式会#不#忽略重复的分割符
			*/
			static void SplitNoSkip(const std::string& strBuf,
					const std::string& strDel,
					std::vector<std::string>& aryStringList)
			{
				size_t pos1 = 0, pos2 = 0;
				while (true)
				{
					pos2 = strBuf.find(strDel, pos1);
					if (pos2 == std::string::npos)
					{
						aryStringList.push_back(strBuf.substr(pos1));
						break;
					}
					else
					{
						aryStringList.push_back(
								strBuf.substr(pos1, pos2 - pos1));
						pos1 = pos2 + strDel.size();
					}
				}
			}


			/**
			* 分割name=value串
			*/
			static bool SplitIni(const std::string& strLine,
					std::string& strName, std::string& strValue)
			{
				if (strLine.size() == 0)
				{
					return false;
				}

				size_t iIndex = strLine.find('=');
				if (iIndex == std::string::npos)
				{
					return false;
				}

				strName = strLine.substr(0, iIndex);
				strValue = strLine.substr(iIndex + 1, strLine.size() - iIndex
						- 1);

				return true;
			}


			/**
			* 分割Url字符串
			* Url串中的特殊字符需要在调用前过滤
			*/
			static bool SplitUrl(const std::string& strLine, std::map<
					std::string, std::string>& mapNameValue, bool bEndecode =
					true, bool bNameCase = false)
			{
				std::vector<std::string> aryList;
				Split(strLine, "&", aryList);

				std::string strName, ssName;
				std::string strValue, ssValue;
				for (unsigned int i = 0; i < aryList.size(); ++i)
				{
					if (aryList[i].size() == 0)
					{
						continue;
					}

					if (!SplitIni(aryList[i], strName, strValue))
					{
						return false;
					}

					if (bEndecode)
					{
						if (!UrlDecode(strName.c_str(), ssName) || !UrlDecode(
								strValue.c_str(), ssValue))
						{
							return false;
						}
					}
					else
					{
						ssName = strName;
						ssValue = strValue;
					}

					if (!bNameCase)
					{
						MakeLower(ssName);
					}

					mapNameValue[ssName] = ssValue;
				}
				return true;
			}


			/**
			* 分割Cookie中的字符串
			*/
			static bool SplitCookie(const std::string& strOriginLine, std::map<
					std::string, std::string>& mapNameValue, bool bEndecode =
					true, bool bNameCase = false)
			{

				std::string strLine = strOriginLine;
				strLine.erase(remove(strLine.begin(), strLine.end(), ' '),
						strLine.end());

				std::vector<std::string> aryList;
				Split(strLine, ";", aryList);

				std::string strName, ssName;
				std::string strValue, ssValue;
				for (unsigned int i = 0; i < aryList.size(); ++i)
				{
					if (aryList[i].size() == 0)
					{
						continue;
					}

					if (!SplitIni(aryList[i], strName, strValue))
					{
						//return false;
						//
						continue;
					}

					ssName = strName;
					ssValue = strValue;

					mapNameValue[ssName] = ssValue;
				}
				return true;
			}

			static void Byte2Hex(unsigned char* pszCharStr, string& strHex,
					int size)
			{
				strHex = "";
				for (int i = 0; i < size; i++)
				{
					char buf[3];
					memset(buf,0x00,3);
					snprintf(buf,3,"%X",pszCharStr[i]);
					string strValue = buf;
					if(strValue.length() == 1)
					{
						strHex += "0";
						strHex += strValue;
					}
					else if(strValue.length() == 2)
					{
						strHex += strValue;
					}
				}
			}

			static void Char2HexStr(unsigned char* pszCharStr, string& strHex,
					int iSize)
			{
				char* pszHex = new char[iSize * 2 + 1];
				if (pszHex)
				{
					Char2HexStr(pszCharStr, pszHex, iSize);
					pszHex[iSize * 2] = 0;
					strHex.assign(pszHex, iSize * 2);
					delete[] pszHex;
					pszHex = NULL;
				}
			}
			static void Char2Hex(unsigned char ch, char* szHex)
			{
				unsigned char sbyte[2];
				sbyte[0] = ch / 16;
				sbyte[1] = ch % 16;
				for (int i = 0; i < 2; i++)
				{
					int nvale = sbyte[i];
					if ((nvale >= 0) && (nvale <= 9))
					{
						szHex[i] = '0' + sbyte[i];
					}
					else
					{
						szHex[i] = 'A' + (sbyte[i] - 10);
					}
				}
				szHex[2] = 0;
			}
			static void Char2HexStr(unsigned char* pszCharStr, char* pszHexStr,
					int iSize)
			{
				char szHex[3];
				pszHexStr[0] = 0;
				for (int i = 0; i < iSize; i++)
				{
					memset(szHex, 0x00, sizeof(szHex));
					Char2Hex(pszCharStr[i], szHex);
					strcat(pszHexStr, szHex);
				}
			}
	};

} // namespace CHLib

#endif	// __CHLIB_STRUTILS_H__
2013-7-29 12:39
0
游客
登录 | 注册 方可回帖
返回
//