/** * Panic is raised, if the header with other header and terminating * ' ' is > 159 characters. Then 1 byte is left for payload ! * what will be the array element type ? */ void TWapTextMessage::EncodeSegmentsL(CArrayPtr<HBufC8>& aSegmentArray) { TBuf8<KMaxSmsChars> header; // buffer for a modifiable header TInt headerLength = 0; TInt segmentNumberIndex = 0; // index of segment number field in the header TBuf8<2> hexSegmentNumber; TInt dataSegmented = 0; OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, TWAPTEXTMESSAGE_ENCODESEGMENTSL_1, "TWapTextMessage::EncodeSegmentsL()"); iSegmentNumber = 0; do { // // Create the segment and add it to the array... // HBufC8* segment = HBufC8::NewL(KMaxSmsChars); // 160 characters CleanupStack::PushL(segment); TPtr8 ptr(segment->Des()); aSegmentArray.AppendL(segment); CleanupStack::Pop(); // segment // // Calculate length of header and copy it... // if (iSegmentNumber==0) { headerLength = CreateHeader(header, segmentNumberIndex); } ptr.Copy(header); if (iTotalSegments>255) { User::Leave(KErrOverflow); } // // Set segment number... // if (segmentNumberIndex != 0) { hexSegmentNumber.NumFixedWidthUC(iSegmentNumber+1, EHex, 2); // two bytes wide ptr.Insert(segmentNumberIndex, hexSegmentNumber); } // // Count any escaped characters we can be sure that the converted data // size fits inside the remaining length (e.g. so that non-7bit characters // when converted by the SMS Stack will still fit). // TInt segmentSize = iRefData.Length() - dataSegmented; if (segmentSize > KMaxSmsChars - headerLength) { segmentSize = KMaxSmsChars - headerLength; } while (segmentSize > 1) { TPtrC8 segmentData(iRefData.Mid(dataSegmented, segmentSize)); TInt non7bitCharEscapes = 0; // // Count all non-7bit characters that will be escaped (many non-7bit // characters are not escaped, but converted to "?"). The ones // that are known to be escaped are list below: // // 12 [Form Feed]. // 91 "[" // 92 "\" // 93 "]" // 94 "^" // 123 "{" // 124 "|" // 125 "}" // 126 "~" // for (TInt ch = 0; ch < segmentSize; ch++) { if (segmentData[ch] == 12 || (segmentData[ch] >= 91 && segmentData[ch] <= 94) || (segmentData[ch] >= 123 && segmentData[ch] <= 126)) { non7bitCharEscapes++; } } // // Can it fit? If so store it, otherwise reduce the size... // if (segmentData.Length() + non7bitCharEscapes <= KMaxSmsChars - headerLength) { ptr.Append(segmentData); break; } segmentSize--; } dataSegmented += segmentSize; iSegmentNumber++; } while (dataSegmented < iRefData.Length()); __ASSERT_DEBUG(iTotalSegments == aSegmentArray.Count(), Panic(KPanicEncodingError)); } // TWapTextMessage::EncodeSegmentsL
/** * Length of header is returned * Sets internally the iTotalSegments * Does not set the segment number into the aFixedHeader * * Length of complete header is returned. * On return the header is not complete, if SAR is needed, because the segment * number is not set. Thus aFixedHeader.Length() != (return value of this function) is true. * The segment number can be set by inserting it into aSegmentNumberIndex position * If SAR is not needed aSegmentNumberIndex = 0 and * aFixedHeader.Length() == (return value of this function) is true */ TInt TWapTextMessage::CreateHeader(TDes8& aFixedHeader, TInt& aSegmentNumberIndex) { OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, TWAPTEXTMESSAGE_CREATEHEADER_1, "TWapTextMessage::CreateHeader"); // Index into KElemIndexes indicating which header elements are present TInt elemIndex; // Index into Indexes, for current header element TInt minorIndex=KIndexDestinationPort; TBuf8<4> hexNumber; // Segment number length is set, if SAR is needed TInt segmentNumberLength = 0; aSegmentNumberIndex = 0; // Determine whether long or short form is used if (iIs16Bit || iSourcePort > 255 || iDestinationPort>255) { elemIndex = 0; aFixedHeader.Copy(KSCKHeaderLong); } else { elemIndex = 3; aFixedHeader.Copy(KSCKHeaderShort); } // Set destination port hexNumber.NumFixedWidthUC(iDestinationPort,EHex, KElemIndexes[elemIndex].iIndexes[minorIndex+1]-KElemIndexes[elemIndex].iIndexes[minorIndex]); aFixedHeader.Append(hexNumber); // Don't set the source port, // 1) if it is not set or it same as destination port and // 2) data (and other header) fits in one segment if (!((iSourcePort==-1 || iDestinationPort==iSourcePort) && CalculateTotalSegments(KElemIndexes[elemIndex].iIndexes[minorIndex+1])==1)) { // Source port is present elemIndex++; minorIndex++; if (iSourcePort==-1) iSourcePort = iDestinationPort; // Set source port hexNumber.NumFixedWidthUC(iSourcePort,EHex, KElemIndexes[elemIndex].iIndexes[minorIndex+1]-KElemIndexes[elemIndex].iIndexes[minorIndex]); aFixedHeader.Append(hexNumber); // Add the SAR info when source port is set elemIndex++; // Set reference minorIndex++; hexNumber.NumFixedWidthUC(iReference,EHex, KElemIndexes[elemIndex].iIndexes[minorIndex+1]-KElemIndexes[elemIndex].iIndexes[minorIndex]); aFixedHeader.Append(hexNumber); // Set fragment count minorIndex++; CalculateTotalSegments(KElemIndexes[elemIndex].iIndexes[KElemIndexes[elemIndex].iLastIndex]); hexNumber.NumFixedWidthUC(iTotalSegments,EHex, KElemIndexes[elemIndex].iIndexes[minorIndex+1]-KElemIndexes[elemIndex].iIndexes[minorIndex]); aFixedHeader.Append(hexNumber); // Return the index for segment number in the header minorIndex++; aSegmentNumberIndex = KElemIndexes[elemIndex].iIndexes[minorIndex]; segmentNumberLength = 2; } aFixedHeader.Append(iRefOtherHeader); aFixedHeader.Append(_L(" ")); return aFixedHeader.Length()+segmentNumberLength; } // TWapTextMessage::CreateHeader