STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

atlstl_string_access.h

Go to the documentation of this file.
00001 /* 
00002  * File:        atlstl_string_access.h
00003  *
00004  * Purpose:     Contains classes and functions for dealing with OLE/COM strings.
00005  *
00006  * Created:
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef ATLSTL_INCL_H_ATLSTL_STRING_ACCESS
00046 #define ATLSTL_INCL_H_ATLSTL_STRING_ACCESS
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define ATLSTL_VER_H_ATLSTL_STRING_ACCESS_MAJOR     2
00050 # define ATLSTL_VER_H_ATLSTL_STRING_ACCESS_MINOR     0
00051 # define ATLSTL_VER_H_ATLSTL_STRING_ACCESS_REVISION  1
00052 # define ATLSTL_VER_H_ATLSTL_STRING_ACCESS_EDIT      56
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef ATLSTL_INCL_H_ATLSTL
00060 # include "atlstl.h"                        // Include the ATLSTL root header
00061 #endif /* !ATLSTL_INCL_H_ATLSTL */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00063 # include "stlsoft_string_access.h"         //
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_STRING_ACCESS */
00065 #ifndef STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER
00066 # include "stlsoft_cstring_maker.h"         //
00067 #endif /* !STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER */
00068 #ifdef STLSOFT_UNITTEST
00069 # include <wchar.h>
00070 #endif /* STLSOFT_UNITTEST */
00071 
00072 //#ifndef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
00073 //# include "winstl_processheap_allocator.h"    // winstl::processheap_allocator
00074 //#endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
00075 
00076 /* 
00077  * Namespace
00078  *
00079  * The ATLSTL components are contained within the atlstl namespace. This is
00080  * actually an alias for stlsoft::atlstl_project,
00081  *
00082  * The definition matrix is as follows:
00083  *
00084  * _STLSOFT_NO_NAMESPACE    _ATLSTL_NO_NAMESPACE    atlstl definition
00085  * ---------------------    --------------------    -----------------
00086  *  not defined              not defined             = stlsoft::atlstl_project
00087  *  not defined              defined                 not defined
00088  *  defined                  not defined             atlstl
00089  *  defined                  defined                 not defined
00090  *
00091  */
00092 
00093 #ifndef _ATLSTL_NO_NAMESPACE
00094 # if defined(_STLSOFT_NO_NAMESPACE) || \
00095      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00096 /* There is no stlsoft namespace, so must define ::atlstl */
00097 namespace atlstl
00098 {
00099 # else
00100 /* Define stlsoft::atlstl_project */
00101 
00102 namespace stlsoft
00103 {
00104 
00105 namespace atlstl_project
00106 {
00107 
00108 # endif /* _STLSOFT_NO_NAMESPACE */
00109 #endif /* !_ATLSTL_NO_NAMESPACE */
00110 
00111 /* 
00112 
00114 
00117 
00121 
00126 
00127 /* 
00128  * Classes
00129  */
00130 
00131 /* CWindow */
00132 
00133 #ifdef __ATLWIN_H__
00137 class c_str_ptr_null_CWindow_proxy
00138 {
00139 private:
00140     typedef cstring_maker<TCHAR>            string_maker_type;
00141     typedef c_str_ptr_null_CWindow_proxy    class_type;
00142 
00143 // Construction
00144 public:
00148     ss_explicit_k c_str_ptr_null_CWindow_proxy(CWindow const &w)
00149     {
00150         int length  =   (NULL == w.m_hWnd) ? 0 : w.GetWindowTextLength();
00151 
00152         if(length == 0)
00153         {
00154             m_buffer = NULL;
00155         }
00156         else
00157         {
00158             m_buffer = string_maker_type::alloc(length);
00159 
00160             if(NULL != m_buffer)
00161             {
00162                 w.GetWindowText(m_buffer, length + 1);
00163             }
00164         }
00165     }
00166 
00167 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00176     c_str_ptr_null_CWindow_proxy(class_type &rhs)
00177         : m_buffer(rhs.m_buffer)
00178     {
00179         rhs.m_buffer = 0;
00180     }
00181 #else /* ? __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
00182     // Copy constructor
00183     c_str_ptr_null_CWindow_proxy(class_type const &rhs)
00184         : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00185     {}
00186 #endif /* __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
00187 
00189     ~c_str_ptr_null_CWindow_proxy()
00190     {
00191         string_maker_type::free(m_buffer);
00192     }
00193 
00194 // Accessors
00195 public:
00198     operator LPCTSTR () const
00199     {
00200         return m_buffer;
00201     }
00202 
00203 // Members
00204 private:
00205     LPTSTR  m_buffer;
00206 
00207 // Not to be implemented
00208 private:
00209     void operator =(class_type const &rhs);
00210 };
00211 
00215 class c_str_ptr_CWindow_proxy
00216 {
00217 private:
00218     typedef cstring_maker<TCHAR>        string_maker_type;
00219     typedef c_str_ptr_CWindow_proxy     class_type;
00220 
00221 // Construction
00222 public:
00226     ss_explicit_k c_str_ptr_CWindow_proxy(CWindow const &w)
00227     {
00228         int length  =   (NULL == w.m_hWnd) ? 0 : w.GetWindowTextLength();
00229 
00230         if(length == 0)
00231         {
00232             m_buffer = string_maker_type::dup("");
00233         }
00234         else
00235         {
00236             m_buffer = string_maker_type::alloc(length);
00237 
00238             if(NULL != m_buffer)
00239             {
00240                 w.GetWindowText(m_buffer, length + 1);
00241             }
00242         }
00243     }
00244 
00245 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00254     c_str_ptr_CWindow_proxy(class_type &rhs)
00255         : m_buffer(rhs.m_buffer)
00256     {
00257         rhs.m_buffer = 0;
00258     }
00259 #else /* ? __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
00260     // Copy constructor
00261     c_str_ptr_CWindow_proxy(class_type const &rhs)
00262         : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00263     {}
00264 #endif /* __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
00265 
00267     ~c_str_ptr_CWindow_proxy()
00268     {
00269         string_maker_type::free(m_buffer);
00270     }
00271 
00272 // Accessors
00273 public:
00276     operator LPCTSTR () const
00277     {
00278         return (NULL == m_buffer) ? "" : m_buffer;
00279     }
00280 
00281 // Members
00282 protected:
00283     LPTSTR  m_buffer;
00284 
00285 // Not to be implemented
00286 protected:
00287     void operator =(class_type const &rhs);
00288 };
00289 #endif /* __ATLWIN_H__ */
00290 
00291 /* 
00292  * Equivalence testing
00293  */
00294 
00295 #ifdef __ATLWIN_H__
00296 inline as_bool_t operator ==(LPCTSTR lhs, c_str_ptr_null_CWindow_proxy const &rhs)
00297 {
00298     return lhs == static_cast<LPCTSTR>(rhs);
00299 }
00300 
00301 inline as_bool_t operator ==(c_str_ptr_null_CWindow_proxy const &lhs, LPCTSTR rhs)
00302 {
00303     return static_cast<LPCTSTR>(lhs) == rhs;
00304 }
00305 
00306 inline as_bool_t operator !=(LPCTSTR lhs, c_str_ptr_null_CWindow_proxy const &rhs)
00307 {
00308     return lhs != static_cast<LPCTSTR>(rhs);
00309 }
00310 
00311 inline as_bool_t operator !=(c_str_ptr_null_CWindow_proxy const &lhs, LPCTSTR rhs)
00312 {
00313     return static_cast<LPCTSTR>(lhs) != rhs;
00314 }
00315 #endif /* __ATLWIN_H__ */
00316 
00317 /* 
00318  * IOStream compatibility
00319  */
00320 
00321 #ifdef __ATLWIN_H__
00322 template<ss_typename_param_k S>
00323 inline S &operator <<(S & s, c_str_ptr_null_CWindow_proxy const &shim)
00324 {
00325     s << static_cast<LPCTSTR>(shim);
00326 
00327     return s;
00328 }
00329 
00330 template <ss_typename_param_k S>
00331 inline S &operator <<(S & s, c_str_ptr_CWindow_proxy const &shim)
00332 {
00333     s << static_cast<LPCTSTR>(shim);
00334 
00335     return s;
00336 }
00337 #endif /* __ATLWIN_H__ */
00338 
00339 /* 
00340  * c_str_ptr_null
00341  *
00342  * This can be applied to an expression, and the return value is either a
00343  * pointer to the character string or NULL.
00344  */
00345 
00346 /* CWindow */
00347 #ifdef __ATLWIN_H__
00348 
00349 inline c_str_ptr_null_CWindow_proxy c_str_ptr_null(atlstl_ns_qual_atl(CWindow) const &w)
00350 {
00351     return c_str_ptr_null_CWindow_proxy(w);
00352 }
00353 #endif /* __ATLWIN_H__ */
00354 
00355 /* CComBSTR */
00357 inline LPCOLESTR c_str_ptr_null(atlstl_ns_qual_atl(CComBSTR) const &s)
00358 {
00359     /* NULL is a valid BSTR value, so may return that */
00360     return s.m_str;
00361 }
00362 
00363 /* 
00364  * c_str_ptr
00365  *
00366  * This can be applied to an expression, and the return value is either a
00367  * pointer to the character string or to an empty string.
00368  */
00369 
00370 /* CWindow */
00371 #ifdef __ATLWIN_H__
00372 
00373 inline c_str_ptr_CWindow_proxy c_str_ptr(atlstl_ns_qual_atl(CWindow) const &w)
00374 {
00375     return c_str_ptr_CWindow_proxy(w);
00376 }
00377 #endif /* __ATLWIN_H__ */
00378 
00379 /* CComBSTR */
00381 inline LPCOLESTR c_str_ptr(atlstl_ns_qual_atl(CComBSTR) const &s)
00382 {
00383     /* NULL is a valid BSTR value, so check for that */
00384     return (s.m_str != 0) ? s.m_str : L"";
00385 }
00386 
00387 /* 
00388  * c_str_len
00389  *
00390  * This can be applied to an expression, and the return value is the number of
00391  * characters in the character string in the expression.
00392  */
00393 
00394 /* CWindow */
00395 #ifdef __ATLWIN_H__
00396 
00397 inline as_size_t c_str_len(atlstl_ns_qual_atl(CWindow) const &w)
00398 {
00399     return static_cast<as_size_t>(w.GetWindowTextLength());
00400 }
00401 #endif /* __ATLWIN_H__ */
00402 
00403 /* CComBSTR */
00405 inline as_size_t c_str_len(atlstl_ns_qual_atl(CComBSTR) const &s)
00406 {
00407     return s.Length();
00408 }
00409 
00410 /* 
00411  * c_str_size
00412  *
00413  * This can be applied to an expression, and the return value is the number of
00414  * bytes required to store the character string in the expression, NOT including
00415  * the null-terminating character.
00416  */
00417 
00418 /* CWindow */
00419 #ifdef __ATLWIN_H__
00420 
00421 inline as_size_t c_str_size(atlstl_ns_qual_atl(CWindow) const &w)
00422 {
00423     return c_str_len(w) * sizeof(TCHAR);
00424 }
00425 #endif /* __ATLWIN_H__ */
00426 
00427 /* CComBSTR */
00429 inline as_size_t c_str_size(atlstl_ns_qual_atl(CComBSTR) const &s)
00430 {
00431     return c_str_len(s) * sizeof(OLECHAR);
00432 }
00433 
00435 // Unit-testing
00436 
00437 #ifdef STLSOFT_UNITTEST
00438 
00439 namespace unittest
00440 {
00441     namespace
00442     {
00443         ss_bool_t test_atlstl_string_access_CComBSTR(unittest_reporter *r)
00444         {
00445             ss_bool_t   bSuccess = true;
00446 #if defined(__STLSOFT_COMPILER_IS_BORLAND)
00447             CComBSTR    bstr1(L"String #1");
00448 #else /* ? Borland */
00449             CComBSTR    bstr1("String #1"); // Borland's CComBSTR(LPCSTR) leaves a character off the end!!
00450 #endif /* Borland */
00451 
00452             if(0 != wcscmp(L"String #1", c_str_ptr(bstr1)))
00453             {
00454                 r->report("c_str_ptr(CComBSTR) failed ", __LINE__);
00455                 bSuccess = false;
00456             }
00457 
00458             if(0 != wcscmp(L"String #1", c_str_ptr_null(bstr1)))
00459             {
00460                 r->report("c_str_ptr_null(CComBSTR) failed ", __LINE__);
00461                 bSuccess = false;
00462             }
00463 
00464             CComBSTR    bstr2;
00465 
00466             if(0 != wcscmp(L"", c_str_ptr(bstr2)))
00467             {
00468                 r->report("c_str_ptr(CComBSTR) failed with empty string", __LINE__);
00469                 bSuccess = false;
00470             }
00471 
00472             if(NULL != c_str_ptr_null(bstr2))
00473             {
00474                 r->report("c_str_ptr_null(CComBSTR) failed with empty string", __LINE__);
00475                 bSuccess = false;
00476             }
00477 
00478             return bSuccess;
00479         }
00480 
00481         ss_bool_t test_atlstl_string_access_CWindow(unittest_reporter *r)
00482         {
00483             ss_bool_t   bSuccess = true;
00484             RECT        rc      =   { 0, 0, 10, 10 };
00485 #if (_ATL_VER & 0xff00) < 0x0300
00486             HWND        hwnd1   =   ::CreateWindowEx(0, "BUTTON", "Window #1", 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, (HMENU)0, _Module.GetModuleInstance(), NULL);
00487             CWindow     wnd1(hwnd1);
00488 #else /* ? _ATL_VER */
00489             CWindow     wnd1;
00490             HWND        hwnd1   =   wnd1.Create("BUTTON", NULL, rc, "Window #1");
00491 #endif /* _ATL_VER */
00492 
00493             if( NULL != hwnd1 &&
00494                 0 != strcmp("Window #1", c_str_ptr(wnd1)))
00495             {
00496                 r->report("c_str_ptr(CWindow) failed ", __LINE__);
00497                 bSuccess = false;
00498             }
00499 
00500             CWindow     wnd2;
00501 
00502             if(0 != lstrcmp(_T(""), c_str_ptr(wnd2)))
00503             {
00504                 r->report("c_str_ptr(CWindow) failed with empty window", __LINE__);
00505                 bSuccess = false;
00506             }
00507 
00508             if(NULL != c_str_ptr_null(wnd2))
00509             {
00510                 r->report("c_str_ptr_null(CWindow) failed with empty window", __LINE__);
00511                 bSuccess = false;
00512             }
00513 
00514             return bSuccess;
00515         }
00516 
00517     } // anonymous namespace
00518 
00519     ss_bool_t test_atlstl_string_access(unittest_reporter *r)
00520     {
00521         using stlsoft::unittest::unittest_initialiser;
00522 
00523         ss_bool_t               bSuccess    =   true;
00524 
00525         unittest_initialiser    init(r, "ATLSTL", "string_access", __FILE__);
00526 
00527         // 1. Test CComBSTR
00528         if(bSuccess)
00529         {
00530             bSuccess = test_atlstl_string_access_CComBSTR(r);
00531         }
00532 
00533         // 1. Test CWindow
00534         if(bSuccess)
00535         {
00536             bSuccess = test_atlstl_string_access_CWindow(r);
00537         }
00538 
00539         return bSuccess;
00540     }
00541 
00542     unittest_registrar    unittest_atlstl_string_access(test_atlstl_string_access);
00543 
00544 } // namespace unittest
00545 
00546 #endif /* STLSOFT_UNITTEST */
00547 
00548 /* 
00549 
00551 
00552 /* 
00553 
00554 #ifndef _ATLSTL_NO_NAMESPACE
00555 # if defined(_STLSOFT_NO_NAMESPACE) || \
00556      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00557 } // namespace atlstl
00558 # else
00559 } // namespace stlsoft::atlstl_project
00560 } // namespace stlsoft
00561 # endif /* _STLSOFT_NO_NAMESPACE */
00562 #endif /* !_ATLSTL_NO_NAMESPACE */
00563 
00564 /* 
00565  * Namespace
00566  *
00567  * The string access shims exist either in the stlsoft namespace, or in the
00568  * global namespace. This is required by the lookup rules.
00569  *
00570  */
00571 
00572 #ifndef _ATLSTL_NO_NAMESPACE
00573 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00574      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00575 namespace stlsoft
00576 {
00577 # else /* ? _STLSOFT_NO_NAMESPACE */
00578 /* There is no stlsoft namespace, so must define in the global namespace */
00579 # endif /* !_STLSOFT_NO_NAMESPACE */
00580 
00581 using ::atlstl::c_str_ptr_null;
00582 
00583 using ::atlstl::c_str_ptr;
00584 
00585 using ::atlstl::c_str_len;
00586 
00587 using ::atlstl::c_str_size;
00588 
00589 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00590      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00591 } // namespace stlsoft
00592 # else /* ? _STLSOFT_NO_NAMESPACE */
00593 /* There is no stlsoft namespace, so must define in the global namespace */
00594 # endif /* !_STLSOFT_NO_NAMESPACE */
00595 #endif /* !_ATLSTL_NO_NAMESPACE */
00596 
00597 /* 
00598 
00599 #endif /* !ATLSTL_INCL_H_ATLSTL_STRING_ACCESS */
00600 
00601 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004