⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 format.cpp

📁 电驴的MAC源代码
💻 CPP
字号:
//// This file is part of the aMule Project.//// Copyright (C) 2005-2008 aMule Team ( admin@amule.org / http://www.amule.org )//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA//#include "Format.h"//! Known type-modifiers. enum Modifiers{	//! No modifier field.	modNone,	//! Argument is interpreted as short int (integer types).	modShort,	//! Argument is interpreted as long int (integer types).	modLong,	//! Two 'long' modifieres, arguments is interpreted as long long (integer types).	modLongLong,	//! Argument is interpreted as long double (floating point types). Not supported.	modLongDouble};/** * Extracts modifiers from the argument. * * Note that this function will possibly return wrong results * for malformed format strings. */Modifiers getModifier(const wxString& str){	switch ( (wxChar)str[str.Len() - 2]) {		case wxT('h'):		// short int (integer types).			return modShort;		case wxT('l'):		// long int (interger types) or double (floating point types).			if ( str.Len() > 3 && str.GetChar( str.Len() - 3 ) == wxT('l') ) {				return modLongLong;			} else {				return modLong;			}		case wxT('L'):		// long double (floating point types).			return modLongDouble;		default:			return modNone;	}}/** Returns true if the char is a format-type. */bool isTypeChar(wxChar c){	switch (c) {		case wxT('s'):		// String of characters		case wxT('u'):		// Unsigned decimal integer		case wxT('i'):		// Signed decimal integer		case wxT('d'):		// Signed decimal integer		case wxT('c'):		// Character		case wxT('f'):		// Decimal floating point		case wxT('F'):		// Decimal floating point		case wxT('x'):		// Unsigned hexadecimal integer		case wxT('X'):		// Unsigned hexadecimal integer (capital letters)		case wxT('o'):		// Unsigned octal		case wxT('e'):		// Scientific notation (mantise/exponent) using e character		case wxT('E'):		// Scientific notation (mantise/exponent) using E character		case wxT('g'):		// Use shorter %e or %f		case wxT('G'):		// Use shorter %E or %f		case wxT('p'):		// Not supported, still needs to be caught though		case wxT('n'):		// Not supported, still needs to be caught though			return true;	}	return false;}/** Returns true if the char is a valid flag. */bool isFlagChar(wxChar c){	switch (c) {		case wxT('+'):		// Include sign for integers		case wxT('-'):		// Left-align output		case wxT('#'):		// Alternate form, varies		case wxT(' '):		// Pad with spaces		case wxT('0'):		// Pad with zeros			return true;	}	return false;}/** Returns true if the char is an integer (for width + precision). */bool isIntChar(wxChar c){	return ((c >= wxT('0')) && (c <= wxT('9')));}/** Returns true if the char is a valid length modifier. */bool isLengthChar(wxChar c){	switch (c) {		case wxT('h'):		// Short ('hh') and char ('h')		case wxT('l'):		// Long ('l') and long long ('ll')		case wxT('L'):		// Double long		case wxT('z'):		// size_t		case wxT('j'):		// intmax_t		case wxT('t'):		// ptrdiff_t			return true;	}	// Catches widths, precisons and zero-padding	return (c >= wxT('0')) && (c <= wxT('9'));}CFormat::CFormat(const wxChar* str){	m_fieldStart = 0;	m_fieldLength = 0;	m_skipCount = 0;	m_format = str;	if (m_format.Length()) {		SetCurrentField(wxEmptyString);	}}bool CFormat::IsReady() const{	return (m_fieldStart == m_format.Length());}wxString CFormat::GetString() const{	if (IsReady()) {		return m_result;	} else {		wxFAIL_MSG(wxT("Called GetString() before all values were passed: ") + m_format);		// Return as much as possible ...		return m_result + m_format.Mid(m_fieldStart);	}}void CFormat::SetCurrentField(const wxString& value){	wxCHECK_RET(m_fieldStart < m_format.Length(),		wxT("Setting field in already completed string: ") + m_format);	if (value.Length()) {		m_result += value;	}	enum {		PosNone = 0,		PosStart,		PosFlags,		PosWidth,		PosPrecision,		PosLength,		PosEnd	} pos = PosNone;	// Format strings are expected to follow the folllowing structure:	// 	%[Flags][Width][.Precision][Length]<Type>	for (size_t i = m_fieldStart + m_fieldLength; i < m_format.Length(); ++i) {		const wxChar c = m_format[i];		if (pos >= PosStart) {			m_fieldLength++;			if ((pos <= PosFlags) && isFlagChar(c)) {				pos = PosFlags;			} else if ((pos <= PosWidth) && isIntChar(c)) {				pos = PosWidth;			} else if ((pos < PosPrecision) && (c == wxT('.'))) {				pos = PosPrecision;			} else if ((pos == PosPrecision) && isIntChar(c)) {				// Nothing to do ...			} else if ((pos < PosLength) && isLengthChar(c)) {				pos = PosLength;			} else if ((pos == PosLength) && isLengthChar(c) && (c == m_format[i - 1])) {				// Nothing to do ...			} else if ((pos <= PosLength) && isTypeChar(c)) {				pos = PosEnd;				break;			} else if ((pos <= PosLength) && (c == wxT('%'))) {				// Append the %*% to the result				m_result += wxT("%");								pos = PosNone;			} else {				// Field is broken ...				break;			}		} else if (c == wxT('%')) {			const size_t offset = m_fieldStart + m_fieldLength;			// If there was anything before this, then prepend it.			if (offset < i) {				m_result += m_format.Mid(offset, i - offset);			}			// Starting a new format string			pos = PosStart;			m_fieldStart = i;			m_fieldLength = 1;		} else {			// Normal text, nothing to do ...		}	}	if (pos == PosNone) {		// No fields left		m_result += m_format.Mid(m_fieldStart + m_fieldLength);				m_fieldStart = m_fieldLength = m_format.Length();	} else if (pos != PosEnd) {		// A partial field was found ...		wxFAIL_MSG(wxT("Invalid field in format string: ") + m_format);		wxASSERT_MSG(m_fieldStart + m_fieldLength <= m_format.Length(),			wxT("Invalid field-start/length in format string: ") + m_format);		// Prepend the parsed part of the format-string		m_result += m_format.Mid(m_fieldStart, m_fieldLength);		// Return an empty string the next time GetCurrentField is called		m_skipCount++;		// Anything left to do?		if (!IsReady()) {			// Find the next format string			SetCurrentField(wxEmptyString);		}	}}wxString CFormat::GetCurrentField(){	wxCHECK_MSG(m_fieldStart < m_format.Length(), wxEmptyString,		wxT("Passing argument to already completed string: ") + m_format);	wxASSERT_MSG(m_fieldStart + m_fieldLength <= m_format.Length(),		wxT("Invalid field-start/length in format string: ") + m_format);	if (m_skipCount) {		// The current field was invalid, so we skip it.		m_skipCount--;		return wxEmptyString;	}	return m_format.Mid(m_fieldStart, m_fieldLength);}wxString CFormat::GetIntegerField(const wxChar* fieldType){	const wxString field = GetCurrentField();	if (field.IsEmpty()) {		// Invalid or missing field ...		return field;	}	// Drop type and length	wxString newField = field;	while (isalpha(newField.Last())) {		newField.RemoveLast();	}		// Set the correct integer type	newField += fieldType;	switch ((wxChar)field.Last()) {		case wxT('o'):		// Unsigned octal		case wxT('x'):		// Unsigned hexadecimal integer		case wxT('X'):		// Unsigned hexadecimal integer (capital letters)			// Override the default type			newField.Last() = field.Last();				case wxT('d'):		// Signed decimal integer		case wxT('i'):		// Signed decimal integer		case wxT('u'):		// Unsigned decimal integer			return newField;				default:			wxFAIL_MSG(wxT("Integer value passed to non-integer format string: ") + m_format);			SetCurrentField(field);			return wxEmptyString;	}}CFormat& CFormat::operator%(double value){	wxString field = GetCurrentField();	if (field.IsEmpty()) {		return *this;	}	switch ( (wxChar)field.Last() ) {		case wxT('e'):		// Scientific notation (mantise/exponent) using e character		case wxT('E'):		// Scientific notation (mantise/exponent) using E character		case wxT('f'):		// Decimal floating point		case wxT('F'):		// Decimal floating point		case wxT('g'):		// Use shorter %e or %f		case wxT('G'):		// Use shorter %E or %f			wxASSERT_MSG(getModifier(field) == modNone, wxT("Invalid modifier specified for floating-point format: ") + m_format);						SetCurrentField(wxString::Format(field, value));			break;				default:			wxFAIL_MSG(wxT("Floating-point value passed to non-float format string: ") + m_format);			SetCurrentField(field);	}	return *this;}CFormat& CFormat::operator%(wxChar value){	wxString field = GetCurrentField();		if (field.IsEmpty()) {		// We've already asserted in GetCurrentField.	} else if (field.Last() != wxT('c')) {		wxFAIL_MSG(wxT("Char value passed to non-char format string: ") + m_format);		SetCurrentField(field);	} else {		SetCurrentField(wxString::Format(field, value));	}	return *this;}CFormat& CFormat::operator%(signed long long value){	wxString field = GetIntegerField(wxLongLongFmtSpec  wxT("i"));	if (!field.IsEmpty()) {		SetCurrentField(wxString::Format(field, value));	}	return *this;}CFormat& CFormat::operator%(unsigned long long value){	wxString field = GetIntegerField(wxLongLongFmtSpec  wxT("u"));	if (!field.IsEmpty()) {		SetCurrentField(wxString::Format(field, value));	}	return *this;}CFormat& CFormat::operator%(const wxString& val){	wxString field = GetCurrentField();		if (field.IsEmpty()) {		// We've already asserted in GetCurrentField	} else if (field.Last() != wxT('s')) {		wxFAIL_MSG(wxT("String value passed to non-string format string:") + m_format);		SetCurrentField(field);	} else if (field.GetChar(1) == wxT('.')) {		// A max-length is specified		wxString size = field.Mid( 2, field.Len() - 3 );		long lSize = 0;		// Try to convert the length-field.		if ((size.IsEmpty() || size.ToLong(&lSize)) && (lSize >= 0)) {			SetCurrentField(val.Left(lSize));		} else {			wxFAIL_MSG(wxT("Invalid value found in 'precision' field: ") + m_format);			SetCurrentField(field);		}	} else if (field.GetChar(1) == wxT('s')) {		// No limit on size, just set the string		SetCurrentField(val);	} else {		SetCurrentField(field);		wxFAIL_MSG(wxT("Malformed string format field: ") + m_format);	}	return *this;}CFormat& CFormat::operator%(void * value){	wxString field = GetCurrentField();		if (field.IsEmpty()) {		// We've already asserted in GetCurrentField.	} else if (field.Last() != wxT('p')) {		wxFAIL_MSG(wxT("Pointer value passed to non-pointer format string: ") + m_format);		SetCurrentField(field);	} else if (field != wxT("%p")) {		wxFAIL_MSG(wxT("Modifiers are not allowed for pointer format string: ") + m_format);		SetCurrentField(field);	} else {		// built-in Format for pointer is not optimal:		// - Windows: uppercase, no leading 0x		// - Linux:   leading zeros missing 		// -> format it as hex		if (sizeof (void *) == 8) { // 64 bit			SetCurrentField(wxString::Format(wxT("0x%016x"), (uintptr_t) value));		} else { // 32 bit			SetCurrentField(wxString::Format(wxT("0x%08x"),  (uintptr_t) value));		}	}	return *this;}// File_checked_for_headers

⌨️ 快捷键说明

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