/******************************************************************************* Copyright (c) 2003, Robert Cowham and Vaccaperna Systems Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL VACCAPERNA SYSTEMS LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /******************************************************************************* * Name: p4clientapi.cpp * * Author: Robert Cowham <robert@vaccaperna.co.uk> * * Description: * COM bindings for the Perforce API. User interface class * for getting Perforce results into COM. * ******************************************************************************/ #include "p4clientapi.h" #include "TraceUtils.h" #include "i18napi.h" // Parse a space-delimited line. Works similar to strtok, except that // fields must be separated by spaces, and fields that contain // spaces must be enclosed in double quotes. White space before // or after a quoted field is ignored. Other white space is // significant. Does not handle quotes embedded in quotes. Does // handle empty fields. // Expects the input and output to be wide strings (i.e. unicode capable) class StrTok { public: StrTok(BSTR s) : m_str(s), m_start(0) { } ~StrTok() {} wstring spacetok() { static const WCHAR space = L' '; static const WCHAR quote = L'\"'; wstring::size_type begin = m_start; wstring::size_type end; wstring ret; wstring::size_type i; if (begin >= m_str.length()) { return ret; } if (m_start == 0) { m_searchfor = space; } i = begin; while ((i < m_str.length()) && (m_str[i] == space)) // skip spaces at start { ++i; } if (i < m_str.length()) { if (m_str[i] == quote) { m_searchfor = quote; // remember for next time ++i; } else { m_searchfor = space; } begin = i; while ((i < m_str.length()) && (m_str[i] != m_searchfor)) { ++i; } } if (i >= m_str.length()) { end = m_str.length(); } else { end = i; ++i; } ret = m_str.substr(begin, end - begin); m_start = i; return ret; } // spacetok private: wstring m_str; WCHAR m_searchfor; int m_start; }; // Function which splits up a parameter string into an array of arguments void p4ClientApi::SplitArgs(BSTR cmd_line, StrBufArray *sba) { USES_CONVERSION; StrTok strtok(cmd_line); /* * While there are tokens in "string" */ wstring token = strtok.spacetok(); while (token.length()) { sba->Put((void *)m_ui.TranslateFromBSTR(token)); token = strtok.spacetok(); } } // SplitArgs p4ClientApi::p4ClientApi() { STACK_TRACE("p4ClientApi::p4ClientApi") m_initCount = 0; m_tagged = 0; m_exceptionLevel = 2; m_prog = "P4COM"; m_version = "2014.1"; } p4ClientApi::~p4ClientApi() { STACK_TRACE("p4ClientApi::~p4ClientApi") if (m_initCount) { Error e; m_client.Final(&e); // Ignore errors } } int p4ClientApi::Connect(StrBuf &errMsg) { STACK_TRACE("p4ClientApi::Connect") if (m_initCount) { return S_OK; } Error e; m_client.Init(&e); if (e.Test() && m_exceptionLevel) { StrBuf m; e.Fmt(&m); errMsg = m.Text(); return E_FAIL; } if (e.Test()) return E_FAIL; m_initCount++; return S_OK; } // // Disconnect session // int p4ClientApi::Disconnect() { STACK_TRACE("p4ClientApi::Disconnect") if (!m_initCount) { return S_OK; } Error e; m_client.Final( &e ); m_initCount--; return S_OK; } void p4ClientApi::Tagged() { STACK_TRACE("p4ClientApi::Tagged") m_client.SetProtocol("tag", ""); m_tagged = 1; } void p4ClientApi::ParseForms() { STACK_TRACE("p4ClientApi::ParseForms") m_client.SetProtocol("tag", ""); m_client.SetProtocol("specstring", ""); m_tagged = 1; } void p4ClientApi::CheckCharset() { STACK_TRACE("p4ClientApi::CheckCharset") StrBuf s; s = GetCharset(); TRACE1("p4com: Charset", s.Text()); if (s.Length() > 0) { // Given that VB is full unicode - always use UTF8 and rely on VB layer // to do translation m_client.SetTrans(CharSetApi::UTF_8, CharSetApi::NOCONV, CharSetApi::UTF_8, CharSetApi::UTF_8); m_ui.TranslateCharset(1); } else { m_ui.TranslateCharset(0); } } long p4ClientApi::Run(BSTR completeCmd, StrBuf &errMsg) { STACK_TRACE("p4ClientApi::Run") if (!m_initCount && m_exceptionLevel) { errMsg = "Not connected."; return E_FAIL; } if (!m_initCount) return E_FAIL; Error e; // Clear out any results from the previous command m_ui.Reset(); CheckCharset(); // Set values which must be done between Init and Run if (m_prog.Length() > 0) m_client.SetProg(&m_prog); if (m_version.Length() > 0) m_client.SetVersion(&m_version); // Store away the parameters StrBufArray args; SplitArgs(completeCmd, &args); // Construct argc and argv. int NumArgs = args.Count(); int StartIndex = 1; int i; // use first element of args as cmd StrBuf cmd; cmd = (LPCSTR)args.Get(0); StartIndex = 1; NumArgs -= 1; char **argv = new char*[NumArgs]; if (NumArgs > 0) { StrBuf s; for (i = StartIndex; i < args.Count(); i++) { s = (LPCSTR) args.Get(i); argv[i - StartIndex] = new char[s.Length() + 1]; strcpy_s(argv[i - StartIndex], s.Length() + 1, s.Text()); } } m_client.SetArgv( NumArgs, argv ); m_client.Run( cmd.Text(), &m_ui ); for (i = 0; i < NumArgs; i++) { delete [] argv[i]; } delete [] argv; m_ui.CloseFiles(); return S_OK; } void GetMsg(StrBuf &msg, StrBufArray *sba) { for (int i = 0; i < sba->Count(); i++) { msg.Append((LPCSTR)sba->Get(i)); msg.Append(" "); } } StrBuf p4ClientApi::ErrorMsg() { STACK_TRACE("p4ClientApi::ErrorMsg") StrBuf errMsg; // Create msg from error array (if exists) if (ExceptionLevel() > 0) { if (ExceptionLevel() == 1) { GetMsg(errMsg, m_ui.ErrorArray()); } else { GetMsg(errMsg, m_ui.WarningArray()); GetMsg(errMsg, m_ui.ErrorArray()); } } return errMsg; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 11314 | Robert Cowham | Initial population of perforce_software version of P4OFC | ||
//guest/robert_cowham/perforce/API/p4com/main/src/p4clientapi.cpp | |||||
#10 | 10720 | Robert Cowham |
Built with Visual Studio 2010 (SP1) Updated to p4 api 2014.1 Uses Open SSL (latest) as a result of the above. A client workspace to use this looks like: //guest/robert_cowham/perforce/API/p4com/main/src/... //cowhamr-p4com-test/... //guest/robert_cowham/perforce/API/p4/p4api-2014.1.821990-vs2010_static/... //cowhamr-p4com-test/p4api/... //guest/robert_cowham/openssl/1.0.1j/out32dll/libeay32.lib //cowhamr-p4com-test/openssl-lib/libeay32.lib //guest/robert_cowham/openssl/1.0.1j/out32dll/libeay32.dll //cowhamr-p4com-test/ReleaseMinDependency/libeay32.dll //guest/robert_cowham/openssl/1.0.1j/out32dll/ssleay32.lib //cowhamr-p4com-test/openssl-lib/ssleay32.lib //guest/robert_cowham/openssl/1.0.1j/out32dll/ssleay32.dll //cowhamr-p4com-test/ReleaseMinDependency/ssleay32.dll |
||
#9 | 7458 | Robert Cowham | Fix similar problem with SetVersion | ||
#8 | 7457 | Robert Cowham | Set default value for Prog | ||
#7 | 7456 | Robert Cowham | Fix setting of Prog and Protocol calls | ||
#6 | 7445 | Robert Cowham | Fix ccompiler warning for VS 2008 | ||
#5 | 5194 | Robert Cowham |
Changes (2005.1.0.0) Added Dropped() to detect dropped connections Added Input property to provide input e.g. for passwords Added FormatDateTime() as a convenience for calling C Runtime function (for VB use) Imported changes from p4ofc which made it more reliable. |
||
#4 | 4242 | Robert Cowham |
Fixed some String leaks. Fixed problem with writing to temporary files. Updated p4API to released version of 2003.2. Start of Delphi example. |
||
#3 | 3612 | Robert Cowham |
Version 1.0.0.2 New interface for ServerVersion. New put property ArrayVarVar which is the same as ArrayVar but takes an Array of Variants rather than strings (for Lisp compatibility!). |
||
#2 | 3542 | Robert Cowham | Update to use exceptions properly - including examples. | ||
#1 | 3525 | Robert Cowham | Initial release |