<commit_before>//
// This sample demonstrates the VboMesh class by creating a simple Plane mesh with a texture mapped onto it.
// The mesh has static indices and texture coordinates, but its vertex positions are dynamic.
//

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/VboMesh.h"
#include "cinder/gl/Shader.h"
#include "cinder/gl/Texture.h"
#include "cinder/GeomIO.h"
#include "cinder/MayaCamUI.h"
#include "cinder/ImageIo.h"

#include "Resources.h"

using namespace ci;
using namespace ci::app;

using std::vector;

const int VERTICES_X = 200;
const int VERTICES_Z = 50;

class VboSampleApp : public App {
 public:
	void	setup() override;
	void	update() override;
	void	draw() override;

	void	keyDown( KeyEvent event ) override;
	void	mouseDown( MouseEvent event ) override;
	void	mouseDrag( MouseEvent event ) override;

  private:
	gl::VboMeshRef	mVboMesh;
	gl::TextureRef	mTexture;
	MayaCamUI		mMayaCam;
};

void VboSampleApp::setup()
{
	auto plane = geom::Plane().size( vec2( 20, 20 ) ).subdivisions( ivec2( VERTICES_X, VERTICES_Z ) );

	vector<gl::VboMesh::Layout> bufferLayout = {
		gl::VboMesh::Layout().usage( GL_DYNAMIC_DRAW ).attrib( geom::Attrib::POSITION, 3 ),
		gl::VboMesh::Layout().usage( GL_STATIC_DRAW ).attrib( geom::Attrib::TEX_COORD_0, 2 )
	};

	mVboMesh = gl::VboMesh::create( plane, bufferLayout );

	mTexture = gl::Texture::create( loadImage( loadResource( RES_IMAGE ) ), gl::Texture::Format().loadTopDown() );
}

void VboSampleApp::keyDown( KeyEvent event )
{
	if( event.getChar() == 'w' )
		gl::setWireframeEnabled( ! gl::isWireframeEnabled() );
}

void VboSampleApp::mouseDown( MouseEvent event )
{
	mMayaCam.mouseDown( event.getPos() );
}

void VboSampleApp::mouseDrag( MouseEvent event )
{
#if defined( CINDER_MAC )
	// remapping key modifiers so mayacam is usable on a mac touchpad
	bool isLeftDown = event.isLeftDown();
	bool isMiddleDown = event.isAltDown();
	bool isRightDown = event.isMetaDown();

	if( isMiddleDown )
		isLeftDown = false;

	mMayaCam.mouseDrag( event.getPos(), isLeftDown, isMiddleDown, isRightDown );
#else
	mMayaCam.mouseDrag( event.getPos(), event.isLeftDown(), event.isMiddleDown(), event.isRightDown() );
#endif
}

void VboSampleApp::update()
{
	const float zFreq = 0.9325f;
	const float xFreq = 1.3467f;
	float offset = getElapsedSeconds() * 5.0f;

	// Dynmaically generate our new positions based on a sin(x) + cos(z) wave
	// We set 'orphanExisting' to false so that we can also read from the position buffer, though keep
	// in mind that this isn't the most efficient way to do cpu-side updates. Consider using VboMesh::bufferAttrib() as well.
	auto mappedPosAttrib = mVboMesh->mapAttrib3f( geom::Attrib::POSITION, false );
	for( int i = 0; i < mVboMesh->getNumVertices(); i++ ) {
		vec3 &pos = *mappedPosAttrib;
		(*mappedPosAttrib).y = ( sinf( pos.x * xFreq + offset ) + cosf( pos.z * zFreq + offset ) ) / 4.0f;;
		++mappedPosAttrib;
	}
	mappedPosAttrib.unmap();
}

void VboSampleApp::draw()
{
	gl::clear( Color( 0.15f, 0.15f, 0.15f ) );

	gl::setMatrices( mMayaCam.getCamera() );

	gl::ScopedGlslProg glslScope( gl::getStockShader( gl::ShaderDef().texture() ) );
	gl::ScopedTextureBind texScope( mTexture );

	gl::draw( mVboMesh );
}

CINDER_APP( VboSampleApp, RendererGl )
<commit_msg>more sample improvements<commit_after>//
// This sample demonstrates basic usage of the VboMesh class by creating a simple Plane mesh
// with a texture mapped onto it. The mesh has static indices and texture coordinates, but
// its vertex positions are dynamic.
//

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/VboMesh.h"
#include "cinder/GeomIO.h"
#include "cinder/ImageIo.h"
#include "cinder/MayaCamUI.h"

#include "Resources.h"

using namespace ci;
using namespace ci::app;

using std::vector;

class VboSampleApp : public App {
 public:
	void	setup() override;
	void	update() override;
	void	draw() override;

	void	keyDown( KeyEvent event ) override;
	void	mouseDown( MouseEvent event ) override;
	void	mouseDrag( MouseEvent event ) override;

  private:
	gl::VboMeshRef	mVboMesh;
	gl::TextureRef	mTexture;
	MayaCamUI		mMayaCam;
};

void VboSampleApp::setup()
{
	auto plane = geom::Plane().size( vec2( 20, 20 ) ).subdivisions( ivec2( 200, 50 ) );

	vector<gl::VboMesh::Layout> bufferLayout = {
		gl::VboMesh::Layout().usage( GL_DYNAMIC_DRAW ).attrib( geom::Attrib::POSITION, 3 ),
		gl::VboMesh::Layout().usage( GL_STATIC_DRAW ).attrib( geom::Attrib::TEX_COORD_0, 2 )
	};

	mVboMesh = gl::VboMesh::create( plane, bufferLayout );

	mTexture = gl::Texture::create( loadImage( loadResource( RES_IMAGE ) ), gl::Texture::Format().loadTopDown() );
}

void VboSampleApp::keyDown( KeyEvent event )
{
	if( event.getChar() == 'w' )
		gl::setWireframeEnabled( ! gl::isWireframeEnabled() );
}

void VboSampleApp::mouseDown( MouseEvent event )
{
	mMayaCam.mouseDown( event.getPos() );
}

void VboSampleApp::mouseDrag( MouseEvent event )
{
#if defined( CINDER_MAC )
	// remapping key modifiers so mayacam is usable on a mac touchpad
	bool isLeftDown = event.isLeftDown();
	bool isMiddleDown = event.isAltDown();
	bool isRightDown = event.isMetaDown();

	if( isMiddleDown )
		isLeftDown = false;

	mMayaCam.mouseDrag( event.getPos(), isLeftDown, isMiddleDown, isRightDown );
#else
	mMayaCam.mouseDrag( event.getPos(), event.isLeftDown(), event.isMiddleDown(), event.isRightDown() );
#endif
}

void VboSampleApp::update()
{
	float offset = getElapsedSeconds() * 4.0f;

	// Dynmaically generate our new positions based on a sin(x) + cos(z) wave
	// We set 'orphanExisting' to false so that we can also read from the position buffer, though keep
	// in mind that this isn't the most efficient way to do cpu-side updates. Consider using VboMesh::bufferAttrib() as well.
	auto mappedPosAttrib = mVboMesh->mapAttrib3f( geom::Attrib::POSITION, false );
	for( int i = 0; i < mVboMesh->getNumVertices(); i++ ) {
		vec3 &pos = *mappedPosAttrib;
		mappedPosAttrib->y = sinf( pos.x * 1.1467f + offset ) * 0.323f + cosf( pos.z * 0.7325f + offset ) * 0.431f;
		++mappedPosAttrib;
	}
	mappedPosAttrib.unmap();
}

void VboSampleApp::draw()
{
	gl::clear( Color( 0.15f, 0.15f, 0.15f ) );

	gl::setMatrices( mMayaCam.getCamera() );

	gl::ScopedGlslProg glslScope( gl::getStockShader( gl::ShaderDef().texture() ) );
	gl::ScopedTextureBind texScope( mTexture );

	gl::draw( mVboMesh );
}

CINDER_APP( VboSampleApp, RendererGl )
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XclImpChangeTrack.hxx,v $
 *
 *  $Revision: 1.20 $
 *
 *  last change: $Author: obo $ $Date: 2006-07-10 13:50:28 $
 *
 *  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
 *
 ************************************************************************/

#ifndef SC_XCLIMPCHANGETRACK_HXX
#define SC_XCLIMPCHANGETRACK_HXX

#ifndef _DATETIME_HXX
#include <tools/datetime.hxx>
#endif

#ifndef SC_XIROOT_HXX
#include "xiroot.hxx"
#endif
#ifndef SC_XISTREAM_HXX
#include "xistream.hxx"
#endif

#ifndef _EXCFORM_HXX
#include "excform.hxx"
#endif
#ifndef _IMP_OP_HXX
#include "imp_op.hxx"
#endif

//___________________________________________________________________

class ScBaseCell;
class ScChangeAction;
class ScChangeTrack;
class XclImpChTrFmlConverter;

//___________________________________________________________________

struct XclImpChTrRecHeader
{
    sal_uInt32                  nSize;
    sal_uInt32                  nIndex;
    sal_uInt16                  nOpCode;
    sal_uInt16                  nAccept;
};

inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
{
    rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
    return rStrm;
}

//___________________________________________________________________

class XclImpChangeTrack : protected XclImpRoot
{
private:
    XclImpChTrRecHeader         aRecHeader;
    String                      sOldUsername;

    ScChangeTrack*              pChangeTrack;
    SotStorageStreamRef          xInStrm;        // input stream
    XclImpStream*               pStrm;          // stream import class
    sal_uInt16                  nTabIdCount;
    sal_Bool                    bGlobExit;      // global exit loop

    enum { nmBase, nmFound, nmNested }
                                eNestedMode;    // action with nested content actions

    inline sal_Bool             FoundNestedMode() { return eNestedMode == nmFound; }

    void                        DoAcceptRejectAction( ScChangeAction* pAction );
    void                        DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );

    void                        DoInsertRange( const ScRange& rRange );
    void                        DoDeleteRange( const ScRange& rRange );

    inline sal_uInt8            LookAtuInt8();
    inline double               ReadRK();
    inline sal_Bool             ReadBool();
    inline void                 Read2DAddress( ScAddress& rAddress );
    inline void                 Read2DRange( ScRange& rRange );
    SCTAB                       ReadTabNum();
    void                        ReadDateTime( DateTime& rDateTime );

    inline void                 ReadString( String& rString );
    inline void                 IgnoreString();

    sal_Bool                    CheckRecord( sal_uInt16 nOpCode );

    void                        ReadFormula(
                                    ScTokenArray*& rpTokenArray,
                                    const ScAddress& rPosition );
    void                        ReadCell(
                                    ScBaseCell*& rpCell,
                                    sal_uInt32& rFormat,
                                    sal_uInt16 nFlags,
                                    const ScAddress& rPosition );

    void                        ReadChTrInsert();           // 0x0137
    void                        ReadChTrInfo();             // 0x0138
    void                        ReadChTrCellContent();      // 0x013B
    void                        ReadChTrTabId();            // 0x013D
    void                        ReadChTrMoveRange();        // 0x0140
    void                        ReadChTrInsertTab();        // 0x014D
    void                        InitNestedMode();           // 0x014E, 0x0150
    void                        ReadNestedRecords();
    sal_Bool                    EndNestedMode();            // 0x014F, 0x0151

    void                        ReadRecords();

public:
                                XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
                                ~XclImpChangeTrack();

                                // reads extended 3D ref info following the formulas, returns sc tab nums
                                // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
    sal_Bool                    Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab );

    void                        Apply();
};

inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
{
    pStrm->PushPosition();
    sal_uInt8 nValue;
    *pStrm >> nValue;
    pStrm->PopPosition();
    return nValue;
}

inline double XclImpChangeTrack::ReadRK()
{
    return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
}

inline sal_Bool XclImpChangeTrack::ReadBool()
{
    return (pStrm->ReaduInt16() != 0);
}

inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
{
    rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
{
    rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::ReadString( String& rString )
{
    rString = pStrm->ReadUniString();
}

inline void XclImpChangeTrack::IgnoreString()
{
    pStrm->IgnoreUniString();
}

//___________________________________________________________________
// derived class for special 3D ref handling

class XclImpChTrFmlConverter : public ExcelToSc8
{
private:
    XclImpChangeTrack&          rChangeTrack;

    virtual BOOL                Read3DTabReference( XclImpStream& rStrm, SCTAB& rFirstTab, SCTAB& rLastTab );

public:
    inline                      XclImpChTrFmlConverter(
                                    const XclImpRoot& rRoot,
                                    XclImpChangeTrack& rXclChTr );
    virtual                     ~XclImpChTrFmlConverter();
};

inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
        const XclImpRoot& rRoot,
        XclImpChangeTrack& rXclChTr ) :
    ExcelToSc8( rRoot ),
    rChangeTrack( rXclChTr )
{
}

//___________________________________________________________________

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.20.498); FILE MERGED 2008/04/01 15:30:13 thb 1.20.498.3: #i85898# Stripping all external header guards 2008/04/01 12:36:18 thb 1.20.498.2: #i85898# Stripping all external header guards 2008/03/31 17:14:42 rt 1.20.498.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XclImpChangeTrack.hxx,v $
 * $Revision: 1.21 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_XCLIMPCHANGETRACK_HXX
#define SC_XCLIMPCHANGETRACK_HXX

#include <tools/datetime.hxx>
#include "xiroot.hxx"
#include "xistream.hxx"
#include "excform.hxx"
#include "imp_op.hxx"

//___________________________________________________________________

class ScBaseCell;
class ScChangeAction;
class ScChangeTrack;
class XclImpChTrFmlConverter;

//___________________________________________________________________

struct XclImpChTrRecHeader
{
    sal_uInt32                  nSize;
    sal_uInt32                  nIndex;
    sal_uInt16                  nOpCode;
    sal_uInt16                  nAccept;
};

inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
{
    rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
    return rStrm;
}

//___________________________________________________________________

class XclImpChangeTrack : protected XclImpRoot
{
private:
    XclImpChTrRecHeader         aRecHeader;
    String                      sOldUsername;

    ScChangeTrack*              pChangeTrack;
    SotStorageStreamRef          xInStrm;        // input stream
    XclImpStream*               pStrm;          // stream import class
    sal_uInt16                  nTabIdCount;
    sal_Bool                    bGlobExit;      // global exit loop

    enum { nmBase, nmFound, nmNested }
                                eNestedMode;    // action with nested content actions

    inline sal_Bool             FoundNestedMode() { return eNestedMode == nmFound; }

    void                        DoAcceptRejectAction( ScChangeAction* pAction );
    void                        DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );

    void                        DoInsertRange( const ScRange& rRange );
    void                        DoDeleteRange( const ScRange& rRange );

    inline sal_uInt8            LookAtuInt8();
    inline double               ReadRK();
    inline sal_Bool             ReadBool();
    inline void                 Read2DAddress( ScAddress& rAddress );
    inline void                 Read2DRange( ScRange& rRange );
    SCTAB                       ReadTabNum();
    void                        ReadDateTime( DateTime& rDateTime );

    inline void                 ReadString( String& rString );
    inline void                 IgnoreString();

    sal_Bool                    CheckRecord( sal_uInt16 nOpCode );

    void                        ReadFormula(
                                    ScTokenArray*& rpTokenArray,
                                    const ScAddress& rPosition );
    void                        ReadCell(
                                    ScBaseCell*& rpCell,
                                    sal_uInt32& rFormat,
                                    sal_uInt16 nFlags,
                                    const ScAddress& rPosition );

    void                        ReadChTrInsert();           // 0x0137
    void                        ReadChTrInfo();             // 0x0138
    void                        ReadChTrCellContent();      // 0x013B
    void                        ReadChTrTabId();            // 0x013D
    void                        ReadChTrMoveRange();        // 0x0140
    void                        ReadChTrInsertTab();        // 0x014D
    void                        InitNestedMode();           // 0x014E, 0x0150
    void                        ReadNestedRecords();
    sal_Bool                    EndNestedMode();            // 0x014F, 0x0151

    void                        ReadRecords();

public:
                                XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
                                ~XclImpChangeTrack();

                                // reads extended 3D ref info following the formulas, returns sc tab nums
                                // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
    sal_Bool                    Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab );

    void                        Apply();
};

inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
{
    pStrm->PushPosition();
    sal_uInt8 nValue;
    *pStrm >> nValue;
    pStrm->PopPosition();
    return nValue;
}

inline double XclImpChangeTrack::ReadRK()
{
    return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
}

inline sal_Bool XclImpChangeTrack::ReadBool()
{
    return (pStrm->ReaduInt16() != 0);
}

inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
{
    rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
{
    rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::ReadString( String& rString )
{
    rString = pStrm->ReadUniString();
}

inline void XclImpChangeTrack::IgnoreString()
{
    pStrm->IgnoreUniString();
}

//___________________________________________________________________
// derived class for special 3D ref handling

class XclImpChTrFmlConverter : public ExcelToSc8
{
private:
    XclImpChangeTrack&          rChangeTrack;

    virtual BOOL                Read3DTabReference( XclImpStream& rStrm, SCTAB& rFirstTab, SCTAB& rLastTab );

public:
    inline                      XclImpChTrFmlConverter(
                                    const XclImpRoot& rRoot,
                                    XclImpChangeTrack& rXclChTr );
    virtual                     ~XclImpChTrFmlConverter();
};

inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
        const XclImpRoot& rRoot,
        XclImpChangeTrack& rXclChTr ) :
    ExcelToSc8( rRoot ),
    rChangeTrack( rXclChTr )
{
}

//___________________________________________________________________

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/dart.h"

#include "vm/code_index_table.h"
#include "vm/freelist.h"
#include "vm/flags.h"
#include "vm/handles.h"
#include "vm/heap.h"
#include "vm/isolate.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/port.h"
#include "vm/snapshot.h"
#include "vm/stub_code.h"
#include "vm/virtual_memory.h"
#include "vm/zone.h"

namespace dart {

Isolate* Dart::vm_isolate_ = NULL;
DebugInfo* Dart::pprof_symbol_generator_ = NULL;

bool Dart::InitOnce(Dart_IsolateCreateCallback create,
                    Dart_IsolateInterruptCallback interrupt) {
  // TODO(iposva): Fix race condition here.
  if (vm_isolate_ != NULL || !Flags::Initialized()) {
    return false;
  }
  OS::InitOnce();
  VirtualMemory::InitOnce();
  Isolate::InitOnce();
  PortMap::InitOnce();
  FreeListElement::InitOnce();
  // Create the VM isolate and finish the VM initialization.
  {
    ASSERT(vm_isolate_ == NULL);
    ASSERT(Flags::Initialized());
    vm_isolate_ = Isolate::Init();
    Zone zone(vm_isolate_);
    HandleScope handle_scope(vm_isolate_);
    Heap::Init(vm_isolate_);
    ObjectStore::Init(vm_isolate_);
    Object::InitOnce();
    StubCode::InitOnce();
    Scanner::InitOnce();
  }
  Isolate::SetCurrent(NULL);  // Unregister the VM isolate from this thread.
  Isolate::SetCreateCallback(create);
  Isolate::SetInterruptCallback(interrupt);
  return true;
}

Isolate* Dart::CreateIsolate() {
  // Create a new isolate.
  Isolate* isolate = Isolate::Init();
  ASSERT(isolate != NULL);
  return isolate;
}

void Dart::InitializeIsolate(const uint8_t* snapshot_buffer, void* data) {
  // Initialize the new isolate.
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  Zone zone(isolate);
  HandleScope handle_scope(isolate);
  Heap::Init(isolate);
  ObjectStore::Init(isolate);

  if (snapshot_buffer == NULL) {
    Object::Init(isolate);
  } else {
    // Initialize from snapshot (this should replicate the functionality
    // of Object::Init(..) in a regular isolate creation path.
    Object::InitFromSnapshot(isolate);
    const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer);
    SnapshotReader reader(snapshot,
                          isolate->heap(),
                          isolate->object_store());
    reader.ReadFullSnapshot();
  }

  StubCode::Init(isolate);
  CodeIndexTable::Init(isolate);
  isolate->set_init_callback_data(data);
}

void Dart::ShutdownIsolate() {
  Isolate* isolate = Isolate::Current();
  isolate->Shutdown();
  delete isolate;
}

}  // namespace dart
<commit_msg>- Apply review feedback. Review URL: http://codereview.chromium.org//8976013<commit_after>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/dart.h"

#include "vm/code_index_table.h"
#include "vm/flags.h"
#include "vm/freelist.h"
#include "vm/handles.h"
#include "vm/heap.h"
#include "vm/isolate.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/port.h"
#include "vm/snapshot.h"
#include "vm/stub_code.h"
#include "vm/virtual_memory.h"
#include "vm/zone.h"

namespace dart {

Isolate* Dart::vm_isolate_ = NULL;
DebugInfo* Dart::pprof_symbol_generator_ = NULL;

bool Dart::InitOnce(Dart_IsolateCreateCallback create,
                    Dart_IsolateInterruptCallback interrupt) {
  // TODO(iposva): Fix race condition here.
  if (vm_isolate_ != NULL || !Flags::Initialized()) {
    return false;
  }
  OS::InitOnce();
  VirtualMemory::InitOnce();
  Isolate::InitOnce();
  PortMap::InitOnce();
  FreeListElement::InitOnce();
  // Create the VM isolate and finish the VM initialization.
  {
    ASSERT(vm_isolate_ == NULL);
    ASSERT(Flags::Initialized());
    vm_isolate_ = Isolate::Init();
    Zone zone(vm_isolate_);
    HandleScope handle_scope(vm_isolate_);
    Heap::Init(vm_isolate_);
    ObjectStore::Init(vm_isolate_);
    Object::InitOnce();
    StubCode::InitOnce();
    Scanner::InitOnce();
  }
  Isolate::SetCurrent(NULL);  // Unregister the VM isolate from this thread.
  Isolate::SetCreateCallback(create);
  Isolate::SetInterruptCallback(interrupt);
  return true;
}

Isolate* Dart::CreateIsolate() {
  // Create a new isolate.
  Isolate* isolate = Isolate::Init();
  ASSERT(isolate != NULL);
  return isolate;
}

void Dart::InitializeIsolate(const uint8_t* snapshot_buffer, void* data) {
  // Initialize the new isolate.
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  Zone zone(isolate);
  HandleScope handle_scope(isolate);
  Heap::Init(isolate);
  ObjectStore::Init(isolate);

  if (snapshot_buffer == NULL) {
    Object::Init(isolate);
  } else {
    // Initialize from snapshot (this should replicate the functionality
    // of Object::Init(..) in a regular isolate creation path.
    Object::InitFromSnapshot(isolate);
    const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer);
    SnapshotReader reader(snapshot,
                          isolate->heap(),
                          isolate->object_store());
    reader.ReadFullSnapshot();
  }

  StubCode::Init(isolate);
  CodeIndexTable::Init(isolate);
  isolate->set_init_callback_data(data);
}

void Dart::ShutdownIsolate() {
  Isolate* isolate = Isolate::Current();
  isolate->Shutdown();
  delete isolate;
}

}  // namespace dart
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<commit_msg>Extend sizeof unit test<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Vector2d()) );
  CALL_SUBTEST(verifySizeOf(Vector4f()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>
#include <atomic>
#include <algorithm>
#include <gtest/gtest.h>
#include "../algorithm.h"
#include "../parallel.h"
#include "../sequence.h"
#include "../async.h"
#include "../task.h"

class Parallel2Test : testing::Test { };

TEST(Parallel2Test, Test1)
{
	std::future<int> f1 = asyncply::_async([](int data){return data;}, 10);
	ASSERT_EQ(f1.get(), 10);
}

TEST(Parallel2Test, Test2)
{
	auto f1 = asyncply::async([](){return 15;});
	auto f2 = f1->then([](int data) {
		std::cout << "post, received: " << data << std::endl;
		return data + 6;
	});
	ASSERT_EQ(f2->get(), 15 + 6);
}

TEST(Parallel2Test, Test3)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each_sync(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test3_async)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test4)
{
	auto total_ps = asyncply::parallel_sync(
				[]()
				{
					return asyncply::sequence(1.0,
						[](double data)
						{
							return data + 1.0;
						},
						[](double data)
						{
							return data + 1.0;
						});
				},
				[]()
				{
					return asyncply::sequence(1.0,
						[](double data)
						{
							return data + 1.0;
						},
						[](double data)
						{
							return data + 1.0;
						});
				}
			);
	ASSERT_EQ(total_ps, 6);
}

TEST(Parallel2Test, Test5)
{
	std::atomic<int> total;
	total = 0;
	auto process = asyncply::parallel(
				[&total]()
				{
					std::cout << "hi" << std::endl;
					total += 1;
				},
				[&total]()
				{
					std::cout << "bye" << std::endl;
					total += 1;
				}
			);
	auto process2 = process->then([&total]()
			{
				std::cout << "no accum" << std::endl;
				total += 1;
			});
	process2->get();
	ASSERT_EQ(total, 3);
}

TEST(Parallel2Test, DISABLED_Test6)
{
	std::atomic<int> total;
	total = 0;
	{
		auto process2 = asyncply::parallel(
					[&total]()
					{
						std::cout << "hi" << std::endl;
						total += 1;
					},
					[&total]()
					{
						std::cout << "bye" << std::endl;
						total += 1;
					}
				);
		process2->then([&total]()
				{
					std::cout << "no accum" << std::endl;
					total += 1;
				});
	}
	ASSERT_EQ(total, 3);
}
<commit_msg>Update test_parallel2.cpp<commit_after>#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>
#include <atomic>
#include <algorithm>
#include <gtest/gtest.h>
#include "../algorithm.h"
#include "../parallel.h"
#include "../sequence.h"
#include "../async.h"
#include "../task.h"

class Parallel2Test : testing::Test { };

TEST(Parallel2Test, Test1)
{
	std::future<int> f1 = asyncply::_async([](int data){return data;}, 10);
	ASSERT_EQ(f1.get(), 10);
}

TEST(Parallel2Test, Test2)
{
	auto f1 = asyncply::async([](){return 15;});
	auto f2 = f1->then([](int data) {
		std::cout << "post, received: " << data << std::endl;
		return data + 6;
	});
	ASSERT_EQ(f2->get(), 15 + 6);
}

TEST(Parallel2Test, Test3)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each_sync(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test3_async)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test4)
{
	auto total_ps = asyncply::parallel_sync(
				[]()
				{
					return asyncply::sequence(1.0,
						[](double data)
						{
							return data + 1.0;
						},
						[](double data)
						{
							return data + 1.0;
						});
				},
				[]()
				{
					return asyncply::sequence(1.0,
						[](double data)
						{
							return data + 1.0;
						},
						[](double data)
						{
							return data + 1.0;
						});
				}
			);
	ASSERT_EQ(total_ps, 6);
}

TEST(Parallel2Test, Test5)
{
	std::atomic<int> total;
	total = 0;
	auto process = asyncply::parallel(
				[&total]()
				{
					std::cout << "hi" << std::endl;
					total += 1;
				},
				[&total]()
				{
					std::cout << "bye" << std::endl;
					total += 1;
				}
			);
	auto process2 = process->then([&total]()
			{
				std::cout << "no accum" << std::endl;
				total += 1;
			});
	process2->get();
	ASSERT_EQ(total, 3);
}

TEST(Parallel2Test, Test6)
{
	std::atomic<int> total;
	total = 0;
	{
		auto process2 = asyncply::parallel(
					[&total]()
					{
						std::cout << "hi" << std::endl;
						total += 1;
					},
					[&total]()
					{
						std::cout << "bye" << std::endl;
						total += 1;
					}
				);
		process2->then([&total]()
				{
					std::cout << "no accum" << std::endl;
					total += 1;
				});
	}
	ASSERT_EQ(total, 3);
}
<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2005-2007 by the FIFE Team                              *
*   fife-public@lists.sourceforge.net                                     *
*   This file is part of FIFE.                                            *
*                                                                         *
*   FIFE is free software; you can redistribute it and/or modify          *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program 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 General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
***************************************************************************/

// Standard C++ library includes
#include <stdio.h>
#include <iostream>
#include <cassert>

// 3rd party library includes
#include <boost/test/unit_test.hpp>
#include <lua.hpp>

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "map/layer.h"
#include "map/objectinfo.h"
#include "map/factory.h"
#include "vfs/vfssourcefactory.h"
#include "vfs/vfs.h"
#include "settingsmanager.h"
#include "script/lua/lunar.h"
#include "exception.cpp"
#include "script/lua/lua_ref.h"

using boost::unit_test::test_suite;
using namespace FIFE::map;
using namespace FIFE;

class DemoObj {
	public:
#define method(name) {#name, DemoObj::name}

	DemoObj(lua_State *L) {
		std::cout << "instance created" << std::endl;
	}

	~DemoObj() {
		std::cout << "instance destroyed" << std::endl;
	}

	static const char className[];
	static Lunar<DemoObj>::RegType methods[];
};

const char DemoObj::className[] = "DemoObj";
Lunar<DemoObj>::RegType DemoObj::methods[] = {
	{NULL, NULL}
};

void lua_run(lua_State *L, const char* cmd_buf) {
	if (luaL_loadbuffer(L, cmd_buf, strlen(cmd_buf), "cmd") || lua_pcall(L, 0, 0, 0)) {
		std::cerr << "Error: " << lua_tostring(L, 1) << std::endl;
		lua_pop(L, 1);
		exit(1);
	}
}

struct environment {
	lua_State * state;
	environment() {
		state = lua_open();
		luaL_openlibs(state);
		Lunar<DemoObj>::Register(state);
	}
	~environment() {
		lua_close(state);
	}
};

void simple_test()
{
	environment env;
	lua_State *L = env.state;

	const char * cmd_buf = "foo = DemoObj()";

	lua_run(L, cmd_buf);

	lua_getglobal(L, "foo");
	BOOST_CHECK( lua_isuserdata(L, 1) );

	BOOST_CHECK( lua_gettop(L) == 1 );

	FIFE::LuaRef luaref;
	luaref.ref(L, 1);
	lua_pop(L, 1);

	BOOST_CHECK( lua_gettop(L) == 0);

	lua_run(L, "_G[\"foo\"] = nil");
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	lua_gc(L, LUA_GCCOLLECT, 0);
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	luaref.unref();
	lua_gc(L, LUA_GCCOLLECT, 0);
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	lua_run(L, cmd_buf);
	luaref.ref(L, 1);
	lua_pop(L, 1);
	FIFE::LuaRef::unrefAll(L);
	BOOST_CHECK( !luaref.isValid() );
}

test_suite* init_unit_test_suite(int argc, char** argv) {
	test_suite* test = BOOST_TEST_SUITE("Lua Ref tests");
	test->add(BOOST_TEST_CASE(&simple_test), 0);
	return test;
}
<commit_msg>Added a test case that shows that anonymous functions can be held with a LuaRef, although they would get collected otherwise.<commit_after>/***************************************************************************
*   Copyright (C) 2005-2007 by the FIFE Team                              *
*   fife-public@lists.sourceforge.net                                     *
*   This file is part of FIFE.                                            *
*                                                                         *
*   FIFE is free software; you can redistribute it and/or modify          *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program 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 General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
***************************************************************************/

// Standard C++ library includes
#include <stdio.h>
#include <iostream>
#include <cassert>

// 3rd party library includes
#include <boost/test/unit_test.hpp>
#include <lua.hpp>

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "map/layer.h"
#include "map/objectinfo.h"
#include "map/factory.h"
#include "vfs/vfssourcefactory.h"
#include "vfs/vfs.h"
#include "settingsmanager.h"
#include "script/lua/lunar.h"
#include "exception.cpp"
#include "script/lua/lua_ref.h"

using boost::unit_test::test_suite;
using namespace FIFE::map;
using namespace FIFE;

class DemoObj {
	public:
#define method(name) {#name, DemoObj::name}

	DemoObj(lua_State *L) {
		std::cout << "instance created" << std::endl;
	}

	~DemoObj() {
		std::cout << "instance destroyed" << std::endl;
	}

	static const char className[];
	static Lunar<DemoObj>::RegType methods[];
};

const char DemoObj::className[] = "DemoObj";
Lunar<DemoObj>::RegType DemoObj::methods[] = {
	{NULL, NULL}
};

void lua_run(lua_State *L, const char* cmd_buf) {
	if (luaL_loadbuffer(L, cmd_buf, strlen(cmd_buf), "cmd") || lua_pcall(L, 0, 0, 0)) {
		std::cerr << "Error: " << lua_tostring(L, 1) << std::endl;
		lua_pop(L, 1);
		exit(1);
	}
}

struct environment {
	lua_State * state;
	environment() {
		state = lua_open();
		luaL_openlibs(state);
		Lunar<DemoObj>::Register(state);
	}
	~environment() {
		lua_close(state);
	}
};

void simple_test()
{
	environment env;
	lua_State *L = env.state;

	const char * cmd_buf = "foo = DemoObj()";

	lua_run(L, cmd_buf);

	lua_getglobal(L, "foo");
	BOOST_CHECK( lua_isuserdata(L, 1) );

	BOOST_CHECK( lua_gettop(L) == 1 );

	LuaRef luaref;
	luaref.ref(L, 1);
	lua_pop(L, 1);

	BOOST_CHECK( lua_gettop(L) == 0);

	lua_run(L, "_G[\"foo\"] = nil");
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	lua_gc(L, LUA_GCCOLLECT, 0);
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	luaref.unref();
	lua_gc(L, LUA_GCCOLLECT, 0);
// 	std::cout << lua_gc(L, LUA_GCCOUNT, 0) << lua_gc(L, LUA_GCCOUNTB, 0) << "B\n";
	lua_run(L, cmd_buf);
	luaref.ref(L, 1);
	lua_pop(L, 1);
	LuaRef::unrefAll(L);
	BOOST_CHECK( !luaref.isValid() );
}

void anonymous_function_test() {
	environment env;
	lua_State *L = env.state;

	LuaRef luaref;
	lua_run(L, "foo = function() print(\"Lambda called.\") end");
	lua_getglobal(L,"foo");
	luaref.ref(L,1);
	lua_pop(L,1);
	lua_run(L, "_G[\"foo\"] = nil");
	BOOST_CHECK( lua_gettop(L) == 0);
	lua_gc(L, LUA_GCCOLLECT, 0);

	lua_getglobal(L,"foo");
	BOOST_CHECK( lua_isnil(L, 1) );
	lua_pop(L,1);

	luaref.push();
	BOOST_CHECK( lua_isfunction(L, 1) );
	lua_call(L,0,0); // Should print the message

	LuaRef::unrefAll(L);
}

test_suite* init_unit_test_suite(int argc, char** argv) {
	test_suite* test = BOOST_TEST_SUITE("Lua Ref tests");
	test->add(BOOST_TEST_CASE(&simple_test), 0);
	test->add(BOOST_TEST_CASE(&anonymous_function_test), 0);
	return test;
}
<|endoftext|>


<commit_before>// @(#)root/cont:$Name:  $:$Id: TCollection.cxx,v 1.21 2003/11/05 14:05:59 brun Exp $
// Author: Fons Rademakers   13/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Collection abstract base class. This class describes the base        //
// protocol all collection classes have to implement. The ROOT          //
// collection classes always store pointers to objects that inherit     //
// from TObject. They never adopt the objects. Therefore, it is the     //
// user's responsability to take care of deleting the actual objects    //
// once they are not needed anymore. In exceptional cases, when the     //
// user is 100% sure nothing else is referencing the objects in the     //
// collection, one can delete all objects and the collection at the     //
// same time using the Delete() function.                               //
//                                                                      //
// Collections can be iterated using an iterator object (see            //
// TIterator). Depending on the concrete collection class there may be  //
// some additional methods of iterating. See the repective classes.     //
//                                                                      //
// TCollection inherits from TObject since we want to be able to have   //
// collections of collections.                                          //
//                                                                      //
// In a later release the collections may become templatized.           //
//                                                                      //
//Begin_Html
/*

*/
//End_Html
//////////////////////////////////////////////////////////////////////////

#include "TCollection.h"
#include "TClass.h"
#include "TROOT.h"
#include "TBrowser.h"
#include "TObjectTable.h"
#include "TRegexp.h"
#include "TVirtualMutex.h"

TCollection  *TCollection::fgCurrentCollection = 0;
TObjectTable *TCollection::fgGarbageCollection = 0;
Bool_t        TCollection::fgEmptyingGarbage   = kFALSE;
Int_t         TCollection::fgGarbageStack      = 0;

ClassImp(TCollection)
ClassImp(TIter)

//______________________________________________________________________________
void TCollection::AddAll(const TCollection *col)
{
   // Add all objects from collection col to this collection.

   TIter next(col);
   TObject *obj;

   while ((obj = next()))
      Add(obj);
}

//______________________________________________________________________________
void TCollection::AddVector(TObject *va_(obj1), ...)
{
   // Add all arguments to this collection.

   va_list ap;
   va_start(ap, va_(obj1));
   TObject *obj;

   Add(va_(obj1));
   while ((obj = va_arg(ap, TObject *)))
      Add(obj);
   va_end(ap);
}

//______________________________________________________________________________
Bool_t TCollection::AssertClass(TClass *cl) const
{
   // Make sure all objects in this collection inherit from class cl.

   TObject *obj;
   TIter    next(this);
   Bool_t   error = kFALSE;

   if (!cl) {
      Error("AssertClass", "class == 0");
      return kTRUE;
   }

   for (int i = 0; (obj = next()); i++)
      if (!obj->InheritsFrom(cl)) {
         Error("AssertClass", "element %d is not an instance of class %s (%s)",
               i, cl->GetName(), obj->ClassName());
         error = kTRUE;
      }
   return error;
}

//______________________________________________________________________________
void TCollection::Browse(TBrowser *b)
{
   // Browse this collection (called by TBrowser).
   // If b=0, there is no Browse call TObject::Browse(0) instead.
   //         This means TObject::Inspect() will be invoked indirectly

   TIter next(this);
   TObject *obj;

   if (b)
      while ((obj = next())) b->Add(obj);
   else
      TObject::Browse(b);
}

//______________________________________________________________________________
void TCollection::Draw(Option_t *option)
{
   // Draw all objects in this collection.
   // wildcarding supported, eg option="xxx*" draws only objects
   // with names xxx*

   TRegexp re(option,kTRUE);
   TIter next(this);
   TObject *object;
   Int_t nch = strlen(option);

   while ((object = next())) {
      TString s = object->GetName();
      if (nch && strcmp(option,object->GetName()) && s.Index(re) == kNPOS) continue;
      object->Draw(option);
   }
}

//______________________________________________________________________________
void TCollection::Dump() const
{
   // Dump all objects in this collection.

   TIter next(this);
   TObject *object;

   while ((object = next())) {
      object->Dump();
   }
}

//______________________________________________________________________________
TObject *TCollection::FindObject(const char *name) const
{
   // Find an object in this collection using its name. Requires a sequential
   // scan till the object has been found. Returns 0 if object with specified
   // name is not found.

   TIter next(this);
   TObject *obj;

   while ((obj = next()))
      if (!strcmp(name, obj->GetName())) return obj;
   return 0;
}

//______________________________________________________________________________
TObject *TCollection::operator()(const char *name) const
{
  // Find an object in this collection by name.

  return FindObject(name);
}

//______________________________________________________________________________
TObject *TCollection::FindObject(const TObject *obj) const
{
   // Find an object in this collection using the object's IsEqual()
   // member function. Requires a sequential scan till the object has
   // been found. Returns 0 if object is not found.
   // Typically this function is overridden by a more efficient version
   // in concrete collection classes (e.g. THashTable).

   TIter next(this);
   TObject *ob;

   while ((ob = next()))
      if (ob->IsEqual(obj)) return ob;
   return 0;
}

//______________________________________________________________________________
const char *TCollection::GetName() const
{
  // Return name of this collection.
  // if no name, return the collection class name.

   if (fName.Length() > 0) return fName.Data();
   return ClassName();
}

//______________________________________________________________________________
Int_t TCollection::GrowBy(Int_t delta) const
{
  // Increase the collection's capacity by delta slots.

  if (delta < 0) {
     Error("GrowBy", "delta < 0");
     delta = Capacity();
  }
  return Capacity() + TMath::Range(2, kMaxInt - Capacity(), delta);
}

//______________________________________________________________________________
Bool_t  TCollection::IsArgNull(const char *where, const TObject *obj) const
{
   // Returns true if object is a null pointer.

   return obj ? kFALSE : (Error(where, "argument is a null pointer"), kTRUE);
}

//______________________________________________________________________________
void TCollection::ls(Option_t *option) const
{
   // List (ls) all objects in this collection.
   // Wildcarding supported, eg option="xxx*" lists only objects
   // with names xxx*.

   TRegexp re(option,kTRUE);
   TIter next(this);
   TObject *object;
   char *star = 0;
   if (option) star = (char*)strchr(option,'*');

   while ((object = next())) {
      if (star) {
         TString s = object->GetName();
         if (s != option && s.Index(re) == kNPOS) continue;
      }
      object->ls(option);
   }
}

//______________________________________________________________________________
void TCollection::Paint(Option_t *option)
{
   // Paint all objects in this collection.

//   this->ForEach(TObject,Paint)((Option_t *)TObjectPaint_nxt.GetOption());
   this->ForEach(TObject,Paint)(option);
}

//______________________________________________________________________________
void TCollection::Print(Option_t *option) const
{
   // Print all objects in this collection.
   // Wildcarding supported, eg option="xxx*" prints only objects
   // with names xxx*.

   TRegexp re(option,kTRUE);
   Int_t nch = (option ? strlen(option) : 0);
   TIter next(this);
   TObject *object;

   while ((object = next())) {
      TString s = object->GetName();
      if (nch && s != option && s.Index(re) == kNPOS) continue;
      object->Print(option);
   }
}

//______________________________________________________________________________
void TCollection::RecursiveRemove(TObject *obj)
{
   // Remove object from this collection and recursively remove the object
   // from all other objects (and collections).

   if (!obj) return;

   // Scan list and remove obj in the list itself
   while (Remove(obj))
      ;

   // Scan again the list and invoke RecursiveRemove for all objects
   TIter next(this);
   TObject *object;

   while ((object = next())) {
      if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
   }
}

//______________________________________________________________________________
void TCollection::RemoveAll(TCollection *col)
{
   // Remove all objects in collection col from this collection.

   TIter next(col);
   TObject *obj;

   while ((obj = next()))
      Remove(obj);
}

//_______________________________________________________________________
void TCollection::Streamer(TBuffer &b)
{
   // Stream all objects in the collection to or from the I/O buffer.

   Int_t nobjects;
   TObject *obj;
   UInt_t R__s, R__c;

   if (b.IsReading()) {
      Version_t v = b.ReadVersion(&R__s, &R__c);
      if (v > 2)
         TObject::Streamer(b);
      if (v > 1)
         fName.Streamer(b);
      b >> nobjects;
      for (Int_t i = 0; i < nobjects; i++) {
         b >> obj;
         Add(obj);
      }
      b.CheckByteCount(R__s, R__c,TCollection::IsA());
   } else {
      R__c = b.WriteVersion(TCollection::IsA(), kTRUE);
      TObject::Streamer(b);
      fName.Streamer(b);
      nobjects = GetSize();
      b << nobjects;

      TIter next(this);

      while ((obj = next())) {
         b << obj;
      }
      b.SetByteCount(R__c, kTRUE);
   }
}

//______________________________________________________________________________
Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize)
{
   // Write all objects in this collection. By default all objects in
   // the collection are written individually (each object gets its
   // own key). Note, this is not recursive, collections in the collection
   // are written with a single key. To write all objects using a single
   // key specify a name and set option to TObject::kSingleKey (i.e. 1).

   if ((option & kSingleKey)) {
      return TObject::Write(name, option, bsize);
   } else {
      option &= ~kSingleKey;
      Int_t nbytes = 0;
      TIter next(this);
      TObject *obj;
      while ((obj = next())) {
         nbytes += obj->Write(name, option, bsize);
      }
      return nbytes;
   }
}

// -------------------- Static data members access -----------------------------
//______________________________________________________________________________
TCollection *TCollection::GetCurrentCollection()
{
   return fgCurrentCollection;
}

//______________________________________________________________________________
void TCollection::SetCurrentCollection()
{
   fgCurrentCollection = this;
}

//______________________________________________________________________________
void TCollection::StartGarbageCollection()
{
   R__LOCKGUARD(gContainerMutex);
   if (!fgGarbageCollection) {
      fgGarbageCollection = new TObjectTable;
      fgEmptyingGarbage   = kFALSE;
      fgGarbageStack      = 0;
   }
   fgGarbageStack++;
}

//______________________________________________________________________________
void TCollection::EmptyGarbageCollection()
{
   R__LOCKGUARD(gContainerMutex);
   if (fgGarbageStack > 0) fgGarbageStack--;
   if (fgGarbageCollection && fgGarbageStack == 0 && fgEmptyingGarbage == kFALSE) {
      fgEmptyingGarbage = kTRUE;
      fgGarbageCollection->Delete();
      fgEmptyingGarbage = kFALSE;
      SafeDelete(fgGarbageCollection);
   }
}

//______________________________________________________________________________
void TCollection::GarbageCollect(TObject *obj)
{
   R__LOCKGUARD(gContainerMutex);
   if (fgGarbageCollection) {
      if (!fgEmptyingGarbage) {
         fgGarbageCollection->Add(obj);
      } else
         delete obj;
   } else
      delete obj;
}

//______________________________________________________________________________
TIter::TIter(const TIter &iter)
{
   // Copy a TIter. This involves allocating a new TIterator of the right
   // sub class and assigning it with the original.

   if (iter.fIterator) {
      fIterator = iter.GetCollection()->MakeIterator();
      fIterator->operator=(*iter.fIterator);
   } else
      fIterator = 0;
}

//______________________________________________________________________________
TIter &TIter::operator=(const TIter &rhs)
{
   // Assigning an TIter to another. This involves allocatiing a new TIterator
   // of the right sub class and assigning it with the original.

   if (this != &rhs) {
      if (rhs.fIterator) {
         delete fIterator;
         fIterator = rhs.GetCollection()->MakeIterator();
         fIterator->operator=(*rhs.fIterator);
      }
   }
   return *this;
}
<commit_msg>correct description of TCollection::Write() where all objects are recursively written individually if the kSingleKey option is not specfied.<commit_after>// @(#)root/cont:$Name:  $:$Id: TCollection.cxx,v 1.22 2004/01/23 23:52:56 rdm Exp $
// Author: Fons Rademakers   13/08/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Collection abstract base class. This class describes the base        //
// protocol all collection classes have to implement. The ROOT          //
// collection classes always store pointers to objects that inherit     //
// from TObject. They never adopt the objects. Therefore, it is the     //
// user's responsability to take care of deleting the actual objects    //
// once they are not needed anymore. In exceptional cases, when the     //
// user is 100% sure nothing else is referencing the objects in the     //
// collection, one can delete all objects and the collection at the     //
// same time using the Delete() function.                               //
//                                                                      //
// Collections can be iterated using an iterator object (see            //
// TIterator). Depending on the concrete collection class there may be  //
// some additional methods of iterating. See the repective classes.     //
//                                                                      //
// TCollection inherits from TObject since we want to be able to have   //
// collections of collections.                                          //
//                                                                      //
// In a later release the collections may become templatized.           //
//                                                                      //
//Begin_Html
/*

*/
//End_Html
//////////////////////////////////////////////////////////////////////////

#include "TCollection.h"
#include "TClass.h"
#include "TROOT.h"
#include "TBrowser.h"
#include "TObjectTable.h"
#include "TRegexp.h"
#include "TVirtualMutex.h"

TCollection  *TCollection::fgCurrentCollection = 0;
TObjectTable *TCollection::fgGarbageCollection = 0;
Bool_t        TCollection::fgEmptyingGarbage   = kFALSE;
Int_t         TCollection::fgGarbageStack      = 0;

ClassImp(TCollection)
ClassImp(TIter)

//______________________________________________________________________________
void TCollection::AddAll(const TCollection *col)
{
   // Add all objects from collection col to this collection.

   TIter next(col);
   TObject *obj;

   while ((obj = next()))
      Add(obj);
}

//______________________________________________________________________________
void TCollection::AddVector(TObject *va_(obj1), ...)
{
   // Add all arguments to this collection.

   va_list ap;
   va_start(ap, va_(obj1));
   TObject *obj;

   Add(va_(obj1));
   while ((obj = va_arg(ap, TObject *)))
      Add(obj);
   va_end(ap);
}

//______________________________________________________________________________
Bool_t TCollection::AssertClass(TClass *cl) const
{
   // Make sure all objects in this collection inherit from class cl.

   TObject *obj;
   TIter    next(this);
   Bool_t   error = kFALSE;

   if (!cl) {
      Error("AssertClass", "class == 0");
      return kTRUE;
   }

   for (int i = 0; (obj = next()); i++)
      if (!obj->InheritsFrom(cl)) {
         Error("AssertClass", "element %d is not an instance of class %s (%s)",
               i, cl->GetName(), obj->ClassName());
         error = kTRUE;
      }
   return error;
}

//______________________________________________________________________________
void TCollection::Browse(TBrowser *b)
{
   // Browse this collection (called by TBrowser).
   // If b=0, there is no Browse call TObject::Browse(0) instead.
   //         This means TObject::Inspect() will be invoked indirectly

   TIter next(this);
   TObject *obj;

   if (b)
      while ((obj = next())) b->Add(obj);
   else
      TObject::Browse(b);
}

//______________________________________________________________________________
void TCollection::Draw(Option_t *option)
{
   // Draw all objects in this collection.
   // wildcarding supported, eg option="xxx*" draws only objects
   // with names xxx*

   TRegexp re(option,kTRUE);
   TIter next(this);
   TObject *object;
   Int_t nch = strlen(option);

   while ((object = next())) {
      TString s = object->GetName();
      if (nch && strcmp(option,object->GetName()) && s.Index(re) == kNPOS) continue;
      object->Draw(option);
   }
}

//______________________________________________________________________________
void TCollection::Dump() const
{
   // Dump all objects in this collection.

   TIter next(this);
   TObject *object;

   while ((object = next())) {
      object->Dump();
   }
}

//______________________________________________________________________________
TObject *TCollection::FindObject(const char *name) const
{
   // Find an object in this collection using its name. Requires a sequential
   // scan till the object has been found. Returns 0 if object with specified
   // name is not found.

   TIter next(this);
   TObject *obj;

   while ((obj = next()))
      if (!strcmp(name, obj->GetName())) return obj;
   return 0;
}

//______________________________________________________________________________
TObject *TCollection::operator()(const char *name) const
{
  // Find an object in this collection by name.

  return FindObject(name);
}

//______________________________________________________________________________
TObject *TCollection::FindObject(const TObject *obj) const
{
   // Find an object in this collection using the object's IsEqual()
   // member function. Requires a sequential scan till the object has
   // been found. Returns 0 if object is not found.
   // Typically this function is overridden by a more efficient version
   // in concrete collection classes (e.g. THashTable).

   TIter next(this);
   TObject *ob;

   while ((ob = next()))
      if (ob->IsEqual(obj)) return ob;
   return 0;
}

//______________________________________________________________________________
const char *TCollection::GetName() const
{
  // Return name of this collection.
  // if no name, return the collection class name.

   if (fName.Length() > 0) return fName.Data();
   return ClassName();
}

//______________________________________________________________________________
Int_t TCollection::GrowBy(Int_t delta) const
{
  // Increase the collection's capacity by delta slots.

  if (delta < 0) {
     Error("GrowBy", "delta < 0");
     delta = Capacity();
  }
  return Capacity() + TMath::Range(2, kMaxInt - Capacity(), delta);
}

//______________________________________________________________________________
Bool_t  TCollection::IsArgNull(const char *where, const TObject *obj) const
{
   // Returns true if object is a null pointer.

   return obj ? kFALSE : (Error(where, "argument is a null pointer"), kTRUE);
}

//______________________________________________________________________________
void TCollection::ls(Option_t *option) const
{
   // List (ls) all objects in this collection.
   // Wildcarding supported, eg option="xxx*" lists only objects
   // with names xxx*.

   TRegexp re(option,kTRUE);
   TIter next(this);
   TObject *object;
   char *star = 0;
   if (option) star = (char*)strchr(option,'*');

   while ((object = next())) {
      if (star) {
         TString s = object->GetName();
         if (s != option && s.Index(re) == kNPOS) continue;
      }
      object->ls(option);
   }
}

//______________________________________________________________________________
void TCollection::Paint(Option_t *option)
{
   // Paint all objects in this collection.

//   this->ForEach(TObject,Paint)((Option_t *)TObjectPaint_nxt.GetOption());
   this->ForEach(TObject,Paint)(option);
}

//______________________________________________________________________________
void TCollection::Print(Option_t *option) const
{
   // Print all objects in this collection.
   // Wildcarding supported, eg option="xxx*" prints only objects
   // with names xxx*.

   TRegexp re(option,kTRUE);
   Int_t nch = (option ? strlen(option) : 0);
   TIter next(this);
   TObject *object;

   while ((object = next())) {
      TString s = object->GetName();
      if (nch && s != option && s.Index(re) == kNPOS) continue;
      object->Print(option);
   }
}

//______________________________________________________________________________
void TCollection::RecursiveRemove(TObject *obj)
{
   // Remove object from this collection and recursively remove the object
   // from all other objects (and collections).

   if (!obj) return;

   // Scan list and remove obj in the list itself
   while (Remove(obj))
      ;

   // Scan again the list and invoke RecursiveRemove for all objects
   TIter next(this);
   TObject *object;

   while ((object = next())) {
      if (object->TestBit(kNotDeleted)) object->RecursiveRemove(obj);
   }
}

//______________________________________________________________________________
void TCollection::RemoveAll(TCollection *col)
{
   // Remove all objects in collection col from this collection.

   TIter next(col);
   TObject *obj;

   while ((obj = next()))
      Remove(obj);
}

//_______________________________________________________________________
void TCollection::Streamer(TBuffer &b)
{
   // Stream all objects in the collection to or from the I/O buffer.

   Int_t nobjects;
   TObject *obj;
   UInt_t R__s, R__c;

   if (b.IsReading()) {
      Version_t v = b.ReadVersion(&R__s, &R__c);
      if (v > 2)
         TObject::Streamer(b);
      if (v > 1)
         fName.Streamer(b);
      b >> nobjects;
      for (Int_t i = 0; i < nobjects; i++) {
         b >> obj;
         Add(obj);
      }
      b.CheckByteCount(R__s, R__c,TCollection::IsA());
   } else {
      R__c = b.WriteVersion(TCollection::IsA(), kTRUE);
      TObject::Streamer(b);
      fName.Streamer(b);
      nobjects = GetSize();
      b << nobjects;

      TIter next(this);

      while ((obj = next())) {
         b << obj;
      }
      b.SetByteCount(R__c, kTRUE);
   }
}

//______________________________________________________________________________
Int_t TCollection::Write(const char *name, Int_t option, Int_t bsize)
{
   // Write all objects in this collection. By default all objects in
   // the collection are written individually (each object gets its
   // own key). Note, this is recursive, i.e. objects in collections
   // in the collection are also written individually. To write all
   // objects using a single key specify a name and set option to
   // TObject::kSingleKey (i.e. 1).

   if ((option & kSingleKey)) {
      return TObject::Write(name, option, bsize);
   } else {
      option &= ~kSingleKey;
      Int_t nbytes = 0;
      TIter next(this);
      TObject *obj;
      while ((obj = next())) {
         nbytes += obj->Write(name, option, bsize);
      }
      return nbytes;
   }
}

// -------------------- Static data members access -----------------------------
//______________________________________________________________________________
TCollection *TCollection::GetCurrentCollection()
{
   return fgCurrentCollection;
}

//______________________________________________________________________________
void TCollection::SetCurrentCollection()
{
   fgCurrentCollection = this;
}

//______________________________________________________________________________
void TCollection::StartGarbageCollection()
{
   R__LOCKGUARD(gContainerMutex);
   if (!fgGarbageCollection) {
      fgGarbageCollection = new TObjectTable;
      fgEmptyingGarbage   = kFALSE;
      fgGarbageStack      = 0;
   }
   fgGarbageStack++;
}

//______________________________________________________________________________
void TCollection::EmptyGarbageCollection()
{
   R__LOCKGUARD(gContainerMutex);
   if (fgGarbageStack > 0) fgGarbageStack--;
   if (fgGarbageCollection && fgGarbageStack == 0 && fgEmptyingGarbage == kFALSE) {
      fgEmptyingGarbage = kTRUE;
      fgGarbageCollection->Delete();
      fgEmptyingGarbage = kFALSE;
      SafeDelete(fgGarbageCollection);
   }
}

//______________________________________________________________________________
void TCollection::GarbageCollect(TObject *obj)
{
   R__LOCKGUARD(gContainerMutex);
   if (fgGarbageCollection) {
      if (!fgEmptyingGarbage) {
         fgGarbageCollection->Add(obj);
      } else
         delete obj;
   } else
      delete obj;
}

//______________________________________________________________________________
TIter::TIter(const TIter &iter)
{
   // Copy a TIter. This involves allocating a new TIterator of the right
   // sub class and assigning it with the original.

   if (iter.fIterator) {
      fIterator = iter.GetCollection()->MakeIterator();
      fIterator->operator=(*iter.fIterator);
   } else
      fIterator = 0;
}

//______________________________________________________________________________
TIter &TIter::operator=(const TIter &rhs)
{
   // Assigning an TIter to another. This involves allocatiing a new TIterator
   // of the right sub class and assigning it with the original.

   if (this != &rhs) {
      if (rhs.fIterator) {
         delete fIterator;
         fIterator = rhs.GetCollection()->MakeIterator();
         fIterator->operator=(*rhs.fIterator);
      }
   }
   return *this;
}
<|endoftext|>


<commit_before>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QtTest/QtTest>

#include "json_driver.h"
#include "serializer.h"

#include <QtCore/QVariant>

using namespace QJSon;

class TestJSonDriver: public QObject
{
  Q_OBJECT
  private slots:
    void parseNonAsciiString();
    void parseSimpleObject();
    void parseEmptyObject();
    void parseUrl();
    void parseMultipleObject();

    void parseSimpleArray();
    void parseInvalidObject();
    void parseMultipleArray();

    void testTrueFalseNullValues();
    void testEscapeChars();
    void testNumbers();

    void testReadWriteEmptyDocument();
    void testReadWrite();
    void testReadWrite_data();
};

Q_DECLARE_METATYPE(QVariant)

void TestJSonDriver::parseSimpleObject() {
  QString json = "{\"foo\":\"bar\"}";
  QVariantMap map;
  map.insert ("foo", "bar");
  QVariant expected(map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseEmptyObject() {
  QString json = "{}";
  QVariantMap map;
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseInvalidObject() {
  QString json = "{\"foo\":\"bar\"";

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (!ok);
}

void TestJSonDriver::parseNonAsciiString() {
  QString json = "{\"artist\":\"Queensr\\u00ffche\"}";
  QVariantMap map;

  QChar unicode_char (0x00ff);
  QString unicode_string;
  unicode_string.setUnicode(&unicode_char, 1);
  unicode_string = "Queensr" + unicode_string + "che";

  map.insert ("artist", unicode_string);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleObject() {
  //put also some extra spaces inside the json string
  QString json = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
  QVariantMap map;
  map.insert ("foo", "bar");
  map.insert ("number", 51.3);
  QVariantList list;
  list.append (QString("item1"));
  list.append (QString("123"));
  map.insert ("array", list);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QVERIFY (result.toMap()["number"].canConvert<float>());
  QVERIFY (result.toMap()["array"].canConvert<QVariantList>());
}

void TestJSonDriver::parseUrl(){
  //"http:\/\/www.last.fm\/venue\/8926427"
  QString json = "[\"http:\\/\\/www.last.fm\\/venue\\/8926427\"]";
  QVariantList list;
  list.append (QVariant(QString("http://www.last.fm/venue/8926427")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

 void TestJSonDriver::parseSimpleArray() {
  QString json = "[\"foo\",\"bar\"]";
  QVariantList list;
  list.append (QVariant(QString("foo")));
  list.append (QVariant(QString("bar")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleArray() {
  //put also some extra spaces inside the json string
  QString json = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
  QVariantMap map;
  map.insert ("foo", "bar");

  QVariantList array;
  array.append (QString("item1"));
  array.append (123);

  QVariantList list;
  list.append (map);
  list.append (QString("number"));
  list.append (QString("51.3"));
  list.append ((QVariant) array);

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testTrueFalseNullValues() {
  QString json = "[true,false, null, {\"foo\" : true}]";
  QVariantList list;
  list.append (QVariant(true));
  list.append (QVariant(false));
  list.append (QVariant());
  QVariantMap map;
  map.insert ("foo", true);
  list.append (map);
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QCOMPARE (result.toList().at(0).toBool(), true);
  QCOMPARE (result.toList().at(1).toBool(), false);
  QVERIFY (result.toList().at(2).isNull());
}

void TestJSonDriver::testEscapeChars() {
  QString json = "[\"\\b \\f \\n \\r \\t \", \" \\\\ \\/ \\\" \", \"http://foo.com\"]";

  QVariantList list;
  list.append (QVariant("\b \f \n \r \t "));
  list.append (QVariant(" \\\\ / \\\" "));
  list.append (QVariant("http://foo.com"));

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testNumbers() {
  QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
  QVariantList list;
  list.append (QVariant(1));
  list.append (QVariant(2.4));
  list.append (QVariant(-100));
  list.append (QVariant(-3.4));
  list.append (QVariant("-5e+"));
  list.append (QVariant("2e"));
  list.append (QVariant("3e+"));
  list.append (QVariant("4.3E"));
  list.append (QVariant("5.4E-"));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);

  QVariantList numbers = result.toList();
  QCOMPARE( numbers[0].type(),QVariant::Int );
  QCOMPARE( numbers[1].type(), QVariant::Double );
  QCOMPARE( numbers[2].type(), QVariant::Int );
  QCOMPARE( numbers[3].type(), QVariant::Double );
}

void TestJSonDriver::testReadWriteEmptyDocument()
{
  QString json = QString("");
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
  QVERIFY( !serialized.isNull() );
  QVERIFY( serialized.isEmpty() );
}

void TestJSonDriver::testReadWrite()
{
  QFETCH( QString, json );
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
//  qWarning() << serialized;
  QVariant writtenThenRead = driver.parse( serialized, &ok );
  QCOMPARE( result, writtenThenRead );
}

void TestJSonDriver::testReadWrite_data()
{
    QTest::addColumn<QString>( "json" );

    // array tests
    QTest::newRow( "empty array" ) << "[]";
    QTest::newRow( "basic array" ) << "[\"foo\",\"bar\"]";
    QTest::newRow( "single int array" ) << "[6]";
    QTest::newRow( "int array" ) << "[6,5,6,7]";
    const QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
    QTest::newRow( "array of various numbers" ) << json;

    // document tests
    QTest::newRow( "empty object" ) << "{}";
    QTest::newRow( "basic document" ) << "{\"foo\":\"bar\"}";
    QTest::newRow( "object with ints" ) << "{\"foo\":6}";
    QString json2 = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
    QTest::newRow( "complicated document" ) << json2;

    // more complex cases
    const QString json3 = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
    QTest::newRow( "complicated array" ) << json3;
}

QTEST_MAIN(TestJSonDriver)
#include "moc_testjsondriver.cxx"
<commit_msg>two more test cases with leading zeros<commit_after>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QtTest/QtTest>

#include "json_driver.h"
#include "serializer.h"

#include <QtCore/QVariant>

using namespace QJSon;

class TestJSonDriver: public QObject
{
  Q_OBJECT
  private slots:
    void parseNonAsciiString();
    void parseSimpleObject();
    void parseEmptyObject();
    void parseUrl();
    void parseMultipleObject();

    void parseSimpleArray();
    void parseInvalidObject();
    void parseMultipleArray();

    void testTrueFalseNullValues();
    void testEscapeChars();
    void testNumbers();

    void testReadWriteEmptyDocument();
    void testReadWrite();
    void testReadWrite_data();
};

Q_DECLARE_METATYPE(QVariant)

void TestJSonDriver::parseSimpleObject() {
  QString json = "{\"foo\":\"bar\"}";
  QVariantMap map;
  map.insert ("foo", "bar");
  QVariant expected(map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseEmptyObject() {
  QString json = "{}";
  QVariantMap map;
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseInvalidObject() {
  QString json = "{\"foo\":\"bar\"";

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (!ok);
}

void TestJSonDriver::parseNonAsciiString() {
  QString json = "{\"artist\":\"Queensr\\u00ffche\"}";
  QVariantMap map;

  QChar unicode_char (0x00ff);
  QString unicode_string;
  unicode_string.setUnicode(&unicode_char, 1);
  unicode_string = "Queensr" + unicode_string + "che";

  map.insert ("artist", unicode_string);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleObject() {
  //put also some extra spaces inside the json string
  QString json = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
  QVariantMap map;
  map.insert ("foo", "bar");
  map.insert ("number", 51.3);
  QVariantList list;
  list.append (QString("item1"));
  list.append (QString("123"));
  map.insert ("array", list);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QVERIFY (result.toMap()["number"].canConvert<float>());
  QVERIFY (result.toMap()["array"].canConvert<QVariantList>());
}

void TestJSonDriver::parseUrl(){
  //"http:\/\/www.last.fm\/venue\/8926427"
  QString json = "[\"http:\\/\\/www.last.fm\\/venue\\/8926427\"]";
  QVariantList list;
  list.append (QVariant(QString("http://www.last.fm/venue/8926427")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

 void TestJSonDriver::parseSimpleArray() {
  QString json = "[\"foo\",\"bar\"]";
  QVariantList list;
  list.append (QVariant(QString("foo")));
  list.append (QVariant(QString("bar")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleArray() {
  //put also some extra spaces inside the json string
  QString json = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
  QVariantMap map;
  map.insert ("foo", "bar");

  QVariantList array;
  array.append (QString("item1"));
  array.append (123);

  QVariantList list;
  list.append (map);
  list.append (QString("number"));
  list.append (QString("51.3"));
  list.append ((QVariant) array);

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testTrueFalseNullValues() {
  QString json = "[true,false, null, {\"foo\" : true}]";
  QVariantList list;
  list.append (QVariant(true));
  list.append (QVariant(false));
  list.append (QVariant());
  QVariantMap map;
  map.insert ("foo", true);
  list.append (map);
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QCOMPARE (result.toList().at(0).toBool(), true);
  QCOMPARE (result.toList().at(1).toBool(), false);
  QVERIFY (result.toList().at(2).isNull());
}

void TestJSonDriver::testEscapeChars() {
  QString json = "[\"\\b \\f \\n \\r \\t \", \" \\\\ \\/ \\\" \", \"http://foo.com\"]";

  QVariantList list;
  list.append (QVariant("\b \f \n \r \t "));
  list.append (QVariant(" \\\\ / \\\" "));
  list.append (QVariant("http://foo.com"));

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testNumbers() {
  QString json = "[1,2.4, -100, -3.4, 1.00004, 01.01, -5e+, 2e,3e+,4.3E,5.4E-]";
  QVariantList list;
  list.append (QVariant(1));
  list.append (QVariant(2.4));
  list.append (QVariant(-100));
  list.append (QVariant(-3.4));
  list.append (QVariant(1.00004));
  list.append (QVariant(1.01));
  list.append (QVariant("-5e+"));
  list.append (QVariant("2e"));
  list.append (QVariant("3e+"));
  list.append (QVariant("4.3E"));
  list.append (QVariant("5.4E-"));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);

  QVariantList numbers = result.toList();
  QCOMPARE( numbers[0].type(),QVariant::Int );
  QCOMPARE( numbers[1].type(), QVariant::Double );
  QCOMPARE( numbers[2].type(), QVariant::Int );
  QCOMPARE( numbers[3].type(), QVariant::Double );
}

void TestJSonDriver::testReadWriteEmptyDocument()
{
  QString json = QString("");
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
  QVERIFY( !serialized.isNull() );
  QVERIFY( serialized.isEmpty() );
}

void TestJSonDriver::testReadWrite()
{
  QFETCH( QString, json );
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
//  qWarning() << serialized;
  QVariant writtenThenRead = driver.parse( serialized, &ok );
  QCOMPARE( result, writtenThenRead );
}

void TestJSonDriver::testReadWrite_data()
{
    QTest::addColumn<QString>( "json" );

    // array tests
    QTest::newRow( "empty array" ) << "[]";
    QTest::newRow( "basic array" ) << "[\"foo\",\"bar\"]";
    QTest::newRow( "single int array" ) << "[6]";
    QTest::newRow( "int array" ) << "[6,5,6,7]";
    const QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
    QTest::newRow( "array of various numbers" ) << json;

    // document tests
    QTest::newRow( "empty object" ) << "{}";
    QTest::newRow( "basic document" ) << "{\"foo\":\"bar\"}";
    QTest::newRow( "object with ints" ) << "{\"foo\":6}";
    QString json2 = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
    QTest::newRow( "complicated document" ) << json2;

    // more complex cases
    const QString json3 = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
    QTest::newRow( "complicated array" ) << json3;
}

QTEST_MAIN(TestJSonDriver)
#include "moc_testjsondriver.cxx"
<|endoftext|>