]> git.saurik.com Git - apple/mdnsresponder.git/blobdiff - mDNSWindows/DLLX/StringServices.cpp
mDNSResponder-212.1.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / DLLX / StringServices.cpp
diff --git a/mDNSWindows/DLLX/StringServices.cpp b/mDNSWindows/DLLX/StringServices.cpp
new file mode 100755 (executable)
index 0000000..a9c1d8a
--- /dev/null
@@ -0,0 +1,196 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+    Change History (most recent first):
+    
+$Log: StringServices.cpp,v $
+Revision 1.2  2009/06/02 18:43:57  herscher
+<rdar://problem/3948252> Allow component consumers to pass in null strings
+
+Revision 1.1  2009/05/26 04:43:54  herscher
+<rdar://problem/3948252> COM component that can be used with any .NET language and VB.
+\r
+\r
+*/\r
+\r
+#include "StringServices.h"\r
+#include <DebugServices.h>\r
+\r
+\r
+extern BOOL\r
+BSTRToUTF8\r
+       (\r
+       BSTR                    inString,\r
+       std::string     &       outString\r
+       )\r
+{\r
+       USES_CONVERSION;\r
+       \r
+       char    *       utf8String      = NULL;\r
+       OSStatus    err                 = kNoErr;\r
+\r
+       outString = "";
+
+       if ( inString )\r
+       {
+               TCHAR   *       utf16String     = NULL;
+               size_t      size                = 0;
+\r
+               utf16String = OLE2T( inString );\r
+               require_action( utf16String != NULL, exit, err = kUnknownErr );\r
+\r
+               if ( wcslen( utf16String ) > 0 )\r
+               {\r
+                       size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), NULL, 0, NULL, NULL );\r
+                       err = translate_errno( size != 0, GetLastError(), kUnknownErr );\r
+                       require_noerr( err, exit );\r
+\r
+                       try\r
+                       {\r
+                               utf8String = new char[ size + 1 ];\r
+                       }\r
+                       catch ( ... )\r
+                       {\r
+                               utf8String = NULL;\r
+                       }\r
+\r
+                       require_action( utf8String != NULL, exit, err = kNoMemoryErr );\r
+                       size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), utf8String, (int) size, NULL, NULL);\r
+                       err = translate_errno( size != 0, GetLastError(), kUnknownErr );\r
+                       require_noerr( err, exit );\r
+\r
+                       // have to add the trailing 0 because WideCharToMultiByte doesn't do it,\r
+                       // although it does return the correct size\r
+\r
+                       utf8String[size] = '\0';\r
+                       outString = utf8String;\r
+               }
+       }\r
+\r
+exit:\r
+\r
+       if ( utf8String != NULL )\r
+       {\r
+               delete [] utf8String;\r
+       }\r
+\r
+       return ( !err ) ? TRUE : FALSE;\r
+}\r
+\r
+\r
+extern BOOL\r
+UTF8ToBSTR\r
+       (\r
+       const char      *       inString,\r
+       CComBSTR        &       outString\r
+       )\r
+{\r
+       wchar_t *       unicode = NULL;\r
+       OSStatus        err             = 0;\r
+\r
+       if ( inString )\r
+       {
+               int n;
+
+               n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, NULL, 0 );\r
+           \r
+               if ( n > 0 )\r
+               {\r
+                       try\r
+                       {\r
+                               unicode = new wchar_t[ n ];\r
+                       }\r
+                       catch ( ... )\r
+                       {\r
+                               unicode = NULL;\r
+                       }\r
+\r
+                       require_action( unicode, exit, err = ERROR_INSUFFICIENT_BUFFER );\r
+\r
+                       n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, unicode, n );\r
+               }\r
+\r
+               outString = unicode;\r
+       }
+\r
+exit:\r
+\r
+    if ( unicode != NULL )\r
+    {\r
+        delete [] unicode;\r
+       }\r
+\r
+       return ( !err ) ? TRUE : FALSE;\r
+}\r
+\r
+\r
+BOOL\r
+ByteArrayToVariant\r
+       (\r
+       const void      *       inArray,\r
+       size_t                  inArrayLen,\r
+       VARIANT         *       outVariant\r
+       )\r
+{\r
+       LPBYTE                  buf     = NULL;\r
+       HRESULT                 hr      = 0;\r
+       BOOL                    ok      = TRUE;\r
+\r
+       VariantClear( outVariant );\r
+       outVariant->vt          = VT_ARRAY|VT_UI1;\r
+       outVariant->parray      = SafeArrayCreateVector( VT_UI1, 0, ( ULONG ) inArrayLen );\r
+       require_action( outVariant->parray, exit, ok = FALSE );\r
+       hr = SafeArrayAccessData( outVariant->parray, (LPVOID *)&buf );\r
+       require_action( hr == S_OK, exit, ok = FALSE );\r
+       memcpy( buf, inArray, inArrayLen );\r
+       hr = SafeArrayUnaccessData( outVariant->parray );\r
+       require_action( hr == S_OK, exit, ok = FALSE );\r
+\r
+exit:\r
+\r
+       return ok;\r
+}\r
+\r
+\r
+extern BOOL\r
+VariantToByteArray\r
+       (\r
+       VARIANT                         *       inVariant,\r
+       std::vector< BYTE >     &       outArray\r
+       )\r
+{\r
+       SAFEARRAY       *       psa                     = NULL;\r
+       BYTE            *       pData           = NULL;\r
+       ULONG                   cElements       = 0;\r
+       HRESULT                 hr;\r
+       BOOL                    ok = TRUE;\r
+\r
+       require_action( V_VT( inVariant ) == ( VT_ARRAY|VT_UI1 ), exit, ok = FALSE );\r
+       psa = V_ARRAY( inVariant );\r
+       require_action( psa, exit, ok = FALSE );\r
+       require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE );\r
+       hr = SafeArrayAccessData( psa, ( LPVOID* )&pData );\r
+       require_action( hr == S_OK, exit, ok = FALSE );\r
+       cElements = psa->rgsabound[0].cElements;\r
+       outArray.reserve( cElements );\r
+       outArray.assign( cElements, 0 );\r
+       memcpy( &outArray[ 0 ], pData, cElements );\r
+       SafeArrayUnaccessData( psa );\r
+\r
+exit:\r
+\r
+       return ok;\r
+}
\ No newline at end of file