<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salinfo.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-26 09:20:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#define VCL_NEED_BASETSD
#include <tools/presys.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <tools/postsys.h>

#include <tools/string.hxx>
#include <salsys.hxx>
#include <salframe.h>
#include <salinst.h>
#include <tools/debug.hxx>
#include <svdata.hxx>
#include <window.hxx>

#include <multimon.h>

#include <vector>

class WinSalSystem : public SalSystem
{
    std::vector< Rectangle > m_aMonitors;
public:
    WinSalSystem() {}
    virtual ~WinSalSystem();

    virtual unsigned int GetDisplayScreenCount();
    virtual Rectangle GetDisplayScreenPosSizePixel( unsigned int nScreen );
    virtual int ShowNativeMessageBox( const String& rTitle,
                                      const String& rMessage,
                                      int nButtonCombination,
                                      int nDefaultButton);

    bool initMonitors();
    void addMonitor( const Rectangle& rRect) { m_aMonitors.push_back( rRect ); }
};

SalSystem* WinSalInstance::CreateSalSystem()
{
    return new WinSalSystem();
}

WinSalSystem::~WinSalSystem()
{
}

// -----------------------------------------------------------------------

static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR hMonitor,
                                          HDC hdcMonitor,
                                          LPRECT lprcMonitor,
                                          LPARAM dwData )
{
    WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
    pSys->addMonitor( Rectangle( Point( lprcMonitor->left,
                                        lprcMonitor->top ),
                                 Size( lprcMonitor->right - lprcMonitor->left,
                                       lprcMonitor->bottom - lprcMonitor->top ) ) );
    return TRUE;
}

bool WinSalSystem::initMonitors()
{
    if( m_aMonitors.size() > 0 )
        return true;

    bool winVerOk = true;

    // multi monitor calls not available on Win95/NT
    OSVERSIONINFO aVerInfo;
    aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
    if ( GetVersionEx( &aVerInfo ) )
    {
        if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
        {
            if ( aVerInfo.dwMajorVersion <= 4 )
                winVerOk = false;   // NT
        }
        else if( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
        {
            if ( aVerInfo.dwMajorVersion == 4 && aVerInfo.dwMinorVersion == 0 )
                winVerOk = false;   // Win95
        }
    }
    if( winVerOk )
    {
        int nMonitors = GetSystemMetrics( SM_CMONITORS );
        if( nMonitors == 1 )
        {
            int w = GetSystemMetrics( SM_CXSCREEN );
            int h = GetSystemMetrics( SM_CYSCREEN );
            m_aMonitors.push_back( Rectangle( Point(), Size( w, h ) ) );
        }
        else
        {
            HDC aDesktopRC = GetDC( NULL );
            EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
        }
    }
    else
    {
        int w = GetSystemMetrics( SM_CXSCREEN );
        int h = GetSystemMetrics( SM_CYSCREEN );
        m_aMonitors.push_back( Rectangle( Point(), Size( w, h ) ) );
    }

    return m_aMonitors.size() > 0;
}

unsigned int WinSalSystem::GetDisplayScreenCount()
{
    initMonitors();
    return m_aMonitors.size();
}

Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
{
    initMonitors();
    return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen] : Rectangle();
}

// -----------------------------------------------------------------------
/* We have to map the button identifier to the identifier used by the Win32
   Platform SDK to specify the default button for the MessageBox API.
   The first dimension is the button combination, the second dimension
   is the button identifier.
*/
static int DEFAULT_BTN_MAPPING_TABLE[][8] =
{
    //  Undefined        OK             CANCEL         ABORT          RETRY          IGNORE         YES             NO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }  //RETRY_CANCEL
};

int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton)
{
    DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
                nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
                nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
                nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );

    int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;

    if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
        nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
        nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
        nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
        nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];

    //#107209 hide the splash screen if active
    ImplSVData* pSVData = ImplGetSVData();
    if (pSVData->mpIntroWindow)
        pSVData->mpIntroWindow->Hide();

    return MessageBoxW(
        0,
        rMessage.GetBuffer(),
        rTitle.GetBuffer(),
        nFlags);
}
<commit_msg>#i10000# ImplEnumMonitorProc: unreferenced formal parameter.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salinfo.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-26 13:47:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#define VCL_NEED_BASETSD
#include <tools/presys.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <tools/postsys.h>

#include <tools/string.hxx>
#include <salsys.hxx>
#include <salframe.h>
#include <salinst.h>
#include <tools/debug.hxx>
#include <svdata.hxx>
#include <window.hxx>

#include <multimon.h>

#include <vector>

class WinSalSystem : public SalSystem
{
    std::vector< Rectangle > m_aMonitors;
public:
    WinSalSystem() {}
    virtual ~WinSalSystem();

    virtual unsigned int GetDisplayScreenCount();
    virtual Rectangle GetDisplayScreenPosSizePixel( unsigned int nScreen );
    virtual int ShowNativeMessageBox( const String& rTitle,
                                      const String& rMessage,
                                      int nButtonCombination,
                                      int nDefaultButton);

    bool initMonitors();
    void addMonitor( const Rectangle& rRect) { m_aMonitors.push_back( rRect ); }
};

SalSystem* WinSalInstance::CreateSalSystem()
{
    return new WinSalSystem();
}

WinSalSystem::~WinSalSystem()
{
}

// -----------------------------------------------------------------------

static BOOL CALLBACK ImplEnumMonitorProc( HMONITOR,
                                          HDC,
                                          LPRECT lprcMonitor,
                                          LPARAM dwData )
{
    WinSalSystem* pSys = reinterpret_cast<WinSalSystem*>(dwData);
    pSys->addMonitor( Rectangle( Point( lprcMonitor->left,
                                        lprcMonitor->top ),
                                 Size( lprcMonitor->right - lprcMonitor->left,
                                       lprcMonitor->bottom - lprcMonitor->top ) ) );
    return TRUE;
}

bool WinSalSystem::initMonitors()
{
    if( m_aMonitors.size() > 0 )
        return true;

    bool winVerOk = true;

    // multi monitor calls not available on Win95/NT
    OSVERSIONINFO aVerInfo;
    aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
    if ( GetVersionEx( &aVerInfo ) )
    {
        if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
        {
            if ( aVerInfo.dwMajorVersion <= 4 )
                winVerOk = false;   // NT
        }
        else if( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
        {
            if ( aVerInfo.dwMajorVersion == 4 && aVerInfo.dwMinorVersion == 0 )
                winVerOk = false;   // Win95
        }
    }
    if( winVerOk )
    {
        int nMonitors = GetSystemMetrics( SM_CMONITORS );
        if( nMonitors == 1 )
        {
            int w = GetSystemMetrics( SM_CXSCREEN );
            int h = GetSystemMetrics( SM_CYSCREEN );
            m_aMonitors.push_back( Rectangle( Point(), Size( w, h ) ) );
        }
        else
        {
            HDC aDesktopRC = GetDC( NULL );
            EnumDisplayMonitors( aDesktopRC, NULL, ImplEnumMonitorProc, reinterpret_cast<LPARAM>(this) );
        }
    }
    else
    {
        int w = GetSystemMetrics( SM_CXSCREEN );
        int h = GetSystemMetrics( SM_CYSCREEN );
        m_aMonitors.push_back( Rectangle( Point(), Size( w, h ) ) );
    }

    return m_aMonitors.size() > 0;
}

unsigned int WinSalSystem::GetDisplayScreenCount()
{
    initMonitors();
    return m_aMonitors.size();
}

Rectangle WinSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
{
    initMonitors();
    return (nScreen < m_aMonitors.size()) ? m_aMonitors[nScreen] : Rectangle();
}

// -----------------------------------------------------------------------
/* We have to map the button identifier to the identifier used by the Win32
   Platform SDK to specify the default button for the MessageBox API.
   The first dimension is the button combination, the second dimension
   is the button identifier.
*/
static int DEFAULT_BTN_MAPPING_TABLE[][8] =
{
    //  Undefined        OK             CANCEL         ABORT          RETRY          IGNORE         YES             NO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //OK_CANCEL
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1 }, //ABORT_RETRY_IGNO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON3, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO_CANCEL
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2 }, //YES_NO
    { MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON2, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1, MB_DEFBUTTON1 }  //RETRY_CANCEL
};

int WinSalSystem::ShowNativeMessageBox(const String& rTitle, const String& rMessage, int nButtonCombination, int nDefaultButton)
{
    DBG_ASSERT( nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
                nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
                nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
                nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, "Invalid arguments!" );

    int nFlags = MB_TASKMODAL | MB_SETFOREGROUND | MB_ICONWARNING | nButtonCombination;

    if (nButtonCombination >= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK &&
        nButtonCombination <= SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL &&
        nDefaultButton >= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK &&
        nDefaultButton <= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO)
        nFlags |= DEFAULT_BTN_MAPPING_TABLE[nButtonCombination][nDefaultButton];

    //#107209 hide the splash screen if active
    ImplSVData* pSVData = ImplGetSVData();
    if (pSVData->mpIntroWindow)
        pSVData->mpIntroWindow->Hide();

    return MessageBoxW(
        0,
        rMessage.GetBuffer(),
        rTitle.GetBuffer(),
        nFlags);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/keygen_handler.h"

#include <Security/SecAsn1Coder.h>
#include <Security/SecAsn1Templates.h>
#include <Security/Security.h>

#include "base/base64.h"
#include "base/logging.h"
#include "base/scoped_cftyperef.h"

// These are in Security.framework but not declared in a public header.
extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[];
extern const SecAsn1Template kSecAsn1SubjectPublicKeyInfoTemplate[];

namespace net {

// Declarations of Netscape keygen cert structures for ASN.1 encoding:

struct PublicKeyAndChallenge {
  CSSM_X509_SUBJECT_PUBLIC_KEY_INFO spki;
  CSSM_DATA challenge_string;
};

static const SecAsn1Template kPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(PublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, spki),
    kSecAsn1SubjectPublicKeyInfoTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, challenge_string),
    kSecAsn1IA5StringTemplate
  },
  {
    0
  }
};

struct SignedPublicKeyAndChallenge {
  PublicKeyAndChallenge pkac;
  CSSM_X509_ALGORITHM_IDENTIFIER signature_algorithm;
  CSSM_DATA signature;
};

static const SecAsn1Template kSignedPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(SignedPublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, pkac),
    kPublicKeyAndChallengeTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, signature_algorithm),
    kSecAsn1AlgorithmIDTemplate
  },
  {
    SEC_ASN1_BIT_STRING,
    offsetof(SignedPublicKeyAndChallenge, signature)
  },
  {
    0
  }
};

static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key);
static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature);

bool KeygenHandler::KeyLocation::Equals(
    const KeygenHandler::KeyLocation& location) const {
  return keychain_path == location.keychain_path;
}

std::string KeygenHandler::GenKeyAndSignChallenge() {
  std::string result;
  OSStatus err;
  SecKeyRef public_key = NULL;
  SecKeyRef private_key = NULL;
  SecAsn1CoderRef coder = NULL;
  CSSM_DATA signature = {0, NULL};

  {
    // Create the key-pair.
    err = CreateRSAKeyPair(key_size_in_bits_, &public_key, &private_key);
    if (err)
      goto failure;

    // Get the public key data (DER sequence of modulus, exponent).
    CFDataRef key_data = NULL;
    err = SecKeychainItemExport(public_key, kSecFormatBSAFE, 0, NULL,
                                &key_data);
    if (err)
      goto failure;
    scoped_cftyperef<CFDataRef> scoped_key_data(key_data);

    // Create an ASN.1 encoder.
    err = SecAsn1CoderCreate(&coder);
    if (err)
      goto failure;

    // Fill in and DER-encode the PublicKeyAndChallenge:
    SignedPublicKeyAndChallenge spkac;
    memset(&spkac, 0, sizeof(spkac));
    spkac.pkac.spki.algorithm.algorithm = CSSMOID_RSA;
    spkac.pkac.spki.subjectPublicKey.Length =
        CFDataGetLength(key_data) * 8;  // interpreted as a _bit_ count
    spkac.pkac.spki.subjectPublicKey.Data =
        const_cast<uint8_t*>(CFDataGetBytePtr(key_data));
    spkac.pkac.challenge_string.Length = challenge_.length();
    spkac.pkac.challenge_string.Data =
        reinterpret_cast<uint8_t*>(const_cast<char*>(challenge_.data()));

    CSSM_DATA encoded;
    err = SecAsn1EncodeItem(coder, &spkac.pkac,
                            kPublicKeyAndChallengeTemplate, &encoded);
    if (err)
      goto failure;

    // Compute a signature of the result:
    err = SignData(encoded, private_key, &signature);
    if (err)
      goto failure;
    spkac.signature.Data = signature.Data;
    spkac.signature.Length = signature.Length * 8;  // a _bit_ count
    spkac.signature_algorithm.algorithm = CSSMOID_MD5WithRSA;
    // TODO(snej): MD5 is weak. Can we use SHA1 instead?
    // See <https://bugzilla.mozilla.org/show_bug.cgi?id=549460>

    // DER-encode the entire SignedPublicKeyAndChallenge:
    err = SecAsn1EncodeItem(coder, &spkac,
                            kSignedPublicKeyAndChallengeTemplate, &encoded);
    if (err)
      goto failure;

    // Base64 encode the result.
    std::string input(reinterpret_cast<char*>(encoded.Data), encoded.Length);
    base::Base64Encode(input, &result);
  }

 failure:
  if (err) {
    LOG(ERROR) << "SSL Keygen failed! OSStatus = " << err;
  } else {
    LOG(INFO) << "SSL Keygen succeeded! Output is: " << result;
  }

  // Remove keys from keychain if asked to during unit testing:
  if (!stores_key_) {
    if (public_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(public_key));
    if (private_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(private_key));
  }

  // Clean up:
  free(signature.Data);
  if (coder)
    SecAsn1CoderRelease(coder);
  if (public_key)
    CFRelease(public_key);
  if (private_key)
    CFRelease(private_key);
  return result;
}

static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key) {
  OSStatus err;
  SecKeychainRef keychain;
  err = SecKeychainCopyDefault(&keychain);
  if (err)
    return err;
  scoped_cftyperef<SecKeychainRef> scoped_keychain(keychain);
  return SecKeyCreatePair(
      keychain,
      CSSM_ALGID_RSA,
      size_in_bits,
      0LL,
      // public key usage and attributes:
      CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP,
      CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT,
      // private key usage and attributes:
      CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP,
      CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT |
          CSSM_KEYATTR_SENSITIVE,
      NULL,
      out_pub_key, out_priv_key);
}

static OSStatus CreateSignatureContext(SecKeyRef key,
                                       CSSM_ALGORITHMS algorithm,
                                       CSSM_CC_HANDLE* out_cc_handle) {
  OSStatus err;
  const CSSM_ACCESS_CREDENTIALS* credentials = NULL;
  err = SecKeyGetCredentials(key,
                             CSSM_ACL_AUTHORIZATION_SIGN,
                             kSecCredentialTypeDefault,
                             &credentials);
  if (err)
      return err;

  CSSM_CSP_HANDLE csp_handle = 0;
  err = SecKeyGetCSPHandle(key, &csp_handle);
  if (err)
    return err;

  const CSSM_KEY* cssm_key = NULL;
  err = SecKeyGetCSSMKey(key, &cssm_key);
  if (err)
    return err;

  return CSSM_CSP_CreateSignatureContext(csp_handle,
                                         algorithm,
                                         credentials,
                                         cssm_key,
                                         out_cc_handle);
}

static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature) {
  CSSM_CC_HANDLE cc_handle;
  OSStatus err = CreateSignatureContext(private_key,
                                        CSSM_ALGID_MD5WithRSA,
                                        &cc_handle);
  if (err)
    return err;
  err = CSSM_SignData(cc_handle, &data, 1, CSSM_ALGID_NONE, signature);
  CSSM_DeleteContext(cc_handle);
  return err;
}

}  // namespace net
<commit_msg>Mac: Generate valid <keygen> data if challenge string is empty This works around an apparent bug in Apple's ASN.1 encoder. BUG=41679 TEST=Manual testing with comodo.com or a local test site<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/keygen_handler.h"

#include <Security/SecAsn1Coder.h>
#include <Security/SecAsn1Templates.h>
#include <Security/Security.h>

#include "base/base64.h"
#include "base/logging.h"
#include "base/scoped_cftyperef.h"

// These are in Security.framework but not declared in a public header.
extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[];
extern const SecAsn1Template kSecAsn1SubjectPublicKeyInfoTemplate[];

namespace net {

// Declarations of Netscape keygen cert structures for ASN.1 encoding:

struct PublicKeyAndChallenge {
  CSSM_X509_SUBJECT_PUBLIC_KEY_INFO spki;
  CSSM_DATA challenge_string;
};

// This is a copy of the built-in kSecAsn1IA5StringTemplate, but without the
// 'streamable' flag, which was causing bogus data to be written.
const SecAsn1Template kIA5StringTemplate[] = {
    { SEC_ASN1_IA5_STRING, 0, NULL, sizeof(CSSM_DATA) }
};

static const SecAsn1Template kPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(PublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, spki),
    kSecAsn1SubjectPublicKeyInfoTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(PublicKeyAndChallenge, challenge_string),
    kIA5StringTemplate
  },
  {
    0
  }
};

struct SignedPublicKeyAndChallenge {
  PublicKeyAndChallenge pkac;
  CSSM_X509_ALGORITHM_IDENTIFIER signature_algorithm;
  CSSM_DATA signature;
};

static const SecAsn1Template kSignedPublicKeyAndChallengeTemplate[] = {
  {
    SEC_ASN1_SEQUENCE,
    0,
    NULL,
    sizeof(SignedPublicKeyAndChallenge)
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, pkac),
    kPublicKeyAndChallengeTemplate
  },
  {
    SEC_ASN1_INLINE,
    offsetof(SignedPublicKeyAndChallenge, signature_algorithm),
    kSecAsn1AlgorithmIDTemplate
  },
  {
    SEC_ASN1_BIT_STRING,
    offsetof(SignedPublicKeyAndChallenge, signature)
  },
  {
    0
  }
};

static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key);
static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature);

bool KeygenHandler::KeyLocation::Equals(
    const KeygenHandler::KeyLocation& location) const {
  return keychain_path == location.keychain_path;
}

std::string KeygenHandler::GenKeyAndSignChallenge() {
  std::string result;
  OSStatus err;
  SecKeyRef public_key = NULL;
  SecKeyRef private_key = NULL;
  SecAsn1CoderRef coder = NULL;
  CSSM_DATA signature = {0, NULL};

  {
    // Create the key-pair.
    err = CreateRSAKeyPair(key_size_in_bits_, &public_key, &private_key);
    if (err)
      goto failure;

    // Get the public key data (DER sequence of modulus, exponent).
    CFDataRef key_data = NULL;
    err = SecKeychainItemExport(public_key, kSecFormatBSAFE, 0, NULL,
                                &key_data);
    if (err)
      goto failure;
    scoped_cftyperef<CFDataRef> scoped_key_data(key_data);

    // Create an ASN.1 encoder.
    err = SecAsn1CoderCreate(&coder);
    if (err)
      goto failure;

    // Fill in and DER-encode the PublicKeyAndChallenge:
    SignedPublicKeyAndChallenge spkac;
    memset(&spkac, 0, sizeof(spkac));
    spkac.pkac.spki.algorithm.algorithm = CSSMOID_RSA;
    spkac.pkac.spki.subjectPublicKey.Length =
        CFDataGetLength(key_data) * 8;  // interpreted as a _bit_ count
    spkac.pkac.spki.subjectPublicKey.Data =
        const_cast<uint8_t*>(CFDataGetBytePtr(key_data));
    spkac.pkac.challenge_string.Length = challenge_.length();
    spkac.pkac.challenge_string.Data =
        reinterpret_cast<uint8_t*>(const_cast<char*>(challenge_.data()));

    CSSM_DATA encoded;
    err = SecAsn1EncodeItem(coder, &spkac.pkac,
                            kPublicKeyAndChallengeTemplate, &encoded);
    if (err)
      goto failure;

    // Compute a signature of the result:
    err = SignData(encoded, private_key, &signature);
    if (err)
      goto failure;
    spkac.signature.Data = signature.Data;
    spkac.signature.Length = signature.Length * 8;  // a _bit_ count
    spkac.signature_algorithm.algorithm = CSSMOID_MD5WithRSA;
    // TODO(snej): MD5 is weak. Can we use SHA1 instead?
    // See <https://bugzilla.mozilla.org/show_bug.cgi?id=549460>

    // DER-encode the entire SignedPublicKeyAndChallenge:
    err = SecAsn1EncodeItem(coder, &spkac,
                            kSignedPublicKeyAndChallengeTemplate, &encoded);
    if (err)
      goto failure;

    // Base64 encode the result.
    std::string input(reinterpret_cast<char*>(encoded.Data), encoded.Length);
    base::Base64Encode(input, &result);
  }

 failure:
  if (err) {
    LOG(ERROR) << "SSL Keygen failed! OSStatus = " << err;
  } else {
    LOG(INFO) << "SSL Keygen succeeded! Output is: " << result;
  }

  // Remove keys from keychain if asked to during unit testing:
  if (!stores_key_) {
    if (public_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(public_key));
    if (private_key)
      SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(private_key));
  }

  // Clean up:
  free(signature.Data);
  if (coder)
    SecAsn1CoderRelease(coder);
  if (public_key)
    CFRelease(public_key);
  if (private_key)
    CFRelease(private_key);
  return result;
}

static OSStatus CreateRSAKeyPair(int size_in_bits,
                                 SecKeyRef* out_pub_key,
                                 SecKeyRef* out_priv_key) {
  OSStatus err;
  SecKeychainRef keychain;
  err = SecKeychainCopyDefault(&keychain);
  if (err)
    return err;
  scoped_cftyperef<SecKeychainRef> scoped_keychain(keychain);
  return SecKeyCreatePair(
      keychain,
      CSSM_ALGID_RSA,
      size_in_bits,
      0LL,
      // public key usage and attributes:
      CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP,
      CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT,
      // private key usage and attributes:
      CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP,
      CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT |
          CSSM_KEYATTR_SENSITIVE,
      NULL,
      out_pub_key, out_priv_key);
}

static OSStatus CreateSignatureContext(SecKeyRef key,
                                       CSSM_ALGORITHMS algorithm,
                                       CSSM_CC_HANDLE* out_cc_handle) {
  OSStatus err;
  const CSSM_ACCESS_CREDENTIALS* credentials = NULL;
  err = SecKeyGetCredentials(key,
                             CSSM_ACL_AUTHORIZATION_SIGN,
                             kSecCredentialTypeDefault,
                             &credentials);
  if (err)
      return err;

  CSSM_CSP_HANDLE csp_handle = 0;
  err = SecKeyGetCSPHandle(key, &csp_handle);
  if (err)
    return err;

  const CSSM_KEY* cssm_key = NULL;
  err = SecKeyGetCSSMKey(key, &cssm_key);
  if (err)
    return err;

  return CSSM_CSP_CreateSignatureContext(csp_handle,
                                         algorithm,
                                         credentials,
                                         cssm_key,
                                         out_cc_handle);
}

static OSStatus SignData(CSSM_DATA data,
                         SecKeyRef private_key,
                         CSSM_DATA* signature) {
  CSSM_CC_HANDLE cc_handle;
  OSStatus err = CreateSignatureContext(private_key,
                                        CSSM_ALGID_MD5WithRSA,
                                        &cc_handle);
  if (err)
    return err;
  err = CSSM_SignData(cc_handle, &data, 1, CSSM_ALGID_NONE, signature);
  CSSM_DeleteContext(cc_handle);
  return err;
}

}  // namespace net
<|endoftext|>


<commit_before><commit_msg>Fix clang warning in UDPSocketTest.<commit_after><|endoftext|>


<commit_before>#include "xchainer/backprop_mode.h"

#include <cstddef>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include "xchainer/context.h"
#include "xchainer/error.h"
#include "xchainer/graph.h"

namespace xchainer {
namespace {

void ExpectLastBackpropModeEqual(Context& context, const nonstd::optional<GraphId>& graph_id, bool backprop) {
    const internal::BackpropMode& actual = internal::GetBackpropModeStack()->back();
    EXPECT_EQ(&context, &actual.context());
    EXPECT_EQ(graph_id, actual.graph_id());
    EXPECT_EQ(backprop, actual.backprop());
}

TEST(BackpropModeScopeTest, BackpropModeScopeOneContext) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1{};
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
        {
            ForceBackpropModeScope backprop_mode_scope2{"default"};
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
            {
                NoBackpropModeScope backprop_mode_scope3{"default"};
                EXPECT_EQ(size_t{3}, internal::GetBackpropModeStack()->size());
                ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
            }
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
        }
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

TEST(BackpropModeScopeTest, BackpropModeScopeMultipleContexts) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1;
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
        {
            Context context2{};
            ContextScope context_scope2{context2};
            EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());

            NoBackpropModeScope backprop_mode_scope1{"default"};
            // New context stack, and a stack for the context should be created.
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
            {
                ForceBackpropModeScope backprop_mode_scope2{"default"};
                EXPECT_EQ(size_t{3}, internal::GetBackpropModeStack()->size());
                ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
            }
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
        }
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

// It is possible to use in flat scope because, in C++ spec, dtors are called in reverse order of ctors.
TEST(BackpropModeScopeTest, BackpropModeScopeFlatScope) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1{};
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);

        ForceBackpropModeScope backprop_mode_scope2{"default"};
        ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

// TODO(niboshi): Write a test where the outermost scope is ForceBackpropMode.

TEST(BackpropModeScopeTest, BackpropModeWithoutContext) {
    EXPECT_THROW({ NoBackpropModeScope{}; }, ContextError);
    EXPECT_THROW({ ForceBackpropModeScope{}; }, ContextError);
}

}  // namespace
}  // namespace xchainer
<commit_msg>Add {}<commit_after>#include "xchainer/backprop_mode.h"

#include <cstddef>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include "xchainer/context.h"
#include "xchainer/error.h"
#include "xchainer/graph.h"

namespace xchainer {
namespace {

void ExpectLastBackpropModeEqual(Context& context, const nonstd::optional<GraphId>& graph_id, bool backprop) {
    const internal::BackpropMode& actual = internal::GetBackpropModeStack()->back();
    EXPECT_EQ(&context, &actual.context());
    EXPECT_EQ(graph_id, actual.graph_id());
    EXPECT_EQ(backprop, actual.backprop());
}

TEST(BackpropModeScopeTest, BackpropModeScopeOneContext) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1{};
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
        {
            ForceBackpropModeScope backprop_mode_scope2{"default"};
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
            {
                NoBackpropModeScope backprop_mode_scope3{"default"};
                EXPECT_EQ(size_t{3}, internal::GetBackpropModeStack()->size());
                ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
            }
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
        }
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

TEST(BackpropModeScopeTest, BackpropModeScopeMultipleContexts) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1{};
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
        {
            Context context2{};
            ContextScope context_scope2{context2};
            EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());

            NoBackpropModeScope backprop_mode_scope1{"default"};
            // New context stack, and a stack for the context should be created.
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
            {
                ForceBackpropModeScope backprop_mode_scope2{"default"};
                EXPECT_EQ(size_t{3}, internal::GetBackpropModeStack()->size());
                ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
            }
            EXPECT_EQ(size_t{2}, internal::GetBackpropModeStack()->size());
            ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, false);
        }
        EXPECT_EQ(size_t{1}, internal::GetBackpropModeStack()->size());
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

// It is possible to use in flat scope because, in C++ spec, dtors are called in reverse order of ctors.
TEST(BackpropModeScopeTest, BackpropModeScopeFlatScope) {
    Context context1{};
    ContextScope context_scope1{context1};

    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
    {
        NoBackpropModeScope backprop_mode_scope1{};
        ExpectLastBackpropModeEqual(GetDefaultContext(), nonstd::nullopt, false);

        ForceBackpropModeScope backprop_mode_scope2{"default"};
        ExpectLastBackpropModeEqual(GetDefaultContext(), {"default"}, true);
    }
    EXPECT_EQ(nullptr, internal::GetBackpropModeStack());
}

// TODO(niboshi): Write a test where the outermost scope is ForceBackpropMode.

TEST(BackpropModeScopeTest, BackpropModeWithoutContext) {
    EXPECT_THROW({ NoBackpropModeScope{}; }, ContextError);
    EXPECT_THROW({ ForceBackpropModeScope{}; }, ContextError);
}

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TProcTop::TProcTop(){
  if((shmid=shmget(gamePort, shm_size, IPC_CREAT | 0666)) < 0){
    vlogf(LOG_BUG, "failed to get shared memory segment in TScheduler()");
  } else if((shm = (char *)shmat(shmid, NULL, 0)) == (char *) -1){
    vlogf(LOG_BUG, "failed to attach shared memory segment in TScheduler()");
  }
}

void TProcTop::clear(){
  memset(shm, 0, shm_size);
  shm_ptr=shm;
  added.clear();
}

void TProcTop::add(const sstring &s){
  if(added.find(s)==added.end()){
    strcpy(shm_ptr, s.c_str());
    shm_ptr+=s.length()+1;
    added[s]=true;
  }
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;
  TTiming timer;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter)
      (*iter)->timing=0;
  }

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, obj)){
	  delete obj;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
	(*iter)->timing=0;
      }
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;
  TTiming timer;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter)
      (*iter)->timing=0;

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
	    tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
	(tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
	    tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, tmp_ch)){
	  delete tmp_ch;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
    temp = tmp_ch->next;  // just for safety
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
      }
    }
  }

}

void TScheduler::run(int pulseNum)
{
  TTiming timer;

  pulse.init(pulseNum);
  top.clear();

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run general processes
  for(std::vector<TProcess *>::iterator iter=procs.begin();
      iter!=procs.end();++iter){
    if((*iter)->should_run(pulse.pulse)){
      if(toggleInfo[TOG_GAMELOOP]->toggle)
	timer.start();
	top.add((*iter)->name);

      (*iter)->run(pulse);

      if(toggleInfo[TOG_GAMELOOP]->toggle){
	timer.end();
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)(timer.getElapsed()*1000000));
      }
    }
  }

  pulse.init12(pulseNum);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) distributed pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<commit_msg>added some crash proofing to TProcTop<commit_after>#include "process.h"
#include "timing.h"
#include "database.h"
#include "shop.h"
#include "parse.h"
#include "faction.h"
#include "extern.h"
#include "toggle.h"
#include "guild.h"
#include "being.h"
#include <sys/shm.h>
#include <sys/ipc.h>

///////////

// procFactoryProduction
procFactoryProduction::procFactoryProduction(const int &p)
{
  trigger_pulse=p;
  name="procFactoryProduction";
}

void procFactoryProduction::run(const TPulse &) const
{
  TDatabase db(DB_SNEEZY);

  db.query("select distinct shop_nr from factoryproducing");

  while(db.fetchRow()){
    factoryProduction(convertTo<int>(db["shop_nr"]));
  }
}

// procSaveFactions
procSaveFactions::procSaveFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveFactions";
}

void procSaveFactions::run(const TPulse &) const
{
  save_factions();
}

// procSaveNewFactions
procSaveNewFactions::procSaveNewFactions(const int &p)
{
  trigger_pulse=p;
  name="procSaveNewFactions";
}

void procSaveNewFactions::run(const TPulse &) const
{
  save_guilds();
}

// procDoComponents
procDoComponents::procDoComponents(const int &p)
{
  trigger_pulse=p;
  name="procDoComponents";
}

void procDoComponents::run(const TPulse &) const
{
  do_components(-1);
}

// procPerformViolence
procPerformViolence::procPerformViolence(const int &p)
{
  trigger_pulse=p;
  name="procPerformViolence";
}

void procPerformViolence::run(const TPulse &pl) const
{
  perform_violence(pl.pulse);
}

///////

bool TBaseProcess::should_run(int p) const
{
  if(!(p % trigger_pulse))
    return true;
  else
    return false;
}

void TScheduler::add(TProcess *p)
{
  procs.push_back(p);
}

void TScheduler::add(TObjProcess *p)
{
  obj_procs.push_back(p);
}

void TScheduler::add(TCharProcess *p)
{
  char_procs.push_back(p);
}

TProcTop::TProcTop(){
  if((shmid=shmget(gamePort, shm_size, IPC_CREAT | 0666)) < 0){
    vlogf(LOG_BUG, "failed to get shared memory segment in TScheduler()");
    shm=NULL;
  } else if((shm = (char *)shmat(shmid, NULL, 0)) == (char *) -1){
    vlogf(LOG_BUG, "failed to attach shared memory segment in TScheduler()");
    shm=NULL;
  }
}

void TProcTop::clear(){
  if(shm){
    memset(shm, 0, shm_size);
    shm_ptr=shm;
    added.clear();
  }
}

void TProcTop::add(const sstring &s){
  if(shm){
    if(added.find(s)==added.end()){
      strcpy(shm_ptr, s.c_str());
      shm_ptr+=s.length()+1;
      added[s]=true;
    }
  }
}

TScheduler::TScheduler(){
  pulse.init(0);
  placeholder=read_object(42, VIRTUAL);
  // don't think we can recover from this
  mud_assert(placeholder!=NULL, "couldn't load placeholder object");
  *(real_roomp(0)) += *placeholder;
  objIter=find(object_list.begin(), object_list.end(), placeholder);
  tmp_ch=NULL;
}

void TScheduler::runObj(int pulseNum)
{
  int count;
  TObj *obj;
  TTiming timer;

  // we want to go through 1/12th of the object list every pulse
  // obviously the object count will change, so this is approximate.
  count=(int)((float)objCount/11.5);

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter)
      (*iter)->timing=0;
  }

  while(count--){
    // remove placeholder from object list and increment iterator
    object_list.erase(objIter++);

    // set object to be processed
    obj=(*objIter);

    // move to front of list if we reach the end
    // otherwise just stick the placeholder in
    if(++objIter == object_list.end()){
      object_list.push_front(placeholder);
      objIter=object_list.begin();
    } else {
      object_list.insert(objIter, placeholder);
      --objIter;
    }

    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, obj)){
	  delete obj;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TObjProcess *>::iterator iter=obj_procs.begin();
	iter!=obj_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
	(*iter)->timing=0;
      }
    }
  }
}

void TScheduler::runChar(int pulseNum)
{
  TBeing *temp;
  int count;
  TTiming timer;

  // we've already finished going through the character list, so start over
  if(!tmp_ch)
    tmp_ch=character_list;

  count=max((int)((float)mobCount/11.5), 1);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter)
      (*iter)->timing=0;

  for (; tmp_ch; tmp_ch = temp) {
    temp = tmp_ch->next;  // just for safety

    if(!count--)
      break;

    if (tmp_ch->getPosition() == POSITION_DEAD) {
      vlogf(LOG_BUG, format("Error: dead creature (%s at %d) in character_list, removing.") %
	    tmp_ch->getName() % tmp_ch->in_room);
      delete tmp_ch;
      continue;
    }
    if ((tmp_ch->getPosition() < POSITION_STUNNED) &&
	(tmp_ch->getHit() > 0)) {
      vlogf(LOG_BUG, format("Error: creature (%s) with hit > 0 found with position < stunned") %
	    tmp_ch->getName());
      vlogf(LOG_BUG, "Setting player to POSITION_STANDING");
      tmp_ch->setPosition(POSITION_STANDING);
    }

    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  timer.start();
	top.add((*iter)->name);

	if((*iter)->run(pulse, tmp_ch)){
	  delete tmp_ch;

	  if(toggleInfo[TOG_GAMELOOP]->toggle)
	    (*iter)->timing+=timer.getElapsed();

	  break;
	}

	if(toggleInfo[TOG_GAMELOOP]->toggle)
	  (*iter)->timing+=timer.getElapsed();
      }
    }
    temp = tmp_ch->next;  // just for safety
  }

  if(toggleInfo[TOG_GAMELOOP]->toggle){
    for(std::vector<TCharProcess *>::iterator iter=char_procs.begin();
	iter!=char_procs.end();++iter){
      if((*iter)->should_run(pulse.pulse)){
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)((*iter)->timing*1000000));
      }
    }
  }

}

void TScheduler::run(int pulseNum)
{
  TTiming timer;

  pulse.init(pulseNum);
  top.clear();

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run general processes
  for(std::vector<TProcess *>::iterator iter=procs.begin();
      iter!=procs.end();++iter){
    if((*iter)->should_run(pulse.pulse)){
      if(toggleInfo[TOG_GAMELOOP]->toggle)
	timer.start();
	top.add((*iter)->name);

      (*iter)->run(pulse);

      if(toggleInfo[TOG_GAMELOOP]->toggle){
	timer.end();
	vlogf(LOG_MISC, format("%i %i) %s: %i") %
	      (pulseNum % 2400) % (pulseNum%12) % (*iter)->name %
	      (int)(timer.getElapsed()*1000000));
      }
    }
  }

  pulse.init12(pulseNum);

  if(toggleInfo[TOG_GAMELOOP]->toggle)
    vlogf(LOG_MISC, format("%i %i) distributed pulses: %s") %
	  pulse.pulse % (pulse.pulse%12) % pulse.showPulses());

  // run object processes
  runObj(pulseNum);

  // run character processes
  runChar(pulseNum);

  pulse.init(pulseNum);
}

procSeedRandom::procSeedRandom(const int &p)
{
  trigger_pulse=p;
  name="procSeedRandom";
}

void procSeedRandom::run(const TPulse &) const
{
  srand(time(0));
  vlogf(LOG_SILENT, "procSeedRandom: Generated new seed.");
}
<|endoftext|>


<commit_before>#ifndef DOMImplementation_HEADER_GUARD_
#define DOMImplementation_HEADER_GUARD_

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

#include <xercesc/dom/DOMImplementationLS.hpp>

class DOMDocument;
class DOMDocumentType;

/**
 *   This class provides a way to query the capabilities of an implementation
 *   of the DOM
 */

class CDOM_EXPORT DOMImplementation : public DOMImplementationLS
{
 protected:
     DOMImplementation() {};                                      // no plain constructor
     DOMImplementation(const DOMImplementation &other) {};   // no copy construtor.
     DOMImplementation & operator = (const DOMImplementation &other) {return *this;};  // No Assignment

 public:

     //  Factory method for getting a DOMImplementation object.
     //     The DOM implementation retains ownership of the returned object.
     //     Application code should NOT delete it.
     //
 static DOMImplementation *getImplementation();

 virtual ~DOMImplementation() {};

virtual bool  hasFeature(const XMLCh *feature,  const XMLCh *version) = 0;

//  Create a new DocumentType.
//     Initially the application owns the returned DocumentType object and is responsible
//        for deleting it.  If the DocumentType is subsequently associated with a Document,
//        that document becomes the owner of the storage and will delete the document type
//        when the document is deleted.
virtual  DOMDocumentType *createDocumentType(const XMLCh *qualifiedName,
                                               const XMLCh *publicId, const XMLCh *systemId) = 0;

virtual DOMDocument *createDocument(const XMLCh *namespaceURI,
                              const XMLCh *qualifiedName, DOMDocumentType *doctype) = 0;

// Non-standard extension.  Create a completely empty document that has neither a root
//          element or a doctype node.
//
virtual DOMDocument *createDocument() = 0;
};

#endif
<commit_msg>Update API documentation for DOMImplementation.<commit_after>#ifndef DOMImplementation_HEADER_GUARD_
#define DOMImplementation_HEADER_GUARD_

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

#include <xercesc/dom/DOMImplementationLS.hpp>

class DOMDocument;
class DOMDocumentType;

/**
 * The DOMImplementation interface provides a number of methods
 * for performing operations that are independent of any particular instance
 * of the document object model.
 */

class CDOM_EXPORT DOMImplementation : public DOMImplementationLS
{

protected :
    // -----------------------------------------------------------------------
    //  Hidden constructors
    // -----------------------------------------------------------------------
    /** @name Constructors */
    //@{

        DOMImplementation() {};                                      // no plain constructor
        DOMImplementation(const DOMImplementation &other) {};   // no copy construtor.
        DOMImplementation & operator = (const DOMImplementation &other) {return *this;};  // No Assignment
    //@}

public:
    // -----------------------------------------------------------------------
    //  All constructors are hidden, just the destructor is available
    // -----------------------------------------------------------------------
    /** @name Destructor */
    //@{
    /**
     * Destructor
     *
     */
    virtual ~DOMImplementation() {};
    //@}

    // -----------------------------------------------------------------------
    // DOMImplementation interface
    // -----------------------------------------------------------------------
    /** @name Virtual DOMImplementation interface */
    //@{
    /**
     * Test if the DOM implementation implements a specific feature.
     * @param feature The name of the feature to test (case-insensitive). The
     *   values used by DOM features are defined throughout the DOM Level 2
     *   specifications and listed in the  section. The name must be an XML
     *   name. To avoid possible conflicts, as a convention, names referring
     *   to features defined outside the DOM specification should be made
     *   unique.
     * @param version This is the version number of the feature to test. In
     *   Level 2, the string can be either "2.0" or "1.0". If the version is
     *   not specified, supporting any version of the feature causes the
     *   method to return true.
     * @return true if the feature is implemented in the
     *   specified version, false otherwise.
     */
    virtual bool  hasFeature(const XMLCh *feature,  const XMLCh *version) = 0;

    /**
     * Introduced in DOM Level 2
     *
     * Creates an empty DocumentType node. Entity declarations
     * and notations are not made available. Entity reference expansions and
     * default attribute additions do not occur. It is expected that a
     * future version of the DOM will provide a way for populating a
     * DocumentType.
     * @param qualifiedName The qualified name of the document type to be
     *   created.
     * @param publicId The external subset public identifier.
     * @param systemId The external subset system identifier.
     * @return A new DocumentType node with
     *   Node.ownerDocument set to null.
     * @exception DOMException
     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name
     *   contains an illegal character.
     *
NAMESPACE_ERR: Raised if the qualifiedName is
     *   malformed.
     *
NOT_SUPPORTED_ERR: May be raised by DOM implementations which do
     *   not support the "XML" feature, if they choose not to
     *   support this method. Other features introduced in the future, by
     *   the DOM WG or in extensions defined by other groups, may also
     *   demand support for this method; please consult the definition of
     *   the feature to see if it requires this method.
     * @since DOM Level 2
     */
    virtual  DOMDocumentType *createDocumentType(const XMLCh *qualifiedName,
                                                 const XMLCh *publicId,
                                                 const XMLCh *systemId) = 0;

    /**
     * Introduced in DOM Level 2
     *
     * Creates a DOM Document object of the specified type with its document
     * element.
     * @param namespaceURI The namespace URI of the document element to
     *   create.
     * @param qualifiedName The qualified name of the document element to be
     *   created.
     * @param doctype The type of document to be created or null.
     *   When doctype is not null, its
     *   Node.ownerDocument attribute is set to the document
     *   being created.
     * @return A new Document object.
     * @exception DOMException
     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name
     *   contains an illegal character.
     *
NAMESPACE_ERR: Raised if the qualifiedName is
     *   malformed, if the qualifiedName has a prefix and the
     *   namespaceURI is null, or if the
     *   qualifiedName has a prefix that is "xml" and the
     *   namespaceURI is different from "
     *   http://www.w3.org/XML/1998/namespace" , or if the DOM
     *   implementation does not support the "XML" feature but
     *   a non-null namespace URI was provided, since namespaces were
     *   defined by XML.
     *
WRONG_DOCUMENT_ERR: Raised if doctype has already
     *   been used with a different document or was created from a different
     *   implementation.
     *
NOT_SUPPORTED_ERR: May be raised by DOM implementations which do
     *   not support the "XML" feature, if they choose not to support this
     *   method. Other features introduced in the future, by the DOM WG or
     *   in extensions defined by other groups, may also demand support for
     *   this method; please consult the definition of the feature to see if
     *   it requires this method.
     * @since DOM Level 2
     */

    virtual DOMDocument *createDocument(const XMLCh *namespaceURI,
                                        const XMLCh *qualifiedName,
                                        DOMDocumentType *doctype) = 0;

    //@}

    // -----------------------------------------------------------------------
    // Non-standard extension
    // -----------------------------------------------------------------------
    /** @name Non-standard extension */
    //@{
    /**
     * Non-standard extension
     *
     *  Factory method for getting a DOMImplementation object.
     *     The DOM implementation retains ownership of the returned object.
     *     Application code should NOT delete it.
     */
    static DOMImplementation *getImplementation();

    /**
     * Non-standard extension
     *
     * Create a completely empty document that has neither a root element or a doctype node.
     */
    virtual DOMDocument *createDocument() = 0;

    //@}
};

#endif
<|endoftext|>