UML软件工程组织

Figure 2 FormatResults.cpp
////////////////
// 将匹配结果格式化为 MFC CString。
// 来自 RegexTest 未使用包装器的原来版本。
// 示范一种灵巧的方式来调用使用托管扩展的托管对象。
//
CString FormatResults(LPCTSTR lpszRegex, LPCTSTR lpszInput)
{
   CString result;
   CString temp;
   Regex* r = new Regex(lpszRegex);
   MatchCollection* mc = r->Matches(lpszInput);
   int n = mc->Count;
   temp.Format(_T("Number of Matches: %d\n"), n);
   result += temp;
   for (int i=0; i<n; i++) {    // for each lpszInput:
      Match *m = mc->Item[i];
      temp.Format(_T("Match %d at %d: %s\n"), i, m->Index, 
         CString(m->Value));
      result += temp;

      // Show groups
      GroupCollection *gc = m->Groups;
      for (int j=0; j<gc->Count; j++) {
         Group *g = gc->Item[j];
         if (g->Success) {
            temp.Format(_T(" Group %d match at %d: %s\n"), j, g->Index, 
               CString(g->Value));
         } else {
            temp.Format(_T(" Group %d failure\n"), j);
         }
         result += temp;
      }

      // Show captures
      CaptureCollection *cc = m->Captures;
      for (j=0; j<cc->Count; j++) {
         Capture *c = cc->Item[j];
         temp.Format(_T(" Capture at %d: %s\n"), c->Index, 
            CString(c->Value));
         result += temp;
      }
      result += _T("\n");
   }

   // Use Regex to convert all newlines to \r\n for edit control
   r = new Regex("\n");
   result = r->Replace(result,"\r\n");

   return result;
}

Figure 4 CMObject—First Pass
//////////////////
// 实现  CMObject 的首要企图, 所有包装器的基类。
// 类声明 — .h 文件
//
class CMObject {
protected:
   gcroot<Object*> m_handle; // handle to managed object
public:
   // fns whose signatures use managed types
   CMObject(Object* o) : m_handle(o) { }
   Object* ThisObject() const { return (Object*)m_handle; }
   Object* operator->() const { return ThisObject(); }

   // fns whose signatures use native types
   CMObject() { }
   CMObject(const CMObject& o) : m_handle(o.m_handle) { }
   CMObject& operator=(const CMObject& r) {
      m_handle = r.m_handle;  // copies underlying GCHandle.Target
      return *this;
   }

   // wrapped methods/properties
   CString ToString() const {
      return (*this)->ToString();
   }
};

Figure 5 CMObject

CMObject.h
//////////////////
// Object 包装器, .NET 类层次的基类。
// CMObject 不使用 DECLARE_WRAPPER,因为它没有基类。
//
class CMObject {
protected:
   GCHANDLE(Object*) m_handle;
public:
#ifdef _MANAGED
   // visible to managed clients only: anything that deals with __gc 
   // objects
   CMObject(Object* o) : m_handle(o) { }
   Object* ThisObject() const { return (Object*)m_handle; }
   Object* operator->() const { return ThisObject(); }
#endif
   // visible to all clients
   CMObject();
   CMObject(const CMObject& o);
   BOOL operator==(const CMObject& r) const;
   BOOL operator!=(const CMObject& r) const { return ! operator==(r); }
   CMObject& operator=(const CMObject& r);
   CString ToString() const;
   CString TypeName() const;
};
CMObject.cpp
////////////////
// CMObject 实现, 来自 ManWrap.cpp
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//

CMObject::CMObject()
{
   // default ctor must be here and not inline, so m_handle is 
   // appropriately initialized to a NULL GCHandle. Otherwise it will 
   // have unpredictable values since native code sees it as intptr_t
}

CMObject::CMObject(const CMObject& o) : m_handle(o.m_handle)
{
   // See remarks above
}

CMObject& CMObject::operator=(const CMObject& r)
{
   m_handle = r.m_handle;  // copies underlying GCHandle.Target
   return *this;
}

BOOL CMObject::operator==(const CMObject& r) const
{
   return (*this)->Equals(r.ThisObject());
}

CString CMObject::ToString() const
{
   return (*this)->ToString();
}

CString CMObject::TypeName() const
{
   return (*this)->GetType()->Name;
}

Figure 6 declare_wrapper.h
// DECLARE_WRAPPER macro from ManWrap.h

#ifdef _MANAGED
// 此声明为 DECLARE_WRAPPER 的托管部分。仅内部使用。
// 使用 DECLARE_WRAPPER。
//
#define DECLARE_WRAPPER_M(MT,BT)                            \
public:                                                     \
   CM##MT(MT* o) : CM##BT(o) { }                            \
   MT* ThisObject() const                                   \
   {                                                        \
      return static_cast<MT*>((Object*)m_handle);           \
   }                                                        \
   MT* operator->() const                                   \
   {                                                        \
      return ThisObject();                                  \
   }                                                        \
   CM##MT& operator=(MT* o)                                 \
   {                                                        \
      m_handle = o;                                         \
      return *this;                                         \
   }                                                        \

#else // NOT _MANAGED

// 本机代码不可见的托管机制: 这个宏什么也不做
#define DECLARE_WRAPPER_M(MT,BT)

#endif // _MANAGED

//////////////////
// 用来的、声明包装器类。声明需要基本的构造函数和操作符,使用时要想类型安全这是必须的。
// MT=托管类型, BT=基(托管)类型。
// 你必须遵循的命名规范:CMFoo = Foo 的包装器。
//
#define DECLARE_WRAPPER(MT,BT)                              \
public:                                                     \
   CM##MT() { }                                             \
   CM##MT(const CM##MT& o) : CM##BT(o) { }                  \
   CM##MT& operator=(const CM##MT &r)                       \
   {                                                        \
      CM##BT::operator=(r);                                 \
      return *this;                                         \
   }                                                        \
   DECLARE_WRAPPER_M(MT,BT)                                 \

Figure 7 RegexWrap.h
////////////////////////////////////////////////////////////////
// MSDN Magazine — February 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//

// 该文件声明 RegexWrap 所有包装器。实现部分在 RegexWrap.cpp。
//
#pragma once
#include "ManWrap.h"
#ifdef _MANAGED
using namespace System::Runtime::InteropServices;
using namespace System::Text::RegularExpressions;
#endif

//////////////////
// 为了初始化 RegexWrap.dll,在调用任何 RegexWrap DLL 函数之前,
// 你必须在应用程序的某个地方实例化其中之一。
// 使用托管扩展的 DLLs 以及 MFN/ATL 需要进行专门初始化,因为它们不
// 使用调用 DllMain 的标准启动代码。最好是在函数范围之外的某个地方或者
// 是在CWinApp派生的应用程序类(MFC)中创建一个静态实例。
//
class WREXPORT CRegexWrapInit {
public:
   CRegexWrapInit();
   ~CRegexWrapInit();
};

//////////////////
// Wrapper for .NET Capture class
//
class WREXPORT CMCapture : public CMObject
{
   DECLARE_WRAPPER(Capture, Object);
public:
   // wrapped properties/methods
   int Index() const;
   int Length() const;
   CString Value() const;
};

//////////////////
// Wrapper for Group.
//
class WREXPORT CMGroup : public CMCapture
{
   DECLARE_WRAPPER(Group, Capture);
public:
   // wrapped properties/methods
   bool Success() const;
   CMCaptureCollection Captures() const;
};

//////////////////
// Wrapper for Match.
//
class WREXPORT CMMatch : public CMGroup
{
   DECLARE_WRAPPER(Match, Group);
public:
   // wrapped properties/methods
   CMMatch NextMatch() const;
   CString Result(CString sReplace) const;
   CMGroupCollection Groups() const;
   static const CMMatch Empty; // constant empty match
   typedef CString (CALLBACK* evaluator)(const CMMatch&, void* param);
};

//////////////////
// Regex 包装器. 所有好东东都在这里。
//
class WREXPORT CMRegex : public CMObject {
   DECLARE_WRAPPER(Regex,Object);
public:
   enum Options {
      None = 0,
      .
      .
   };

   CMRegex(LPCTSTR s);
   CMRegex(LPCTSTR s, Options opt);
   CMMatch Match(LPCTSTR input);
   static CMMatch Match(LPCTSTR input, LPCTSTR pattern);
   .
   . // lots more
   . 

};

Figure 8 GroupCollection.cpp
//////////////////
// ManWrap wrapper for GroupCollection.
//

// In header, RegexWrap.h
class WREXPORT CMGroupCollection : public CMObject
{
   DECLARE_COLLECTION(GroupCollection, Object);
public:
   CMGroup operator[](int i);
   CMGroup operator[](LPCTSTR name);
};

// In module, RegexWrap.cpp
IMPLEMENT_COLLECTION(GroupCollection, Object)

CMGroup CMGroupCollection::operator[](int i)
{
   return (*this)->Item[i];
}

CMGroup CMGroupCollection::operator[](LPCTSTR name)
{
   return (*this)->Item[name];
}

Figure 11 WordMess Scrambler Function
//////////////////
// 匹配求值会调用:该函数接收一个匹配并返回要用来替代的文本。
// 算法是:打乱单词中间的字母。
//
// - 少于四个字母的单词不改变.
// - 四个字母的单词将其中间两个字母交换.
// - 五个字母的单词保留其第一个和最后一个字母不变.
// - 长单词保留开始和结尾两个字母不变.
//
// 瞧瞧使用 STL 算法一切变得多容易!!——swap 和 random_shuffle.
// Scrambler 在 CString 中报告其行为,该 CString 通过 void* param 传递.
//
CString CALLBACK Scrambler(const CMMatch& m, void* param)
{
   tstring word = m.Value(); // STL 字符串比 CString 容易处理
   size_t len = word.size();
   if (len>=4) {
      if (len==4) {
         swap(word[1],word[2]);   // 使用 STL swap 算法!
      } else {
         // STL 洗牌算法!
         random_shuffle(word.begin()+(len <=5 ? 1 : 2), word.end()-1);
      }
   }
   if (param) {
      CString temp;
      temp.Format(_T("Scramble: '%s' -> '%s'\n"), m.Value(), 
         word.c_str());
      (*(CString*)param) += temp;
   }
   return word.c_str();
}
 

版权所有:UML软件工程组织