First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_pgcompr.cpp
27 #include "sf_pgcompr.h"
29 extern TInt BytePairDecompress(TUint8* /*dst*/, TInt /*dstSize*/, TUint8* /*src*/, TInt /*srcSize*/, TUint8*& /*srcNext*/);
32 // CBytePairReader - reading from in-memory buffer
35 CBytePairReader* CBytePairReader::NewLC(TUint8* aBuffer, TUint32 aLength)
37 CBytePairReader* reader = new (ELeave) CBytePairReader(aBuffer, aLength);
38 CleanupStack::PushL(reader);
43 CBytePairReader::CBytePairReader(TUint8* aBuffer, TUint32 aLength)
44 : iNextPage(aBuffer), iBytesLeft(aLength)
49 void CBytePairReader::SeekForwardL(TUint aBytes)
51 if (iBytesLeft < aBytes)
52 LEAVE_FAILURE(KErrCorrupt);
58 void CBytePairReader::ReadInTableL()
60 if (KIndexTableHeaderSize > iBytesLeft)
61 LEAVE_FAILURE(KErrCorrupt);
62 Mem::Copy(&iHeader, iNextPage, KIndexTableHeaderSize);
63 iNextPage += KIndexTableHeaderSize;
64 iBytesLeft -= KIndexTableHeaderSize;
66 __IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
68 TUint size = iHeader.iNumberOfPages * sizeof(TUint16);
69 if (size > iBytesLeft)
70 LEAVE_FAILURE(KErrCorrupt);
71 // coverity[buffer_alloc]
72 iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
73 Mem::Copy(iIndexTable, iNextPage, size);
79 void CBytePairReader::ReleaseTable()
86 TUint CBytePairReader::GetPageL(TUint aPageNum, TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
88 if (iIndexTable[aPageNum] > iBytesLeft)
89 LEAVE_FAILURE(KErrCorrupt);
90 iBytesLeft -= iIndexTable[aPageNum];
91 aLength = Min(aLength, KBytePairPageSize);
97 size = BytePairDecompress(iPageBuf, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
99 size = BytePairDecompress(aTarget, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
101 User::LeaveIfError(size);
103 LEAVE_FAILURE(KErrCorrupt);
104 if (iNextPage + iIndexTable[aPageNum] != nextPage)
105 LEAVE_FAILURE(KErrCorrupt);
107 // If a memmove() was provided, use that to copy the data to its final target
109 aMemMoveFn(aTarget, iPageBuf, size);
111 iNextPage = nextPage;
116 TUint CBytePairReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
118 TUint decompressedSize = 0;
122 for (TUint curPage = 0; curPage < iHeader.iNumberOfPages; ++curPage)
124 TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
126 decompressedSize += size;
130 __IF_DEBUG(Printf("decomp page size:%d\n", size ));
133 __IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
137 return decompressedSize;
141 void CBytePairReader::GetPageOffsetsL(TInt32 aInitialOffset, TInt& aPageCount, TInt32*& aPageOffsets)
144 aPageCount = iHeader.iNumberOfPages;
145 aPageOffsets = new (ELeave) TInt32[aPageCount+1];
147 TInt bytes = aInitialOffset + KIndexTableHeaderSize + aPageCount * sizeof(TUint16);
148 for (TInt i = 0; i < aPageCount; ++i)
150 aPageOffsets[i] = bytes;
151 bytes += iIndexTable[i];
153 aPageOffsets[aPageCount] = bytes;
159 // CBytePairFileReader - reading from file
162 CBytePairFileReader* CBytePairFileReader::NewLC(RFile& aFile)
164 CBytePairFileReader* reader = new (ELeave) CBytePairFileReader(aFile);
165 CleanupStack::PushL(reader);
170 CBytePairFileReader::CBytePairFileReader(RFile& aFile)
171 : CBytePairReader(NULL, 0), iFile(aFile)
176 CBytePairFileReader::~CBytePairFileReader()
182 void CBytePairFileReader::SeekForwardL(TUint aBytes)
185 User::LeaveIfError(iFile.Seek(ESeekCurrent, bytes));
189 void CBytePairFileReader::ReadInTableL()
191 TPtr8 header((TUint8*)&iHeader, KIndexTableHeaderSize);
192 User::LeaveIfError(iFile.Read(header, KIndexTableHeaderSize));
193 if (header.Length() != (TInt)KIndexTableHeaderSize)
194 LEAVE_FAILURE(KErrCorrupt);
196 __IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
198 TInt size = iHeader.iNumberOfPages * sizeof(TUint16);
199 iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
200 TPtr8 indexTable((TUint8*)iIndexTable, size);
201 User::LeaveIfError(iFile.Read(indexTable, size));
202 if (indexTable.Length() != size)
203 LEAVE_FAILURE(KErrCorrupt);
207 TUint CBytePairFileReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
209 TUint decompressedSize = 0;
214 while (curPage < iHeader.iNumberOfPages)
218 while (curPage + pages < iHeader.iNumberOfPages &&
219 bytes + iIndexTable[curPage+pages] < sizeof(iBuffer))
221 bytes += iIndexTable[curPage+pages];
225 LEAVE_FAILURE(KErrCorrupt);
226 TPtr8 data(iBuffer, bytes);
227 User::LeaveIfError(iFile.Read(data, bytes));
228 if (data.Length() != (TInt)bytes)
229 LEAVE_FAILURE(KErrCorrupt);
233 for (; pages; ++curPage, --pages)
235 TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
237 decompressedSize += size;
241 __IF_DEBUG(Printf("decomp page size:%d\n", size ));
245 __IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
249 return decompressedSize;