<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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/.
 */

#ifndef DATASERIES_HXX
#define DATASERIES_HXX

#include <rtl/ustring.hxx>
#include <mdds/multi_type_vector.hpp>
#include <mdds/multi_type_vector_trait.hpp>
#include <vector>
#include <map>

#include <com/sun/star/uno/Any.h>

namespace chart {

class DataSeries
{
public:
    typedef mdds::multi_type_vector<mdds::mtv::element_block_func> DataSeriesType;

    DataSeriesType getDataSeries();

    size_t size();
    double getValue(size_t nIndex);

private:
    OUString maLabel;
    DataSeriesType maDataSeries;

};

/**
 * point properties overwrite series properties
 */
struct DataSeriesProperties
{
    typedef std::map< OUString, com::sun::star::uno::Any > PropertyMap;
    PropertyMap aSeriesProps;
    std::vector< PropertyMap > aPointProps;
};

struct Axis
{
    double nMin;
    double nMax;
    bool bLog;
    bool bInverseDirection;
};

struct DataSeriesState
{
    DataSeries aXValue;
    DataSeries aYValue;
    DataSeriesProperties aProperties;
    std::map<OUString, DataSeries> aMapProperties;
    Axis aXAxis;
    Axis aYAxis;
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>some small cosmetic changes<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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/.
 */

#ifndef DATASERIES_HXX
#define DATASERIES_HXX

#include <rtl/ustring.hxx>
#include <mdds/multi_type_vector.hpp>
#include <mdds/multi_type_vector_trait.hpp>
#include <vector>
#include <map>

#include <com/sun/star/uno/Any.h>

namespace chart {

class DataSequence
{
public:
    typedef mdds::multi_type_vector<mdds::mtv::element_block_func> DataSeriesType;

    // used for fast iteration through data series
    // allows to easily skip empty data ranges
    DataSeriesType getDataSeries();

    size_t size();
    double getValue(size_t nIndex);

private:
    OUString maLabel;
    DataSeriesType maDataSeries;

};

/**
 * point properties overwrite series properties
 */
struct DataSeriesProperties
{
    typedef std::map< OUString, com::sun::star::uno::Any > PropertyMap;
    PropertyMap aSeriesProps;
    // we might want to switch to multi_type_vector for better memory usage
    // hopefully this vector is empty most of the time
    std::vector< PropertyMap > aPointProps;

    com::sun::star::chart::MissingValueTreatment eMissingValueTreatment;
};

struct Axis
{
    double nMin;
    double nMax;
    bool bLog;
    bool bInverseDirection;
};

struct DataSeriesState
{
    // length of the data series is min(aXValue.size(), aYValue.size());
    DataSequence aXValue;
    DataSequence aYValue;
    DataSeriesProperties aProperties;
    // also contains bubble chart bubble size
    // apply values to properties with functor
    std::map<OUString, DataSeries> aMappedProperties;
    Axis aXAxis;
    Axis aYAxis;
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include <malloc.h>
#include <stdarg.h>
#include <string.h>
#include <io.h>

#include "Resource.h"

#define USE_NAMETREES
#define filesize(fileptr) (filelength(fileno(fileptr)))

CResource::CResource()
{
	drs=NULL;
	Init();
}

CResource::~CResource()
{
	ShutDown();
}

bool CResource::Init()
{
	ShutDown();
	return true;
}

void CResource::ShutDown()
{
	CloseResource();
}

void CResource::DestroyNameTree()
{
	nametree.Destroy();
}

bool CResource::BuildNameTree()
{
	int i;
	for (i=0;i<NUM_RES_ENTRIES;i++)
	{
		if (drstable[i].foffset!=0)
		{
			if (!nametree.AddLeaf(drstable[i].fname,i))
			{
				nametree.Destroy();
				return false;
			}
		}
	}
	return true;
}

int CResource::SearchNameTree(char *name)
{
	return nametree.FindLeaf(name);
}

int CResource::FindEntryBrutal(char *entryname)
{
	int i;
	if (drs!=NULL)
	{
		for (i=0;i<NUM_RES_ENTRIES;i++)
		{
			if (!stricmp(entryname,drstable[i].fname))
				return i;
		}
	}
	return -1;
}

bool CResource::OpenResource(const char *filename)
{
	int i;
	uint32_t size,drssize;
	const int hdrlen=8;
	char cmphdr[hdrlen];
	char idhdr[hdrlen]={'v','s',' ','d','2',0,0,0};
	if (filename==NULL || filename[0]==0)
		return false;
	if (strcmp(filename, path)==0)
		return true;
	memset(cmphdr, 0, sizeof(cmphdr));
	CloseResource();
	drs=fopen((const char *)filename, "rb");
	if (drs==NULL)
		return false;
	size=fread(cmphdr,1,hdrlen,drs);
	if (size==hdrlen)
	{
		size=memcmp(cmphdr,idhdr, hdrlen);
		if (size==0)
		{
			for (i=0,size=0,drssize=0;i<NUM_RES_ENTRIES;i++)
			{
				memset(drstable[i].fname,0,sizeof(drstable[i].fname));
				size+=fread(&drstable[i].fname,1,sizeof(drstable[i].fname),drs);
				size+=fread(&drstable[i].foffset,1,sizeof(drstable[i].foffset),drs);
				size+=fread(&drstable[i].fsize,1,sizeof(drstable[i].fname)-1,drs);
				strupr(drstable[i].fname);
				drssize+=drstable[i].fsize;
			}
			drssize+=size+hdrlen;
			if (drssize==filesize(drs) && size==NUM_RES_ENTRIES*((sizeof(drstable[0].fname)-1)+sizeof(drstable[0].fsize)+sizeof(drstable[0].foffset)))
			{
#ifdef USE_NAMETREES
				if (BuildNameTree())
#endif
				{
					strncpy(path, filename, sizeof(path));
					path[sizeof(path)-1]=0;
					return true;
				}
			}
		}
	}
	CloseResource();
	return false;
}

void CResource::CloseResource()
{
	if (drs!=NULL)
	{
		fclose(drs);
	}
	drs=NULL;
	memset(drstable,0,sizeof(drstable));
	path[0]=0;
#ifdef USE_NAMETREES
	DestroyNameTree();
#endif
}

int CResource::FindEntry(const char *entryname)
{
	char uprname[16];
	if (entryname==NULL)
		return -1;
	strncpy(uprname,entryname,sizeof(uprname));
	uprname[sizeof(uprname)-1]=0;
	strupr(uprname);
#ifdef USE_NAMETREES
	return SearchNameTree(uprname);
#else
	return FindEntryBrutal(uprname);
#endif
}

bool CResource::ReadEntry(void *buffer, int entrynum)
{
	if (drs!=NULL && buffer!=NULL && entrynum<NUM_RES_ENTRIES && entrynum>=0)
	{
		if (!fseek(drs,drstable[entrynum].foffset,SEEK_SET))
		{
			if (fread(buffer,1,drstable[entrynum].fsize,drs)==drstable[entrynum].fsize)
				return true;
		}
	}
	return false;
}

bool CResource::ReadEntryEx(void *buffer, int entrynum, int offset, int size)
{
	if (drs!=NULL && buffer!=NULL && entrynum<NUM_RES_ENTRIES && entrynum>=0)
	{
		if (size==0)
			size=drstable[entrynum].fsize;
		if ((offset+size)<=(int)drstable[entrynum].fsize)
		{
			if (!fseek(drs,drstable[entrynum].foffset+offset,SEEK_SET))
			{
				if ((int)fread(buffer,1,size,drs)==size)
					return true;
			}
		}
	}
	return false;
}

char *CResource::GetEntryName(int entrynum)
{
	if (drs==NULL || entrynum>=NUM_RES_ENTRIES || entrynum<0)
		return NULL;
	return drstable[entrynum].fname;
}

int CResource::GetEntrySize(int entrynum)
{
	if (drs==NULL || entrynum>=NUM_RES_ENTRIES || entrynum<0)
		return -1;
	return (int)drstable[entrynum].fsize;
}
<commit_msg>Fixed a bug in the resource loader.<commit_after>#include <malloc.h>
#include <stdarg.h>
#include <string.h>
#include <io.h>

#include "Resource.h"

#define USE_NAMETREES
#define filesize(fileptr) (filelength(fileno(fileptr)))

CResource::CResource()
{
	drs=NULL;
	Init();
}

CResource::~CResource()
{
	ShutDown();
}

bool CResource::Init()
{
	ShutDown();
	return true;
}

void CResource::ShutDown()
{
	CloseResource();
}

void CResource::DestroyNameTree()
{
	nametree.Destroy();
}

bool CResource::BuildNameTree()
{
	int i;
	for (i=0;i<NUM_RES_ENTRIES;i++)
	{
		if (drstable[i].foffset!=0)
		{
			if (!nametree.AddLeaf(drstable[i].fname,i))
			{
				nametree.Destroy();
				return false;
			}
		}
	}
	return true;
}

int CResource::SearchNameTree(char *name)
{
	return nametree.FindLeaf(name);
}

int CResource::FindEntryBrutal(char *entryname)
{
	int i;
	if (drs!=NULL)
	{
		for (i=0;i<NUM_RES_ENTRIES;i++)
		{
			if (!stricmp(entryname,drstable[i].fname))
				return i;
		}
	}
	return -1;
}

bool CResource::OpenResource(const char *filename)
{
	int i;
	uint32_t size,drssize;
	const int hdrlen=8;
	char cmphdr[hdrlen];
	char idhdr[hdrlen]={'v','s',' ','d','2',0,0,0};
	if (filename==NULL || filename[0]==0)
		return false;
	if (strcmp(filename, path)==0)
		return true;
	memset(cmphdr, 0, sizeof(cmphdr));
	CloseResource();
	drs=fopen((const char *)filename, "rb");
	if (drs==NULL)
		return false;
	size=fread(cmphdr,1,hdrlen,drs);
	if (size==hdrlen)
	{
		size=memcmp(cmphdr,idhdr, hdrlen);
		if (size==0)
		{
			for (i=0,size=0,drssize=0;i<NUM_RES_ENTRIES;i++)
			{
				memset(drstable[i].fname,0,sizeof(drstable[i].fname));
				size+=fread(&drstable[i].fname,1,sizeof(drstable[i].fname)-1,drs);
				size+=fread(&drstable[i].foffset,1,sizeof(drstable[i].foffset),drs);
				size+=fread(&drstable[i].fsize,1,sizeof(drstable[i].fsize),drs);
				strupr(drstable[i].fname);
				drssize+=drstable[i].fsize;
			}
			drssize+=size+hdrlen;
			if (drssize==filesize(drs) && size==NUM_RES_ENTRIES*((sizeof(drstable[0].fname)-1)+sizeof(drstable[0].fsize)+sizeof(drstable[0].foffset)))
			{
#ifdef USE_NAMETREES
				if (BuildNameTree())
#endif
				{
					strncpy(path, filename, sizeof(path));
					path[sizeof(path)-1]=0;
					return true;
				}
			}
		}
	}
	CloseResource();
	return false;
}

void CResource::CloseResource()
{
	if (drs!=NULL)
	{
		fclose(drs);
	}
	drs=NULL;
	memset(drstable,0,sizeof(drstable));
	path[0]=0;
#ifdef USE_NAMETREES
	DestroyNameTree();
#endif
}

int CResource::FindEntry(const char *entryname)
{
	char uprname[16];
	if (entryname==NULL)
		return -1;
	strncpy(uprname,entryname,sizeof(uprname));
	uprname[sizeof(uprname)-1]=0;
	strupr(uprname);
#ifdef USE_NAMETREES
	return SearchNameTree(uprname);
#else
	return FindEntryBrutal(uprname);
#endif
}

bool CResource::ReadEntry(void *buffer, int entrynum)
{
	if (drs!=NULL && buffer!=NULL && entrynum<NUM_RES_ENTRIES && entrynum>=0)
	{
		if (!fseek(drs,drstable[entrynum].foffset,SEEK_SET))
		{
			if (fread(buffer,1,drstable[entrynum].fsize,drs)==drstable[entrynum].fsize)
				return true;
		}
	}
	return false;
}

bool CResource::ReadEntryEx(void *buffer, int entrynum, int offset, int size)
{
	if (drs!=NULL && buffer!=NULL && entrynum<NUM_RES_ENTRIES && entrynum>=0)
	{
		if (size==0)
			size=drstable[entrynum].fsize;
		if ((offset+size)<=(int)drstable[entrynum].fsize)
		{
			if (!fseek(drs,drstable[entrynum].foffset+offset,SEEK_SET))
			{
				if ((int)fread(buffer,1,size,drs)==size)
					return true;
			}
		}
	}
	return false;
}

char *CResource::GetEntryName(int entrynum)
{
	if (drs==NULL || entrynum>=NUM_RES_ENTRIES || entrynum<0)
		return NULL;
	return drstable[entrynum].fname;
}

int CResource::GetEntrySize(int entrynum)
{
	if (drs==NULL || entrynum>=NUM_RES_ENTRIES || entrynum<0)
		return -1;
	return (int)drstable[entrynum].fsize;
}
<|endoftext|>


<commit_before>#include "Course.h"
#include "CourseCont.h"
#include "Options.h"
#include "Scheduler.h"

#include <iostream>

CourseSched Scheduler::generateSchedule(CourseCont& courseList, Options &opts){
	CourseSched schedule;
	courseList.sort();
	courseList.begin();
	bool reachEnd = false;

	for(int i = 0; i < opts.getNumCourses() && !reachEnd;){
		reachEnd = courseList.getCourse().equal(courseList.last());
		try{
			courseList.getCourse().addPadding(opts.getBreakPadding());
			schedule.addCourse(courseList.getCourse());
			courseList.next();
			i++;
		}catch(const TimeConflict &expt){
			courseList.next();
		}catch(const EmptyContainer &epct){
			break;
		}
	}

	return schedule;
}<commit_msg>fixes #12 - uses functions available to check for conflicts with padding without changing the course times that are added to the schedule<commit_after>#include "Course.h"
#include "CourseCont.h"
#include "Options.h"
#include "Scheduler.h"

#include <iostream>

CourseSched Scheduler::generateSchedule(CourseCont& courseList, Options &opts){
	CourseSched schedule;
	courseList.sort();
	courseList.begin();
	bool reachEnd = false;

	for(int i = 0; i < opts.getNumCourses() && !reachEnd;){
		reachEnd = courseList.getCourse().equal(courseList.last());
		try{
			Course add, comp;
			add = comp = courseList.getCourse(); //.addPadding(opts.getBreakPadding());
			comp.addPadding(opts.getBreakPadding());
			schedule.findCourseConflict(comp); //will throw and skip if conflict
			schedule.addCourse(add);
			courseList.next();
			i++;
		}catch(const TimeConflict &expt){
			courseList.next();
		}catch(const EmptyContainer &epct){
			break;
		}
	}

	return schedule;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dsEntriesNoExp.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-10-22 12:03:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SBA_UNODATBR_HXX_
#include "unodatbr.hxx"
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _DBAUI_LISTVIEWITEMS_HXX_
#include "listviewitems.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef DBACCESS_UI_DBTREEVIEW_HXX
#include "dbtreeview.hxx"
#endif
#ifndef DBAUI_DBTREELISTBOX_HXX
#include "dbtreelistbox.hxx"
#endif
#ifndef _DBU_BRW_HRC_
#include "dbu_brw.hrc"
#endif
#ifndef DBAUI_DBTREEMODEL_HXX
#include "dbtreemodel.hxx"
#endif

using namespace ::dbtools;
using namespace ::svx;

// .........................................................................
namespace dbaui
{
// .........................................................................
// -----------------------------------------------------------------------------
SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getChildType( SvLBoxEntry* _pEntry ) const
{
    DBG_ASSERT(isContainer(_pEntry), "SbaTableQueryBrowser::getChildType: invalid entry!");
    switch (getEntryType(_pEntry))
    {
        case etTableContainer:
            return etTable;
        case etQueryContainer:
            return etQuery;
    }
    return etUnknown;
}

// -----------------------------------------------------------------------------
String SbaTableQueryBrowser::GetEntryText( SvLBoxEntry* _pEntry ) const
{
    return m_pTreeView->getListBox()->GetEntryText(_pEntry);
}

// -----------------------------------------------------------------------------
SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getEntryType( SvLBoxEntry* _pEntry ) const
{
    if (!_pEntry)
        return etUnknown;

    SvLBoxEntry* pRootEntry     = m_pTreeView->getListBox()->GetRootLevelParent(_pEntry);
    SvLBoxEntry* pEntryParent   = m_pTreeView->getListBox()->GetParent(_pEntry);
    SvLBoxEntry* pTables        = m_pTreeView->getListBox()->GetEntry(pRootEntry, CONTAINER_TABLES);
    SvLBoxEntry* pQueries       = m_pTreeView->getListBox()->GetEntry(pRootEntry, CONTAINER_QUERIES);

#ifdef DBG_UTIL
    String sTest;
    if (pTables) sTest = m_pTreeView->getListBox()->GetEntryText(pTables);
    if (pQueries) sTest = m_pTreeView->getListBox()->GetEntryText(pQueries);
#endif

    if (pRootEntry == _pEntry)
        return etDatasource;

    if (pTables == _pEntry)
        return etTableContainer;

    if (pQueries == _pEntry)
        return etQueryContainer;

    if (pTables == pEntryParent)
        return etTable;

    if (pQueries == pEntryParent)
        return etQuery;

    return etUnknown;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::select(SvLBoxEntry* _pEntry, sal_Bool _bSelect)
{
    SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL;
    if (pTextItem)
    {
        static_cast<OBoldListboxString*>(pTextItem)->emphasize(_bSelect);
        m_pTreeModel->InvalidateEntry(_pEntry);
    }
    else
        DBG_ERROR("SbaTableQueryBrowser::select: invalid entry!");
}

//------------------------------------------------------------------------------
void SbaTableQueryBrowser::selectPath(SvLBoxEntry* _pEntry, sal_Bool _bSelect)
{
    while (_pEntry)
    {
        select(_pEntry, _bSelect);
        _pEntry = m_pTreeModel->GetParent(_pEntry);
    }
}
//------------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::isSelected(SvLBoxEntry* _pEntry) const
{
    SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL;
    if (pTextItem)
        return static_cast<OBoldListboxString*>(pTextItem)->isEmphasized();
    else
        DBG_ERROR("SbaTableQueryBrowser::isSelected: invalid entry!");
    return sal_False;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::AddSupportedFeatures()
{
    SbaXDataBrowserController::AddSupportedFeatures();

    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:Title")]                           = ID_BROWSER_TITLE;
    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DSBrowserExplorer")]               = ID_BROWSER_EXPLORER;

    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DSBFormLetter")]                   = ID_BROWSER_FORMLETTER;
    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DSBInsertColumns")]                = ID_BROWSER_INSERTCOLUMNS;
    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DSBInsertContent")]                = ID_BROWSER_INSERTCONTENT;
    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DSBDocumentDataSource")]           = ID_BROWSER_DOCUMENT_DATASOURCE;

    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:CloseWin")]                        = ID_BROWSER_CLOSE;
    m_aSupportedFeatures[ ::rtl::OUString::createFromAscii(".uno:DBRebuildData")]                   = ID_BROWSER_REFRESH_REBUILD;
}
// -------------------------------------------------------------------------
String SbaTableQueryBrowser::getURL() const
{
    return String();
}
// -----------------------------------------------------------------------------
void SbaTableQueryBrowser::notifyHiContrastChanged()
{
    if ( m_pTreeView )
    {
        sal_Bool bHiContrast = isHiContrast();

        if ( m_bHiContrast != bHiContrast )
        {
            m_bHiContrast = bHiContrast;
            // change all bitmap entries
            DBTreeListBox* pListBox = m_pTreeView->getListBox();

            SvLBoxEntry* pEntryLoop = m_pTreeModel->First();
            while ( pEntryLoop )
            {
                DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(pEntryLoop->GetUserData());
                if ( pData )
                {
                    ModuleRes aResId(DBTreeListModel::getImageResId(pData->eType,isHiContrast()));
                    Image aImage(aResId);
                    USHORT nCount = pEntryLoop->ItemCount();
                    for (USHORT i=0;i<nCount;++i)
                    {
                        SvLBoxItem* pItem = pEntryLoop->GetItem(i);
                        if ( pItem && pItem->IsA() == SV_ITEM_ID_LBOXCONTEXTBMP)
                        {
                            static_cast<SvLBoxContextBmp*>(pItem)->SetBitmap1(pEntryLoop,aImage);
                            static_cast<SvLBoxContextBmp*>(pItem)->SetBitmap2(pEntryLoop,aImage);
                            break;
                        }
                    }
                }
                pEntryLoop = m_pTreeModel->Next(pEntryLoop);
            }
        }
    }
}
// -----------------------------------------------------------------------------
// .........................................................................
}   // namespace dbaui
// .........................................................................

<commit_msg>INTEGRATION: CWS dba19 (1.10.8); FILE MERGED 2004/11/09 08:09:14 oj 1.10.8.1: #i36540# add forma letter again to supported features<commit_after>/*************************************************************************
 *
 *  $RCSfile: dsEntriesNoExp.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 09:29:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SBA_UNODATBR_HXX_
#include "unodatbr.hxx"
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _DBAUI_LISTVIEWITEMS_HXX_
#include "listviewitems.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef DBACCESS_UI_DBTREEVIEW_HXX
#include "dbtreeview.hxx"
#endif
#ifndef DBAUI_DBTREELISTBOX_HXX
#include "dbtreelistbox.hxx"
#endif
#ifndef _DBU_BRW_HRC_
#include "dbu_brw.hrc"
#endif
#ifndef DBAUI_DBTREEMODEL_HXX
#include "dbtreemodel.hxx"
#endif

using namespace ::dbtools;
using namespace ::svx;

// .........................................................................
namespace dbaui
{
// .........................................................................
// -----------------------------------------------------------------------------
SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getChildType( SvLBoxEntry* _pEntry ) const
{
    DBG_ASSERT(isContainer(_pEntry), "SbaTableQueryBrowser::getChildType: invalid entry!");
    switch (getEntryType(_pEntry))
    {
        case etTableContainer:
            return etTable;
        case etQueryContainer:
            return etQuery;
    }
    return etUnknown;
}

// -----------------------------------------------------------------------------
String SbaTableQueryBrowser::GetEntryText( SvLBoxEntry* _pEntry ) const
{
    return m_pTreeView->getListBox()->GetEntryText(_pEntry);
}

// -----------------------------------------------------------------------------
SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getEntryType( SvLBoxEntry* _pEntry ) const
{
    if (!_pEntry)
        return etUnknown;

    SvLBoxEntry* pRootEntry     = m_pTreeView->getListBox()->GetRootLevelParent(_pEntry);
    SvLBoxEntry* pEntryParent   = m_pTreeView->getListBox()->GetParent(_pEntry);
    SvLBoxEntry* pTables        = m_pTreeView->getListBox()->GetEntry(pRootEntry, CONTAINER_TABLES);
    SvLBoxEntry* pQueries       = m_pTreeView->getListBox()->GetEntry(pRootEntry, CONTAINER_QUERIES);

#ifdef DBG_UTIL
    String sTest;
    if (pTables) sTest = m_pTreeView->getListBox()->GetEntryText(pTables);
    if (pQueries) sTest = m_pTreeView->getListBox()->GetEntryText(pQueries);
#endif

    if (pRootEntry == _pEntry)
        return etDatasource;

    if (pTables == _pEntry)
        return etTableContainer;

    if (pQueries == _pEntry)
        return etQueryContainer;

    if (pTables == pEntryParent)
        return etTable;

    if (pQueries == pEntryParent)
        return etQuery;

    return etUnknown;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::select(SvLBoxEntry* _pEntry, sal_Bool _bSelect)
{
    SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL;
    if (pTextItem)
    {
        static_cast<OBoldListboxString*>(pTextItem)->emphasize(_bSelect);
        m_pTreeModel->InvalidateEntry(_pEntry);
    }
    else
        DBG_ERROR("SbaTableQueryBrowser::select: invalid entry!");
}

//------------------------------------------------------------------------------
void SbaTableQueryBrowser::selectPath(SvLBoxEntry* _pEntry, sal_Bool _bSelect)
{
    while (_pEntry)
    {
        select(_pEntry, _bSelect);
        _pEntry = m_pTreeModel->GetParent(_pEntry);
    }
}
//------------------------------------------------------------------------------
sal_Bool SbaTableQueryBrowser::isSelected(SvLBoxEntry* _pEntry) const
{
    SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL;
    if (pTextItem)
        return static_cast<OBoldListboxString*>(pTextItem)->isEmphasized();
    else
        DBG_ERROR("SbaTableQueryBrowser::isSelected: invalid entry!");
    return sal_False;
}
//------------------------------------------------------------------------------
void SbaTableQueryBrowser::AddSupportedFeatures()
{
    SbaXDataBrowserController::AddSupportedFeatures();

    m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Title"))]                               = ID_BROWSER_TITLE;
    if ( !m_bShowMenu )
    {
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DSBrowserExplorer"))]                   = ID_BROWSER_EXPLORER;

        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DSBFormLetter"))]                       = ID_BROWSER_FORMLETTER;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DSBInsertColumns"))]                    = ID_BROWSER_INSERTCOLUMNS;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DSBInsertContent"))]                    = ID_BROWSER_INSERTCONTENT;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DSBDocumentDataSource"))]               = ID_BROWSER_DOCUMENT_DATASOURCE;

        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DataSourceBrowser/FormLetter"))]        = ID_BROWSER_FORMLETTER;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DataSourceBrowser/InsertColumns"))]     = ID_BROWSER_INSERTCOLUMNS;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DataSourceBrowser/InsertContent"))]     = ID_BROWSER_INSERTCONTENT;
        m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DataSourceBrowser/DocumentDataSource"))]= ID_BROWSER_DOCUMENT_DATASOURCE;
    }

    m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"))]                            = ID_BROWSER_CLOSE;
    m_aSupportedFeatures[ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:DBRebuildData"))]                       = ID_BROWSER_REFRESH_REBUILD;
}
// -------------------------------------------------------------------------
String SbaTableQueryBrowser::getURL() const
{
    return String();
}
// -----------------------------------------------------------------------------
void SbaTableQueryBrowser::notifyHiContrastChanged()
{
    if ( m_pTreeView )
    {
        sal_Bool bHiContrast = isHiContrast();

        if ( m_bHiContrast != bHiContrast )
        {
            m_bHiContrast = bHiContrast;
            // change all bitmap entries
            DBTreeListBox* pListBox = m_pTreeView->getListBox();

            SvLBoxEntry* pEntryLoop = m_pTreeModel->First();
            while ( pEntryLoop )
            {
                DBTreeListModel::DBTreeListUserData* pData = static_cast<DBTreeListModel::DBTreeListUserData*>(pEntryLoop->GetUserData());
                if ( pData )
                {
                    ModuleRes aResId(DBTreeListModel::getImageResId(pData->eType,isHiContrast()));
                    Image aImage(aResId);
                    USHORT nCount = pEntryLoop->ItemCount();
                    for (USHORT i=0;i<nCount;++i)
                    {
                        SvLBoxItem* pItem = pEntryLoop->GetItem(i);
                        if ( pItem && pItem->IsA() == SV_ITEM_ID_LBOXCONTEXTBMP)
                        {
                            static_cast<SvLBoxContextBmp*>(pItem)->SetBitmap1(pEntryLoop,aImage);
                            static_cast<SvLBoxContextBmp*>(pItem)->SetBitmap2(pEntryLoop,aImage);
                            break;
                        }
                    }
                }
                pEntryLoop = m_pTreeModel->Next(pEntryLoop);
            }
        }
    }
}
// -----------------------------------------------------------------------------
// .........................................................................
}   // namespace dbaui
// .........................................................................

<|endoftext|>


<commit_before>/*
Copyright (c) 2014 Ableton AG, Berlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// clang-format off

#pragma once

#if defined(__clang__)

  #if __has_warning("-Wreserved-id-macro")
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO \
    _Pragma("clang diagnostic ignored \"-Wreserved-id-macro\"")
  #else
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO
  #endif

  #if __has_warning("-Wunused-local-typedef")
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF \
    _Pragma("clang diagnostic ignored \"-Wunused-local-typedef\"")
  #else
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF
  #endif

  #define SUPPRESS_WARNINGS \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Wconditional-uninitialized\"") \
    _Pragma("clang diagnostic ignored \"-Wconversion\"") \
    _Pragma("clang diagnostic ignored \"-Wcovered-switch-default\"") \
    _Pragma("clang diagnostic ignored \"-Wdeprecated\"") \
    _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \
    _Pragma("clang diagnostic ignored \"-Wdocumentation-unknown-command\"") \
    _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
    _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
    _Pragma("clang diagnostic ignored \"-Wextra-semi\"") \
    _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \
    _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
    _Pragma("clang diagnostic ignored \"-Wheader-hygiene\"") \
    _Pragma("clang diagnostic ignored \"-Wmissing-noreturn\"") \
    _Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"") \
    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
    _Pragma("clang diagnostic ignored \"-Wpadded\"") \
    _Pragma("clang diagnostic ignored \"-Wshadow\"") \
    _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \
    _Pragma("clang diagnostic ignored \"-Wshorten-64-to-32\"") \
    _Pragma("clang diagnostic ignored \"-Wsign-compare\"") \
    _Pragma("clang diagnostic ignored \"-Wsign-conversion\"") \
    _Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \
    _Pragma("clang diagnostic ignored \"-Wundef\"") \
    _Pragma("clang diagnostic ignored \"-Wundefined-reinterpret-cast\"") \
    _Pragma("clang diagnostic ignored \"-Wunreachable-code\"") \
    _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
    _Pragma("clang diagnostic ignored \"-Wused-but-marked-unused\"") \
    _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
    ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO \
    ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF

  #define RESTORE_WARNINGS \
    _Pragma("clang diagnostic pop")

#elif defined(_MSC_VER)

  #if _MSC_VER < 1900
    #define ABL_PRAGMA_MSVC_DISABLE_4459
  #else
    #define ABL_PRAGMA_MSVC_DISABLE_4459 \
    __pragma(warning(disable: 4459))
  #endif

  /**
  * C4100: 'identifier' : unreferenced formal parameter
  * C4127: conditional expression is constant
  * C4191: 'type cast' : unsafe conversion from 'function pointer type' to 'function pointer type'
  *        Calling this function through the result pointer may cause your program to fail
  * C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data
  * C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
  * C4365: 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
  * C4388: signed/unsigned mismatch
  * C4459: declaration of 'identifier' hides global declaration
  * C4555: expression has no effect; expected expression with side-effect
  * C4619: #pragma warning : there is no warning number 'number'
  * C4628: digraphs not supported with -Ze. Character sequence 'digraph' not interpreted as alternate token for 'char'
  * C4640: 'instance' : construction of local static object is not thread-safe
  * C4668: 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
  * C4714: function 'function' marked as __forceinline not inlined
  * C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
  * C4826: Conversion from 'type1 ' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
  */
  #define SUPPRESS_WARNINGS \
    __pragma(warning(push)) \
    __pragma(warning(disable: 4100)) \
    __pragma(warning(disable: 4127)) \
    __pragma(warning(disable: 4191)) \
    __pragma(warning(disable: 4244)) \
    __pragma(warning(disable: 4251)) \
    __pragma(warning(disable: 4365)) \
    __pragma(warning(disable: 4388)) \
    __pragma(warning(disable: 4555)) \
    __pragma(warning(disable: 4619)) \
    __pragma(warning(disable: 4628)) \
    __pragma(warning(disable: 4640)) \
    __pragma(warning(disable: 4668)) \
    __pragma(warning(disable: 4714)) \
    __pragma(warning(disable: 4800)) \
    __pragma(warning(disable: 4826)) \
    ABL_PRAGMA_MSVC_DISABLE_4459

  #define RESTORE_WARNINGS \
    __pragma(warning(pop))

#else

  #define SUPPRESS_WARNINGS
  #define RESTORE_WARNINGS

#endif
<commit_msg>Disable MSVC warning C4242 produced by Qt5.6 headers<commit_after>/*
Copyright (c) 2014 Ableton AG, Berlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// clang-format off

#pragma once

#if defined(__clang__)

  #if __has_warning("-Wreserved-id-macro")
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO \
    _Pragma("clang diagnostic ignored \"-Wreserved-id-macro\"")
  #else
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO
  #endif

  #if __has_warning("-Wunused-local-typedef")
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF \
    _Pragma("clang diagnostic ignored \"-Wunused-local-typedef\"")
  #else
    #define ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF
  #endif

  #define SUPPRESS_WARNINGS \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Wconditional-uninitialized\"") \
    _Pragma("clang diagnostic ignored \"-Wconversion\"") \
    _Pragma("clang diagnostic ignored \"-Wcovered-switch-default\"") \
    _Pragma("clang diagnostic ignored \"-Wdeprecated\"") \
    _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \
    _Pragma("clang diagnostic ignored \"-Wdocumentation-unknown-command\"") \
    _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
    _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
    _Pragma("clang diagnostic ignored \"-Wextra-semi\"") \
    _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \
    _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
    _Pragma("clang diagnostic ignored \"-Wheader-hygiene\"") \
    _Pragma("clang diagnostic ignored \"-Wmissing-noreturn\"") \
    _Pragma("clang diagnostic ignored \"-Wmissing-prototypes\"") \
    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
    _Pragma("clang diagnostic ignored \"-Wpadded\"") \
    _Pragma("clang diagnostic ignored \"-Wshadow\"") \
    _Pragma("clang diagnostic ignored \"-Wshift-sign-overflow\"") \
    _Pragma("clang diagnostic ignored \"-Wshorten-64-to-32\"") \
    _Pragma("clang diagnostic ignored \"-Wsign-compare\"") \
    _Pragma("clang diagnostic ignored \"-Wsign-conversion\"") \
    _Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \
    _Pragma("clang diagnostic ignored \"-Wundef\"") \
    _Pragma("clang diagnostic ignored \"-Wundefined-reinterpret-cast\"") \
    _Pragma("clang diagnostic ignored \"-Wunreachable-code\"") \
    _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
    _Pragma("clang diagnostic ignored \"-Wused-but-marked-unused\"") \
    _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
    ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_RESERVED_ID_MACRO \
    ABL_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNUSED_LOCAL_TYPEDEF

  #define RESTORE_WARNINGS \
    _Pragma("clang diagnostic pop")

#elif defined(_MSC_VER)

  #if _MSC_VER < 1900
    #define ABL_PRAGMA_MSVC_DISABLE_4459
  #else
    #define ABL_PRAGMA_MSVC_DISABLE_4459 \
    __pragma(warning(disable: 4459))
  #endif

  /**
  * C4100: 'identifier' : unreferenced formal parameter
  * C4127: conditional expression is constant
  * C4191: 'type cast' : unsafe conversion from 'function pointer type' to 'function pointer type'
  *        Calling this function through the result pointer may cause your program to fail
  * C4242: 'identifier' : conversion from 'type1' to 'type2', possible loss of data
  * C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data
  * C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
  * C4365: 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
  * C4388: signed/unsigned mismatch
  * C4459: declaration of 'identifier' hides global declaration
  * C4555: expression has no effect; expected expression with side-effect
  * C4619: #pragma warning : there is no warning number 'number'
  * C4628: digraphs not supported with -Ze. Character sequence 'digraph' not interpreted as alternate token for 'char'
  * C4640: 'instance' : construction of local static object is not thread-safe
  * C4668: 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
  * C4714: function 'function' marked as __forceinline not inlined
  * C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
  * C4826: Conversion from 'type1 ' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
  */
  #define SUPPRESS_WARNINGS \
    __pragma(warning(push)) \
    __pragma(warning(disable: 4100)) \
    __pragma(warning(disable: 4127)) \
    __pragma(warning(disable: 4191)) \
    __pragma(warning(disable: 4242)) \
    __pragma(warning(disable: 4244)) \
    __pragma(warning(disable: 4251)) \
    __pragma(warning(disable: 4365)) \
    __pragma(warning(disable: 4388)) \
    __pragma(warning(disable: 4555)) \
    __pragma(warning(disable: 4619)) \
    __pragma(warning(disable: 4628)) \
    __pragma(warning(disable: 4640)) \
    __pragma(warning(disable: 4668)) \
    __pragma(warning(disable: 4714)) \
    __pragma(warning(disable: 4800)) \
    __pragma(warning(disable: 4826)) \
    ABL_PRAGMA_MSVC_DISABLE_4459

  #define RESTORE_WARNINGS \
    __pragma(warning(pop))

#else

  #define SUPPRESS_WARNINGS
  #define RESTORE_WARNINGS

#endif
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014 Johannes Hggqvist

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "WaveFile.h"

#include <fstream>
#include <iostream>
#include <cstdint>
#include <cassert>
#include <cstring>

namespace
{
	struct RIFFChunk
	{
		std::uint32_t chunkID;
		std::uint32_t chunkSize;
		std::uint32_t format;
	};
	struct fmtChunk
	{
		std::uint32_t chunkID;
		std::uint32_t chunkSize;
		std::uint16_t audioFormat;
		std::uint16_t numChannels;
		std::uint32_t sampleRate;
		std::uint32_t byteRate;
		std::uint16_t blockAlign;
		std::uint16_t bitsPerSample;
	};
	struct WaveHeader
	{
		RIFFChunk riff;
		fmtChunk fmt;
	};
}

WaveFile::WaveFile() : data(nullptr), size(0)
{
}
WaveFile::WaveFile(const std::string &filename) : data(nullptr), size(0)
{
	Load(filename);
}
WaveFile::~WaveFile()
{
	Unload();
}

bool WaveFile::Load(const std::string &filename)
{
	if (IsLoaded())
	{
		Unload();
	}

	std::fstream file(filename, std::ios::in | std::ios::binary);

	if (!file.is_open())
	{
		std::cerr << "Error: Could not open file." << std::endl;
		return false;
	}

	WaveHeader header;
	std::memset(&header, 0, sizeof(WaveHeader));

	while (file.peek() != std::char_traits<char>::eof())
	{
		std::uint32_t chunkID;
		std::uint32_t chunkSize;

		file.read(reinterpret_cast<char*>(&chunkID), sizeof(std::uint32_t));
		file.read(reinterpret_cast<char*>(&chunkSize), sizeof(std::uint32_t));

		switch (chunkID)
		{
		case 'FFIR':
			{
				header.riff.chunkID = chunkID;
				header.riff.chunkSize = chunkSize;
				file.read(reinterpret_cast<char*>(&header.riff.format), sizeof(std::uint32_t));

				if (header.riff.format != 'EVAW')
				{
					std::cerr << "Error: Not a valid WAVE file." << std::endl;
					return false;
				}

				break;
			}
		case ' tmf':
			{
				header.fmt.chunkID = chunkID;
				header.fmt.chunkSize = chunkSize;
				file.read(reinterpret_cast<char*>(&header.fmt.audioFormat), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.numChannels), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.sampleRate), sizeof(std::uint32_t));
				file.read(reinterpret_cast<char*>(&header.fmt.byteRate), sizeof(std::uint32_t));
				file.read(reinterpret_cast<char*>(&header.fmt.blockAlign), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.bitsPerSample), sizeof(std::uint16_t));

				if (header.fmt.bitsPerSample % 2 != 0)
				{
					std::cerr << "Error: Invalid number of bits per sample" << std::endl;
					return false;
				}
				if (header.fmt.byteRate != (header.fmt.sampleRate * header.fmt.numChannels * header.fmt.bitsPerSample / 8))
				{
					std::cerr << "Error: Invalid byte rate" << std::endl;
					return false;
				}
				if (header.fmt.blockAlign != (header.fmt.numChannels * header.fmt.bitsPerSample / 8))
				{
					std::cerr << "Error: Invalid block align" << std::endl;
					return false;
				}

				break;
			}
		case 'atad':
			{
				assert(data == nullptr);
				size = chunkSize;
				data = new char[size];
				file.read(data, chunkSize);

				break;
			}
		default:
			{
				file.ignore(chunkSize);

				break;
			}
		}
	}

	// Check that we got all chunks
	if (header.riff.chunkID != 'FFIR')
	{
		std::cerr << "Error: Missing RIFF chunk." << std::endl;
		return false;
	}
	if (header.fmt.chunkID != ' tmf')
	{
		std::cerr << "Error: Missing fmt chunk." << std::endl;
		return false;
	}
	if (data == nullptr)
	{
		std::cerr << "Error: Missing data chunk." << std::endl;
		return false;
	}

	// Fill meta struct
	meta.audioFormat   = static_cast<AudioFormat>(header.fmt.audioFormat);
	meta.numChannels   = header.fmt.numChannels;
	meta.sampleRate    = header.fmt.sampleRate;
	meta.bitsPerSample = header.fmt.bitsPerSample;

	return true;
}
void WaveFile::Unload()
{
	delete[] data;
	data = nullptr;
	size = 0;
}

std::string WaveFile::GetAudioFormatString() const
{
	switch (meta.audioFormat)
	{
	case WaveFile::PCM: return "PCM";
	case WaveFile::IEEE_FLOAT: return "IEEE float";
	default: return "Unknown";
	}
}
<commit_msg>Replaced all magic numbers with static const's<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014 Johannes Hggqvist

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "WaveFile.h"

#include <fstream>
#include <iostream>
#include <cstdint>
#include <cassert>
#include <cstring>

namespace
{
	static const std::uint32_t RIFF_ID = 'FFIR';
	static const std::uint32_t FMT_ID  = ' tmf';
	static const std::uint32_t DATA_ID = 'atad';

	struct RIFFChunk
	{
		static const std::uint32_t FORMAT_WAVE = 'EVAW';

		std::uint32_t chunkID;
		std::uint32_t chunkSize;
		std::uint32_t format;
	};
	struct fmtChunk
	{
		std::uint32_t chunkID;
		std::uint32_t chunkSize;
		std::uint16_t audioFormat;
		std::uint16_t numChannels;
		std::uint32_t sampleRate;
		std::uint32_t byteRate;
		std::uint16_t blockAlign;
		std::uint16_t bitsPerSample;
	};
	struct WaveHeader
	{
		RIFFChunk riff;
		fmtChunk fmt;
	};
}

WaveFile::WaveFile() : data(nullptr), size(0)
{
}
WaveFile::WaveFile(const std::string &filename) : data(nullptr), size(0)
{
	Load(filename);
}
WaveFile::~WaveFile()
{
	Unload();
}

bool WaveFile::Load(const std::string &filename)
{
	if (IsLoaded())
	{
		Unload();
	}

	std::fstream file(filename, std::ios::in | std::ios::binary);

	if (!file.is_open())
	{
		std::cerr << "Error: Could not open file." << std::endl;
		return false;
	}

	WaveHeader header;
	std::memset(&header, 0, sizeof(WaveHeader));

	while (file.peek() != std::char_traits<char>::eof())
	{
		std::uint32_t chunkID;
		std::uint32_t chunkSize;

		file.read(reinterpret_cast<char*>(&chunkID), sizeof(std::uint32_t));
		file.read(reinterpret_cast<char*>(&chunkSize), sizeof(std::uint32_t));

		switch (chunkID)
		{
		case RIFF_ID:
			{
				header.riff.chunkID = chunkID;
				header.riff.chunkSize = chunkSize;
				file.read(reinterpret_cast<char*>(&header.riff.format), sizeof(std::uint32_t));

				if (header.riff.format != RIFFChunk::FORMAT_WAVE)
				{
					std::cerr << "Error: Not a valid WAVE file." << std::endl;
					return false;
				}

				break;
			}
		case FMT_ID:
			{
				header.fmt.chunkID = chunkID;
				header.fmt.chunkSize = chunkSize;
				file.read(reinterpret_cast<char*>(&header.fmt.audioFormat), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.numChannels), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.sampleRate), sizeof(std::uint32_t));
				file.read(reinterpret_cast<char*>(&header.fmt.byteRate), sizeof(std::uint32_t));
				file.read(reinterpret_cast<char*>(&header.fmt.blockAlign), sizeof(std::uint16_t));
				file.read(reinterpret_cast<char*>(&header.fmt.bitsPerSample), sizeof(std::uint16_t));

				if (header.fmt.bitsPerSample % 2 != 0)
				{
					std::cerr << "Error: Invalid number of bits per sample" << std::endl;
					return false;
				}
				if (header.fmt.byteRate != (header.fmt.sampleRate * header.fmt.numChannels * header.fmt.bitsPerSample / 8))
				{
					std::cerr << "Error: Invalid byte rate" << std::endl;
					return false;
				}
				if (header.fmt.blockAlign != (header.fmt.numChannels * header.fmt.bitsPerSample / 8))
				{
					std::cerr << "Error: Invalid block align" << std::endl;
					return false;
				}

				break;
			}
		case DATA_ID:
			{
				assert(data == nullptr);
				size = chunkSize;
				data = new char[size];
				file.read(data, chunkSize);

				break;
			}
		default:
			{
				file.ignore(chunkSize);

				break;
			}
		}
	}

	// Check that we got all chunks
	if (header.riff.chunkID != RIFF_ID)
	{
		std::cerr << "Error: Missing RIFF chunk." << std::endl;
		return false;
	}
	if (header.fmt.chunkID != FMT_ID)
	{
		std::cerr << "Error: Missing fmt chunk." << std::endl;
		return false;
	}
	if (data == nullptr)
	{
		std::cerr << "Error: Missing data chunk." << std::endl;
		return false;
	}

	// Fill meta struct
	meta.audioFormat   = static_cast<AudioFormat>(header.fmt.audioFormat);
	meta.numChannels   = header.fmt.numChannels;
	meta.sampleRate    = header.fmt.sampleRate;
	meta.bitsPerSample = header.fmt.bitsPerSample;

	return true;
}
void WaveFile::Unload()
{
	delete[] data;
	data = nullptr;
	size = 0;
}

std::string WaveFile::GetAudioFormatString() const
{
	switch (meta.audioFormat)
	{
	case WaveFile::PCM: return "PCM";
	case WaveFile::IEEE_FLOAT: return "IEEE float";
	default: return "Unknown";
	}
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 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 "Xalan" 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) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "AVT.hpp"

#include <algorithm>

#include <Include/STLHelper.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/StringTokenizer.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

#include <DOMSupport/DOMServices.hpp>

#include "AVTPartSimple.hpp"
#include "AVTPartXPath.hpp"
#include "StylesheetConstructionContext.hpp"

static const XalanDOMChar	theTokenDelimiterCharacters[] =
{
		XalanUnicode::charLeftCurlyBracket,
		XalanUnicode::charRightCurlyBracket,
		XalanUnicode::charApostrophe,
		XalanUnicode::charQuoteMark,
		0
};

static const XalanDOMChar	theLeftCurlyBracketString[] =
{
		XalanUnicode::charLeftCurlyBracket,
		0
};

static const XalanDOMChar	theRightCurlyBracketString[] =
{
		XalanUnicode::charRightCurlyBracket,
		0
};

/**
 * Construct an AVT by parsing the string, and either
 * constructing a vector of AVTParts, or simply hold
 * on to the string if the AVT is simple.
 */
AVT::AVT(
			const XalanDOMChar*				name,
			const XalanDOMChar*				type,
			const XalanDOMChar*				stringedValue,
			const PrefixResolver&			resolver,
			StylesheetConstructionContext&	constructionContext) :
		m_parts(),
		m_simpleString(),
		// $$$ ToDo: Explicit XalanDOMString constructor
		m_name(XalanDOMString(name)),
		m_prefix(getPrefix(name)),
		m_pcType(type)
{
	StringTokenizer		tokenizer(stringedValue, theTokenDelimiterCharacters, true);

	const unsigned int	nTokens = tokenizer.countTokens();

	if(nTokens < 2)
	{
		m_simpleString = stringedValue; // then do the simple thing
	}
	else
	{
		m_parts.reserve(nTokens + 1);

		XalanDOMString	buffer;
		XalanDOMString	exprBuffer;
		XalanDOMString	t; // base token
		XalanDOMString	lookahead; // next token
		XalanDOMString	error; // if non-null, break from loop

		while(tokenizer.hasMoreTokens())
		{
			if(length(lookahead))
			{
				t = lookahead;

				clear(lookahead);
			}
			else
			{
				t = tokenizer.nextToken();
			}

			if(length(t) == 1)
			{
				const XalanDOMChar	theChar = charAt(t, 0);

				switch(theChar)
				{
					case(XalanUnicode::charLeftCurlyBracket):
					{
						// Attribute Value Template start
						lookahead = tokenizer.nextToken();
						if(equals(lookahead, theLeftCurlyBracketString))
						{
							// Double curlys mean escape to show curly
							append(buffer, lookahead);

							clear(lookahead);

							break; // from switch
						}
						else
						{
							if(length(buffer) > 0)
							{
								m_parts.push_back(new AVTPartSimple(buffer));

								clear(buffer);
							}

							clear(exprBuffer);

							while(length(lookahead) > 0 && !equals(lookahead, theRightCurlyBracketString))
							{
								if(length(lookahead) == 1)
								{
									switch(charAt(lookahead, 0))
									{
										case XalanUnicode::charApostrophe:
										case XalanUnicode::charQuoteMark:
										{
											// String start
											append(exprBuffer, lookahead);

											const XalanDOMString	quote = lookahead;

											// Consume stuff 'till next quote
											lookahead = tokenizer.nextToken();

											while(!equals(lookahead, quote))
											{
												append(exprBuffer, lookahead);

												lookahead = tokenizer.nextToken();
											}

											append(exprBuffer,lookahead);

											break;
										}
										case XalanUnicode::charLeftCurlyBracket:
										{
											// What's another curly doing here?
											error = TranscodeFromLocalCodePage("Error: Can not have \"{\" within expression.");

											break;
										}
										default:
										{
											// part of the template stuff, just add it.
											append(exprBuffer, lookahead);
										}
									} // end inner switch
								} // end if lookahead length == 1
								else
								{
									// part of the template stuff, just add it.
									append(exprBuffer,lookahead);
								}

								lookahead = tokenizer.nextToken();
							} // end while(!equals(lookahead, "}"))
							assert(equals(lookahead, theRightCurlyBracketString));

							// Proper close of attribute template. Evaluate the
							// expression.
							clear(buffer);

							const XPath* const	xpath = constructionContext.createXPath(exprBuffer, resolver);
							assert(xpath != 0);

							m_parts.push_back(new AVTPartXPath(xpath));

							clear(lookahead); // breaks out of inner while loop

							if(length(error) > 0)
							{
								break; // from inner while loop
							}
						}
						break;
					}
					case(XalanUnicode::charRightCurlyBracket):
					{
						lookahead = tokenizer.nextToken();

						if(equals(lookahead, theRightCurlyBracketString))
						{
							// Double curlys mean escape to show curly
							append(buffer, lookahead);

							clear(lookahead); // swallow
						}
						else
						{
							// Illegal, I think...
							constructionContext.warn("Found \"}\" but no attribute template open!");

							append(buffer, theRightCurlyBracketString);
							// leave the lookahead to be processed by the next round.
						}
						break;
					}
					default:
					{
						const XalanDOMString	s(&theChar, 1);

						// Anything else just add to string.
						append(buffer, s);
					}
				} // end switch t
			} // end if length == 1
			else
			{
				// Anything else just add to string.
				append(buffer,t);
			}

			if(length(error) > 0)
			{
				constructionContext.warn("Attr Template, " + error);

				break;
			}
		} // end while(tokenizer.hasMoreTokens())

		if(length(buffer) > 0)
		{
			m_parts.push_back(new AVTPartSimple(buffer));

			clear(buffer);
		}

	} // end else nTokens > 1

	if(m_parts.empty() && length(m_simpleString) == 0)
	{
		// Error?
		clear(m_simpleString);
	}
	else if (m_parts.size() < m_parts.capacity())
	{
		AVTPartPtrVectorType(m_parts).swap(m_parts);
	}

}

AVT::~AVT()
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Clean up all entries in the vector.
	for_each(m_parts.begin(),
			 m_parts.end(),
			 DeleteFunctor<AVTPart>());
}

void
AVT::evaluate(
			XalanDOMString&			buf,
			XalanNode*				contextNode,
			const PrefixResolver&	prefixResolver,
			XPathExecutionContext&	executionContext) const
{
	if(length(m_simpleString) > 0)
	{
		buf = m_simpleString;
	}
	else
	{
		clear(buf);

		if(m_parts.empty() == false)
		{
			const AVTPartPtrVectorType::size_type	n = m_parts.size();

			for(AVTPartPtrVectorType::size_type i = 0; i < n; i++)
			{
				assert(m_parts[i] != 0);

				m_parts[i]->evaluate(buf, contextNode, prefixResolver, executionContext);
			}
		}
	}
}

XalanDOMString
AVT::getPrefix(const XalanDOMChar*	theName)
{
	if (startsWith(theName, DOMServices::s_XMLNamespaceWithSeparator) == true)
	{
		return substring(theName, DOMServices::s_XMLNamespaceWithSeparatorLength);
	}
	else
	{
		return XalanDOMString();
	}
}
<commit_msg>Use new StringTokenizer overload.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 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 "Xalan" 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) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "AVT.hpp"

#include <algorithm>

#include <Include/STLHelper.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/StringTokenizer.hpp>
#include <PlatformSupport/XalanUnicode.hpp>

#include <DOMSupport/DOMServices.hpp>

#include "AVTPartSimple.hpp"
#include "AVTPartXPath.hpp"
#include "StylesheetConstructionContext.hpp"

static const XalanDOMChar	theTokenDelimiterCharacters[] =
{
		XalanUnicode::charLeftCurlyBracket,
		XalanUnicode::charRightCurlyBracket,
		XalanUnicode::charApostrophe,
		XalanUnicode::charQuoteMark,
		0
};

static const XalanDOMChar	theLeftCurlyBracketString[] =
{
		XalanUnicode::charLeftCurlyBracket,
		0
};

static const XalanDOMChar	theRightCurlyBracketString[] =
{
		XalanUnicode::charRightCurlyBracket,
		0
};

/**
 * Construct an AVT by parsing the string, and either
 * constructing a vector of AVTParts, or simply hold
 * on to the string if the AVT is simple.
 */
AVT::AVT(
			const XalanDOMChar*				name,
			const XalanDOMChar*				type,
			const XalanDOMChar*				stringedValue,
			const PrefixResolver&			resolver,
			StylesheetConstructionContext&	constructionContext) :
		m_parts(),
		m_simpleString(),
		// $$$ ToDo: Explicit XalanDOMString constructor
		m_name(XalanDOMString(name)),
		m_prefix(getPrefix(name)),
		m_pcType(type)
{
	StringTokenizer		tokenizer(stringedValue, theTokenDelimiterCharacters, true);

	const unsigned int	nTokens = tokenizer.countTokens();

	if(nTokens < 2)
	{
		m_simpleString = stringedValue; // then do the simple thing
	}
	else
	{
		m_parts.reserve(nTokens + 1);

		XalanDOMString	buffer;
		XalanDOMString	exprBuffer;
		XalanDOMString	t; // base token
		XalanDOMString	lookahead; // next token
		XalanDOMString	error; // if non-null, break from loop

		while(tokenizer.hasMoreTokens())
		{
			if(length(lookahead))
			{
				t = lookahead;

				clear(lookahead);
			}
			else
			{
				tokenizer.nextToken(t);
			}

			if(length(t) == 1)
			{
				const XalanDOMChar	theChar = charAt(t, 0);

				switch(theChar)
				{
					case(XalanUnicode::charLeftCurlyBracket):
					{
						// Attribute Value Template start
						tokenizer.nextToken(lookahead);

						if(equals(lookahead, theLeftCurlyBracketString))
						{
							// Double curlys mean escape to show curly
							append(buffer, lookahead);

							clear(lookahead);

							break; // from switch
						}
						else
						{
							if(length(buffer) > 0)
							{
								m_parts.push_back(new AVTPartSimple(buffer));

								clear(buffer);
							}

							clear(exprBuffer);

							while(length(lookahead) > 0 && !equals(lookahead, theRightCurlyBracketString))
							{
								if(length(lookahead) == 1)
								{
									switch(charAt(lookahead, 0))
									{
										case XalanUnicode::charApostrophe:
										case XalanUnicode::charQuoteMark:
										{
											// String start
											append(exprBuffer, lookahead);

											const XalanDOMString	quote = lookahead;

											// Consume stuff 'till next quote
											tokenizer.nextToken(lookahead);

											while(!equals(lookahead, quote))
											{
												append(exprBuffer, lookahead);

												 tokenizer.nextToken(lookahead);
											}

											append(exprBuffer,lookahead);

											break;
										}
										case XalanUnicode::charLeftCurlyBracket:
										{
											// What's another curly doing here?
											error = TranscodeFromLocalCodePage("Error: Can not have \"{\" within expression.");

											break;
										}
										default:
										{
											// part of the template stuff, just add it.
											append(exprBuffer, lookahead);
										}
									} // end inner switch
								} // end if lookahead length == 1
								else
								{
									// part of the template stuff, just add it.
									append(exprBuffer,lookahead);
								}

								tokenizer.nextToken(lookahead);
							} // end while(!equals(lookahead, "}"))
							assert(equals(lookahead, theRightCurlyBracketString));

							// Proper close of attribute template. Evaluate the
							// expression.
							clear(buffer);

							const XPath* const	xpath = constructionContext.createXPath(exprBuffer, resolver);
							assert(xpath != 0);

							m_parts.push_back(new AVTPartXPath(xpath));

							clear(lookahead); // breaks out of inner while loop

							if(length(error) > 0)
							{
								break; // from inner while loop
							}
						}
						break;
					}
					case(XalanUnicode::charRightCurlyBracket):
					{
						tokenizer.nextToken(lookahead);

						if(equals(lookahead, theRightCurlyBracketString))
						{
							// Double curlys mean escape to show curly
							append(buffer, lookahead);

							clear(lookahead); // swallow
						}
						else
						{
							// Illegal, I think...
							constructionContext.warn("Found \"}\" but no attribute template open!");

							append(buffer, theRightCurlyBracketString);
							// leave the lookahead to be processed by the next round.
						}
						break;
					}
					default:
					{
						const XalanDOMString	s(&theChar, 1);

						// Anything else just add to string.
						append(buffer, s);
					}
				} // end switch t
			} // end if length == 1
			else
			{
				// Anything else just add to string.
				append(buffer,t);
			}

			if(length(error) > 0)
			{
				constructionContext.warn("Attr Template, " + error);

				break;
			}
		} // end while(tokenizer.hasMoreTokens())

		if(length(buffer) > 0)
		{
			m_parts.push_back(new AVTPartSimple(buffer));

			clear(buffer);
		}

	} // end else nTokens > 1

	if(m_parts.empty() && length(m_simpleString) == 0)
	{
		// Error?
		clear(m_simpleString);
	}
	else if (m_parts.size() < m_parts.capacity())
	{
		AVTPartPtrVectorType(m_parts).swap(m_parts);
	}

}

AVT::~AVT()
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::for_each;
#endif

	// Clean up all entries in the vector.
	for_each(m_parts.begin(),
			 m_parts.end(),
			 DeleteFunctor<AVTPart>());
}

void
AVT::evaluate(
			XalanDOMString&			buf,
			XalanNode*				contextNode,
			const PrefixResolver&	prefixResolver,
			XPathExecutionContext&	executionContext) const
{
	if(length(m_simpleString) > 0)
	{
		buf = m_simpleString;
	}
	else
	{
		clear(buf);

		if(m_parts.empty() == false)
		{
			const AVTPartPtrVectorType::size_type	n = m_parts.size();

			for(AVTPartPtrVectorType::size_type i = 0; i < n; i++)
			{
				assert(m_parts[i] != 0);

				m_parts[i]->evaluate(buf, contextNode, prefixResolver, executionContext);
			}
		}
	}
}

XalanDOMString
AVT::getPrefix(const XalanDOMChar*	theName)
{
	if (startsWith(theName, DOMServices::s_XMLNamespaceWithSeparator) == true)
	{
		return substring(theName, DOMServices::s_XMLNamespaceWithSeparatorLength);
	}
	else
	{
		return XalanDOMString();
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ecclesia/lib/redfish/testing/grpc_dynamic_mockup_server.h"

#include <memory>
#include <string>
#include <string_view>

#include "google/protobuf/struct.pb.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "ecclesia/lib/file/test_filesystem.h"
#include "ecclesia/lib/http/codes.h"
#include "ecclesia/lib/network/testing.h"
#include "ecclesia/lib/protobuf/parse.h"
#include "ecclesia/lib/redfish/interface.h"
#include "ecclesia/lib/redfish/proto/redfish_v1.grpc.pb.h"
#include "ecclesia/lib/redfish/proto/redfish_v1.pb.h"
#include "ecclesia/lib/redfish/transport/grpc.h"
#include "ecclesia/lib/redfish/transport/grpc_dynamic_impl.h"
#include "ecclesia/lib/redfish/transport/grpc_dynamic_options.h"
#include "ecclesia/lib/status/rpc.h"
#include "ecclesia/lib/testing/proto.h"
#include "ecclesia/lib/testing/status.h"
#include "grpcpp/channel.h"
#include "grpcpp/client_context.h"
#include "grpcpp/create_channel.h"
#include "grpcpp/security/credentials.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/status.h"

namespace ecclesia {
namespace {

using ::google::protobuf::Struct;
using ::redfish::v1::Request;
using ::redfish::v1::Response;
using ::testing::Eq;
using ::testing::Test;

class GrpcRedfishMockUpServerTest : public Test {
 protected:
  GrpcRedfishMockUpServerTest() {
    GrpcDynamicImplOptions options;
    options.SetToInsecure();
    int port = FindUnusedPortOrDie();
    mockup_server_ = absl::make_unique<GrpcDynamicMockupServer>(
        "barebones_session_auth/mockup.shar", "[::1]", port);
    GrpcRedfishTransport::Params params;
    client_ = absl::make_unique<GrpcRedfishTransport>(
        absl::StrCat("[::1]:", port), params);
    std::shared_ptr<grpc::Channel> channel = CreateChannel(
        absl::StrCat("[::1]:", port), grpc::InsecureChannelCredentials());
    stub_ = ::redfish::v1::RedfishV1::NewStub(channel);
  }

  std::unique_ptr<GrpcDynamicMockupServer> mockup_server_;
  std::unique_ptr<GrpcRedfishTransport> client_;
  std::unique_ptr<::redfish::v1::RedfishV1::Stub> stub_;
};

// Testing Post, Patch and Get requests. The Patch request can verify the
// resource has been Posted. And The Get Request can verify that the
// resource has been Patched.
TEST_F(GrpcRedfishMockUpServerTest, TestPostPatchAndGetRequest) {
  // Test Post request
  std::string_view data_post = R"json({
    "ChassisType": "RackMount",
    "Name": "MyChassis"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_EQ(result_post->code,
            ecclesia::HttpResponseCode::HTTP_CODE_NO_CONTENT);

  // Test Patch request
  std::string_view data_patch = R"json({
    "Name": "MyNewName"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1/Chassis/Member1", data_patch);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_EQ(result_patch->code,
            ecclesia::HttpResponseCode::HTTP_CODE_NO_CONTENT);

  // Test Get Request
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1/Chassis/Member1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name;
  name = (result_get->body)["Name"];
  EXPECT_EQ(name, "MyNewName");
  EXPECT_EQ(result_get->code,
            ecclesia::HttpResponseCode::HTTP_CODE_REQUEST_OK);
}

TEST_F(GrpcRedfishMockUpServerTest, TestPutRequests) {
  grpc::ClientContext context;
  Request request;
  Response response;
  EXPECT_THAT(AsAbslStatus(stub_->Put(&context, request, &response)),
              IsStatusUnimplemented());
}

TEST_F(GrpcRedfishMockUpServerTest, TestDeleteRequests) {
  grpc::ClientContext context;
  Request request;
  Response response;
  EXPECT_THAT(AsAbslStatus(stub_->Delete(&context, request, &response)),
              IsStatusUnimplemented());
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomGet) {
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Name"
      value: { string_value: "MyResource" }
    }
  )pb");
  mockup_server_->AddHttpGetHandler(
      "/redfish/v1/MyResource",
      [&kResponse](grpc::ServerContext *context,
                   const ::redfish::v1::Request *request, Response *response) {
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1/MyResource");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name = (result_get->body)["Name"];
  EXPECT_THAT(name, Eq("MyResource"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomPost) {
  const ::redfish::v1::Request kRequest = ParseTextProtoOrDie(R"pb(
    url: "/redfish/v1/MyResource"
    message {
      fields {
        key: "num"
        value: { number_value: 1 }
      }
      fields {
        key: "str"
        value: { string_value: "hi" }
      }
    }
  )pb");
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Result"
      value: { string_value: "OK" }
    }
  )pb");
  bool called = false;
  mockup_server_->AddHttpPostHandler(
      "/redfish/v1/MyResource",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        EXPECT_THAT(*request, EqualsProto(kRequest));
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  std::string_view data_post = R"json({
    "num": 1,
    "str": "hi"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/MyResource", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  ASSERT_TRUE(called);
  std::string name = (result_post->body)["Result"];
  EXPECT_THAT(name, Eq("OK"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomPatch) {
  const ::redfish::v1::Request kRequest = ParseTextProtoOrDie(R"pb(
    url: "/redfish/v1/MyResource"
    message {
      fields {
        key: "num"
        value: { number_value: 1 }
      }
      fields {
        key: "str"
        value: { string_value: "hi" }
      }
    }
  )pb");
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Result"
      value: { string_value: "OK" }
    }
  )pb");
  bool called = false;
  mockup_server_->AddHttpPatchHandler(
      "/redfish/v1/MyResource",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        EXPECT_THAT(*request, EqualsProto(kRequest));
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  std::string_view data_patch = R"json({
    "num": 1,
    "str": "hi"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1/MyResource", data_patch);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_TRUE(called);
  std::string name = (result_patch->body)["Result"];
  EXPECT_THAT(name, Eq("OK"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestPostReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpPostHandler(
      "/redfish/v1/Chassis",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  std::string_view data_post = R"json({
    "Id": "id",
    "Name": "MyChassis"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_post = client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_FALSE(called);
}

TEST_F(GrpcRedfishMockUpServerTest, TestPatchReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpPatchHandler(
      "/redfish/v1",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  std::string_view data = R"json({
    "Name": "Test Name"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1", data);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_patch = client_->Patch("/redfish/v1", data);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_FALSE(called);
}

TEST_F(GrpcRedfishMockUpServerTest, TestGetReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpGetHandler(
      "/redfish/v1",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_get = client_->Get("/redfish/v1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name = (result_get->body)["Name"];
  EXPECT_THAT(name, Eq("Root Service"));
  EXPECT_FALSE(called);
}

TEST(GrpcRedfishMockUpServerUdsTest, TestUds) {
  absl::flat_hash_map<std::string, std::string> headers;
  std::string mockup_uds =
      absl::StrCat(GetTestTempUdsDirectory(), "/mockup.socket");
  GrpcDynamicMockupServer mockup_server("barebones_session_auth/mockup.shar",
                                        mockup_uds);
  GrpcRedfishTransport transport(absl::StrCat("unix://", mockup_uds), {});
  std::string_view expexted_str = R"json({
    "@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
    "@odata.id": "/redfish/v1",
    "@odata.type": "#ServiceRoot.v1_5_0.ServiceRoot",
    "Chassis": {
        "@odata.id": "/redfish/v1/Chassis"
    },
    "Id": "RootService",
    "Links": {
        "Sessions": {
            "@odata.id": "/redfish/v1/SessionService/Sessions"
        }
    },
    "Name": "Root Service",
    "RedfishVersion": "1.6.1"
  })json";
  nlohmann::json expected = nlohmann::json::parse(expexted_str, nullptr, false);
  absl::StatusOr<GrpcRedfishTransport::Result> res_get =
      transport.Get("/redfish/v1");
  ASSERT_THAT(res_get, IsOk());
  EXPECT_THAT(res_get->body, Eq(expected));
}

}  // namespace
}  // namespace ecclesia
<commit_msg>Internal change<commit_after>/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ecclesia/lib/redfish/testing/grpc_dynamic_mockup_server.h"

#include <memory>
#include <string>

#include "google/protobuf/struct.pb.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "ecclesia/lib/file/test_filesystem.h"
#include "ecclesia/lib/http/codes.h"
#include "ecclesia/lib/network/testing.h"
#include "ecclesia/lib/protobuf/parse.h"
#include "ecclesia/lib/redfish/interface.h"
#include "ecclesia/lib/redfish/proto/redfish_v1.grpc.pb.h"
#include "ecclesia/lib/redfish/proto/redfish_v1.pb.h"
#include "ecclesia/lib/redfish/transport/grpc.h"
#include "ecclesia/lib/redfish/transport/grpc_dynamic_impl.h"
#include "ecclesia/lib/redfish/transport/grpc_dynamic_options.h"
#include "ecclesia/lib/status/rpc.h"
#include "ecclesia/lib/testing/proto.h"
#include "ecclesia/lib/testing/status.h"
#include "grpcpp/channel.h"
#include "grpcpp/client_context.h"
#include "grpcpp/create_channel.h"
#include "grpcpp/security/credentials.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/status.h"

namespace ecclesia {
namespace {

using ::google::protobuf::Struct;
using ::redfish::v1::Request;
using ::redfish::v1::Response;
using ::testing::Eq;
using ::testing::Test;

class GrpcRedfishMockUpServerTest : public Test {
 protected:
  GrpcRedfishMockUpServerTest() {
    GrpcDynamicImplOptions options;
    options.SetToInsecure();
    int port = FindUnusedPortOrDie();
    mockup_server_ = absl::make_unique<GrpcDynamicMockupServer>(
        "barebones_session_auth/mockup.shar", "[::1]", port);
    GrpcRedfishTransport::Params params;
    client_ = absl::make_unique<GrpcRedfishTransport>(
        absl::StrCat("[::1]:", port), params);
    std::shared_ptr<grpc::Channel> channel = CreateChannel(
        absl::StrCat("[::1]:", port), grpc::InsecureChannelCredentials());
    stub_ = ::redfish::v1::RedfishV1::NewStub(channel);
  }

  std::unique_ptr<GrpcDynamicMockupServer> mockup_server_;
  std::unique_ptr<GrpcRedfishTransport> client_;
  std::unique_ptr<::redfish::v1::RedfishV1::Stub> stub_;
};

// Testing Post, Patch and Get requests. The Patch request can verify the
// resource has been Posted. And The Get Request can verify that the
// resource has been Patched.
TEST_F(GrpcRedfishMockUpServerTest, TestPostPatchAndGetRequest) {
  // Test Post request
  std::string_view data_post = R"json({
    "ChassisType": "RackMount",
    "Name": "MyChassis"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_EQ(result_post->code,
            ecclesia::HttpResponseCode::HTTP_CODE_NO_CONTENT);

  // Test Patch request
  std::string_view data_patch = R"json({
    "Name": "MyNewName"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1/Chassis/Member1", data_patch);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_EQ(result_patch->code,
            ecclesia::HttpResponseCode::HTTP_CODE_NO_CONTENT);

  // Test Get Request
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1/Chassis/Member1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name;
  name = (result_get->body)["Name"];
  EXPECT_EQ(name, "MyNewName");
  EXPECT_EQ(result_get->code,
            ecclesia::HttpResponseCode::HTTP_CODE_REQUEST_OK);
}

TEST_F(GrpcRedfishMockUpServerTest, TestPutRequests) {
  grpc::ClientContext context;
  Request request;
  Response response;
  EXPECT_THAT(AsAbslStatus(stub_->Put(&context, request, &response)),
              IsStatusUnimplemented());
}

TEST_F(GrpcRedfishMockUpServerTest, TestDeleteRequests) {
  grpc::ClientContext context;
  Request request;
  Response response;
  EXPECT_THAT(AsAbslStatus(stub_->Delete(&context, request, &response)),
              IsStatusUnimplemented());
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomGet) {
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Name"
      value: { string_value: "MyResource" }
    }
  )pb");
  mockup_server_->AddHttpGetHandler(
      "/redfish/v1/MyResource",
      [&kResponse](grpc::ServerContext *context,
                   const ::redfish::v1::Request *request, Response *response) {
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1/MyResource");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name = (result_get->body)["Name"];
  EXPECT_THAT(name, Eq("MyResource"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomPost) {
  const ::redfish::v1::Request kRequest = ParseTextProtoOrDie(R"pb(
    url: "/redfish/v1/MyResource"
    message {
      fields {
        key: "num"
        value: { number_value: 1 }
      }
      fields {
        key: "str"
        value: { string_value: "hi" }
      }
    }
  )pb");
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Result"
      value: { string_value: "OK" }
    }
  )pb");
  bool called = false;
  mockup_server_->AddHttpPostHandler(
      "/redfish/v1/MyResource",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        EXPECT_THAT(*request, EqualsProto(kRequest));
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  std::string_view data_post = R"json({
    "num": 1,
    "str": "hi"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/MyResource", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  ASSERT_TRUE(called);
  std::string name = (result_post->body)["Result"];
  EXPECT_THAT(name, Eq("OK"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestCustomPatch) {
  const ::redfish::v1::Request kRequest = ParseTextProtoOrDie(R"pb(
    url: "/redfish/v1/MyResource"
    message {
      fields {
        key: "num"
        value: { number_value: 1 }
      }
      fields {
        key: "str"
        value: { string_value: "hi" }
      }
    }
  )pb");
  const google::protobuf::Struct kResponse = ParseTextProtoOrDie(R"pb(
    fields {
      key: "Result"
      value: { string_value: "OK" }
    }
  )pb");
  bool called = false;
  mockup_server_->AddHttpPatchHandler(
      "/redfish/v1/MyResource",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        EXPECT_THAT(*request, EqualsProto(kRequest));
        *response->mutable_message() = kResponse;
        return grpc::Status::OK;
      });
  std::string_view data_patch = R"json({
    "num": 1,
    "str": "hi"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1/MyResource", data_patch);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_TRUE(called);
  std::string name = (result_patch->body)["Result"];
  EXPECT_THAT(name, Eq("OK"));
}

TEST_F(GrpcRedfishMockUpServerTest, TestPostReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpPostHandler(
      "/redfish/v1/Chassis",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  std::string_view data_post = R"json({
    "Id": "id",
    "Name": "MyChassis"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_post =
      client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_post = client_->Post("/redfish/v1/Chassis", data_post);
  ASSERT_TRUE(result_post.status().ok()) << result_post.status().message();
  EXPECT_FALSE(called);
}

TEST_F(GrpcRedfishMockUpServerTest, TestPatchReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpPatchHandler(
      "/redfish/v1",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  std::string_view data = R"json({
    "Name": "Test Name"
  })json";
  absl::StatusOr<RedfishTransport::Result> result_patch =
      client_->Patch("/redfish/v1", data);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_patch = client_->Patch("/redfish/v1", data);
  ASSERT_TRUE(result_patch.status().ok()) << result_patch.status().message();
  EXPECT_FALSE(called);
}

TEST_F(GrpcRedfishMockUpServerTest, TestGetReset) {
  bool called = false;
  // Register the handler.
  mockup_server_->AddHttpGetHandler(
      "/redfish/v1",
      [&](grpc::ServerContext *context, const ::redfish::v1::Request *request,
          Response *response) {
        called = true;
        return grpc::Status::OK;
      });
  absl::StatusOr<RedfishTransport::Result> result_get =
      client_->Get("/redfish/v1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  EXPECT_TRUE(called);

  // Clear the registered handler.
  called = false;
  mockup_server_->ClearHandlers();
  result_get = client_->Get("/redfish/v1");
  ASSERT_TRUE(result_get.status().ok()) << result_get.status().message();
  std::string name = (result_get->body)["Name"];
  EXPECT_THAT(name, Eq("Root Service"));
  EXPECT_FALSE(called);
}

TEST(GrpcRedfishMockUpServerUdsTest, TestUds) {
  absl::flat_hash_map<std::string, std::string> headers;
  std::string mockup_uds =
      absl::StrCat(GetTestTempUdsDirectory(), "/mockup.socket");
  GrpcDynamicMockupServer mockup_server("barebones_session_auth/mockup.shar",
                                        mockup_uds);
  GrpcRedfishTransport transport(absl::StrCat("unix://", mockup_uds), {});
  std::string_view expexted_str = R"json({
    "@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
    "@odata.id": "/redfish/v1",
    "@odata.type": "#ServiceRoot.v1_5_0.ServiceRoot",
    "Chassis": {
        "@odata.id": "/redfish/v1/Chassis"
    },
    "Id": "RootService",
    "Links": {
        "Sessions": {
            "@odata.id": "/redfish/v1/SessionService/Sessions"
        }
    },
    "Name": "Root Service",
    "RedfishVersion": "1.6.1"
  })json";
  nlohmann::json expected = nlohmann::json::parse(expexted_str, nullptr, false);
  absl::StatusOr<GrpcRedfishTransport::Result> res_get =
      transport.Get("/redfish/v1");
  ASSERT_THAT(res_get, IsOk());
  EXPECT_THAT(res_get->body, Eq(expected));
}

}  // namespace
}  // namespace ecclesia
<|endoftext|>