porting1.cpp
来自「《UIQ 3 The Complete Guide》书的源代码」· C++ 代码 · 共 731 行 · 第 1/2 页
CPP
731 行
//
// Porting1.cpp - Porting example
//
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality.
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material.
//
#include "Porting1.h"
#include "Porting1.hrh"
#include <Porting1.rsg>
#include <QikViewBase.h>
#include <QikCommand.h>
#include <eikstart.h>
//////////////////////////////////////////////////////////////////////////////
// The application Uid here MUST match UID3 defined in the MMP file
// This is a development UID and must NOT be used in production type software
const TUid KAppSpecificUid={0xEDEAD022};
// internal secondary view id, must be unique amongst this applications views
const TUid KUidListView={0x00000001};
// views within applications are fully identified by the app Uid and secondary view id
#define KViewIdListView TVwsViewId(KAppSpecificUid,KUidListView)
//////////////////////////////////////////////////////////////////////////////////
// If we had some Windows type code to port we might define those things that are
// missing in the symbian environment...
// we need to cause Windows data types to exist.
// This can be achieved using statements such as:
typedef signed char CHAR;
typedef signed int INT;
// we need to make some of the std C like functions exist.
// one technique is to redefine the existance of functions such as:
#define strlen(arg) User::StringLength((unsigned char *)arg)
#define strcpy(arg1,arg2) Mem::Copy(arg1,arg2,User::StringLength((unsigned char *)arg2))
// a different technique is to implement the function
void* malloc(int size)
{
// this is basically what the Symbian std C library will be doing
return(User::Alloc(size));
}
void strcat(signed char* arg1,signed char* arg2)
{
// note, you will invariably need casts to cause this type of technique to clean compile.
int len=User::StringLength((unsigned char *)arg1);
Mem::Copy(arg1+len,arg2,User::StringLength((unsigned char *)arg2)+1); // incl trailing zero
}
/////////////////////////////////////////////////////////////////////////////////////////
// The Windows code can then remain unchanged...
class WindowsLikeFunctions
{
public:
CHAR* AppendString(CHAR* str1,CHAR* str2);
};
CHAR* WindowsLikeFunctions::AppendString(CHAR* str1,CHAR* str2)
// Create a new string being the concatenation of the two original strings
{
CHAR* result=(CHAR*)malloc(strlen(str1)+strlen(str2)+1);
strcpy(result,str1);
strcat(result,str2);
return(result);
}
/////////////////////////////////////////////////////////////////////////////////////////
// If we had some Palm type code to port we might define those things that are
// missing in the symbian environment...
// we need to cause Palm data types to exist.
// This can be achieved using statements such as:
typedef signed char Char;
// we need to make some of the std C like functions exist.
// one technique is to redefine the existance of functions such as:
#define StrLen(arg) User::StringLength((unsigned char *)arg)
#define StrCopy(arg1,arg2) Mem::Copy(arg1,arg2,User::StringLength((unsigned char *)arg2))
// a different technique is to implement the function
void* MemPtrNew(int size)
{
// this is basically what the Symbian std C library will be doing
return(User::Alloc(size));
}
void StrCat(signed char* arg1,signed char* arg2)
{
// note, you will invariably need casts to cause this type of technique to clean compile.
int len=User::StringLength((unsigned char *)arg1);
Mem::Copy(arg1+len,arg2,User::StringLength((unsigned char *)arg2)+1); // incl trailing zero
}
/////////////////////////////////////////////////////////////////////////////////////////
// The Palm code can then remain unchanged...
class PalmLikeFunctions
{
public:
Char* AppendString(Char* str1,Char* str2);
};
Char* PalmLikeFunctions::AppendString(Char* str1,Char* str2)
// Create a new string being the concatenation of the two original strings
{
Char* result=(Char*)MemPtrNew(StrLen(str1)+StrLen(str2)+1);
StrCopy(result,str1);
StrCat(result,str2);
return(result);
}
//////////////////////////////////////////////////////////////////////////////////
class object1
{
public:
object1();
int object1Count();
protected:
int count;
};
object1::object1()
{
count=1;
}
int object1::object1Count()
{
return(count);
}
//////////////////////////////////////////////////////////////////////////////////
class object2
{
public:
object2();
int object2Count();
protected:
int count;
};
object2::object2()
{
count=2;
}
int object2::object2Count()
{
return(count);
}
//////////////////////////////////////////////////////////////////////////////////
class object3 : public object2, public object1
{
public:
int objectCount();
};
int object3::objectCount()
{
return(object1Count()+object2Count());
}
//////////////////////////////////////////////////////////////////////////////////
class ExceptionHandling
{
protected:
void ThrowFunction(const int aVal);
public:
void TryFunction();
inline int Count() const {return(count);};
protected:
int count;
};
void ExceptionHandling::ThrowFunction(const int aVal)
{
if (aVal>5)
throw aVal;
count++;
}
void ExceptionHandling::TryFunction()
{
try
{
count=0;
for (int i=0;i<10;i++)
ThrowFunction(i);
}
catch (...)
{
count=100;
}
}
////////////////////////////////////////////////////////////////////////
// These object show how you can easily use regular C arrays in your code
// should you choose to do so. It also shows you can ignore any naming conventions
// if you want to + the code still works. However the code is not recommended
// practice and the comments give some reasons why. Different companies have
// different views on how much you should conform to standards, how well others
// in your team need to understand the code, how well external people need to
// understand the code, where documentation occurs etc so all these factors
// should be considered when deciding what rules to follow.
class DataExample1 : public CBase
{
public:
~DataExample1();
void Construct(const int smallBufSize,const int bigBufferSize);
int ProcessData(const int val);
protected:
int bufSize;
unsigned char buffer[32];
int bigBufSize;
unsigned char *bigBuffer;
};
// Note the object is derived from the CBase object, however it does not start
// with the letter C. Information has been lost as to what can be done with the
// object, where its ultimately derived from etc. If the object name started
// with a 'C' then any experianced Symbian programmmer will assume it derived
// from CBase and knows without reference to the declaration various attributes
// of the object. This saves time (hence money) when code is reviewed,
// handled by non authors, external programmers etc.
DataExample1::~DataExample1()
{
User::Free(bigBuffer);
}
void DataExample1::Construct(const int smallBufSize,const int bigBufferSize)
// Initialize our object.
//
// Note that the function name does not end in an L. However we call a function
// User::AllocL(). We have lost information about what the function does and
// how it operates in error conditions. The function is no longer self documenting.
// One of the development aids - LeaveScan will report this method as being
// potentially problematic.
{
int i;
unsigned char* p;
// set up a small fixed size buffer to contain zeros.
// With no naming convention its not immediately obvious whether 'bufSize'
// is instance property, stack variable, a passed function parameter etc
bufSize=smallBufSize;
// Again with no naming conventions its not obvious where buffer[] is defined
// where bufSize is coming from etc.
p=(&buffer[0]);
for (i=0;i<bufSize;i++)
*p++=0;
// allocate a variable sized buffer + init it to contain zeros
// Note this example deliberatly uses the AllocL() variant so we
// dont have to check for NULL pointers (out of memory) being returned.
// Since 'bigBuffer' does not follow any naming conventions its not obvious
// how the ownership of the heap cell resource is being handled, and therefore
// how the resource will be freed up after usage.
bigBuffer=(unsigned char*)User::AllocL(bigBufferSize);
bigBufSize=bigBufferSize;
for (p=bigBuffer,i=0;i<bigBufferSize;i++)
*p++=0;
/*
If you used Alloc() you might do something along the lines of:
bigBuffer=(unsigned char*)User::Alloc(bigBufferSize);
if (bigBuffer)
{
bigBufSize=bigBufferSize;
for (p=bigBuffer,i=0;i<bigBufferSize;i++)
*p++=0;
}
but how are you going to deal with Out Of Memory ?. The function may have
change to return error conditions (increase code). The ProcessData()
function has to check the bigBuffer is non NULL (increase code) etc.
*/
}
int DataExample1::ProcessData(const int val)
// Locate all occurances of the indicated value in our data.
{
// in this simple example code its reasonably clear what each of the
// entity names refer to - because we can see more or less all the code.
// As soon as functions get longer than a screen full of code it becomes
// increasingly difficult to know if variable names are arguments, local
// variables, global variables, object property etc. If the only person that
// ever looks at the code is the author this may be reasonable. In most
// situations this is not going to be true so any self documentation has
// to be good.
int i;
int count=0;
for (i=0;i<bufSize;i++)
{
if (buffer[i]==val)
count++;
}
// one of a number of ways in which you could scan the alloc cell to
// count the number of occurances of the indicated value
for (i=0;i<bigBufSize;i++)
{
if (bigBuffer[i]==val)
count++;
}
/*
The same code could be implemented using a pointer - as in:
unsigned char* p=bigBuffer;
for (i=0;i<bigBufSize;i++)
{
if ((*p++)==val)
count++;
}
*/
return(count);
}
////////////////////////////////////////////////////////////////////////
// The same functionality as above - DataExample1, but this time using Symbian naming
// conventions and starting to use Symbian descriptors.
// This example is intended to show the first steps you might consider when
// trying to move from regular C arrays to using descriptors. This object does
// NOT contain recommended practice. It is intended to show how close
// descriptors and regular C arrays really are.
class CDataExample2 : public CBase
{
public:
~CDataExample2();
void ConstructL(const TInt aSmallBufSize,const TInt aBigBufferSize);
TInt ProcessData(const TInt aVal);
protected:
TBuf8<32> iBuffer; // TBuf8 is templated, the param is the size - so this is a '32 byte buffer'
HBufC8* iBigBuffer; // a descriptor we can allocate at run time - approx a 'byte ptr'
};
CDataExample2::~CDataExample2()
{
delete(iBigBuffer);
}
void CDataExample2::ConstructL(const TInt aSmallBufSize,const TInt aBigBufferSize)
//
// Notice the method name ends in an L. This documents that the method can
// 'leave'. The parameters start with 'a' (a for arguments).
// The LeaveScan tool will no longer flag this function as problematic.
//
{
TInt i;
TUint8* p;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?