--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/clogger/inc/SensibleFormat.h Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,145 @@
+// SensibleFormat.h
+//
+// Copyright (c) 2006 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+// The purpose of this file is to define a generic format command that works reasonably even when there's no heap free
+// Because it uses a stack buffer in this case, it is very difficult to make this a generic function without macroing
+
+// Because I needed a 16-bit variant as well, and even templating would generate the same amount of code, I've done it
+// as a #includable code snippet
+
+// Note: If you do define SF_WIDE, Collapse() will be called on the result of the format before being passed to SF_ACTION
+
+// If you want to pass in a VA_LIST, then #define SF_LIST aArgList
+// If you want to pass in a bunch of arguments, #define SF_ARGLIST arg1,arg2,arg3
+
+#if !defined(SF_FORMAT) || !defined(SF_BUF) || !defined(SF_ACTION)
+#error "you must define all of SF_FORMAT, SF_BUF and SF_ACTION before including this file"
+#endif
+
+#if !((defined(SF_LIST) && !defined(SF_ARGLIST)) || (!defined(SF_LIST) && defined(SF_ARGLIST)))
+#error "you must define exactly one of SF_LIST and SF_ARGLIST before including this file"
+#endif
+
+#ifndef COMMON_H
+#error "you need to include common.h somewhere before including this file"
+#endif
+
+#ifdef SF_WIDE
+#define TOverflowX TOverflow16
+#define TBufX TBuf16<256>
+#else
+#define TOverflowX TOverflow8
+#define TBufX TBuf8<256>
+#endif
+
+#ifdef SF_ARGLIST
+#define SFAppend() AppendFormat(SF_FORMAT, &overflow, SF_ARGLIST)
+#else
+#define SFAppend() AppendFormatList(SF_FORMAT, SF_LIST, &overflow)
+#endif
+
+// Think of this as Format(RBuf8& SF_BUF, FunctionPointer SF_ACTION, const TDesCX& SF_FORMAT, TBool SF_STACKONLY, VA_LIST SF_LIST)
+// where SF_ACTION(SF_BUF) is called passing in the fully formatted string
+ {
+ const TInt minBufSize = Max(SF_BUF.MaxSize(), 512);
+ const TInt KMaxBufSize = 8192;
+ TInt err = KErrNone;
+
+#ifdef SF_STACKONLY
+ if (SF_STACKONLY)
+ {
+ err = KErrNoMemory;
+ }
+ else
+#endif
+ {
+ if (SF_BUF.MaxSize() == 0)
+ {
+ err = SF_BUF.Create(256);
+ }
+ else
+ {
+ SF_BUF.Zero();
+ }
+ }
+
+ TOverflowX overflow;
+ if (err == KErrNone)
+ {
+ // Do clever things to try and ensure that the format string won't be truncated, while at the same time not allocating an insanely big buffer
+ for (TInt bufSize = minBufSize; bufSize <= KMaxBufSize; bufSize*=2)
+ {
+ #ifdef SF_WIDE
+ TPtr16 widePtr((TUint16*)SF_BUF.Ptr(), SF_BUF.MaxSize()/2);
+ widePtr.SFAppend();
+ #else
+ SF_BUF.SFAppend();
+ #endif
+ if (!overflow.iOverflow)
+ {
+ // Then the format went ok
+ #ifdef SF_WIDE
+ TPtr8 collapsed = widePtr.Collapse();
+ SF_ACTION(collapsed);
+ #else
+ SF_ACTION(SF_BUF);
+ #endif
+ break;
+ }
+ else
+ {
+ // Overflowed
+
+ if (bufSize == KMaxBufSize)
+ {
+ // We've grown up to our (self-imposed) max buf size, so just live with the truncation
+ #ifdef SF_WIDE
+ TPtr8 collapsed = widePtr.Collapse();
+ SF_ACTION(collapsed);
+ #else
+ SF_ACTION(SF_BUF);
+ #endif
+ break;
+ }
+
+ // Try and grow
+ SF_BUF.Close();
+ err = SF_BUF.Create(bufSize*2);
+ if (err) break;
+ else continue;
+ }
+ }
+ }
+ if (err)
+ {
+ // Last resort, use 256 char buf on the stack
+ TBufX stackBuf;
+ stackBuf.SFAppend(); // Silently truncate if overflow happens now
+ #ifdef SF_WIDE
+ TPtr8 collapsed = stackBuf.Collapse();
+ SF_ACTION(collapsed);
+ #else
+ SF_ACTION(stackBuf);
+ #endif
+ }
+ }
+
+#undef SF_WIDE
+#undef SF_FORMAT
+#undef SF_LIST
+#undef SF_ARGLIST
+#undef SF_BUF
+#undef SF_ACTION
+#undef TBufX
+#undef TOverflowX
+#undef SFAppend
+#undef SF_STACKONLY