예제 #1
0
StringBuffer *StringBufferASCII::Append(const char szString[], uint32 nCount)
{
	// Calculate the new total length of the string (excluding the terminating zero)
	const uint32 nNewLength = m_nLength + nCount;

	// Is it possible to just modify the current internal string in place? (FAST!)
	if (nNewLength <= m_nMaxLength && GetRefCount() < 2) {
		// Just modify the current internal string in place
		memcpy(&m_pszString[m_nLength], szString, nCount);	// Append the new string
		m_pszString[nNewLength] = '\0';						// Set the terminating zero
		SetNewStringLength(nNewLength);						// Set the new string length

		// Return this string buffer
		return this;
	} else {
		// Request an ASCII string buffer from the string buffer manager
		StringBuffer *pStringBuffer = Manager.GetStringBufferASCII(nNewLength);
		if (pStringBuffer) {
			// Add old string
			if (m_nLength)
				pStringBuffer->Append(m_pszString, m_nLength);

			// Add string to append
			pStringBuffer->Append(szString, nCount);
		}

		// Done
		return pStringBuffer;
	}
}
예제 #2
0
    void AddFilesFromDirectoryToTPAList(wchar_t* targetPath, wchar_t** rgTPAExtensions, int countExtensions)
    {
        *m_log << W("Adding assemblies from ") << targetPath << W(" to the TPA list") << Logger::endl;
        wchar_t assemblyPath[MAX_PATH];

        for (int iExtension = 0; iExtension < countExtensions; iExtension++)
        {
            wcscpy_s(assemblyPath, MAX_PATH, targetPath);

            const size_t dirLength = wcslen(targetPath);
            wchar_t* const fileNameBuffer = assemblyPath + dirLength;
            const size_t fileNameBufferSize = MAX_PATH - dirLength;

            wcscat_s(assemblyPath, rgTPAExtensions[iExtension]);
            WIN32_FIND_DATA data;
            HANDLE findHandle = FindFirstFile(assemblyPath, &data);

            if (findHandle != INVALID_HANDLE_VALUE) {
                do {
                    if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                        // It seems that CoreCLR doesn't always use the first instance of an assembly on the TPA list (ni's may be preferred
                        // over il, even if they appear later). So, only include the first instance of a simple assembly name to allow
                        // users the opportunity to override Framework assemblies by placing dlls in %CORE_LIBRARIES%

                        // ToLower for case-insensitive comparisons
                        wchar_t* fileNameChar = data.cFileName;
                        while (*fileNameChar)
                        {
                            *fileNameChar = towlower(*fileNameChar);
                            fileNameChar++;
                        }

                        // Remove extension
                        wchar_t fileNameWithoutExtension[MAX_PATH];
                        wcscpy_s(fileNameWithoutExtension, MAX_PATH, data.cFileName);

                        RemoveExtensionAndNi(fileNameWithoutExtension);

                        // Add to the list if not already on it
                        if (!TPAListContainsFile(fileNameWithoutExtension, rgTPAExtensions, countExtensions))
                        {
                            const size_t fileLength = wcslen(data.cFileName);
                            const size_t assemblyPathLength = dirLength + fileLength;
                            wcsncpy_s(fileNameBuffer, fileNameBufferSize, data.cFileName, fileLength);
                            m_tpaList.Append(assemblyPath, assemblyPathLength);
                            m_tpaList.Append(W(";"), 1);
                        }
                        else
                        {
                            *m_log << W("Not adding ") << targetPath << data.cFileName << W(" to the TPA list because another file with the same name is already present on the list") << Logger::endl;
                        }
                    }
                } while (0 != FindNextFile(findHandle, &data));

                FindClose(findHandle);
            }
        }
    }
예제 #3
0
void StackTraceFormatter::AppendArgumentType(Thread *const thread, StringBuffer &buf, const Value *arg)
{
	Value argValue; // Copy, because arg is const

	if (IS_REFERENCE(*arg))
	{
		// If the argument is a reference, it must be dereferenced before
		// we can make use of the type information.
		buf.Append(4, "ref ");
		ReadReference(const_cast<Value*>(arg), &argValue);
	}
	else
	{
		argValue = *arg;
	}

	Type *type = argValue.type;
	if (type == nullptr)
	{
		buf.Append(4, "null");
		return;
	}

	// To make the stack trace more readable, we only append the last component
	// of the type name, so 'osprey.compiler.parser.Token' becomes just 'Token'.
	AppendShortMemberName(thread, buf, type->fullName);

	// When the argument is an aves.Method, we append some information about
	// the instance and method group, too, in the format
	//   Method(this: <instance type>, <method name>)
	//
	// Note that this is applied recursively to the instance type, which means
	// you can end up with situations like
	//   Method(this: Method(this: Method(...), ...), ...)
	//
	// It should at least be impossible for an aves.Method to be bound to iself.
	// Otherwise, well, we'll get infinite recursion!
	if (type == thread->GetVM()->types.Method)
	{
		// Append some information about the instance and method group, too.
		MethodInst *method = argValue.v.method;

		buf.Append(7, "(this: ");

		// It should be impossible for an aves.Method to be bound to iself.
		OVUM_ASSERT(method->instance.v.instance != argValue.v.instance);
		AppendArgumentType(thread, buf, &method->instance);

		buf.Append(2, ", ");

		AppendShortMethodName(thread, buf, method->method);

		buf.Append(')');
	}
}
예제 #4
0
void StackTraceFormatter::AppendMethodName(Thread *const thread, StringBuffer &buf, Method *method)
{
	// The method name is the fully qualified name of the method.

	// If method->declType is null, we're dealing with a global function, where
	// method->name already contains the fully qualified name.
	if (method->declType != nullptr)
	{
		buf.Append(method->declType->fullName);
		buf.Append('.');
	}
	buf.Append(method->name);
}
예제 #5
0
void StackTraceFormatter::AppendSourceLocation(Thread *const thread, StringBuffer &buf, MethodOverload *method, const void *ip)
{
	uint32_t offset = (uint32_t)((uint8_t*)ip - method->entry);

	debug::DebugSymbol *sym = method->debugSymbols->FindSymbol(offset);
	if (sym == nullptr)
		return;

	buf.Append(13, "\n    at line ");
	AppendLineNumber(thread, buf, sym->startLocation.lineNumber);

	buf.Append(5, " in \"");
	buf.Append(sym->file->fileName);
	buf.Append('"');
}
예제 #6
0
AVES_API NATIVE_FUNCTION(aves_StringBuffer_appendLine)
{
	StringBuffer *buf = THISV.Get<StringBuffer>();
	if (!buf->Append(strings::newline))
		return VM_ThrowMemoryError(thread);

	VM_Push(thread, THISP);
	RETURN_SUCCESS;
}
예제 #7
0
StringBuffer *StringBufferASCII::Clone() const
{
	// Request an ASCII string buffer from the string buffer manager
	StringBuffer *pStringBuffer = Manager.GetStringBufferASCII(m_nLength);
	if (pStringBuffer)
		pStringBuffer->Append(m_pszString, m_nLength);

	// Done
	return pStringBuffer;
}
예제 #8
0
StringBuffer *StringBufferASCII::GetSubstring(uint32 nPos, uint32 nCount) const
{
	// Request an ASCII string buffer from the string buffer manager
	StringBuffer *pStringBuffer = Manager.GetStringBufferASCII(nCount);
	if (pStringBuffer)
		pStringBuffer->Append(m_pszString + nPos, nCount);

	// Done
	return pStringBuffer;
}
예제 #9
0
void StackTraceFormatter::AppendShortMethodName(Thread *const thread, StringBuffer &buf, Method *method)
{
	// The short method name is the semi-qualified name of the method. That means
	// the last component of the name if it's a global function, or the last part
	// of the type name followed by the method name if it's a class method.

	// If method->declType is null, we're dealing with a global function, where
	// method->name already contains the fully qualified name.
	if (method->declType != nullptr)
	{
		AppendShortMemberName(thread, buf, method->declType->fullName);
		buf.Append('.');
		buf.Append(method->name);
	}
	else
	{
		AppendShortMemberName(thread, buf, method->name);
	}
}
예제 #10
0
void StackTraceFormatter::AppendShortMemberName(Thread *const thread, StringBuffer &buf, String *fullName)
{
	const ovchar_t *fullNameChars = &fullName->firstChar;
	int32_t lastDotIndex = fullName->length - 1;
	while (lastDotIndex >= 0)
	{
		if (fullNameChars[lastDotIndex] == '.')
			break;
		lastDotIndex--;
	}

	if (lastDotIndex >= 0)
		// The name contains one or more dots! Append everything
		// after the last dot.
		buf.Append(fullName->length - lastDotIndex - 1, fullNameChars + lastDotIndex + 1);
	else
		// No dot found, so just append the whole name
		buf.Append(fullName);
}
예제 #11
0
StringBuffer *StringBufferASCII::Append(const wchar_t szString[], uint32 nCount)
{
	// Calculate the new total length of the string (excluding the terminating zero)
	const uint32 nNewLength = m_nLength + nCount;

	// Request an unicode string buffer from the string buffer manager
	StringBuffer *pStringBuffer = Manager.GetStringBufferUnicode(nNewLength);
	if (pStringBuffer) {
		// Add old string
		if (m_nLength)
			pStringBuffer->Append(m_pszString, m_nLength);

		// Add string to append
		pStringBuffer->Append(szString, nCount);
	}

	// Done
	return pStringBuffer;
}
예제 #12
0
void StackTraceFormatter::AppendParameters(Thread *const thread, StringBuffer &buf, const StackFrame *frame, MethodOverload *method)
{
	ovlocals_t paramCount = method->GetEffectiveParamCount();
	const Value *args = reinterpret_cast<const Value*>(frame) - paramCount;

	for (ovlocals_t i = 0; i < paramCount; i++)
	{
		if (i > 0)
			buf.Append(2, ", ");

		if (i == 0 && method->IsInstanceMethod())
			buf.Append(4, "this");
		else
			buf.Append(method->paramNames[i - method->InstanceOffset()]);

		buf.Append(2, ": ");

		AppendArgumentType(thread, buf, args + i);
	}
}
예제 #13
0
StringBuffer *StringBufferASCII::Insert(const char szString[], uint32 nPos, uint32 nCount)
{
	// Calculate the new total length of the string (excluding the terminating zero)
	const uint32 nNewLength = m_nLength + nCount;

	// Is it possible to just modify the current internal string in place? (FAST!)
	if (nNewLength <= m_nMaxLength && GetRefCount() < 2) {
		// Just modify the current internal string in place
		const int nLeftCharacters = m_nLength - nPos;
		if (nLeftCharacters > 0) {
			// Make space for the new string by moving everything to the right
			// (in here, we KNOW that there's enough memory in the right to hold the string!)
			memcpy(&m_pszString[nPos + nCount], &m_pszString[nPos], nLeftCharacters);
		}
		memcpy(&m_pszString[nPos], szString, nCount);	// Append the new string at the now free space
		m_pszString[nNewLength] = '\0';					// Set the terminating zero
		SetNewStringLength(nNewLength);					// Set the new string length

		// Return this string buffer
		return this;
	} else {
		// Request an ASCII string buffer from the string buffer manager
		StringBuffer *pStringBuffer = Manager.GetStringBufferASCII(nNewLength);
		if (pStringBuffer) {
			// Add old string in front of the insert place
			if (m_nLength && nPos)
				pStringBuffer->Append(m_pszString, nPos);

			// Add new string
			pStringBuffer->Append(szString, nCount);

			// Add old string in back of the insert place
			const int nLeftCharacters = m_nLength - nPos;
			if (m_nLength && nLeftCharacters > 0)
				pStringBuffer->Append(&m_pszString[nPos], nLeftCharacters);
		}

		// Done
		return pStringBuffer;
	}
}
예제 #14
0
static void
apply_safe_mode_path_blacklist()
{
	if (sPathBlacklist->IsEmpty())
		return;

	bool success = sSafeModeOptionsBuffer.Append("EntryBlacklist {\n");

	for (PathBlacklist::Iterator it = sPathBlacklist->GetIterator();
		BlacklistedPath* path = it.Next();) {
		success &= sSafeModeOptionsBuffer.Append(path->Path());
		success &= sSafeModeOptionsBuffer.Append("\n", 1);
	}

	success &= sSafeModeOptionsBuffer.Append("}\n");

	if (!success) {
		dprintf("apply_safe_mode_options(): failed to append path "
			"blacklist to buffer\n");
	}
}
예제 #15
0
void StackTraceFormatter::AppendStackFrame(Thread *const thread, StringBuffer &buf, const StackFrame *frame, const void *ip)
{
	MethodOverload *method = frame->method;
	Method *group = method->group;

	// Each line in the stack trace is indented with two spaces.
	buf.Append(2, ' ');

	AppendMethodName(thread, buf, group);

	buf.Append('(');

	AppendParameters(thread, buf, frame, method);

	buf.Append(')');

	if (method->debugSymbols)
		AppendSourceLocation(thread, buf, method, ip);

	buf.Append('\n');
}
예제 #16
0
AVES_API NATIVE_FUNCTION(aves_StringBuffer_appendCodePoint)
{
	// appendCodepoint(cp: Int)
	// The public-facing method makes sure the type is right,
	// and also range-checks the value

	StringBuffer *buf = THISV.Get<StringBuffer>();
	ovwchar_t codepoint = (ovwchar_t)args[1].v.integer;

	if (codepoint > 0xFFFF)
	{
		// Surrogate pair, whoo!
		SurrogatePair pair = UC_ToSurrogatePair(codepoint);
		if (!buf->Append(2, (ovchar_t*)&pair))
			return VM_ThrowMemoryError(thread);
	}
	else
		if (!buf->Append(1, (ovchar_t)codepoint))
			return VM_ThrowMemoryError(thread);

	VM_Push(thread, THISP);
	RETURN_SUCCESS;
}
예제 #17
0
//
// String
//
static void FmtString(StringBuffer   & oBuffer,
                      const CDT      & oCurrentArgument,
                      const UINT_32    iFmtFlags,
                      const INT_32     iWidth,
                      const INT_32     iMaxChars,
                      CHAR_8           chPadSymbol)
{
	const STLW::string sTMP    = oCurrentArgument.GetString();

	INT_32 iFormatSize = sTMP.size();
	if (iFormatSize > iMaxChars && iMaxChars > 0) { iFormatSize = iMaxChars; }

	if (iFmtFlags & F_LEFT_ALIGN)
	{
		oBuffer.Append(sTMP.data(), iFormatSize);
		if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); }
	}
	else
	{
		if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); }
		oBuffer.Append(sTMP.data(), iFormatSize);
	}
}
예제 #18
0
StringBuffer *StringBufferASCII::Insert(const wchar_t szString[], uint32 nPos, uint32 nCount)
{
	// Calculate the new total length of the string (excluding the terminating zero)
	const uint32 nNewLength = m_nLength + nCount;

	// Request an unicode string buffer from the string buffer manager
	StringBuffer *pStringBuffer = Manager.GetStringBufferUnicode(nNewLength);
	if (pStringBuffer) {
		// Add old string in front of the insert place
		if (m_nLength && nPos)
			pStringBuffer->Append(m_pszString, nPos);

		// Add new string
		pStringBuffer->Append(szString, nCount);

		// Add old string in back of the insert place
		const int nLeftCharacters = m_nLength - nPos;
		if (m_nLength && nLeftCharacters > 0)
			pStringBuffer->Append(&m_pszString[nPos], nLeftCharacters);
	}

	// Done
	return pStringBuffer;
}
예제 #19
0
AVES_API NATIVE_FUNCTION(aves_StringBuffer_appendSubstringFromBuffer)
{
	// appendSubstrFromBuffer(sb: StringBuffer, index: Int, count: Int)
	// The public-facing method also range-checks the values

	StringBuffer *dest = THISV.Get<StringBuffer>();
	StringBuffer *src = args[1].Get<StringBuffer>();
	size_t index = (size_t)args[2].v.integer;
	size_t count = (size_t)args[3].v.integer;

	if (!dest->Append(count, src->GetDataPointer() + index))
		return VM_ThrowMemoryError(thread);

	VM_Push(thread, THISP);
	RETURN_SUCCESS;
}
예제 #20
0
AVES_API NATIVE_FUNCTION(aves_StringBuffer_appendSubstringFromString)
{
	// appendSubstrFromString(str: String, index: Int, count: Int)
	// The public-facing method also range-checks the values

	StringBuffer *buf = THISV.Get<StringBuffer>();
	String *str = args[1].v.string;
	size_t index = (size_t)args[2].v.integer;
	size_t count = (size_t)args[3].v.integer;

	if (!buf->Append(count, &str->firstChar + index))
		return VM_ThrowMemoryError(thread);

	VM_Push(thread, THISP);
	RETURN_SUCCESS;
}
예제 #21
0
void StackTraceFormatter::AppendLineNumber(Thread *const thread, StringBuffer &buf, int32_t line)
{
	// 32 digits ought to be enough for anybody
	const size_t BUFFER_SIZE = 32;

	ovchar_t lineNumberStr[BUFFER_SIZE];
	ovchar_t *chp = lineNumberStr + BUFFER_SIZE;
	int32_t length = 0;

	do
	{
		*--chp = (ovchar_t)'0' + line % 10;
		length++;
	} while (line /= 10);

	buf.Append(length, chp);
}
예제 #22
0
static bool
debug_menu_add_advanced_option(Menu* menu, MenuItem* item)
{
	char buffer[256];

	size_t size = platform_get_user_input_text(menu, item, buffer,
		sizeof(buffer) - 1);

	if (size > 0) {
		buffer[size] = '\n';
		if (!sSafeModeOptionsBuffer.Append(buffer)) {
			dprintf("debug_menu_add_advanced_option(): failed to append option "
				"to buffer\n");
		}
	}

	return true;
}
예제 #23
0
static void
apply_safe_mode_options(Menu* menu)
{
	MenuItemIterator iterator = menu->ItemIterator();
	while (MenuItem* item = iterator.Next()) {
		if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked()
			|| item->Data() == NULL) {
			continue;
		}

		char buffer[256];
		if (snprintf(buffer, sizeof(buffer), "%s true\n",
				(const char*)item->Data()) >= (int)sizeof(buffer)
			|| !sSafeModeOptionsBuffer.Append(buffer)) {
			dprintf("apply_safe_mode_options(): failed to append option to "
				"buffer\n");
		}
	}
}
예제 #24
0
AVES_API NATIVE_FUNCTION(aves_StringBuffer_append)
{
	Aves *aves = Aves::Get(thread);

	// append(value is String, times is Int)
	int64_t times = args[2].v.integer;

	if (times < 0 || times > OVUM_ISIZE_MAX)
	{
		VM_PushString(thread, strings::times);
		return VM_ThrowErrorOfType(thread, aves->aves.ArgumentRangeError, 1);
	}

	StringBuffer *buf = THISV.Get<StringBuffer>();
	String *str = args[1].v.string;

	for (size_t i = 0; i < (size_t)times; i++)
		if (!buf->Append(str))
			return VM_ThrowMemoryError(thread);

	VM_Push(thread, THISP);
	RETURN_SUCCESS;
}
예제 #25
0
//
// Character
//
static void FmtChar(StringBuffer   & oBuffer,
                    const CDT      & oCurrentArgument,
                    const UINT_32    iFmtFlags,
                    const INT_32     iWidth,
                    CHAR_8           chPadSymbol)
{
	const CDT::eValType oValType = oCurrentArgument.GetType();
	if (oValType == CDT::UNDEF && iWidth > 0)
	{
		oBuffer.Append(iWidth, chPadSymbol);
		return;
	}

	UCHAR_8 ucTMP = ' ';
	if (oValType == CDT::INT_VAL || oValType == CDT::REAL_VAL)
	{
		ucTMP = oCurrentArgument.GetInt();
	}
	else if (oValType == CDT::STRING_VAL)
	{
		const STLW::string sTMP = oCurrentArgument.GetString();
		if (sTMP.empty() && iWidth > 0)
		{
			oBuffer.Append(iWidth, chPadSymbol);
			return;
		}
		ucTMP = sTMP[0];
	}
	else if (oValType == CDT::POINTER_VAL) { ucTMP = 'P'; }
	else if (oValType == CDT::ARRAY_VAL)   { ucTMP = 'A'; }
	else if (oValType == CDT::HASH_VAL)    { ucTMP = 'H'; }

	if (iFmtFlags & F_LEFT_ALIGN)
	{
		oBuffer.Append(1, ucTMP);
		if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
	}
	else
	{
		if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
		oBuffer.Append(1, ucTMP);
	}
}
ECode MessageFormat::FormatImpl(
    /* [in] */ ArrayOf< IInterface* >* objects,
    /* [in] */ IStringBuffer* inbuffer,
    /* [in] */ IFieldPosition* position,
    /* [in] */ List<AutoPtr<FieldContainer> >* fields)
{
    VALIDATE_NOT_NULL(inbuffer);

    StringBuffer * buffer = (StringBuffer *)inbuffer;
    AutoPtr<IFieldPosition> passedField;
    CFieldPosition::New(0, (IFieldPosition**)&passedField);

    Int32 begin;
    String result;
    for (Int32 i = 0; i <= mMaxOffset; i++) {
        *buffer += (*mStrings)[i];
        begin = buffer->GetLength();
        AutoPtr<IInterface> arg;
        if (objects != NULL && (*mArgumentNumbers)[i] < objects->GetLength()) {
            arg = (*objects)[(*mArgumentNumbers)[i]];
        }
        else {
            buffer->AppendChar('{');
            *buffer += (*mArgumentNumbers)[i];
            buffer->AppendChar('}');
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i],
                    position, fields);
            continue;
        }

        AutoPtr<IFormat> format = (*mFormats)[i];
        if (format == NULL || arg == NULL) {
            if (INumber::Probe(arg) != NULL) {
                AutoPtr<INumberFormat> nf;
                NumberFormat::GetInstance((INumberFormat**)&nf);
                format = IFormat::Probe(nf);
            }
            else if (IDate::Probe(arg) != NULL) {
                AutoPtr<IDateFormat> df;
                DateFormat::GetInstance((IDateFormat**)&df);
                format = IFormat::Probe(df);
            }
            else {
                buffer->Append(Object::ToString(arg));
                HandleArgumentField(begin, buffer->GetLength(),
                        (*mArgumentNumbers)[i], position, fields);
                continue;
            }
        }

        if (IChoiceFormat::Probe(format) != NULL) {
            format->Format(arg, &result);
            AutoPtr<IMessageFormat> mf;
            CMessageFormat::New(result, (IMessageFormat**)&mf);
            mf->SetLocale(mLocale);
            mf->Format(objects, buffer , passedField);
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i], position, fields);
            HandleFormat(format, arg, begin, fields);
        }
        else {
            format->Format(arg, buffer, passedField);
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i], position, fields);
            HandleFormat(format, arg, begin, fields);
        }
    }
    if (mMaxOffset + 1 < mStrings->GetLength()) {
        (*buffer) += (*mStrings)[mMaxOffset + 1];
    }

    return NOERROR;
}
예제 #27
0
//
// Floating point
//
static void FmtFloat(StringBuffer            & oBuffer,
                     const CDT               & oCurrentArgument,
                     const UINT_32             iFmtFlags,
                     const eFmtLengths       & oFmtLengths,
                     const CHAR_8              chExponentSymbol,
                     const eFmtSpecifier     & oFmtSpecifier,
                     INT_32                    iWidth,
                     INT_32                    iPrecision,
                     CHAR_8                    chPadSymbol)
{
	using namespace CTPP;

	/*
	 * fF  The double argument is rounded and converted to decimal notation
	 *     in the style [-]ddd.ddd, where the number of digits after the
	 *     decimal-point character is equal to the precision specification.
	 *     If the precision is missing, it is taken as 6; if the precision
	 *     is explicitly zero, no decimal-point character appears.  If a
	 *     decimal point appears, at least one digit appears before it.
	 *
	 * gG  The double argument is converted in style f or e (or F or E for G
	 *     conversions).  The precision specifies the number of significant
	 *     digits.  If the precision is missing, 6 digits are given; if the
	 *     precision is zero, it is treated as 1.  Style e is used if the
	 *     exponent from its conversion is less than -4 or greater than or
	 *     equal to the precision.  Trailing zeros are removed from the
	 *     fractional part of the result; a decimal point appears only if it
	 *     is followed by at least one digit.
	 */
//	if (iWidth == -1) { iWidth = 6; }

	INT_32 iMode;
	INT_32 iExponent = 0;
	INT_32 iSign     = 0;
	CHAR_P szEnd     = NULL;
	INT_32 iFormatPrecision;
	if (oFmtSpecifier == F_FLOAT_F)
	{
		iMode = 3;
		if (iPrecision == -1) { iPrecision = 6; }

		iFormatPrecision = iPrecision;
	}
	// Only one decision left
	else /* if (oFmtSpecifier == F_FLOAT_G) */
	{
		iMode = 2;
		if      (iPrecision == -1) { iPrecision = 6; }
		else if (iPrecision ==  0) { iPrecision = 1; }

		iFormatPrecision = iPrecision + 1;
	}

	Bigint *freelist[Kmax+1];
	for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; }

	W_FLOAT dData = oCurrentArgument.GetFloat();
	AllocatedBlock * aBlocks = NULL;

	CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iFormatPrecision, &iExponent, &iSign, &szEnd);
	bool bIsNegative = iSign < 0;
	--iExponent;

	INT_32 iPos = szEnd - szBuffer;

	// Data length
	INT_32 iFormattedLength;
	if (oFmtSpecifier == F_FLOAT_F)
	{
		if (iExponent < 0)
		{
			iFormattedLength = iPrecision + 2;
		}
		else
		{
			iFormattedLength = iPrecision + iExponent + 1;
		}

	}
	else /* if (oFmtSpecifier == F_FLOAT_G) */
	{
		/*
		 *  Style e is used if the
		 *  exponent from its conversion is less than -4 or greater than or
		 *  equal to the precision.
		 */
		if (iExponent < -4 || iExponent >= iPrecision)
		{
			// Free memory
			freedtoa(&aBlocks);

			if (iWidth == -1) { iWidth = 6; }
			FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, chExponentSymbol, iWidth, iPrecision, chPadSymbol);
			return;
		}

		if (iPos > iPrecision) { iPos = iPrecision; }
		else                   { iPrecision = iPos; }

		iFormattedLength = iPrecision;
		if (iExponent < 0) { iFormattedLength += 1 - iExponent; }
	}

	// Sign?
	if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }

	// Right-aligned
	if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN)
	{
		// Spaces, if need
		if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
	}

	// Sign
	if      (bIsNegative)              { oBuffer.Append(1, '-'); }
	else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); }
	else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); }

	if (oFmtSpecifier == F_FLOAT_F)
	{
		// Value
		if (iExponent < 0)
		{
			const INT_32 iChars = iPrecision + iExponent + 1;

			oBuffer.Append(1, '0');
			oBuffer.Append(1, '.');
			oBuffer.Append(-iExponent - 1, '0');

			if (iChars > iPos)
			{
				oBuffer.Append(szBuffer, iPos);
				oBuffer.Append(iChars - iPos, '0');
			}
			else
			{
				oBuffer.Append(szBuffer, iChars);
			}
		}
		else
		{
			// Value
			oBuffer.Append(szBuffer, iExponent + 1);
			if (iPrecision > 0)
			{
				iPos -= iExponent;
				oBuffer.Append(1, '.');
				oBuffer.Append(szBuffer + iExponent + 1, iPos - 1);

				if (iPrecision + 1 > iPos)
				{
					oBuffer.Append(iPrecision - iPos + 1, '0');
				}
			}
		}
	}
	else /* if (oFmtSpecifier == F_FLOAT_G) */
	{
		// Value
		if (iExponent < 0)
		{
			const INT_32 iChars = (iPrecision < iPos) ? iPrecision : iPos;

			oBuffer.Append(1, '0');
			oBuffer.Append(1, '.');
			oBuffer.Append(- iExponent - 1, '0');
			oBuffer.Append(szBuffer, iChars);
		}
		else
		{
			oBuffer.Append(szBuffer, iExponent + 1);
			if (iPos > iExponent + 1)
			{
				oBuffer.Append(1, '.');
				oBuffer.Append(szBuffer + iExponent + 1, iPrecision - iExponent - 1);
			}
		}
	}

	// Free memory
	freedtoa(&aBlocks);

	// Left-aligned
	if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN)
	{
		// Spaces, if need
		if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
	}
}
예제 #28
0
//
// Scientific
//
static void FmtSci(StringBuffer       & oBuffer,
                   const CDT          & oCurrentArgument,
                   const UINT_32        iFmtFlags,
                   const eFmtLengths  & oFmtLengths,
                   const CHAR_8         chExponentSymbol,
                   INT_32               iWidth,
                   INT_32               iPrecision,
                   CHAR_8               chPadSymbol)
{
	using namespace CTPP;

	/*
	 * eE  The double argument is rounded and converted in the style
	 *     [-]d.ddde+-dd where there is one digit before the decimal-point
	 *     character and the number of digits after it is equal to the pre-
	 *     cision; if the precision is missing, it is taken as 6; if the
	 *     precision is zero, no decimal-point character appears.  An E con-
	 *     version uses the letter `E' (rather than `e') to introduce the
	 *     exponent.  The exponent always contains at least two digits; if
	 *     the value is zero, the exponent is 00.
	 */

	if (iPrecision == -1) { iPrecision = 6; }
	if (iWidth == -1)     { iWidth     = 6; }

	const INT_32   iMode     = 2;
	INT_32         iExponent = 0;
	INT_32         iSign     = 0;
	CHAR_P         szEnd     = NULL;

	Bigint *freelist[Kmax+1];
	for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; }

	W_FLOAT dData = oCurrentArgument.GetFloat();
	AllocatedBlock * aBlocks = NULL;

	CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iPrecision, &iExponent, &iSign, &szEnd);
	bool bIsNegative = iSign < 0;
	--iExponent;

	// Format Exponent
	CHAR_8 szExponentBuffer[C_INT_BUFFER_LEN + 1];
	szExponentBuffer[C_INT_BUFFER_LEN] = 0;
	bool bExponentIsNegative = false;
	// Signed
	INT_32 iExponentPos = DoFormat<INT_32>(iExponent, 10, szDigitsUc, szExponentBuffer, bExponentIsNegative);

	// Atleast 2 digits in exponent
	if (iExponentPos == 1)
	{
		iExponentPos = 2;
		szExponentBuffer[C_INT_BUFFER_LEN - 2] = '0';
	}

	++iExponentPos;
	// Add exponent sign
	szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = bExponentIsNegative ? '-' : '+';
	// Add exponent char
	++iExponentPos;
	szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = chExponentSymbol;

	INT_32 iPos = szEnd - szBuffer;

	// Data length
	INT_32 iFormattedLength = iExponentPos + 1;
	//;// = iPos + iExponentPos + 1;
	// Precision
	if (iPrecision > iPos)
	{
		//iFormattedLength += (iPrecision - iPos);
		iFormattedLength += iPrecision;
	}
	else
	{
		iPos = iPrecision;
		iFormattedLength += iPos;
	}

	// Sign?
	if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }

	// Right-aligned
	if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN)
	{
		// Spaces, if need
		if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
	}

	// Sign
	if      (bIsNegative)              { oBuffer.Append(1, '-'); }
	else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); }
	else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); }

	// Value
	oBuffer.Append(szBuffer, 1);
	oBuffer.Append(1, '.');
	oBuffer.Append(szBuffer + 1, iPos - 1);

	// Free memory
	freedtoa(&aBlocks);

	// Zeroes, if need
	if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); }
	// Exponent
	oBuffer.Append(szExponentBuffer + C_INT_BUFFER_LEN - iExponentPos, iExponentPos);

	// Left-aligned
	if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN)
	{
		// Spaces, if need
		if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
	}
}
예제 #29
0
//
// Integer
//
static void FmtInt(StringBuffer        & oBuffer,
                   const CDT           & oCurrentArgument,
                   const UINT_32         iFmtFlags,
                   const eFmtLengths   & oFmtLengths,
                   CCHAR_P               szDigits,
                   const eFmtSpecifier & oFmtSpecifier,
                   const INT_32          iRadix,
                   INT_32                iWidth,
                   INT_32                iPrecision,
                   CHAR_8                chPadSymbol)
{
	if (iWidth < 0)     { iWidth = 0; }
	if (iPrecision < 0) { iPrecision = 0; }

	CHAR_8 szBuffer[C_INT_BUFFER_LEN + 1];
	szBuffer[C_INT_BUFFER_LEN] = 0;
	INT_32 iPos      = 0;
	bool bIsNegative = false;
	// Signed
	if (oFmtSpecifier == F_DECIMAL)
	{
		switch (oFmtLengths)
		{
			case F_NONE:
			case F_LONG:
				iPos = DoFormat<INT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_SHORT:
				iPos = DoFormat<INT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_LONG_LONG:
				iPos = DoFormat<INT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
		}
	}
	// Unsigned, hex, octal
	else
	{
		switch (oFmtLengths)
		{
			case F_NONE:
			case F_LONG:
				iPos = DoFormat<UINT_32>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_SHORT:
				iPos = DoFormat<UINT_16>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
			case F_LONG_LONG:
				iPos = DoFormat<UINT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
				break;
		}
	}

	UINT_32 iBufferPos = C_INT_BUFFER_LEN - iPos;
	// Left-aligned output
	if (iFmtFlags & F_LEFT_ALIGN || chPadSymbol == '0')
	{
		// Sign
		if      (bIsNegative)              { oBuffer.Append(1, '-'); --iWidth; }
		else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
		else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }

		// Hash
		if (iFmtFlags & F_HASH_SIGN)
		{
			if      (oFmtSpecifier == F_OCTAL)
			{
				oBuffer.Append(1, '0');
			}
			else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
			{
				oBuffer.Append(1, '0');
				oBuffer.Append(1, szDigits[16]);
			}
		}

		// Zeroes, if need
		if (iPrecision > iPos)
		{
			iWidth -= (iPrecision - iPos);
			oBuffer.Append(iPrecision - iPos, '0');
		}

		if (chPadSymbol == '0')
		{
			// Spaces, if need
			if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, '0'); }
			// Value
			oBuffer.Append(szBuffer + iBufferPos, iPos);
		}
		else
		{
			// Value
			oBuffer.Append(szBuffer + iBufferPos, iPos);
			// Spaces, if need
			if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, ' '); }
		}
		return;
	}

	// Right-aligned
	INT_32 iFormattedLength = iPos;

	// Precision
	if (iPrecision > iPos)
	{
		iFormattedLength += (iPrecision - iPos);
	}

	// Sign?
	if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }

	// Hash
	if (iFmtFlags & F_HASH_SIGN)
	{
		if      (oFmtSpecifier == F_OCTAL)   { ++iFormattedLength; }
		else if (oFmtSpecifier == F_HEX ||
		         oFmtSpecifier == F_POINTER) { iFormattedLength += 2; }
	}

	// Spaces, if need
	if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }

	// Sign
	if      (bIsNegative)              { oBuffer.Append(1, '-'); --iWidth; }
	else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
	else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }

	// Hash
	if (iFmtFlags & F_HASH_SIGN)
	{
		if      (oFmtSpecifier == F_OCTAL)
		{
			oBuffer.Append(1, '0');
		}
		else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
		{
			oBuffer.Append(1, '0');
			oBuffer.Append(1, szDigits[16]);
		}
	}

	if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); }
	// Value
	oBuffer.Append(szBuffer + iBufferPos, iPos);
}
예제 #30
0
// @Override
ECode CWifiInfo::ToString(
    /* [out] */ String* str)
{
    StringBuffer sb;
    String none("<none>");

    sb.Append("SSID: ");
    String sidStr;
    mWifiSsid->ToString(&sidStr);
    sb.Append(mWifiSsid == NULL ? IWifiSsid::NONE : sidStr);
    sb.Append(", BSSID: ");
    sb.Append(mBSSID.IsNull() ? none : mBSSID);
    sb.Append(", MAC: ");
    sb.Append(mMacAddress.IsNull() ? none : mMacAddress);
    sb.Append(", Supplicant state: ");
    if (mSupplicantState == NULL) sb.Append(none);
    sb.Append(mSupplicantState);
    sb.Append(", RSSI: ");
    sb.Append(mRssi);
    sb.Append(", Link speed: ");
    sb.Append(mLinkSpeed);
    sb.Append(", Net ID: ");
    sb.Append(mNetworkId);
    sb.Append(", Metered hint: ");
    sb.AppendBoolean(mMeteredHint);

    *str = sb.ToString();
    return NOERROR;
}