<commit_before>/*
    Calendar access for KDE Alarm Daemon.

    This file is part of the KDE alarm daemon.
    Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <unistd.h>
#include <time.h>

#include <qfile.h>

#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <ktempfile.h>
#include <kio/job.h>
#include <kio/jobclasses.h>
#include <kdebug.h>

#include "adcalendarbase.h"

ADCalendarBase::EventsMap ADCalendarBase::eventsHandled_;

ADCalendarBase::ADCalendarBase(const QString& url, const QCString& appname, Type type)
  : mUrlString(url),
    mAppName(appname),
    mActionType(type),
    mRcIndex(-1),
    mLoaded(false),
    mUnregistered(false)
{
  if (mAppName == "korgac")
  {
    KConfig cfg( locate( "config", "korganizerrc" ) );
    cfg.setGroup( "Time & Date" );
    QString tz = cfg.readEntry( "TimeZoneId" );
    kdDebug(5900) << "ADCalendarBase(): tz: " << tz << endl;
    if( tz.isEmpty() ) {
      // Set a reasonable default timezone is none
      // was found in the config file
      // see koprefs.cpp in korganizer
      QString zone;
      char zonefilebuf[100];
      int len = readlink("/etc/localtime",zonefilebuf,100);
      if (len > 0 && len < 100) {
	zonefilebuf[len] = '\0';
	zone = zonefilebuf;
	zone = zone.mid(zone.find("zoneinfo/") + 9);
      } else {
	tzset();
	zone = tzname[0];
      }
      tz = zone;
    }
    setTimeZoneId( tz );
  }
}

/*
 * Load the calendar file.
 */
bool ADCalendarBase::loadFile_(const QCString& appName)
{
  if ( !mTempFileName.isNull() ) {
    // Don't try to load the file if already downloading it
    kdError(5900) << "ADCalendarBase::loadFile_(): already downloading another file\n";
    return false;
  }
  mLoaded = false;
  KURL url( mUrlString );
  if ( url.isLocalFile() ) {
    // It's a local file
    loadLocalFile( url.path() );
    emit loaded( this, mLoaded );
  } else {
    // It's a remote file. Download to a temporary file before loading it.
    KTempFile tempFile;
    mTempFileName = tempFile.name();
    KURL dest;
    dest.setPath( mTempFileName );
    KIO::FileCopyJob *job = KIO::file_copy( url, dest, -1, true );
    connect( job, SIGNAL( result( KIO::Job * ) ),
             SLOT( slotDownloadJobResult( KIO::Job * ) ) );
  }
  return true;
}

void ADCalendarBase::slotDownloadJobResult( KIO::Job *job )
{
  if ( job->error() ) {
    KURL url( mUrlString );
    kdDebug(5900) << "Error downloading calendar from " << url.prettyURL() << endl;
    job->showErrorDialog( 0 );
  } else {
    kdDebug(5900) << "--- Downloaded to " << mTempFileName << endl;
    loadLocalFile( mTempFileName );
  }
  unlink( QFile::encodeName( mTempFileName ) );
  mTempFileName = QString::null;
  emit loaded( this, mLoaded );
}

void ADCalendarBase::loadLocalFile( const QString& filename )
{
  mLoaded = load( filename );
  if (!mLoaded)
    kdDebug(5900) << "ADCalendarBase::loadLocalFile(): Error loading calendar file '" << filename << "'\n";
  else
  {
    // Remove all now non-existent events from the handled list
    for (EventsMap::Iterator it = eventsHandled_.begin();  it != eventsHandled_.end();  )
    {
      if (it.data().calendarURL == mUrlString  &&  !event(it.key()))
      {
        // Event belonged to this calendar, but can't find it any more
        EventsMap::Iterator i = it;
        ++it;                      // prevent iterator becoming invalid with remove()
        eventsHandled_.remove(i);
      }
      else
        ++it;
    }
  }
}

void ADCalendarBase::dump() const
{
  kdDebug(5900) << "  <calendar>" << endl;
  kdDebug(5900) << "    <url>" << urlString() << "</url>" << endl;
  kdDebug(5900) << "    <appname>" << appName() << "</appname>" << endl;
  if ( loaded() ) kdDebug(5900) << "    <loaded/>" << endl;
  kdDebug(5900) << "    <actiontype>" << int(actionType()) << "</actiontype>" << endl;
  if (enabled() ) kdDebug(5900) << "    <enabled/>" << endl;
  else kdDebug(5900) << "    <disabled/>" << endl;
  if (available()) kdDebug(5900) << "    <available/>" << endl;
  kdDebug(5900) << "  </calendar>" << endl;
}
<commit_msg>Make it work with unsermake.<commit_after>/*
    Calendar access for KDE Alarm Daemon.

    This file is part of the KDE alarm daemon.
    Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <unistd.h>
#include <time.h>

#include <qfile.h>

#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <ktempfile.h>
#include <kio/job.h>
#include <kio/jobclasses.h>
#include <kdebug.h>

#include "adcalendarbase.h"
#include "adcalendarbase.moc"

ADCalendarBase::EventsMap ADCalendarBase::eventsHandled_;

ADCalendarBase::ADCalendarBase(const QString& url, const QCString& appname, Type type)
  : mUrlString(url),
    mAppName(appname),
    mActionType(type),
    mRcIndex(-1),
    mLoaded(false),
    mUnregistered(false)
{
  if (mAppName == "korgac")
  {
    KConfig cfg( locate( "config", "korganizerrc" ) );
    cfg.setGroup( "Time & Date" );
    QString tz = cfg.readEntry( "TimeZoneId" );
    kdDebug(5900) << "ADCalendarBase(): tz: " << tz << endl;
    if( tz.isEmpty() ) {
      // Set a reasonable default timezone is none
      // was found in the config file
      // see koprefs.cpp in korganizer
      QString zone;
      char zonefilebuf[100];
      int len = readlink("/etc/localtime",zonefilebuf,100);
      if (len > 0 && len < 100) {
	zonefilebuf[len] = '\0';
	zone = zonefilebuf;
	zone = zone.mid(zone.find("zoneinfo/") + 9);
      } else {
	tzset();
	zone = tzname[0];
      }
      tz = zone;
    }
    setTimeZoneId( tz );
  }
}

/*
 * Load the calendar file.
 */
bool ADCalendarBase::loadFile_(const QCString& appName)
{
  if ( !mTempFileName.isNull() ) {
    // Don't try to load the file if already downloading it
    kdError(5900) << "ADCalendarBase::loadFile_(): already downloading another file\n";
    return false;
  }
  mLoaded = false;
  KURL url( mUrlString );
  if ( url.isLocalFile() ) {
    // It's a local file
    loadLocalFile( url.path() );
    emit loaded( this, mLoaded );
  } else {
    // It's a remote file. Download to a temporary file before loading it.
    KTempFile tempFile;
    mTempFileName = tempFile.name();
    KURL dest;
    dest.setPath( mTempFileName );
    KIO::FileCopyJob *job = KIO::file_copy( url, dest, -1, true );
    connect( job, SIGNAL( result( KIO::Job * ) ),
             SLOT( slotDownloadJobResult( KIO::Job * ) ) );
  }
  return true;
}

void ADCalendarBase::slotDownloadJobResult( KIO::Job *job )
{
  if ( job->error() ) {
    KURL url( mUrlString );
    kdDebug(5900) << "Error downloading calendar from " << url.prettyURL() << endl;
    job->showErrorDialog( 0 );
  } else {
    kdDebug(5900) << "--- Downloaded to " << mTempFileName << endl;
    loadLocalFile( mTempFileName );
  }
  unlink( QFile::encodeName( mTempFileName ) );
  mTempFileName = QString::null;
  emit loaded( this, mLoaded );
}

void ADCalendarBase::loadLocalFile( const QString& filename )
{
  mLoaded = load( filename );
  if (!mLoaded)
    kdDebug(5900) << "ADCalendarBase::loadLocalFile(): Error loading calendar file '" << filename << "'\n";
  else
  {
    // Remove all now non-existent events from the handled list
    for (EventsMap::Iterator it = eventsHandled_.begin();  it != eventsHandled_.end();  )
    {
      if (it.data().calendarURL == mUrlString  &&  !event(it.key()))
      {
        // Event belonged to this calendar, but can't find it any more
        EventsMap::Iterator i = it;
        ++it;                      // prevent iterator becoming invalid with remove()
        eventsHandled_.remove(i);
      }
      else
        ++it;
    }
  }
}

void ADCalendarBase::dump() const
{
  kdDebug(5900) << "  <calendar>" << endl;
  kdDebug(5900) << "    <url>" << urlString() << "</url>" << endl;
  kdDebug(5900) << "    <appname>" << appName() << "</appname>" << endl;
  if ( loaded() ) kdDebug(5900) << "    <loaded/>" << endl;
  kdDebug(5900) << "    <actiontype>" << int(actionType()) << "</actiontype>" << endl;
  if (enabled() ) kdDebug(5900) << "    <enabled/>" << endl;
  else kdDebug(5900) << "    <disabled/>" << endl;
  if (available()) kdDebug(5900) << "    <available/>" << endl;
  kdDebug(5900) << "  </calendar>" << endl;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR 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.
 */

#include "base/loader/aout_object.hh"
#include "base/loader/ecoff_object.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/remote_gdb.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/tru64/tru64_system.hh"
#include "mem/functional_mem/memory_control.hh"
#include "mem/functional_mem/physical_memory.hh"
#include "sim/builder.hh"
#include "targetarch/isa_traits.hh"
#include "targetarch/vtophys.hh"

using namespace std;

Tru64System::Tru64System(const string _name, const uint64_t _init_param,
                         MemoryController *_memCtrl, PhysicalMemory *_physmem,
                         const string &kernel_path, const string &console_path,
                         const string &palcode, const string &boot_osflags,
                         const bool _bin, const vector<string> &binned_fns)
    : System(_name, _init_param, _memCtrl, _physmem, _bin), bin(_bin),
      binned_fns(binned_fns)
{
    kernelSymtab = new SymbolTable;
    consoleSymtab = new SymbolTable;

    ObjectFile *kernel = createObjectFile(kernel_path);
    if (kernel == NULL)
        fatal("Could not load kernel file %s", kernel_path);

    ObjectFile *console = createObjectFile(console_path);
    if (console == NULL)
        fatal("Could not load console file %s", console_path);

    if (!kernel->loadGlobalSymbols(kernelSymtab))
        panic("could not load kernel symbols\n");

    if (!console->loadGlobalSymbols(consoleSymtab))
        panic("could not load console symbols\n");

    // Load pal file
    ObjectFile *pal = createObjectFile(palcode);
    if (pal == NULL)
        fatal("Could not load PALcode file %s", palcode);
    pal->loadSections(physmem, true);

    // Load console file
    console->loadSections(physmem, true);

    // Load kernel file
    kernel->loadSections(physmem, true);
    kernelStart = kernel->textBase();
    kernelEnd = kernel->bssBase() + kernel->bssSize();
    kernelEntry = kernel->entryPoint();

    DPRINTF(Loader, "Kernel start = %#x\n"
            "Kernel end   = %#x\n"
            "Kernel entry = %#x\n",
            kernelStart, kernelEnd, kernelEntry);

    DPRINTF(Loader, "Kernel loaded...\n");

#ifdef DEBUG
    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
#endif
    badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
    skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
                                            "tl_v48_capture_power_state");
    skipScavengeBootEvent = new SkipFuncEvent(&pcEventQueue,
                                              "pmap_scavenge_boot");
    printfEvent = new PrintfEvent(&pcEventQueue, "printf");
    debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue,
                                            "debug_printf", false);
    debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue,
                                             "debug_printfr", true);
    dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf");

    Addr addr = 0;
    if (kernelSymtab->findAddress("enable_async_printf", addr)) {
        Addr paddr = vtophys(physmem, addr);
        uint8_t *enable_async_printf =
            physmem->dma_addr(paddr, sizeof(uint32_t));

        if (enable_async_printf)
            *(uint32_t *)enable_async_printf = 0;
    }

    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
        Addr paddr = vtophys(physmem, addr);
        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));

        if (osflags)
            strcpy(osflags, boot_osflags.c_str());
    }

#ifdef DEBUG
    if (kernelSymtab->findAddress("panic", addr))
        kernelPanicEvent->schedule(addr);
    else
        panic("could not find kernel symbol \'panic\'");

    if (consoleSymtab->findAddress("panic", addr))
        consolePanicEvent->schedule(addr);
#endif

    if (kernelSymtab->findAddress("badaddr", addr))
        badaddrEvent->schedule(addr);
    else
        panic("could not find kernel symbol \'badaddr\'");

    if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
        skipPowerStateEvent->schedule(addr);

    if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
        skipScavengeBootEvent->schedule(addr);

#if TRACING_ON
    if (kernelSymtab->findAddress("printf", addr))
        printfEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5printf", addr))
        debugPrintfEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5printfr", addr))
        debugPrintfrEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
        dumpMbufEvent->schedule(addr);
#endif

    // BINNING STUFF
    if (bin == true) {
        int end = binned_fns.size();
        assert(!(end & 1));

        Statistics::MainBin *Bin;
        Addr address = 0;

        fnEvents.resize(end>>1);

        for (int i = 0; i < end; i +=2) {
            cout << "creating Bin for " << binned_fns[i] << endl;
            Bin = new Statistics::MainBin(name() + " " + binned_fns[i]);
            fnBins.insert(make_pair(binned_fns[i], Bin));

            fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this);
            if (kernelSymtab->findAddress(binned_fns[i], address))
                fnEvents[(i>>1)]->schedule(address);
            else
                panic("could not find kernel symbol %s\n", binned_fns[i]);

            if (binned_fns[i+1] == "null")
                populateMap(binned_fns[i], "");
            else
                populateMap(binned_fns[i], binned_fns[i+1]);
        }

        fnCalls
            .name(name() + ":fnCalls")
            .desc("all fn calls being tracked")
            ;
    }
    //
}

Tru64System::~Tru64System()
{
    delete kernel;
    delete console;

    delete kernelSymtab;
    delete consoleSymtab;

#ifdef DEBUG
    delete kernelPanicEvent;
    delete consolePanicEvent;
#endif
    delete badaddrEvent;
    delete skipPowerStateEvent;
    delete skipScavengeBootEvent;
    delete printfEvent;
    delete debugPrintfEvent;
    delete debugPrintfrEvent;
    delete dumpMbufEvent;

    if (bin == true) {
        int end = fnEvents.size();
        for (int i = 0; i < end; ++i) {
            delete fnEvents[i];
        }
        fnEvents.clear();
    }
}

int
Tru64System::registerExecContext(ExecContext *xc)
{
    int xcIndex = System::registerExecContext(xc);

    if (xcIndex == 0) {
        // activate with zero delay so that we start ticking right
        // away on cycle 0
        xc->activate(0);
    }

    RemoteGDB *rgdb = new RemoteGDB(this, xc);
    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
    gdbl->listen();

    if (remoteGDB.size() <= xcIndex) {
        remoteGDB.resize(xcIndex+1);
    }

    remoteGDB[xcIndex] = rgdb;

    return xcIndex;
}

void
Tru64System::replaceExecContext(ExecContext *xc, int xcIndex)
{
    System::replaceExecContext(xcIndex, xc);
    remoteGDB[xcIndex]->replaceExecContext(xc);
}

bool
Tru64System::breakpoint()
{
    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
}

void
Tru64System::populateMap(std::string callee, std::string caller)
{
    multimap<const string, string>::const_iterator i;
    i = callerMap.insert(make_pair(callee, caller));
    assert(i != callerMap.end() && "should not fail populating callerMap");
}

bool
Tru64System::findCaller(std::string callee, std::string caller) const
{
    typedef multimap<const std::string, std::string>::const_iterator iter;
    pair<iter, iter> range;

    range = callerMap.equal_range(callee);
    for (iter i = range.first; i != range.second; ++i) {
        if ((*i).second == caller)
            return true;
    }
    return false;
}

void
Tru64System::dumpState(ExecContext *xc) const
{
    if (xc->swCtx) {
        stack<fnCall *> copy(xc->swCtx->callStack);
        if (copy.empty())
            return;
        DPRINTF(TCPIP, "xc->swCtx:\n");
        fnCall *top;
        DPRINTF(TCPIP, "||     call : %d\n",xc->swCtx->calls);
        for (top = copy.top(); !copy.empty(); copy.pop() ) {
            top = copy.top();
            DPRINTF(TCPIP, "||  %13s : %s \n", top->name, top->myBin->name());
        }
    }
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)

    Param<bool> bin;
    SimObjectParam<MemoryController *> mem_ctl;
    SimObjectParam<PhysicalMemory *> physmem;
    Param<uint64_t> init_param;

    Param<string> kernel_code;
    Param<string> console_code;
    Param<string> pal_code;
    Param<string> boot_osflags;
    VectorParam<string> binned_fns;

END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)

BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)

    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
    INIT_PARAM(mem_ctl, "memory controller"),
    INIT_PARAM(physmem, "phsyical memory"),
    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
    INIT_PARAM(kernel_code, "file that contains the kernel code"),
    INIT_PARAM(console_code, "file that contains the console code"),
    INIT_PARAM(pal_code, "file that contains palcode"),
    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
                    "a"),
    INIT_PARAM(binned_fns, "functions to be broken down and binned")

END_INIT_SIM_OBJECT_PARAMS(Tru64System)

CREATE_SIM_OBJECT(Tru64System)
{
    Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl,
                                       physmem, kernel_code, console_code,
                                       pal_code, boot_osflags, bin,
                                       binned_fns);

    return sys;
}

REGISTER_SIM_OBJECT("Tru64System", Tru64System)
<commit_msg>change the naming of MainBins.  didn't check this in before because i had random debug statements i didn't want to push along with it.<commit_after>/*
 * Copyright (c) 2003 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR 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.
 */

#include "base/loader/aout_object.hh"
#include "base/loader/ecoff_object.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/remote_gdb.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/tru64/tru64_system.hh"
#include "mem/functional_mem/memory_control.hh"
#include "mem/functional_mem/physical_memory.hh"
#include "sim/builder.hh"
#include "targetarch/isa_traits.hh"
#include "targetarch/vtophys.hh"

using namespace std;

Tru64System::Tru64System(const string _name, const uint64_t _init_param,
                         MemoryController *_memCtrl, PhysicalMemory *_physmem,
                         const string &kernel_path, const string &console_path,
                         const string &palcode, const string &boot_osflags,
                         const bool _bin, const vector<string> &binned_fns)
    : System(_name, _init_param, _memCtrl, _physmem, _bin),
      bin(_bin), binned_fns(binned_fns)
{
    kernelSymtab = new SymbolTable;
    consoleSymtab = new SymbolTable;

    ObjectFile *kernel = createObjectFile(kernel_path);
    if (kernel == NULL)
        fatal("Could not load kernel file %s", kernel_path);

    ObjectFile *console = createObjectFile(console_path);
    if (console == NULL)
        fatal("Could not load console file %s", console_path);

    if (!kernel->loadGlobalSymbols(kernelSymtab))
        panic("could not load kernel symbols\n");

    if (!console->loadGlobalSymbols(consoleSymtab))
        panic("could not load console symbols\n");

    // Load pal file
    ObjectFile *pal = createObjectFile(palcode);
    if (pal == NULL)
        fatal("Could not load PALcode file %s", palcode);
    pal->loadSections(physmem, true);

    // Load console file
    console->loadSections(physmem, true);

    // Load kernel file
    kernel->loadSections(physmem, true);
    kernelStart = kernel->textBase();
    kernelEnd = kernel->bssBase() + kernel->bssSize();
    kernelEntry = kernel->entryPoint();

    DPRINTF(Loader, "Kernel start = %#x\n"
            "Kernel end   = %#x\n"
            "Kernel entry = %#x\n",
            kernelStart, kernelEnd, kernelEntry);

    DPRINTF(Loader, "Kernel loaded...\n");

#ifdef DEBUG
    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
#endif
    badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
    skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
                                            "tl_v48_capture_power_state");
    skipScavengeBootEvent = new SkipFuncEvent(&pcEventQueue,
                                              "pmap_scavenge_boot");
    printfEvent = new PrintfEvent(&pcEventQueue, "printf");
    debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue,
                                            "debug_printf", false);
    debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue,
                                             "debug_printfr", true);
    dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf");

    Addr addr = 0;
    if (kernelSymtab->findAddress("enable_async_printf", addr)) {
        Addr paddr = vtophys(physmem, addr);
        uint8_t *enable_async_printf =
            physmem->dma_addr(paddr, sizeof(uint32_t));

        if (enable_async_printf)
            *(uint32_t *)enable_async_printf = 0;
    }

    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
        Addr paddr = vtophys(physmem, addr);
        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));

        if (osflags)
            strcpy(osflags, boot_osflags.c_str());
    }

#ifdef DEBUG
    if (kernelSymtab->findAddress("panic", addr))
        kernelPanicEvent->schedule(addr);
    else
        panic("could not find kernel symbol \'panic\'");

    if (consoleSymtab->findAddress("panic", addr))
        consolePanicEvent->schedule(addr);
#endif

    if (kernelSymtab->findAddress("badaddr", addr))
        badaddrEvent->schedule(addr);
    else
        panic("could not find kernel symbol \'badaddr\'");

    if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
        skipPowerStateEvent->schedule(addr);

    if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
        skipScavengeBootEvent->schedule(addr);

#if TRACING_ON
    if (kernelSymtab->findAddress("printf", addr))
        printfEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5printf", addr))
        debugPrintfEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5printfr", addr))
        debugPrintfrEvent->schedule(addr);

    if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
        dumpMbufEvent->schedule(addr);
#endif

    // BINNING STUFF
    if (bin == true) {
        int end = binned_fns.size();
        assert(!(end & 1));

        Statistics::MainBin *Bin;
        Addr address = 0;

        fnEvents.resize(end>>1);

        for (int i = 0; i < end; i +=2) {
            Bin = new Statistics::MainBin(binned_fns[i]);
            fnBins.insert(make_pair(binned_fns[i], Bin));

            fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this);
            if (kernelSymtab->findAddress(binned_fns[i], address))
                fnEvents[(i>>1)]->schedule(address);
            else
                panic("could not find kernel symbol %s\n", binned_fns[i]);

            if (binned_fns[i+1] == "null")
                populateMap(binned_fns[i], "");
            else
                populateMap(binned_fns[i], binned_fns[i+1]);
        }

        fnCalls
            .name(name() + ":fnCalls")
            .desc("all fn calls being tracked")
            ;
    }
    //
}

Tru64System::~Tru64System()
{
    delete kernel;
    delete console;

    delete kernelSymtab;
    delete consoleSymtab;

#ifdef DEBUG
    delete kernelPanicEvent;
    delete consolePanicEvent;
#endif
    delete badaddrEvent;
    delete skipPowerStateEvent;
    delete skipScavengeBootEvent;
    delete printfEvent;
    delete debugPrintfEvent;
    delete debugPrintfrEvent;
    delete dumpMbufEvent;

    if (bin == true) {
        int end = fnEvents.size();
        for (int i = 0; i < end; ++i) {
            delete fnEvents[i];
        }
        fnEvents.clear();
    }
}

int
Tru64System::registerExecContext(ExecContext *xc)
{
    int xcIndex = System::registerExecContext(xc);

    if (xcIndex == 0) {
        // activate with zero delay so that we start ticking right
        // away on cycle 0
        xc->activate(0);
    }

    RemoteGDB *rgdb = new RemoteGDB(this, xc);
    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
    gdbl->listen();

    if (remoteGDB.size() <= xcIndex) {
        remoteGDB.resize(xcIndex+1);
    }

    remoteGDB[xcIndex] = rgdb;

    return xcIndex;
}

void
Tru64System::replaceExecContext(ExecContext *xc, int xcIndex)
{
    System::replaceExecContext(xcIndex, xc);
    remoteGDB[xcIndex]->replaceExecContext(xc);
}

bool
Tru64System::breakpoint()
{
    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
}

void
Tru64System::populateMap(std::string callee, std::string caller)
{
    multimap<const string, string>::const_iterator i;
    i = callerMap.insert(make_pair(callee, caller));
    assert(i != callerMap.end() && "should not fail populating callerMap");
}

bool
Tru64System::findCaller(std::string callee, std::string caller) const
{
    typedef multimap<const std::string, std::string>::const_iterator iter;
    pair<iter, iter> range;

    range = callerMap.equal_range(callee);
    for (iter i = range.first; i != range.second; ++i) {
        if ((*i).second == caller)
            return true;
    }
    return false;
}

void
Tru64System::dumpState(ExecContext *xc) const
{
    if (xc->swCtx) {
        stack<fnCall *> copy(xc->swCtx->callStack);
        if (copy.empty())
            return;
        DPRINTF(TCPIP, "xc->swCtx, size: %d:\n", copy.size());
        fnCall *top;
        DPRINTF(TCPIP, "||     call : %d\n",xc->swCtx->calls);
        for (top = copy.top(); !copy.empty(); copy.pop() ) {
            top = copy.top();
            DPRINTF(TCPIP, "||  %13s : %s \n", top->name, top->myBin->name());
        }
    }
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)

    Param<bool> bin;
    SimObjectParam<MemoryController *> mem_ctl;
    SimObjectParam<PhysicalMemory *> physmem;
    Param<uint64_t> init_param;

    Param<string> kernel_code;
    Param<string> console_code;
    Param<string> pal_code;
    Param<string> boot_osflags;
    VectorParam<string> binned_fns;

END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)

BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)

    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
    INIT_PARAM(mem_ctl, "memory controller"),
    INIT_PARAM(physmem, "phsyical memory"),
    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
    INIT_PARAM(kernel_code, "file that contains the kernel code"),
    INIT_PARAM(console_code, "file that contains the console code"),
    INIT_PARAM(pal_code, "file that contains palcode"),
    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
                    "a"),
    INIT_PARAM(binned_fns, "functions to be broken down and binned")

END_INIT_SIM_OBJECT_PARAMS(Tru64System)

CREATE_SIM_OBJECT(Tru64System)
{
    Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl,
                                       physmem, kernel_code, console_code,
                                       pal_code, boot_osflags, bin,
                                       binned_fns);

    return sys;
}

REGISTER_SIM_OBJECT("Tru64System", Tru64System)
<|endoftext|>


<commit_before>#include <stdio.h>

#include "mem_dense_matrix.h"

using namespace fm;

class set_col_operate: public type_set_operate<int>
{
	size_t num_cols;
public:
	set_col_operate(size_t num_cols) {
		this->num_cols = num_cols;
	}

	void set(int *arr, size_t num_eles, off_t row_idx, off_t col_idx) const {
		for (size_t i = 0; i < num_eles; i++) {
			arr[i] = (row_idx + i) * num_cols + col_idx;
		}
	}
};

class set_row_operate: public type_set_operate<int>
{
	size_t num_cols;
public:
	set_row_operate(size_t num_cols) {
		this->num_cols = num_cols;
	}

	void set(int *arr, size_t num_eles, off_t row_idx, off_t col_idx) const {
		for (size_t i = 0; i < num_eles; i++) {
			arr[i] = row_idx * num_cols + col_idx + i;
		}
	}
};

/*
 * This is a naive implementation of matrix multiplication.
 * It should be correct
 */
I_mem_dense_matrix::ptr naive_multiply(const I_mem_dense_matrix &m1,
		const I_mem_dense_matrix &m2)
{
	I_mem_dense_matrix::ptr res = I_mem_dense_matrix::create(
			m1.get_num_rows(), m2.get_num_cols(), matrix_layout_t::L_ROW);
	for (size_t i = 0; i < m1.get_num_rows(); i++) {
		for (size_t j = 0; j < m2.get_num_cols(); j++) {
			int sum = 0;
			for (size_t k = 0; k < m1.get_num_cols(); k++) {
				sum += m1.get(i, k) * m2.get(k, j);
			}
			res->set(i, j, sum);
		}
	}
	return res;
}

void verify_result(const I_mem_dense_matrix &m1, const I_mem_dense_matrix &m2)
{
	assert(m1.get_num_rows() == m2.get_num_rows());
	assert(m1.get_num_cols() == m2.get_num_cols());

	for (size_t i = 0; i < m1.get_num_rows(); i++)
		for (size_t j = 0; j < m1.get_num_cols(); j++)
			assert(m1.get(i, j) == m2.get(i, j));
}

void test_multiply_col()
{
	printf("Test multiplication on tall matrix stored column wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(10, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on col_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on col_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_agg_col()
{
	printf("Test aggregation on tall matrix stored column wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	const bulk_operate &op
		= m1->get_matrix()->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = m1->get_matrix()->aggregate(op);
	assert(res->get_type() == m1->get_matrix()->get_type());
	int sum = *(int *) res->get_raw();
	int num_eles = m1->get_num_rows() * m1->get_num_cols();
	assert(sum == (num_eles - 1) * num_eles / 2);
}

void test_multiply_wide_row()
{
	printf("Test multiplication on wide matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(10, 100,
			matrix_layout_t::L_ROW, set_row_operate(100));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(100, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on row_matrix X col_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on row_matrix X col_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_multiply_tall_row()
{
	printf("Test multiplication on tall matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_ROW, set_col_operate(10));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(10, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on row_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on row_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_agg_row()
{
	printf("Test aggregation on tall matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_ROW, set_row_operate(10));
	const bulk_operate &op
		= m1->get_matrix()->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = m1->get_matrix()->aggregate(op);
	assert(res->get_type() == m1->get_matrix()->get_type());
	int sum = *(int *) res->get_raw();
	int num_eles = m1->get_num_rows() * m1->get_num_cols();
	assert(sum == (num_eles - 1) * num_eles / 2);
}

void test_submatrix()
{
	printf("test submatrix of a column-wise matrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_m = mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	assert(sub_m != NULL);
	assert(sub_m->get_num_rows() == col_m->get_num_rows());
	assert(sub_m->get_num_cols() == idxs.size());
	assert(sub_m->store_layout() == col_m->store_layout());
	assert(sub_m->get_entry_size() == col_m->get_entry_size());
	assert(sub_m->get_type() == col_m->get_type());
	for (size_t i = 0; i < idxs.size(); i++)
		assert(memcmp(sub_m->get_col(i), col_m->get_col(idxs[i]),
				sub_m->get_entry_size() * sub_m->get_num_rows()) == 0);
}

void test_agg_sub_col()
{
	printf("Test aggregation on a column-wise submatrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_m
		= mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	assert(sub_m != NULL);

	const bulk_operate &op = sub_m->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = sub_m->aggregate(op);
	assert(res->get_type() == sub_m->get_type());
	size_t sum = *(int *) res->get_raw();
	size_t ncol = m1->get_num_cols();
	size_t nrow = m1->get_num_rows();
	size_t sub_ncol = sub_m->get_num_cols();
	size_t expected = sub_ncol * ncol * (nrow - 1) * nrow / 2;
	for (size_t i = 0; i < idxs.size(); i++)
		expected += idxs[i] * nrow;
	assert(sum == expected);
}

void test_agg_sub_row()
{
	printf("Test aggregation on a row-wise submatrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_col_m
		= mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	mem_row_dense_matrix::ptr sub_row_m
		= mem_row_dense_matrix::cast(sub_col_m->transpose());

	const bulk_operate &op = sub_col_m->get_type().get_basic_ops().get_add();
	scalar_variable::ptr col_res = sub_col_m->aggregate(op);
	assert(col_res->get_type() == sub_col_m->get_type());
	scalar_variable::ptr row_res = sub_row_m->aggregate(op);
	assert(row_res->get_type() == sub_row_m->get_type());
	assert(*(int *) col_res->get_raw() == *(int *) row_res->get_raw());
}

void test_conv_row_col()
{
	printf("test conv col-wise to row-wise, row-wise to col-wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(10000, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	mem_row_dense_matrix::ptr row_m = col_m->get_row_store();
	I_mem_dense_matrix::ptr c1 = I_mem_dense_matrix::create(col_m);
	I_mem_dense_matrix::ptr c2 = I_mem_dense_matrix::create(row_m);
	for (size_t i = 0; i < col_m->get_num_rows(); i++) {
		for (size_t j = 0; j < col_m->get_num_cols(); j++)
			assert(c1->get(i, j) == c2->get(i, j));
	}
	col_m = row_m->get_col_store();
	c1 = I_mem_dense_matrix::create(col_m);
	c2 = I_mem_dense_matrix::create(row_m);
	for (size_t i = 0; i < col_m->get_num_rows(); i++)
		for (size_t j = 0; j < col_m->get_num_cols(); j++)
			assert(c1->get(i, j) == c2->get(i, j));
}

int main()
{
	test_multiply_col();
	test_agg_col();
	test_multiply_wide_row();
	test_multiply_tall_row();
	test_agg_row();
	test_submatrix();
	test_agg_sub_col();
	test_agg_sub_row();
	test_conv_row_col();
}
<commit_msg>[Matrix]: more unit tests on mem_dense_matrix.<commit_after>#include <stdio.h>

#include "mem_dense_matrix.h"

using namespace fm;

class set_col_operate: public type_set_operate<int>
{
	size_t num_cols;
public:
	set_col_operate(size_t num_cols) {
		this->num_cols = num_cols;
	}

	void set(int *arr, size_t num_eles, off_t row_idx, off_t col_idx) const {
		for (size_t i = 0; i < num_eles; i++) {
			arr[i] = (row_idx + i) * num_cols + col_idx;
		}
	}
};

class set_row_operate: public type_set_operate<int>
{
	size_t num_cols;
public:
	set_row_operate(size_t num_cols) {
		this->num_cols = num_cols;
	}

	void set(int *arr, size_t num_eles, off_t row_idx, off_t col_idx) const {
		for (size_t i = 0; i < num_eles; i++) {
			arr[i] = row_idx * num_cols + col_idx + i;
		}
	}
};

/*
 * This is a naive implementation of matrix multiplication.
 * It should be correct
 */
I_mem_dense_matrix::ptr naive_multiply(const I_mem_dense_matrix &m1,
		const I_mem_dense_matrix &m2)
{
	I_mem_dense_matrix::ptr res = I_mem_dense_matrix::create(
			m1.get_num_rows(), m2.get_num_cols(), matrix_layout_t::L_ROW);
	for (size_t i = 0; i < m1.get_num_rows(); i++) {
		for (size_t j = 0; j < m2.get_num_cols(); j++) {
			int sum = 0;
			for (size_t k = 0; k < m1.get_num_cols(); k++) {
				sum += m1.get(i, k) * m2.get(k, j);
			}
			res->set(i, j, sum);
		}
	}
	return res;
}

void verify_result(const I_mem_dense_matrix &m1, const I_mem_dense_matrix &m2)
{
	assert(m1.get_num_rows() == m2.get_num_rows());
	assert(m1.get_num_cols() == m2.get_num_cols());

	for (size_t i = 0; i < m1.get_num_rows(); i++)
		for (size_t j = 0; j < m1.get_num_cols(); j++)
			assert(m1.get(i, j) == m2.get(i, j));
}

void test_multiply_scalar()
{
	printf("Test scalar multiplication\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_dense_matrix::ptr orig = mem_dense_matrix::cast(m1->get_matrix());
	mem_dense_matrix::ptr res = mem_dense_matrix::cast(orig->multiply_scalar(10));
	for (size_t i = 0; i < res->get_num_rows(); i++)
		for (size_t j = 0; j < res->get_num_cols(); j++)
			assert(res->get<int>(i, j) == orig->get<int>(i, j) * 10);

	m1 = I_mem_dense_matrix::create(100, 10, matrix_layout_t::L_ROW,
			set_row_operate(10));
	orig = mem_dense_matrix::cast(m1->get_matrix());
	res = mem_dense_matrix::cast(orig->multiply_scalar(10));
	for (size_t i = 0; i < res->get_num_rows(); i++)
		for (size_t j = 0; j < res->get_num_cols(); j++)
			assert(res->get<int>(i, j) == orig->get<int>(i, j) * 10);
}

void test_ele_wise()
{
	printf("Test element-wise operations\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_dense_matrix::ptr res = mem_dense_matrix::cast(
			m1->get_matrix()->add(*m2->get_matrix()));
	for (size_t i = 0; i < res->get_num_rows(); i++)
		for (size_t j = 0; j < res->get_num_cols(); j++)
			assert(res->get<int>(i, j) == m1->get_matrix()->get<int>(i, j) * 2);
}

void test_multiply_col()
{
	printf("Test multiplication on tall matrix stored column wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(10, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on col_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on col_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_agg_col()
{
	printf("Test aggregation on tall matrix stored column wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	const bulk_operate &op
		= m1->get_matrix()->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = m1->get_matrix()->aggregate(op);
	assert(res->get_type() == m1->get_matrix()->get_type());
	int sum = *(int *) res->get_raw();
	int num_eles = m1->get_num_rows() * m1->get_num_cols();
	assert(sum == (num_eles - 1) * num_eles / 2);
}

void test_multiply_wide_row()
{
	printf("Test multiplication on wide matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(10, 100,
			matrix_layout_t::L_ROW, set_row_operate(100));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(100, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on row_matrix X col_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on row_matrix X col_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_multiply_tall_row()
{
	printf("Test multiplication on tall matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_ROW, set_col_operate(10));
	I_mem_dense_matrix::ptr m2 = I_mem_dense_matrix::create(10, 9,
			matrix_layout_t::L_COL, set_col_operate(9));
	I_mem_dense_matrix::ptr correct = naive_multiply(*m1, *m2);

	printf("Test multiply on row_matrix in one thread\n");
	I_mem_dense_matrix::ptr res1 = multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);

	printf("Test multiply on row_matrix in parallel\n");
	res1 = par_multiply<int, int, int>(*m1, *m2);
	verify_result(*res1, *correct);
}

void test_agg_row()
{
	printf("Test aggregation on tall matrix stored row wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_ROW, set_row_operate(10));
	const bulk_operate &op
		= m1->get_matrix()->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = m1->get_matrix()->aggregate(op);
	assert(res->get_type() == m1->get_matrix()->get_type());
	int sum = *(int *) res->get_raw();
	int num_eles = m1->get_num_rows() * m1->get_num_cols();
	assert(sum == (num_eles - 1) * num_eles / 2);
}

void test_submatrix()
{
	printf("test submatrix of a column-wise matrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_m = mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	assert(sub_m != NULL);
	assert(sub_m->get_num_rows() == col_m->get_num_rows());
	assert(sub_m->get_num_cols() == idxs.size());
	assert(sub_m->store_layout() == col_m->store_layout());
	assert(sub_m->get_entry_size() == col_m->get_entry_size());
	assert(sub_m->get_type() == col_m->get_type());
	for (size_t i = 0; i < idxs.size(); i++)
		assert(memcmp(sub_m->get_col(i), col_m->get_col(idxs[i]),
				sub_m->get_entry_size() * sub_m->get_num_rows()) == 0);
}

void test_agg_sub_col()
{
	printf("Test aggregation on a column-wise submatrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_m
		= mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	assert(sub_m != NULL);

	const bulk_operate &op = sub_m->get_type().get_basic_ops().get_add();
	scalar_variable::ptr res = sub_m->aggregate(op);
	assert(res->get_type() == sub_m->get_type());
	size_t sum = *(int *) res->get_raw();
	size_t ncol = m1->get_num_cols();
	size_t nrow = m1->get_num_rows();
	size_t sub_ncol = sub_m->get_num_cols();
	size_t expected = sub_ncol * ncol * (nrow - 1) * nrow / 2;
	for (size_t i = 0; i < idxs.size(); i++)
		expected += idxs[i] * nrow;
	assert(sum == expected);
}

void test_agg_sub_row()
{
	printf("Test aggregation on a row-wise submatrix\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(100, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	std::vector<off_t> idxs(3);
	idxs[0] = 1;
	idxs[1] = 5;
	idxs[2] = 3;
	mem_col_dense_matrix::ptr sub_col_m
		= mem_col_dense_matrix::cast(col_m->get_cols(idxs));
	mem_row_dense_matrix::ptr sub_row_m
		= mem_row_dense_matrix::cast(sub_col_m->transpose());

	const bulk_operate &op = sub_col_m->get_type().get_basic_ops().get_add();
	scalar_variable::ptr col_res = sub_col_m->aggregate(op);
	assert(col_res->get_type() == sub_col_m->get_type());
	scalar_variable::ptr row_res = sub_row_m->aggregate(op);
	assert(row_res->get_type() == sub_row_m->get_type());
	assert(*(int *) col_res->get_raw() == *(int *) row_res->get_raw());
}

void test_conv_row_col()
{
	printf("test conv col-wise to row-wise, row-wise to col-wise\n");
	I_mem_dense_matrix::ptr m1 = I_mem_dense_matrix::create(10000, 10,
			matrix_layout_t::L_COL, set_col_operate(10));
	mem_col_dense_matrix::ptr col_m
		= mem_col_dense_matrix::cast(m1->get_matrix());
	mem_row_dense_matrix::ptr row_m = col_m->get_row_store();
	I_mem_dense_matrix::ptr c1 = I_mem_dense_matrix::create(col_m);
	I_mem_dense_matrix::ptr c2 = I_mem_dense_matrix::create(row_m);
	for (size_t i = 0; i < col_m->get_num_rows(); i++) {
		for (size_t j = 0; j < col_m->get_num_cols(); j++)
			assert(c1->get(i, j) == c2->get(i, j));
	}
	col_m = row_m->get_col_store();
	c1 = I_mem_dense_matrix::create(col_m);
	c2 = I_mem_dense_matrix::create(row_m);
	for (size_t i = 0; i < col_m->get_num_rows(); i++)
		for (size_t j = 0; j < col_m->get_num_cols(); j++)
			assert(c1->get(i, j) == c2->get(i, j));
}

int main()
{
	test_multiply_scalar();
	test_ele_wise();
	test_multiply_col();
	test_agg_col();
	test_multiply_wide_row();
	test_multiply_tall_row();
	test_agg_row();
	test_submatrix();
	test_agg_sub_col();
	test_agg_sub_row();
	test_conv_row_col();
}
<|endoftext|>


<commit_before>#pragma once

#include "wrdTest.hpp"
#include <iostream>

struct wrdSyntaxTest : public wrdTest {
    void TearDown() {
        wrdTest::TearDown();
        _rel();
    }

    wrd::node& getSubPack() { return *_subpack; }
    wrd::pack& getPack() { return *_pack; }
    wrd::errReport& getReport() { return _rpt; }

    wrdSyntaxTest& make() {
        return make(wrd::manifest());
    }

    wrdSyntaxTest& make(const wrd::manifest& mani) {
        _rel();
        _pack.bind(new wrd::pack(mani, wrd::packLoadings()));
        return *this;
    }

    wrdSyntaxTest& parse(const wrd::wchar* src) {
        WRD_I("====================================");
        WRD_I("parsing src:");
        WRD_I("%s", src);
        WRD_I("====================================");
        wrd::parser p;
        _subpack = p.setPack(*_pack).setReport(_rpt).parse(_src = src);
        _isParsed = _subpack && _pack && !_rpt;
        if(!_isParsed) return *this;

        wrd::packs* paks = new wrd::packs();
        paks->add(_pack->getManifest().name, *_pack);
        wrd::packChain verifying(paks);
        verifying.link(wrd::thread::get().getSystemPacks());

        wrd::verifier v;
        v.setReport(_rpt).setPacks(verifying).verify(*_subpack);
        return *this;
    }

    wrd::wbool shouldParsed(wrd::wbool well) const {
        EXPECT_EQ(_isParsed, well);
        wrd::wbool ret = _isParsed == well;
        if(!ret)
            _log(well);
        return ret;
    }
    wrd::wbool shouldVerified(wrd::wbool well) const {
        wrd::wbool verified = _isParsed && !_rpt;
        EXPECT_EQ(verified, well);

        wrd::wbool ret = verified == well;
        if(!ret)
            _log(well);
        return ret;
    }

private:
    void _log(wrd::wbool expected) const {
        std::cout   << "  code: " << _src << "\n"
                    << "  errReport:\n";
        _rpt.log();
    }

    void _rel() {
        _src = "";
        _subpack.rel();
        _pack.rel();
        _rpt.rel();
        _isParsed = false;
    }

private:
    const wrd::wchar* _src;
    wrd::str _subpack;
    wrd::tstr<wrd::pack> _pack;
    wrd::errReport _rpt;
    wrd::wbool _isParsed;
};
<commit_msg>wrd: test: show structure of parsed AST if it failed<commit_after>#pragma once

#include "wrdTest.hpp"
#include <iostream>

struct wrdSyntaxTest : public wrdTest {
    void TearDown() {
        wrdTest::TearDown();
        _rel();
    }

    wrd::node& getSubPack() { return *_subpack; }
    wrd::pack& getPack() { return *_pack; }
    wrd::errReport& getReport() { return _rpt; }

    wrdSyntaxTest& make() {
        return make(wrd::manifest());
    }

    wrdSyntaxTest& make(const wrd::manifest& mani) {
        _rel();
        _pack.bind(new wrd::pack(mani, wrd::packLoadings()));
        return *this;
    }

    wrdSyntaxTest& parse(const wrd::wchar* src) {
        WRD_I("====================================");
        WRD_I("parsing src:");
        WRD_I("%s", src);
        WRD_I("====================================");
        wrd::parser p;
        _subpack = p.setPack(*_pack).setReport(_rpt).parse(_src = src);
        _isParsed = _subpack && _pack && !_rpt;
        if(!_isParsed) return *this;

        wrd::packs* paks = new wrd::packs();
        paks->add(_pack->getManifest().name, *_pack);
        wrd::packChain verifying(paks);
        verifying.link(wrd::thread::get().getSystemPacks());

        wrd::verifier v;
        v.setReport(_rpt).setPacks(verifying).verify(*_subpack);
        return *this;
    }

    wrd::wbool shouldParsed(wrd::wbool well) const {
        EXPECT_EQ(_isParsed, well);
        wrd::wbool ret = _isParsed == well;
        if(!ret)
            _log(well);
        return ret;
    }
    wrd::wbool shouldVerified(wrd::wbool well) const {
        wrd::wbool verified = _isParsed && !_rpt;
        EXPECT_EQ(verified, well);

        wrd::wbool ret = verified == well;
        if(!ret)
            _log(well);
        return ret;
    }

private:
    void _log(wrd::wbool expected) const {
        std::cout   << "  code: " << _src << "\n"
                    << "  structure:\n";
        _logStructure(*_subpack, 0, 0, true, true);
        std::cout   << "  errReport:\n";
        _rpt.log();
    }

    void _logStructure(const wrd::node& n, int idx, int level, bool isLast, bool isParentLast) const {
        _logIndent(level, isParentLast);
        std::cout << (isLast ? "┗━[" : "┣━[") << idx << "]: " << n.getType().getName() << " \"" << n.getName() << "\"\n";

        int subN = -1;
        for(const wrd::node& sub : n.subs()) {
            subN++;
            _logStructure(sub, subN, level + 2, subN == n.subs().len()-1, isLast);
        }
    }

    void _logIndent(int level, bool isParentLast) const {
        std::cout << "  ";
        for(int n=0; n < level-1; n++)
            std::cout << (isParentLast ? "  " : "┃ ");
    }

    void _rel() {
        _src = "";
        _subpack.rel();
        _pack.rel();
        _rpt.rel();
        _isParsed = false;
    }

private:
    const wrd::wchar* _src;
    wrd::str _subpack;
    wrd::tstr<wrd::pack> _pack;
    wrd::errReport _rpt;
    wrd::wbool _isParsed;
};
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "PageListWatcher.hxx"

#include "sdpage.hxx"
#include <tools/debug.hxx>
#include <svx/svdmodel.hxx>

//////////////////////////////////////////////////////////////////////////////
// #109538#

void ImpPageListWatcher::ImpRecreateSortedPageListOnDemand()
{
    // clear vectors
    maPageVectorStandard.clear();
    maPageVectorNotes.clear();
    mpHandoutPage = 0L;

    // build up vectors again
    const sal_uInt32 nPageCount(ImpGetPageCount());

    for(sal_uInt32 a(0L); a < nPageCount; a++)
    {
        SdPage* pCandidate = ImpGetPage(a);
        DBG_ASSERT(pCandidate, "ImpPageListWatcher::ImpRecreateSortedPageListOnDemand: Invalid PageList in Model (!)");

        switch(pCandidate->GetPageKind())
        {
            case PK_STANDARD:
            {
                maPageVectorStandard.push_back(pCandidate);
                break;
            }
            case PK_NOTES:
            {
                maPageVectorNotes.push_back(pCandidate);
                break;
            }
            case PK_HANDOUT:
            {
                DBG_ASSERT(!mpHandoutPage, "ImpPageListWatcher::ImpRecreateSortedPageListOnDemand: Two Handout pages in PageList of Model (!)");
                mpHandoutPage = pCandidate;
                break;
            }
        }
    }

    // set to valid
    mbPageListValid = sal_True;
}

ImpPageListWatcher::ImpPageListWatcher(const SdrModel& rModel)
:   mrModel(rModel),
    mpHandoutPage(0L),
    mbPageListValid(sal_False)
{
}

ImpPageListWatcher::~ImpPageListWatcher()
{
}

SdPage* ImpPageListWatcher::GetSdPage(PageKind ePgKind, sal_uInt32 nPgNum)
{
    SdPage* pRetval(0L);

    if(!mbPageListValid)
    {
        ImpRecreateSortedPageListOnDemand();
    }

    switch(ePgKind)
    {
        case PK_STANDARD:
        {
            if( nPgNum < (sal_uInt32)maPageVectorStandard.size() )
                pRetval = maPageVectorStandard[nPgNum];
            else
            {
                DBG_ASSERT(nPgNum <= maPageVectorStandard.size(),
                    "ImpPageListWatcher::GetSdPage(PK_STANDARD): access out of range");
                DBG_WARNING2 ("    %d  > %d",
                    nPgNum, nPgNum<maPageVectorStandard.size());
            }
            break;
        }
        case PK_NOTES:
        {
            if( nPgNum < (sal_uInt32)maPageVectorNotes.size() )
                pRetval = maPageVectorNotes[nPgNum];
            else
            {
                DBG_ASSERT(nPgNum <= maPageVectorNotes.size(),
                    "ImpPageListWatcher::GetSdPage(PK_NOTES): access out of range");
                DBG_WARNING2("    %d > %d",
                    nPgNum, nPgNum<maPageVectorNotes.size());
            }
            break;
        }
        case PK_HANDOUT:
        {
//          #11420# for models used to transfer drawing shapes via clipboard its
//          ok to not have a handout page
//          DBG_ASSERT(mpHandoutPage, "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            DBG_ASSERT(nPgNum == 0L, "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            if (nPgNum == 0)
                pRetval = mpHandoutPage;
            else
            {
                DBG_ASSERT(nPgNum == 0L,
                    "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            }
            break;
        }
    }

    return pRetval;
}

sal_uInt32 ImpPageListWatcher::GetSdPageCount(PageKind ePgKind)
{
    sal_uInt32 nRetval(0L);

    if(!mbPageListValid)
    {
        ImpRecreateSortedPageListOnDemand();
    }

    switch(ePgKind)
    {
        case PK_STANDARD:
        {
            nRetval = maPageVectorStandard.size();
            break;
        }
        case PK_NOTES:
        {
            nRetval = maPageVectorNotes.size();
            break;
        }
        case PK_HANDOUT:
        {
            if(mpHandoutPage)
            {
                nRetval = 1L;
            }

            break;
        }
    }

    return nRetval;
}

//////////////////////////////////////////////////////////////////////////////

sal_uInt32 ImpDrawPageListWatcher::ImpGetPageCount() const
{
    return (sal_uInt32)mrModel.GetPageCount();
}

SdPage* ImpDrawPageListWatcher::ImpGetPage(sal_uInt32 nIndex) const
{
    return (SdPage*)mrModel.GetPage((sal_uInt16)nIndex);
}

ImpDrawPageListWatcher::ImpDrawPageListWatcher(const SdrModel& rModel)
:   ImpPageListWatcher(rModel)
{
}

ImpDrawPageListWatcher::~ImpDrawPageListWatcher()
{
}

//////////////////////////////////////////////////////////////////////////////

sal_uInt32 ImpMasterPageListWatcher::ImpGetPageCount() const
{
    return (sal_uInt32)mrModel.GetMasterPageCount();
}

SdPage* ImpMasterPageListWatcher::ImpGetPage(sal_uInt32 nIndex) const
{
    return (SdPage*)mrModel.GetMasterPage((sal_uInt16)nIndex);
}

ImpMasterPageListWatcher::ImpMasterPageListWatcher(const SdrModel& rModel)
:   ImpPageListWatcher(rModel)
{
}

ImpMasterPageListWatcher::~ImpMasterPageListWatcher()
{
}
<commit_msg>INTEGRATION: CWS changefileheader (1.7.298); FILE MERGED 2008/03/31 13:56:44 rt 1.7.298.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: PageListWatcher.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "PageListWatcher.hxx"

#include "sdpage.hxx"
#include <tools/debug.hxx>
#include <svx/svdmodel.hxx>

//////////////////////////////////////////////////////////////////////////////
// #109538#

void ImpPageListWatcher::ImpRecreateSortedPageListOnDemand()
{
    // clear vectors
    maPageVectorStandard.clear();
    maPageVectorNotes.clear();
    mpHandoutPage = 0L;

    // build up vectors again
    const sal_uInt32 nPageCount(ImpGetPageCount());

    for(sal_uInt32 a(0L); a < nPageCount; a++)
    {
        SdPage* pCandidate = ImpGetPage(a);
        DBG_ASSERT(pCandidate, "ImpPageListWatcher::ImpRecreateSortedPageListOnDemand: Invalid PageList in Model (!)");

        switch(pCandidate->GetPageKind())
        {
            case PK_STANDARD:
            {
                maPageVectorStandard.push_back(pCandidate);
                break;
            }
            case PK_NOTES:
            {
                maPageVectorNotes.push_back(pCandidate);
                break;
            }
            case PK_HANDOUT:
            {
                DBG_ASSERT(!mpHandoutPage, "ImpPageListWatcher::ImpRecreateSortedPageListOnDemand: Two Handout pages in PageList of Model (!)");
                mpHandoutPage = pCandidate;
                break;
            }
        }
    }

    // set to valid
    mbPageListValid = sal_True;
}

ImpPageListWatcher::ImpPageListWatcher(const SdrModel& rModel)
:   mrModel(rModel),
    mpHandoutPage(0L),
    mbPageListValid(sal_False)
{
}

ImpPageListWatcher::~ImpPageListWatcher()
{
}

SdPage* ImpPageListWatcher::GetSdPage(PageKind ePgKind, sal_uInt32 nPgNum)
{
    SdPage* pRetval(0L);

    if(!mbPageListValid)
    {
        ImpRecreateSortedPageListOnDemand();
    }

    switch(ePgKind)
    {
        case PK_STANDARD:
        {
            if( nPgNum < (sal_uInt32)maPageVectorStandard.size() )
                pRetval = maPageVectorStandard[nPgNum];
            else
            {
                DBG_ASSERT(nPgNum <= maPageVectorStandard.size(),
                    "ImpPageListWatcher::GetSdPage(PK_STANDARD): access out of range");
                DBG_WARNING2 ("    %d  > %d",
                    nPgNum, nPgNum<maPageVectorStandard.size());
            }
            break;
        }
        case PK_NOTES:
        {
            if( nPgNum < (sal_uInt32)maPageVectorNotes.size() )
                pRetval = maPageVectorNotes[nPgNum];
            else
            {
                DBG_ASSERT(nPgNum <= maPageVectorNotes.size(),
                    "ImpPageListWatcher::GetSdPage(PK_NOTES): access out of range");
                DBG_WARNING2("    %d > %d",
                    nPgNum, nPgNum<maPageVectorNotes.size());
            }
            break;
        }
        case PK_HANDOUT:
        {
//          #11420# for models used to transfer drawing shapes via clipboard its
//          ok to not have a handout page
//          DBG_ASSERT(mpHandoutPage, "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            DBG_ASSERT(nPgNum == 0L, "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            if (nPgNum == 0)
                pRetval = mpHandoutPage;
            else
            {
                DBG_ASSERT(nPgNum == 0L,
                    "ImpPageListWatcher::GetSdPage: access to non existing handout page (!)");
            }
            break;
        }
    }

    return pRetval;
}

sal_uInt32 ImpPageListWatcher::GetSdPageCount(PageKind ePgKind)
{
    sal_uInt32 nRetval(0L);

    if(!mbPageListValid)
    {
        ImpRecreateSortedPageListOnDemand();
    }

    switch(ePgKind)
    {
        case PK_STANDARD:
        {
            nRetval = maPageVectorStandard.size();
            break;
        }
        case PK_NOTES:
        {
            nRetval = maPageVectorNotes.size();
            break;
        }
        case PK_HANDOUT:
        {
            if(mpHandoutPage)
            {
                nRetval = 1L;
            }

            break;
        }
    }

    return nRetval;
}

//////////////////////////////////////////////////////////////////////////////

sal_uInt32 ImpDrawPageListWatcher::ImpGetPageCount() const
{
    return (sal_uInt32)mrModel.GetPageCount();
}

SdPage* ImpDrawPageListWatcher::ImpGetPage(sal_uInt32 nIndex) const
{
    return (SdPage*)mrModel.GetPage((sal_uInt16)nIndex);
}

ImpDrawPageListWatcher::ImpDrawPageListWatcher(const SdrModel& rModel)
:   ImpPageListWatcher(rModel)
{
}

ImpDrawPageListWatcher::~ImpDrawPageListWatcher()
{
}

//////////////////////////////////////////////////////////////////////////////

sal_uInt32 ImpMasterPageListWatcher::ImpGetPageCount() const
{
    return (sal_uInt32)mrModel.GetMasterPageCount();
}

SdPage* ImpMasterPageListWatcher::ImpGetPage(sal_uInt32 nIndex) const
{
    return (SdPage*)mrModel.GetMasterPage((sal_uInt16)nIndex);
}

ImpMasterPageListWatcher::ImpMasterPageListWatcher(const SdrModel& rModel)
:   ImpPageListWatcher(rModel)
{
}

ImpMasterPageListWatcher::~ImpMasterPageListWatcher()
{
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, 2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file urbi/uvalue.hxx

#include <libport/preproc.hh>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include <libport/cassert>

namespace urbi
{

  /*--------.
  | UList.  |
  `--------*/

# define ULIST_NTH(Const)                       \
  inline                                        \
  Const UValue&                                 \
  UList::operator[](size_t i) Const             \
  {                                             \
    i += offset;                                \
    if (i < size())                             \
      return *array[i];                         \
    else                                        \
      return UValue::error();                   \
  }

  ULIST_NTH(__)
  ULIST_NTH(const)

# undef ULIST_NTH

  inline
  size_t
  UList::size() const
  {
    return array.size();
  }

  inline
  void
  UList::setOffset(size_t n)
  {
    offset = n;
  }

  template<typename T>
  UList&
  UList::push_back(const T& v)
  {
    array.push_back(new UValue(v));
    return *this;
  }

  inline
  UValue&
  UList::front()
  {
   return *array.front();
  }

  inline
  void
  UList::pop_back()
  {
    array.pop_back();
  }

  /*--------------.
  | UNamedValue.  |
  `--------------*/

  inline
  UNamedValue::UNamedValue(const std::string& n, UValue* v)
    : name(n)
    , val(v)
  {}

  inline
  UNamedValue&
  UNamedValue::error()
  {
    static UNamedValue instance("<<UNamedValue::error (denotes an error)>>");
    return instance;
  }

  /*----------------.
  | UObjectStruct.  |
  `----------------*/

# define UOBJECTSTRUCT_NTH(Const)               \
  inline                                        \
  Const UNamedValue&                            \
  UObjectStruct::operator[](size_t i) Const     \
  {                                             \
    if (i < size())                             \
      return array[i];                          \
    else                                        \
      return UNamedValue::error();              \
  }

  UOBJECTSTRUCT_NTH(__)
  UOBJECTSTRUCT_NTH(const)

# undef UOBJECTSTRUCT_NTH

  inline
  size_t
  UObjectStruct::size() const
  {
    return array.size();
  }

  /*---------.
  | UValue.  |
  `---------*/

  /// We use an operator , that behaves like an assignment.  The
  /// only difference is when the rhs is void, in which case it is
  /// the regular comma which is used.  This allows to write "uval,
  /// expr" to mean "compute expr and assign its result to uval,
  /// unless expr is void".
  inline
  UValue&
  UValue::operator, (const UValue &b)
  {
    return *this = b;
  }

#  define CONTAINER_TO_UVALUE_DECLARE(Type)                     \
  template <typename T>                                         \
  inline                                                        \
  UValue&                                                       \
  operator, (UValue &b, const Type<T> &v)                       \
  {                                                             \
    b.type = DATA_LIST;                                         \
    b.list = new UList();                                       \
    for (typename Type<T>::const_iterator i = v.begin(),        \
           i_end = v.end();                                     \
         i != i_end; ++i)                                       \
    {                                                           \
      UValue r;                                                 \
      r, *i;                                                    \
      b.list->array.push_back(new UValue(r));                   \
    }                                                           \
    return b;                                                   \
  }

  CONTAINER_TO_UVALUE_DECLARE(std::list)
  CONTAINER_TO_UVALUE_DECLARE(std::vector)

# undef CONTAINER_TO_UVALUE_DECLARE

# define OP_COMMA(Type)                         \
  inline                                        \
  UValue& UValue::operator, (Type rhs)          \
  {						\
    return *this = rhs;                         \
  }

  LIBPORT_LIST_APPLY(OP_COMMA, URBI_NUMERIC_TYPES)
  LIBPORT_LIST_APPLY(OP_COMMA, URBI_STRING_TYPES)
  LIBPORT_LIST_APPLY(OP_COMMA, URBI_MISC_TYPES)

# undef OP_COMMA

# define UVALUE_INTEGRAL_CAST(Type)                             \
  inline                                                        \
  UValue::operator Type() const                                 \
  {                                                             \
    return static_cast<Type>(static_cast<ufloat>((*this)));     \
  }

  LIBPORT_LIST_APPLY(UVALUE_INTEGRAL_CAST, URBI_DERIVED_NUMERIC_TYPES)
# undef UVALUE_INTEGRAL_CAST

  inline
  UValue::operator bool() const
  {
    return static_cast<int>(static_cast<ufloat>((*this))) != 0;
  }

  inline
  UValue&
  UValue::operator()()
  {
    return *this;
  }

  inline
  std::ostream&
  operator<<(std::ostream& s, const UValue& v)
  {
    // Looks bizarre, but might happen without have the "print" die
    // (it *has* happened).
    aver(&v);
    return v.print(s);
  }

  /*----------.
  | Casters.  |
  `----------*/

  // Run the uvalue_caster<Type> on v.
  template <typename Type>
  typename uvar_ref_traits<typename uvalue_cast_return_type<Type>::type>::type
  uvalue_cast(UValue& v)
  {
    typedef typename libport::traits::remove_reference<Type>::type res_type;
    return uvalue_caster<res_type>()(v);
  }

# define UVALUE_CASTER_DEFINE(Type)		\
  template <>					\
  struct uvalue_caster <Type>			\
  {						\
    Type operator() (UValue& v)			\
    {						\
      return v;					\
    }						\
  };

  LIBPORT_LIST_APPLY(UVALUE_CASTER_DEFINE, URBI_NUMERIC_TYPES)
  UVALUE_CASTER_DEFINE(std::string);
  UVALUE_CASTER_DEFINE(const std::string);
  UVALUE_CASTER_DEFINE(bool);
  UVALUE_CASTER_DEFINE(UImage);
  UVALUE_CASTER_DEFINE(USound);

#undef UVALUE_CASTER_DEFINE

  /*-----------------------------------.
  | Casting an UValue into an UValue.  |
  `-----------------------------------*/

  // Always return a const UValue&, a copy will be made if required.
# define UVALUE_CASTER_DEFINE(Type)              \
  template <>                                   \
  struct uvalue_caster<Type>                    \
  {                                             \
    const UValue& operator()(UValue& v)         \
    {                                           \
      return v;                                 \
    }                                           \
  }

  UVALUE_CASTER_DEFINE(const UValue&);
  UVALUE_CASTER_DEFINE(UValue&);
  UVALUE_CASTER_DEFINE(const UValue);
  UVALUE_CASTER_DEFINE(UValue);
# undef UVALUE_CASTER_DEFINE

  // The following ones are defined in uvalue-common.cc.
  template <>
  struct URBI_SDK_API uvalue_caster<UVar>
  {
    UVar& operator () (UValue& v);
  };

# define UVALUE_CASTER_DECLARE(Type)		\
  template <>					\
  struct URBI_SDK_API uvalue_caster<Type>       \
  {                                             \
    Type operator () (UValue& v);		\
  }

  UVALUE_CASTER_DECLARE(UBinary);
  UVALUE_CASTER_DECLARE(UList);
  UVALUE_CASTER_DECLARE(UDictionary);
  UVALUE_CASTER_DECLARE(UObjectStruct);
  UVALUE_CASTER_DECLARE(const char*);

# undef UVALUE_CASTER_DECLARE

# ifndef UOBJECT_NO_LIST_CAST

#  define UVALUE_CONTAINER_CASTER_DECLARE(Type)                 \
  template <typename T>                                         \
  struct uvalue_caster< Type<T> >                               \
  {                                                             \
    Type<T>                                                     \
    operator()(UValue& v)                                       \
    {                                                           \
      Type<T> res;                                              \
      if (v.type != DATA_LIST)                                  \
        /* Cast just the element.  */                           \
        res.push_back(uvalue_cast<T>(v));                       \
      else                                                      \
        for (size_t i = 0; i < v.list->size(); ++i)             \
          res.push_back(uvalue_cast<T>(*v.list->array[i]));     \
      return res;                                               \
    }                                                           \
  }

  UVALUE_CONTAINER_CASTER_DECLARE(std::list);
  UVALUE_CONTAINER_CASTER_DECLARE(std::vector);

#  undef UVALUE_CONTAINER_CASTER_DECLARE

# endif

  // Dictionary casters.
  template<typename V>
  struct uvalue_caster<boost::unordered_map<std::string, V> >
  {
    boost::unordered_map<std::string, V> operator()(UValue& v)
    {
      boost::unordered_map<std::string, V> res;
      if (v.type != DATA_DICTIONARY)
        throw std::runtime_error("UValue is not a dictionary.");
      typedef UDictionary::value_type DictVal;
      BOOST_FOREACH(UDictionary::value_type& val, *v.dictionary)
        res[val.first] = uvalue_cast<V>(val.second);
      return res;
    }
  };

  template<typename V>
  inline UValue&
  operator,(UValue& v, const boost::unordered_map<std::string, V> & d)
  {
    typedef typename boost::unordered_map<std::string, V>::value_type DictVal;
    v.clear();
    v.type = DATA_DICTIONARY;
    v.dictionary = new UDictionary;
    BOOST_FOREACH(const DictVal & val, d)
    {
      UValue nv;
      nv, val.second;
      (*v.dictionary)[val.first] = nv;
     }
     return v;
  }

  // Uses casters, must be at the end
  template<typename T>
  UList&
  UList::operator=(const T& container)
  {
    array.clear();
    typedef const typename T::value_type constv;
    BOOST_FOREACH(constv& v, container)
    {
      UValue val;
      val,v;
      array.push_back(new UValue(val));
    }
    return *this;
  }

  template<typename T>
  T
  UList::as()
  {
    T res;
    BOOST_FOREACH(UValue* v, array)
      res.push_back(uvalue_caster<typename T::value_type>()(*v));
    return res;
  }

  /** Bounce to uvalue_cast(). Useful when the type of the argument is not
   * directly available.
   */
  template<typename T>
  void uvalue_cast_bounce(T& t, UValue& v)
  {
    t = uvalue_cast<T>(v);
  }

  template<typename T>
  struct uvalue_caster<UPackedData<T> >
  {
    UPackedData<T> operator() (UValue& v)
    {
      if (v.type != DATA_BINARY)
        throw std::runtime_error("invalid cast to UPackedData: not a Binary");
      if (v.binary->common.size % sizeof(T))
        throw std::runtime_error("invalid cast to UPackedData: incorrect binary"
                                 "size");
      return UPackedData<T>((T*)v.binary->common.data,
                            (T*)((char*)v.binary->common.data
                                 + v.binary->common.size));
    }
  };

  template<typename T>
  UValue& operator, (UValue&v, const UPackedData<T>& d)
  {
    v = UBinary();
    UBinary& b = *v.binary;
    b.common.size = sizeof(T)*d.size();
    b.common.data = malloc(b.common.size);
    b.message = "packed " + boost::lexical_cast<std::string>(sizeof(T))
      + " " + typeid(T).name();
    memcpy(b.common.data, &d.front(), b.common.size);
    return v;
  }

} // namespace urbi
<commit_msg>build: missing inline.<commit_after>/*
 * Copyright (C) 2009-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/// \file urbi/uvalue.hxx

#include <libport/preproc.hh>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include <libport/cassert>

namespace urbi
{

  /*--------.
  | UList.  |
  `--------*/

# define ULIST_NTH(Const)                       \
  inline                                        \
  Const UValue&                                 \
  UList::operator[](size_t i) Const             \
  {                                             \
    i += offset;                                \
    if (i < size())                             \
      return *array[i];                         \
    else                                        \
      return UValue::error();                   \
  }

  ULIST_NTH(__)
  ULIST_NTH(const)

# undef ULIST_NTH

  inline
  size_t
  UList::size() const
  {
    return array.size();
  }

  inline
  void
  UList::setOffset(size_t n)
  {
    offset = n;
  }

  template<typename T>
  inline
  UList&
  UList::push_back(const T& v)
  {
    array.push_back(new UValue(v));
    return *this;
  }

  inline
  UValue&
  UList::front()
  {
   return *array.front();
  }

  inline
  void
  UList::pop_back()
  {
    array.pop_back();
  }

  /*--------------.
  | UNamedValue.  |
  `--------------*/

  inline
  UNamedValue::UNamedValue(const std::string& n, UValue* v)
    : name(n)
    , val(v)
  {}

  inline
  UNamedValue&
  UNamedValue::error()
  {
    static UNamedValue instance("<<UNamedValue::error (denotes an error)>>");
    return instance;
  }

  /*----------------.
  | UObjectStruct.  |
  `----------------*/

# define UOBJECTSTRUCT_NTH(Const)               \
  inline                                        \
  Const UNamedValue&                            \
  UObjectStruct::operator[](size_t i) Const     \
  {                                             \
    if (i < size())                             \
      return array[i];                          \
    else                                        \
      return UNamedValue::error();              \
  }

  UOBJECTSTRUCT_NTH(__)
  UOBJECTSTRUCT_NTH(const)

# undef UOBJECTSTRUCT_NTH

  inline
  size_t
  UObjectStruct::size() const
  {
    return array.size();
  }

  /*---------.
  | UValue.  |
  `---------*/

  /// We use an operator , that behaves like an assignment.  The
  /// only difference is when the rhs is void, in which case it is
  /// the regular comma which is used.  This allows to write "uval,
  /// expr" to mean "compute expr and assign its result to uval,
  /// unless expr is void".
  inline
  UValue&
  UValue::operator, (const UValue &b)
  {
    return *this = b;
  }

#  define CONTAINER_TO_UVALUE_DECLARE(Type)                     \
  template <typename T>                                         \
  inline                                                        \
  UValue&                                                       \
  operator, (UValue &b, const Type<T> &v)                       \
  {                                                             \
    b.type = DATA_LIST;                                         \
    b.list = new UList();                                       \
    for (typename Type<T>::const_iterator i = v.begin(),        \
           i_end = v.end();                                     \
         i != i_end; ++i)                                       \
    {                                                           \
      UValue r;                                                 \
      r, *i;                                                    \
      b.list->array.push_back(new UValue(r));                   \
    }                                                           \
    return b;                                                   \
  }

  CONTAINER_TO_UVALUE_DECLARE(std::list)
  CONTAINER_TO_UVALUE_DECLARE(std::vector)

# undef CONTAINER_TO_UVALUE_DECLARE

# define OP_COMMA(Type)                         \
  inline                                        \
  UValue& UValue::operator, (Type rhs)          \
  {						\
    return *this = rhs;                         \
  }

  LIBPORT_LIST_APPLY(OP_COMMA, URBI_NUMERIC_TYPES)
  LIBPORT_LIST_APPLY(OP_COMMA, URBI_STRING_TYPES)
  LIBPORT_LIST_APPLY(OP_COMMA, URBI_MISC_TYPES)

# undef OP_COMMA

# define UVALUE_INTEGRAL_CAST(Type)                             \
  inline                                                        \
  UValue::operator Type() const                                 \
  {                                                             \
    return static_cast<Type>(static_cast<ufloat>((*this)));     \
  }

  LIBPORT_LIST_APPLY(UVALUE_INTEGRAL_CAST, URBI_DERIVED_NUMERIC_TYPES)
# undef UVALUE_INTEGRAL_CAST

  inline
  UValue::operator bool() const
  {
    return static_cast<int>(static_cast<ufloat>((*this))) != 0;
  }

  inline
  UValue&
  UValue::operator()()
  {
    return *this;
  }

  inline
  std::ostream&
  operator<<(std::ostream& s, const UValue& v)
  {
    // Looks bizarre, but might happen without have the "print" die
    // (it *has* happened).
    aver(&v);
    return v.print(s);
  }

  /*----------.
  | Casters.  |
  `----------*/

  // Run the uvalue_caster<Type> on v.
  template <typename Type>
  inline
  typename uvar_ref_traits<typename uvalue_cast_return_type<Type>::type>::type
  uvalue_cast(UValue& v)
  {
    typedef typename libport::traits::remove_reference<Type>::type res_type;
    return uvalue_caster<res_type>()(v);
  }

# define UVALUE_CASTER_DEFINE(Type)		\
  template <>					\
  struct uvalue_caster <Type>			\
  {						\
    Type operator() (UValue& v)			\
    {						\
      return v;					\
    }						\
  };

  LIBPORT_LIST_APPLY(UVALUE_CASTER_DEFINE, URBI_NUMERIC_TYPES)
  UVALUE_CASTER_DEFINE(std::string);
  UVALUE_CASTER_DEFINE(const std::string);
  UVALUE_CASTER_DEFINE(bool);
  UVALUE_CASTER_DEFINE(UImage);
  UVALUE_CASTER_DEFINE(USound);

#undef UVALUE_CASTER_DEFINE

  /*-----------------------------------.
  | Casting an UValue into an UValue.  |
  `-----------------------------------*/

  // Always return a const UValue&, a copy will be made if required.
# define UVALUE_CASTER_DEFINE(Type)              \
  template <>                                   \
  struct uvalue_caster<Type>                    \
  {                                             \
    const UValue& operator()(UValue& v)         \
    {                                           \
      return v;                                 \
    }                                           \
  }

  UVALUE_CASTER_DEFINE(const UValue&);
  UVALUE_CASTER_DEFINE(UValue&);
  UVALUE_CASTER_DEFINE(const UValue);
  UVALUE_CASTER_DEFINE(UValue);
# undef UVALUE_CASTER_DEFINE

  // The following ones are defined in uvalue-common.cc.
  template <>
  struct URBI_SDK_API uvalue_caster<UVar>
  {
    UVar& operator () (UValue& v);
  };

# define UVALUE_CASTER_DECLARE(Type)		\
  template <>					\
  struct URBI_SDK_API uvalue_caster<Type>       \
  {                                             \
    Type operator () (UValue& v);		\
  }

  UVALUE_CASTER_DECLARE(UBinary);
  UVALUE_CASTER_DECLARE(UList);
  UVALUE_CASTER_DECLARE(UDictionary);
  UVALUE_CASTER_DECLARE(UObjectStruct);
  UVALUE_CASTER_DECLARE(const char*);

# undef UVALUE_CASTER_DECLARE

# ifndef UOBJECT_NO_LIST_CAST

#  define UVALUE_CONTAINER_CASTER_DECLARE(Type)                 \
  template <typename T>                                         \
  struct uvalue_caster< Type<T> >                               \
  {                                                             \
    Type<T>                                                     \
    operator()(UValue& v)                                       \
    {                                                           \
      Type<T> res;                                              \
      if (v.type != DATA_LIST)                                  \
        /* Cast just the element.  */                           \
        res.push_back(uvalue_cast<T>(v));                       \
      else                                                      \
        for (size_t i = 0; i < v.list->size(); ++i)             \
          res.push_back(uvalue_cast<T>(*v.list->array[i]));     \
      return res;                                               \
    }                                                           \
  }

  UVALUE_CONTAINER_CASTER_DECLARE(std::list);
  UVALUE_CONTAINER_CASTER_DECLARE(std::vector);

#  undef UVALUE_CONTAINER_CASTER_DECLARE

# endif

  // Dictionary casters.
  template <typename V>
  struct uvalue_caster<boost::unordered_map<std::string, V> >
  {
    boost::unordered_map<std::string, V> operator()(UValue& v)
    {
      boost::unordered_map<std::string, V> res;
      if (v.type != DATA_DICTIONARY)
        throw std::runtime_error("UValue is not a dictionary.");
      typedef UDictionary::value_type DictVal;
      BOOST_FOREACH(UDictionary::value_type& val, *v.dictionary)
        res[val.first] = uvalue_cast<V>(val.second);
      return res;
    }
  };

  template <typename V>
  inline
  UValue&
  operator,(UValue& v, const boost::unordered_map<std::string, V> & d)
  {
    typedef typename boost::unordered_map<std::string, V>::value_type DictVal;
    v.clear();
    v.type = DATA_DICTIONARY;
    v.dictionary = new UDictionary;
    BOOST_FOREACH(const DictVal & val, d)
    {
      UValue nv;
      nv, val.second;
      (*v.dictionary)[val.first] = nv;
     }
     return v;
  }

  // Uses casters, must be at the end
  template <typename T>
  inline
  UList&
  UList::operator=(const T& container)
  {
    array.clear();
    typedef const typename T::value_type constv;
    BOOST_FOREACH(constv& v, container)
    {
      UValue val;
      val,v;
      array.push_back(new UValue(val));
    }
    return *this;
  }

  template <typename T>
  inline
  T
  UList::as()
  {
    T res;
    BOOST_FOREACH(UValue* v, array)
      res.push_back(uvalue_caster<typename T::value_type>()(*v));
    return res;
  }

  /** Bounce to uvalue_cast(). Useful when the type of the argument is not
   * directly available.
   */
  template <typename T>
  inline
  void uvalue_cast_bounce(T& t, UValue& v)
  {
    t = uvalue_cast<T>(v);
  }

  template <typename T>
  struct uvalue_caster<UPackedData<T> >
  {
    UPackedData<T> operator() (UValue& v)
    {
      if (v.type != DATA_BINARY)
        throw std::runtime_error("invalid cast to UPackedData: not a Binary");
      if (v.binary->common.size % sizeof(T))
        throw std::runtime_error("invalid cast to UPackedData: incorrect binary"
                                 "size");
      return UPackedData<T>((T*)v.binary->common.data,
                            (T*)((char*)v.binary->common.data
                                 + v.binary->common.size));
    }
  };

  template <typename T>
  inline
  UValue& operator, (UValue&v, const UPackedData<T>& d)
  {
    v = UBinary();
    UBinary& b = *v.binary;
    b.common.size = sizeof(T)*d.size();
    b.common.data = malloc(b.common.size);
    b.message = "packed " + boost::lexical_cast<std::string>(sizeof(T))
      + " " + typeid(T).name();
    memcpy(b.common.data, &d.front(), b.common.size);
    return v;
  }

} // namespace urbi
<|endoftext|>