1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/securityanddataprivacytools/securitytools/certapp/encdec/encdec.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,858 @@
1.4 +/*
1.5 +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include "encdec.h"
1.23 +#include <sstream>
1.24 +#include <errno.h>
1.25 +#include <s32ucmp.h>
1.26 +#include "stringconv.h"
1.27 +#include <stdio.h>
1.28 +#include "x509utils.h"
1.29 +
1.30 +RDecodeReadStream::RDecodeReadStream(CFileStore *aStore, RReadStream &aReadStream)
1.31 + : iStore(aStore), iCertBaseName(), iReadStream(aReadStream), iHumanReadable(false), iToken(),
1.32 + iPrefetchedTokenIsValid(false), iPrefetchedToken()
1.33 +{
1.34 +}
1.35 +
1.36 +RDecodeReadStream::RDecodeReadStream(const std::string &aCertBaseName, RReadStream &aReadStream)
1.37 + : iStore(0), iCertBaseName(aCertBaseName), iReadStream(aReadStream), iHumanReadable(true), iToken(),
1.38 + iPrefetchedTokenIsValid(false), iPrefetchedToken()
1.39 +{
1.40 +}
1.41 +
1.42 +void RDecodeReadStream::RawRead(void *aPtr, TUint32 aLength)
1.43 +{
1.44 + iReadStream.ReadL((TUint8 *)aPtr, aLength);
1.45 +}
1.46 +
1.47 +void RDecodeReadStream::CheckName(const std::string &aExpected)
1.48 +{
1.49 + ReadNextToken();
1.50 +
1.51 + if(iToken != aExpected)
1.52 + {
1.53 + dbg << Log::Indent() << "Expected token '" << aExpected <<"' but got token '" << iToken << "'" << Log::Endl();
1.54 + FatalError();
1.55 + }
1.56 +
1.57 +}
1.58 +
1.59 +TUint32 ReadUnsignedNumber(std::string &aStr, size_t aSize)
1.60 +{
1.61 + TUint32 val;
1.62 + std::istringstream ss(aStr);
1.63 +
1.64 + if((aStr.length() > 2) &&
1.65 + (aStr[0] == '0') &&
1.66 + ((aStr[1] == 'x') || (aStr[1] == 'X')))
1.67 + {
1.68 + // Hex number starting with 0x
1.69 + char ch;
1.70 + ss >> ch >> ch; // Discard the 0x
1.71 + ss >> std::hex >> val;
1.72 + }
1.73 + else
1.74 + {
1.75 + // Decimal number
1.76 + ss >> val;
1.77 + }
1.78 +
1.79 + // Now work out if we consumed the entire token without error
1.80 + if(ss.fail())
1.81 + {
1.82 + // Number decode failed
1.83 + dbg << Log::Indent() << "Failed to decode '" << aStr << "' as a number" << Log::Endl();
1.84 + FatalError();
1.85 + }
1.86 +
1.87 + // Make sure we consumed all data
1.88 + if(! ss.eof())
1.89 + {
1.90 + // Trailing chars on numeric token
1.91 + FatalError();
1.92 + }
1.93 +
1.94 + if(aSize != 4)
1.95 + {
1.96 + // Check range
1.97 + // nb the following check would fail if aSize==4 because x>>32 == x if sizeof(x)==4
1.98 + if((val >> (8*aSize)) != 0)
1.99 + {
1.100 + // Higher order bits are set above the size of the variable we
1.101 + // are returning into
1.102 + FatalError();
1.103 + }
1.104 + }
1.105 +return val;
1.106 +}
1.107 +
1.108 +
1.109 +TUint32 RDecodeReadStream::ReadUnsignedNumber(size_t aSize)
1.110 +{
1.111 +BULLSEYE_OFF
1.112 + if((TUint32(aSize)>4))
1.113 + {
1.114 + FatalError();
1.115 + }
1.116 +BULLSEYE_RESTORE
1.117 +
1.118 + ReadNextToken();
1.119 +
1.120 + return ::ReadUnsignedNumber(iToken, aSize);
1.121 +}
1.122 +
1.123 +const std::string &RDecodeReadStream::Token() const
1.124 +{
1.125 + return iToken;
1.126 +}
1.127 +
1.128 +void RDecodeReadStream::ReadNextToken()
1.129 +{
1.130 + if(iPrefetchedTokenIsValid)
1.131 + {
1.132 + // Copy prefetched token to current token
1.133 + iToken = iPrefetchedToken;
1.134 + iPrefetchedToken.clear();
1.135 + iPrefetchedTokenIsValid = false;
1.136 + return;
1.137 + }
1.138 +
1.139 + GetToken(iToken);
1.140 +}
1.141 +
1.142 +const std::string &RDecodeReadStream::PeakToken()
1.143 +{
1.144 + if(!iPrefetchedTokenIsValid)
1.145 + {
1.146 + GetToken(iPrefetchedToken);
1.147 + iPrefetchedTokenIsValid = true;
1.148 + }
1.149 +
1.150 + return iPrefetchedToken;
1.151 +}
1.152 +
1.153 +
1.154 +
1.155 +
1.156 +
1.157 +bool RDecodeReadStream::HumanReadable() const
1.158 +{
1.159 + return iHumanReadable;
1.160 +}
1.161 +
1.162 +
1.163 +void RDecodeReadStream::Close()
1.164 +{
1.165 + iReadStream.Close();
1.166 +}
1.167 +
1.168 +void RDecodeReadStream::GetToken(std::string &aToken)
1.169 +{
1.170 + aToken.clear();
1.171 +
1.172 + TUint8 ch;
1.173 + do
1.174 + {
1.175 + iReadStream >> ch;
1.176 + if(ch == '#')
1.177 + {
1.178 + // Skip comment
1.179 + ++ch;
1.180 + while((ch != '\r') && (ch != '\n'))
1.181 + {
1.182 + iReadStream >> ch;
1.183 + }
1.184 +
1.185 + }
1.186 + } while((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'));
1.187 +
1.188 + if(ch == '"')
1.189 + {
1.190 + // Read a string
1.191 + iReadStream >> ch; // read first char
1.192 + while(ch != '"')
1.193 + {
1.194 + if(ch=='\\')
1.195 + {
1.196 + // \X causes X to always be saved (even if X is ")
1.197 + iReadStream >> ch;
1.198 + }
1.199 +
1.200 + aToken.push_back(ch);
1.201 + iReadStream >> ch;
1.202 + }
1.203 + // At this point ch contains WS so it can be discarded.
1.204 + return;
1.205 + }
1.206 +
1.207 + // Read a non-string token
1.208 + while((ch != ' ') && (ch != '\t') && (ch != '\r') && (ch != '\n'))
1.209 + {
1.210 + aToken.push_back(ch);
1.211 + iReadStream >> ch;
1.212 + }
1.213 + // At this point ch contains WS so it can be discarded.
1.214 + return;
1.215 +}
1.216 +
1.217 +
1.218 +
1.219 +
1.220 +
1.221 +REncodeWriteStream::REncodeWriteStream(CFileStore *aStore, RWriteStream &aWriteStream)
1.222 + : iStore(aStore),
1.223 + iCertBaseName(), // not used for STORE based streams
1.224 + iWriteStream(&aWriteStream),
1.225 + iLogStream(0),
1.226 + iHumanReadable(false), iPemOut(false), iVerbose(false), iIndentLevel(0)
1.227 +{
1.228 +}
1.229 +
1.230 +REncodeWriteStream::REncodeWriteStream(const std::string &aCertBaseName, RWriteStream &aWriteStream)
1.231 + : iStore(0), iCertBaseName(aCertBaseName), iWriteStream(&aWriteStream),
1.232 + iLogStream(0),
1.233 + iHumanReadable(true), iPemOut(false), iVerbose(false), iIndentLevel(0)
1.234 +{
1.235 +}
1.236 +
1.237 +REncodeWriteStream::REncodeWriteStream(Log &aLog)
1.238 + : iStore(0), iWriteStream(0), iLogStream(&aLog.Stream()),
1.239 + iHumanReadable(true), iPemOut(false), iVerbose(false), iIndentLevel(aLog.IndentLevel())
1.240 +{
1.241 +}
1.242 +
1.243 +void REncodeWriteStream::WriteBin(const void *aPtr, TUint32 aLength)
1.244 +{
1.245 + if(iWriteStream)
1.246 + {
1.247 + iWriteStream->WriteL((TUint8 *)aPtr, aLength);
1.248 + }
1.249 + if(iLogStream)
1.250 + {
1.251 + iLogStream->write((const char *)aPtr, aLength);
1.252 + iLogStream->flush();
1.253 + }
1.254 +}
1.255 +
1.256 +void REncodeWriteStream::WriteQuotedUtf8(const void *aStr, TUint32 aLength)
1.257 +{
1.258 + std::string tmp((const char *)aStr, aLength);
1.259 +
1.260 + // Insert a backslash before any backslash chars
1.261 + size_t pos = 0;
1.262 + while((pos = tmp.find('\\', pos)) != std::string::npos)
1.263 + {
1.264 + tmp.insert(pos, "\\", 1);
1.265 + pos += 2;
1.266 + }
1.267 +
1.268 + // Insert a backslash before any double quote chars
1.269 + pos = 0;
1.270 + while((pos = tmp.find('"', pos)) != std::string::npos)
1.271 + {
1.272 + tmp.insert(pos, "\\", 1);
1.273 + pos += 2;
1.274 + }
1.275 +
1.276 + if(iWriteStream)
1.277 + {
1.278 + iWriteStream->WriteL((TUint8 *)tmp.data(), tmp.size());
1.279 + }
1.280 + if(iLogStream)
1.281 + {
1.282 + iLogStream->write(tmp.data(), tmp.size());
1.283 + iLogStream->flush();
1.284 + }
1.285 +}
1.286 +
1.287 +void REncodeWriteStream::WriteByte(TUint8 aByte)
1.288 +{
1.289 + WriteBin(&aByte, 1);
1.290 +}
1.291 +
1.292 +void REncodeWriteStream::WriteCStr(const void *aCstr)
1.293 +{
1.294 + WriteBin(aCstr, strlen((const char *)aCstr));
1.295 +}
1.296 +
1.297 +void REncodeWriteStream::WriteHexNumber(TUint32 aNumber)
1.298 +{
1.299 + char buf[20];
1.300 + int len = sprintf(buf, "0x%x", aNumber);
1.301 + WriteBin(buf, len);
1.302 +}
1.303 +
1.304 +
1.305 +void REncodeWriteStream::WriteSpace()
1.306 +{
1.307 +BULLSEYE_OFF
1.308 + if(!iHumanReadable) return;
1.309 +BULLSEYE_RESTORE
1.310 + WriteByte(' ');
1.311 +}
1.312 +
1.313 +void REncodeWriteStream::WriteLineEnd()
1.314 +{
1.315 +BULLSEYE_OFF
1.316 + if(!iHumanReadable) return;
1.317 +BULLSEYE_RESTORE
1.318 +#ifdef linux
1.319 + WriteByte('\n');
1.320 +#else
1.321 + WriteBin("\r\n", 2);
1.322 +#endif
1.323 +}
1.324 +
1.325 +
1.326 +void REncodeWriteStream::WriteIndent()
1.327 +{
1.328 +BULLSEYE_OFF
1.329 + if(!iHumanReadable) return;
1.330 +BULLSEYE_RESTORE
1.331 + for(int i=0; i<iIndentLevel; ++i)
1.332 + {
1.333 + WriteByte('\t');
1.334 + }
1.335 +}
1.336 +
1.337 +void REncodeWriteStream::IncIndent()
1.338 +{
1.339 + prog.IncIndent();
1.340 + ++iIndentLevel;
1.341 +BULLSEYE_OFF
1.342 + if(iIndentLevel < 0) FatalError();
1.343 +BULLSEYE_RESTORE
1.344 +}
1.345 +
1.346 +void REncodeWriteStream::DecIndent()
1.347 +{
1.348 + prog.DecIndent();
1.349 + --iIndentLevel;
1.350 +BULLSEYE_OFF
1.351 + if(iIndentLevel < 0) FatalError();
1.352 +BULLSEYE_RESTORE
1.353 +}
1.354 +
1.355 +bool REncodeWriteStream::HumanReadable() const
1.356 +{
1.357 + return iHumanReadable;
1.358 +}
1.359 +
1.360 +bool &REncodeWriteStream::PemOut()
1.361 +{
1.362 + return iPemOut;
1.363 +}
1.364 +
1.365 +bool &REncodeWriteStream::Verbose()
1.366 +{
1.367 + return iVerbose;
1.368 +}
1.369 +
1.370 +
1.371 +
1.372 +std::string REncodeWriteStream::CertFileName(TUint32 aFormat, TUint32 aCertNumber)
1.373 +{
1.374 + std::stringstream ss;
1.375 + ss << iCertBaseName;
1.376 + ss << "cert";
1.377 + ss << aCertNumber;
1.378 + if(aFormat == EX509Certificate)
1.379 + {
1.380 + if(iPemOut)
1.381 + {
1.382 + ss << ".pem";
1.383 + }
1.384 + else
1.385 + {
1.386 + ss << ".der";
1.387 + }
1.388 + }
1.389 + else
1.390 + {
1.391 + ss << ".dat";
1.392 + }
1.393 +
1.394 + return ss.str();
1.395 +}
1.396 +
1.397 +
1.398 +
1.399 +void REncodeWriteStream::Close()
1.400 +{
1.401 +BULLSEYE_OFF
1.402 + if(iWriteStream)
1.403 +BULLSEYE_RESTORE
1.404 + {
1.405 + iWriteStream->Close();
1.406 + }
1.407 +}
1.408 +
1.409 +CFileStore *REncodeWriteStream::StoreObject()
1.410 +{
1.411 +BULLSEYE_OFF
1.412 + if(iStore == 0) FatalError();
1.413 +BULLSEYE_RESTORE
1.414 + return iStore;
1.415 +}
1.416 +
1.417 +RWriteStream &REncodeWriteStream::StoreWriteStream()
1.418 +{
1.419 +BULLSEYE_OFF
1.420 + if(iWriteStream == 0) FatalError();
1.421 +BULLSEYE_RESTORE
1.422 + return *iWriteStream;
1.423 +}
1.424 +
1.425 +bool REncodeWriteStream::Quiet() const
1.426 +{
1.427 + return iLogStream != 0;
1.428 +}
1.429 +
1.430 +TUint8 fromHex(TUint8 ch)
1.431 + /**
1.432 + Convert a single hex char from ascii
1.433 + */
1.434 +{
1.435 + // convert to lowercase
1.436 + if((ch >= 'A') && (ch <= 'F'))
1.437 + {
1.438 + ch -= ('A' -'a');
1.439 + }
1.440 + // Handle a-f
1.441 + if((ch >= 'a') && (ch <= 'f'))
1.442 + {
1.443 + return ch - 'a' + 10;
1.444 + }
1.445 +
1.446 + // Handle 0-9
1.447 + if((ch >= '0') && (ch <= '9'))
1.448 + {
1.449 + return ch - '0';
1.450 + }
1.451 +
1.452 + // Illegal
1.453 + FatalError();
1.454 + return 0xff;
1.455 +}
1.456 +
1.457 +EncDecContainerItem::~EncDecContainerItem()
1.458 +{
1.459 +}
1.460 +
1.461 +
1.462 +#ifdef _BullseyeCoverage
1.463 +#pragma BullseyeCoverage off
1.464 +#endif
1.465 +std::string EncDecContainerItem::ItemName() const
1.466 +{
1.467 + // Should never be called
1.468 + exit(-1);
1.469 + std::string tmp;
1.470 + return tmp;
1.471 +}
1.472 +
1.473 +void EncDecContainerItem::SetItemName(const std::string &)
1.474 +{
1.475 + // Should never be called
1.476 + exit(-1);
1.477 +}
1.478 +#ifdef _BullseyeCoverage
1.479 +#pragma BullseyeCoverage restore
1.480 +#endif
1.481 +
1.482 +
1.483 +
1.484 +EncDecContainer::EncDecContainer(const char *aContainerName, EncDecContainerItemFactoryFunc *aFactory)
1.485 + : iName(aContainerName), iFactory(aFactory), iArray()
1.486 +{
1.487 +}
1.488 +
1.489 +EncDecContainer::~EncDecContainer()
1.490 +{
1.491 + reset();
1.492 +}
1.493 +
1.494 +void EncDecContainer::push_back(EncDecContainerItem *aItem)
1.495 +{
1.496 + iArray.push_back(aItem);
1.497 +}
1.498 +
1.499 +const EncDecContainerItem &EncDecContainer::operator[](TUint32 aIndex) const
1.500 +{
1.501 + return *iArray[aIndex];
1.502 +}
1.503 +
1.504 +EncDecContainerItem &EncDecContainer::operator[](TUint32 aIndex)
1.505 +{
1.506 + return *iArray[aIndex];
1.507 +}
1.508 +
1.509 +TUint32 EncDecContainer::size() const
1.510 +{
1.511 + return iArray.size();
1.512 +}
1.513 +
1.514 +void EncDecContainer::reset()
1.515 +{
1.516 + while(!iArray.empty())
1.517 + {
1.518 + EncDecContainerItem *p = iArray.back();
1.519 + iArray.pop_back();
1.520 + delete p;
1.521 + }
1.522 +}
1.523 +
1.524 +
1.525 +
1.526 +void EncDecContainer::Encode(REncodeWriteStream &aWriteStream) const
1.527 +{
1.528 + // Calculate Start/End container names
1.529 + std::string startName("Start");
1.530 + startName.append(iName);
1.531 + std::string endName("End");
1.532 + endName.append(iName);
1.533 +
1.534 + prog << Log::Indent() << "Writing " << startName << Log::Endl();
1.535 +
1.536 + TUint32 arrayLength = iArray.size();
1.537 +
1.538 + if(aWriteStream.HumanReadable())
1.539 + {
1.540 + // Human
1.541 + aWriteStream.WriteIndent();
1.542 + aWriteStream.WriteBin(startName.data(), startName.size());
1.543 + aWriteStream.WriteLineEnd();
1.544 + }
1.545 + else
1.546 + {
1.547 + // Binary
1.548 + // Write length of array
1.549 + aWriteStream.WriteBin(&arrayLength, sizeof(arrayLength));
1.550 + }
1.551 +
1.552 + aWriteStream.IncIndent();
1.553 +
1.554 + // Write array entries
1.555 + for(TUint32 i=0; i < arrayLength; ++i)
1.556 + {
1.557 + std::ostringstream entryComment;
1.558 + entryComment << "# Entry " << i+1;
1.559 + prog << Log::Indent() << entryComment.str() << Log::Endl();
1.560 +
1.561 + bool bracketItem = (iArray[i]->ItemType() != 0);
1.562 + if(aWriteStream.HumanReadable())
1.563 + {
1.564 + if(bracketItem)
1.565 + {
1.566 + std::ostringstream itemStart;
1.567 + itemStart << "Start" << iArray[i]->ItemType() << " " << iArray[i]->ItemName();
1.568 + prog << Log::Indent() << itemStart.str() << Log::Endl();
1.569 +
1.570 + aWriteStream.WriteIndent();
1.571 + aWriteStream.WriteCStr("Start");
1.572 + aWriteStream.WriteCStr(iArray[i]->ItemType());
1.573 + aWriteStream.WriteCStr(" \"");
1.574 + aWriteStream.WriteQuotedUtf8(iArray[i]->ItemName().data(), iArray[i]->ItemName().size());
1.575 + aWriteStream.WriteCStr("\"");
1.576 + aWriteStream.WriteLineEnd();
1.577 + }
1.578 + else
1.579 + {
1.580 + aWriteStream.WriteIndent();
1.581 + aWriteStream.WriteBin(entryComment.str().data(), entryComment.str().size());
1.582 + aWriteStream.WriteLineEnd();
1.583 + }
1.584 + }
1.585 + aWriteStream.IncIndent();
1.586 + iArray[i]->Encode(aWriteStream);
1.587 + aWriteStream.DecIndent();
1.588 + if(bracketItem && aWriteStream.HumanReadable())
1.589 + {
1.590 + std::ostringstream tmp;
1.591 + tmp << "End" << iArray[i]->ItemType();
1.592 +
1.593 + prog << Log::Indent() << tmp.str() << Log::Endl();
1.594 +
1.595 + aWriteStream.WriteIndent();
1.596 + aWriteStream.WriteBin(tmp.str().data(), tmp.str().size());
1.597 + aWriteStream.WriteLineEnd();
1.598 + }
1.599 + }
1.600 +
1.601 + aWriteStream.DecIndent();
1.602 +
1.603 + if(aWriteStream.HumanReadable())
1.604 + {
1.605 + // Human
1.606 + aWriteStream.WriteIndent();
1.607 + aWriteStream.WriteCStr("End");
1.608 + aWriteStream.WriteBin(iName.data(), iName.size());
1.609 + aWriteStream.WriteLineEnd();
1.610 + }
1.611 +
1.612 + prog << Log::Indent() << endName << Log::Endl();
1.613 +
1.614 + return;
1.615 +}
1.616 +
1.617 +void EncDecContainer::Decode(RDecodeReadStream &aReadStream)
1.618 +{
1.619 + // Calculate Start/End container names
1.620 + std::string startName("Start");
1.621 + startName.append(iName);
1.622 + std::string endName("End");
1.623 + endName.append(iName);
1.624 +
1.625 + prog << Log::Indent() << "Reading " << startName << Log::Endl();
1.626 +
1.627 + if(aReadStream.HumanReadable())
1.628 + {
1.629 + // Human
1.630 +
1.631 + // Check/consume container StartX
1.632 + aReadStream.CheckName(startName);
1.633 +
1.634 + prog.IncIndent();
1.635 +
1.636 + // Create items until we find the container EndX
1.637 + TUint32 entryNum=1;
1.638 + while(aReadStream.PeakToken() != endName)
1.639 + {
1.640 + // Progress message
1.641 + prog << Log::Indent() << "# Entry " << std::dec << entryNum++ << std::hex << Log::Endl();
1.642 +
1.643 + EncDecContainerItem *item = iFactory();
1.644 + bool bracketedItem = (item->ItemType() != 0);
1.645 + std::string itemName;
1.646 + if(bracketedItem && aReadStream.HumanReadable())
1.647 + {
1.648 + // Bracketed item, so read ItemType tag and ItemName
1.649 + std::string itemStart("Start");
1.650 + itemStart.append(item->ItemType());
1.651 + aReadStream.CheckName(itemStart);
1.652 + prog << Log::Indent() << itemStart;
1.653 +
1.654 + // Read item name
1.655 + aReadStream.ReadNextToken();
1.656 + itemName = aReadStream.Token();
1.657 + }
1.658 +
1.659 + prog.IncIndent();
1.660 + item->Decode(aReadStream);
1.661 + iArray.push_back(item);
1.662 + prog.DecIndent();
1.663 + if(bracketedItem && aReadStream.HumanReadable())
1.664 + {
1.665 + // Bracketed item, so read End ItemType tag
1.666 + std::string itemEnd("End");
1.667 + itemEnd.append(item->ItemType());
1.668 + aReadStream.CheckName(itemEnd);
1.669 + // and set item name
1.670 + item->SetItemName(itemName);
1.671 + }
1.672 + }
1.673 +
1.674 + // Check/consume container EndX
1.675 + aReadStream.CheckName(endName);
1.676 +
1.677 + prog.DecIndent();
1.678 + }
1.679 + else
1.680 + {
1.681 + // Binary
1.682 + // Read number of entries
1.683 + TUint32 arrayLength;
1.684 + aReadStream.RawRead(&arrayLength, sizeof(arrayLength));
1.685 +
1.686 + prog.IncIndent();
1.687 + for(TUint32 i=0; i < arrayLength; ++i)
1.688 + {
1.689 + EncDecContainerItem *item = iFactory();
1.690 + prog << Log::Indent() << "# Entry " << std::dec << i+1 << std::hex << Log::Endl();
1.691 + prog.IncIndent();
1.692 + item->Decode(aReadStream);
1.693 + prog.DecIndent();
1.694 + iArray.push_back(item);
1.695 + }
1.696 + prog.DecIndent();
1.697 + }
1.698 +
1.699 + prog << Log::Indent() << endName << Log::Endl();
1.700 +
1.701 +}
1.702 +
1.703 +
1.704 +
1.705 +
1.706 +REncodeWriteStream& operator<<(REncodeWriteStream& aStream, const EncDecContainer &aContainer)
1.707 +{
1.708 + aContainer.Encode(aStream);
1.709 + return aStream;
1.710 +}
1.711 +
1.712 +RDecodeReadStream& operator>>(RDecodeReadStream& aStream,EncDecContainer &aContainer)
1.713 +{
1.714 + aContainer.Decode(aStream);
1.715 + return aStream;
1.716 +}
1.717 +
1.718 +//
1.719 +// TUid
1.720 +//
1.721 +void EncodeHuman(REncodeWriteStream& aStream,const TUid &aUid)
1.722 +{
1.723 + aStream.WriteHexNumber(aUid.iUid);
1.724 +}
1.725 +void DecodeHuman(RDecodeReadStream& aStream,TUid &aUid)
1.726 +{
1.727 + aUid.iUid = aStream.ReadUnsignedNumber(sizeof(aUid.iUid));
1.728 +}
1.729 +
1.730 +//
1.731 +// TName
1.732 +//
1.733 +void EncodeHuman(REncodeWriteStream& aStream,const TName &aName)
1.734 +{
1.735 + // Compress the internal UTF-16 to human readable UTF-8
1.736 + ;
1.737 + TInt outputBytes = 0;
1.738 + TUint8 *outBuf = cstrFromUtf16(aName.Ptr(), aName.Length(), outputBytes);
1.739 +
1.740 + aStream.WriteByte('"');
1.741 + aStream.WriteQuotedUtf8(outBuf, outputBytes);
1.742 + aStream.WriteByte('"');
1.743 +
1.744 + delete [] outBuf;
1.745 +}
1.746 +void DecodeHuman(RDecodeReadStream& aStream,TName &aName)
1.747 +{
1.748 + aStream.ReadNextToken();
1.749 +
1.750 + // Expand UTF-8 into internal UTF-16LE representation
1.751 + TInt outputWords = 0;
1.752 + TText *outputBuf = utf16FromUtf8((const TUint8 *)aStream.Token().data(), aStream.Token().size(), outputWords);
1.753 + memcpy((void *)aName.Ptr(), outputBuf, outputWords*2);
1.754 + aName.SetLength(outputWords);
1.755 + delete [] outputBuf;
1.756 +}
1.757 +
1.758 +void readContainer(const std::string &aFileName, bool aHuman, EncDecContainer &container)
1.759 +{
1.760 + if(aHuman)
1.761 + {
1.762 + FileReadStream fileReadStream(aFileName, true);
1.763 + std::string certBaseName(aFileName);
1.764 + size_t dotLoc = certBaseName.rfind('.');
1.765 + if(dotLoc != std::string::npos)
1.766 + {
1.767 + certBaseName.erase(dotLoc);
1.768 + }
1.769 + certBaseName += '_';
1.770 + RDecodeReadStream inStream(certBaseName, fileReadStream); // human readable
1.771 + inStream >> container;
1.772 + inStream.Close();
1.773 + }
1.774 + else
1.775 + {
1.776 + RFs fs;
1.777 + User::LeaveIfError(fs.Connect());
1.778 + CleanupClosePushL(fs);
1.779 +
1.780 + CPermanentFileStore* store = CPermanentFileStore::OpenLC(fs, _L16(aFileName.c_str()),EFileShareAny | EFileRead);
1.781 + store->SetTypeL(KPermanentFileStoreLayoutUid);
1.782 +
1.783 + RStoreReadStream rootStream;
1.784 + rootStream.OpenLC(*store, store->Root());
1.785 + TUint32 dataStreamId;
1.786 + rootStream >> dataStreamId;
1.787 + CleanupStack::PopAndDestroy(&rootStream);
1.788 +
1.789 + RStoreReadStream dataStream;
1.790 + dataStream.OpenLC(*store, dataStreamId);
1.791 +
1.792 + RDecodeReadStream readStream(store, dataStream); // binary store
1.793 +
1.794 + readStream >> container;
1.795 +
1.796 + CleanupStack::PopAndDestroy(&dataStream);
1.797 + CleanupStack::PopAndDestroy(store);
1.798 + CleanupStack::PopAndDestroy(&fs);
1.799 + }
1.800 +}
1.801 +
1.802 +
1.803 +void writeContainer(const char *aFileName, bool aHuman, bool aPemOut, bool aVerbose, const EncDecContainer &container)
1.804 +{
1.805 + prog << Log::Indent() << "Writing output file '" << aFileName << "'" << Log::Endl();
1.806 + prog.IncIndent();
1.807 + if(aHuman)
1.808 + {
1.809 + FileWriteStream fileWriteStream(aFileName);
1.810 + // Calculate based name by striping last .xx extension and appending an underscore.
1.811 + std::string certBaseName(aFileName);
1.812 + size_t dotLoc = certBaseName.rfind('.');
1.813 + if(dotLoc != std::string::npos)
1.814 + {
1.815 + certBaseName.erase(dotLoc);
1.816 + }
1.817 + certBaseName += '_';
1.818 +
1.819 + REncodeWriteStream outStream(certBaseName, fileWriteStream); // human readable
1.820 + outStream.PemOut() = aPemOut;
1.821 + outStream.Verbose() = aVerbose;
1.822 + outStream << container;
1.823 + outStream.Close();
1.824 + }
1.825 + else
1.826 + {
1.827 + RFs fs;
1.828 + User::LeaveIfError(fs.Connect());
1.829 + CleanupClosePushL(fs);
1.830 +
1.831 + CFileStore* store = CPermanentFileStore::ReplaceLC(fs,_L16(aFileName),EFileShareAny | EFileRead | EFileWrite);
1.832 + store->SetTypeL(KPermanentFileStoreLayoutUid);
1.833 +
1.834 + RStoreWriteStream dataStream;
1.835 + TStreamId dataStreamId = dataStream.CreateLC(*store);
1.836 +
1.837 + REncodeWriteStream outStream(store, dataStream); // binary
1.838 + outStream << container;
1.839 + outStream.Close();
1.840 +
1.841 + dataStream.CommitL();
1.842 + dataStream.Close();
1.843 +
1.844 + RStoreWriteStream rootStream;
1.845 + TStreamId rootId = rootStream.CreateLC(*store);
1.846 + rootStream << dataStreamId;
1.847 + rootStream.CommitL();
1.848 + rootStream.Close();
1.849 +
1.850 +
1.851 + store->SetRootL(rootId);
1.852 + store->CommitL();
1.853 + CleanupStack::PopAndDestroy(&dataStream);
1.854 + CleanupStack::PopAndDestroy(store);
1.855 + CleanupStack::PopAndDestroy(&fs);
1.856 + }
1.857 + prog.DecIndent();
1.858 +}
1.859 +
1.860 +
1.861 +// End of file