sl@0: /* sl@0: * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Header STRNG.CPP sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "STRNG.H" sl@0: sl@0: extern bool OutputUnicode; sl@0: sl@0: ostream& operator << (ostream& out, const String& aString) sl@0: { sl@0: for (int i = 0; i < aString.iLength; i++) sl@0: out << aString.iText[i]; sl@0: out << '\n'; sl@0: return out; sl@0: } sl@0: sl@0: EXPORT_C void String::Externalize(ostream& out) sl@0: { sl@0: if (OutputUnicode) sl@0: { sl@0: // Convert the string to Unicode, allowing #NNNN (each N is a hex digit) sl@0: // to represent an arbitrary Unicode character. Other values are just sl@0: // extended, so don't use codepage 1252 values in the range 128..159. sl@0: unsigned short* buffer = new unsigned short[iLength]; sl@0: int i = 0; sl@0: int j = 0; sl@0: while (i < iLength) sl@0: { sl@0: if (iText[i] == '#') sl@0: { sl@0: i++; sl@0: char hex[5]; sl@0: hex[0] = iText[i++]; sl@0: hex[1] = iText[i++]; sl@0: hex[2] = iText[i++]; sl@0: hex[3] = iText[i++]; sl@0: hex[4] = 0; sl@0: buffer[j++] = (unsigned short)strtoul(hex, NULL, 16); sl@0: } sl@0: else sl@0: { sl@0: buffer[j] = iText[i]; sl@0: buffer[j] &= 0xFF; sl@0: i++; sl@0: j++; sl@0: } sl@0: } sl@0: int unicode_characters = j; sl@0: int32 length = (unicode_characters << 1); // 16-bit data sl@0: if (length < 0x80) sl@0: { sl@0: unsigned char len = (unsigned char)(length << 1); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: else if (length < 0x4000) sl@0: { sl@0: uint16 len = (uint16)((length << 2) + 1); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: else sl@0: { sl@0: // assert len<0x20000000 ? sl@0: uint32 len = (uint32)((length << 3) + 3); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: // Output Unicode characters using the Standard Compression Scheme for Unicode. sl@0: // To save the bother of doing this properly, use a degenerate form whereby each sl@0: // Unicode character is output as itself. 0x0F selects Unicode mode and 0xF0 quotes sl@0: // characters that would conflict with other tags. sl@0: out << (unsigned char)0x0F; sl@0: sl@0: for (i = 0; i < unicode_characters; i++) sl@0: { sl@0: unsigned char hi = (unsigned char)(buffer[i] >> 8); sl@0: unsigned char lo = (unsigned char)buffer[i]; sl@0: if ((hi >= 0xe0) && (hi <= 0xf2)) sl@0: out << 0xf0; sl@0: out << hi; sl@0: out << lo; sl@0: } sl@0: sl@0: delete [] buffer; sl@0: } sl@0: else sl@0: { sl@0: int32 length = (iLength << 1) + 1; // 8-bit data sl@0: if (length < 0x80) sl@0: { sl@0: unsigned char len = (unsigned char)(length << 1); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: else if (length < 0x4000) sl@0: { sl@0: uint16 len = (uint16)((length << 2) + 1); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: else sl@0: { sl@0: // assert len<0x20000000 ? sl@0: uint32 len = (uint32)((length << 3) + 3); sl@0: out.write((char*)&len, sizeof(len)); sl@0: } sl@0: out.write(iText, iLength); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C int String::CreateText(const int aLength) sl@0: { sl@0: if (aLength != iLength) sl@0: { sl@0: char* text = new char[aLength + 1]; sl@0: if (text) sl@0: { sl@0: iLength = aLength; sl@0: iText = text; sl@0: } sl@0: else sl@0: { sl@0: iLength = 0; sl@0: delete [] iText; sl@0: iText = NULL; sl@0: } sl@0: } sl@0: return iLength; sl@0: } sl@0: sl@0: EXPORT_C void String::DeleteText(char* aText) const sl@0: { sl@0: if (aText != iText) sl@0: delete [] aText; sl@0: } sl@0: sl@0: EXPORT_C String::~String() sl@0: { sl@0: delete [] iText; sl@0: }