<commit_before>/*************************************************************************
 *
 *  $RCSfile: shdwcrsr.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 15:56:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#include "swtypes.hxx"
#include "shdwcrsr.hxx"

SwShadowCursor::~SwShadowCursor()
{
    if( USHRT_MAX != nOldMode )
        DrawCrsr( aOldPt, nOldHeight, nOldMode );
}

void SwShadowCursor::SetPos( const Point& rPt, long nHeight, USHORT nMode )
{
    Point aPt( pWin->LogicToPixel( rPt ));
    nHeight = pWin->LogicToPixel( Size( 0, nHeight )).Height();
    if( aOldPt != aPt || nOldHeight != nHeight || nOldMode != nMode )
    {
        if( USHRT_MAX != nOldMode )
            DrawCrsr( aOldPt, nOldHeight, nOldMode );

        DrawCrsr( aPt, nHeight, nMode );
        nOldMode = nMode;
        nOldHeight = nHeight;
        aOldPt = aPt;
    }
}

void SwShadowCursor::DrawTri( const Point& rPt, long nHeight, BOOL bLeft )
{
    USHORT nLineDiff = ( nHeight / 2 );
    USHORT nLineDiffHalf = nLineDiff / 2;

    // Punkt oben
    Point aPt1( (bLeft ? rPt.X() - 3 : rPt.X() + 3),
                rPt.Y() + nLineDiffHalf );
    // Punkt unten
    Point aPt2( aPt1.X(), aPt1.Y() + nHeight - nLineDiff - 1 );
    short nDiff = bLeft ? -1 : 1;
    while( aPt1.Y() <= aPt2.Y() )
    {
        pWin->DrawLine( aPt1, aPt2 );
        aPt1.Y()++, aPt2.Y()--;
        aPt2.X() = aPt1.X() += nDiff;
    }
}

void SwShadowCursor::DrawCrsr( const Point& rPt, long nHeight, USHORT nMode )
{
    nHeight = (((nHeight / 4)+1) * 4) + 1;

    pWin->Push();

    pWin->SetMapMode( MAP_PIXEL );
    pWin->SetRasterOp( ROP_XOR );

    pWin->SetLineColor( Color( aCol.GetColor() ^ COL_WHITE ) );

    // 1. der Strich:
    pWin->DrawLine( Point( rPt.X(), rPt.Y() + 1),
              Point( rPt.X(), rPt.Y() - 2 + nHeight ));

    // 2. das Dreieck
    if( HORI_LEFT == nMode || HORI_CENTER == nMode )    // Pfeil nach rechts
        DrawTri( rPt, nHeight, FALSE );
    if( HORI_RIGHT == nMode || HORI_CENTER == nMode )   // Pfeil nach links
        DrawTri( rPt, nHeight, TRUE );

    pWin->Pop();
}

void SwShadowCursor::Paint()
{
    if( USHRT_MAX != nOldMode )
        DrawCrsr( aOldPt, nOldHeight, nOldMode );
}

Rectangle SwShadowCursor::GetRect() const
{
    long nH = nOldHeight;
    Point aPt( aOldPt );

    nH = (((nH / 4)+1) * 4) + 1;
    USHORT nWidth = nH / 4 + 3 + 1;

    Size aSz( nWidth, nH );

    if( HORI_RIGHT == nOldMode )
        aPt.X() -= aSz.Width();
    else if( HORI_CENTER == nOldMode )
    {
        aPt.X() -= aSz.Width();
        aSz.Width() *= 2;
    }

    return pWin->PixelToLogic( Rectangle( aPt, aSz ) );
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.1254); FILE MERGED 2005/09/05 13:48:16 rt 1.3.1254.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: shdwcrsr.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 11:30:29 $
 *
 *  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
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#include "swtypes.hxx"
#include "shdwcrsr.hxx"

SwShadowCursor::~SwShadowCursor()
{
    if( USHRT_MAX != nOldMode )
        DrawCrsr( aOldPt, nOldHeight, nOldMode );
}

void SwShadowCursor::SetPos( const Point& rPt, long nHeight, USHORT nMode )
{
    Point aPt( pWin->LogicToPixel( rPt ));
    nHeight = pWin->LogicToPixel( Size( 0, nHeight )).Height();
    if( aOldPt != aPt || nOldHeight != nHeight || nOldMode != nMode )
    {
        if( USHRT_MAX != nOldMode )
            DrawCrsr( aOldPt, nOldHeight, nOldMode );

        DrawCrsr( aPt, nHeight, nMode );
        nOldMode = nMode;
        nOldHeight = nHeight;
        aOldPt = aPt;
    }
}

void SwShadowCursor::DrawTri( const Point& rPt, long nHeight, BOOL bLeft )
{
    USHORT nLineDiff = ( nHeight / 2 );
    USHORT nLineDiffHalf = nLineDiff / 2;

    // Punkt oben
    Point aPt1( (bLeft ? rPt.X() - 3 : rPt.X() + 3),
                rPt.Y() + nLineDiffHalf );
    // Punkt unten
    Point aPt2( aPt1.X(), aPt1.Y() + nHeight - nLineDiff - 1 );
    short nDiff = bLeft ? -1 : 1;
    while( aPt1.Y() <= aPt2.Y() )
    {
        pWin->DrawLine( aPt1, aPt2 );
        aPt1.Y()++, aPt2.Y()--;
        aPt2.X() = aPt1.X() += nDiff;
    }
}

void SwShadowCursor::DrawCrsr( const Point& rPt, long nHeight, USHORT nMode )
{
    nHeight = (((nHeight / 4)+1) * 4) + 1;

    pWin->Push();

    pWin->SetMapMode( MAP_PIXEL );
    pWin->SetRasterOp( ROP_XOR );

    pWin->SetLineColor( Color( aCol.GetColor() ^ COL_WHITE ) );

    // 1. der Strich:
    pWin->DrawLine( Point( rPt.X(), rPt.Y() + 1),
              Point( rPt.X(), rPt.Y() - 2 + nHeight ));

    // 2. das Dreieck
    if( HORI_LEFT == nMode || HORI_CENTER == nMode )    // Pfeil nach rechts
        DrawTri( rPt, nHeight, FALSE );
    if( HORI_RIGHT == nMode || HORI_CENTER == nMode )   // Pfeil nach links
        DrawTri( rPt, nHeight, TRUE );

    pWin->Pop();
}

void SwShadowCursor::Paint()
{
    if( USHRT_MAX != nOldMode )
        DrawCrsr( aOldPt, nOldHeight, nOldMode );
}

Rectangle SwShadowCursor::GetRect() const
{
    long nH = nOldHeight;
    Point aPt( aOldPt );

    nH = (((nH / 4)+1) * 4) + 1;
    USHORT nWidth = nH / 4 + 3 + 1;

    Size aSz( nWidth, nH );

    if( HORI_RIGHT == nOldMode )
        aPt.X() -= aSz.Width();
    else if( HORI_CENTER == nOldMode )
    {
        aPt.X() -= aSz.Width();
        aSz.Width() *= 2;
    }

    return pWin->PixelToLogic( Rectangle( aPt, aSz ) );
}

<|endoftext|>


<commit_before>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "rocksdb/cache.h"

#include <vector>
#include <string>
#include <iostream>
#include "util/coding.h"
#include "util/testharness.h"

namespace rocksdb {

// Conversions between numeric keys/values and the types expected by Cache.
static std::string EncodeKey(int k) {
  std::string result;
  PutFixed32(&result, k);
  return result;
}
static int DecodeKey(const Slice& k) {
  assert(k.size() == 4);
  return DecodeFixed32(k.data());
}
static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
static int DecodeValue(void* v) {
  return static_cast<int>(reinterpret_cast<uintptr_t>(v));
}

class CacheTest {
 public:
  static CacheTest* current_;

  static void Deleter(const Slice& key, void* v) {
    current_->deleted_keys_.push_back(DecodeKey(key));
    current_->deleted_values_.push_back(DecodeValue(v));
  }

  static const int kCacheSize = 1000;
  static const int kNumShardBits = 4;
  static const int kRemoveScanCountLimit = 16;

  static const int kCacheSize2 = 100;
  static const int kNumShardBits2 = 2;
  static const int kRemoveScanCountLimit2 = 200;

  std::vector<int> deleted_keys_;
  std::vector<int> deleted_values_;
  shared_ptr<Cache> cache_;
  shared_ptr<Cache> cache2_;

  CacheTest() :
      cache_(NewLRUCache(kCacheSize, kNumShardBits, kRemoveScanCountLimit)),
      cache2_(NewLRUCache(kCacheSize2, kNumShardBits2,
                          kRemoveScanCountLimit2)) {
    current_ = this;
  }

  ~CacheTest() {
  }

  int Lookup(shared_ptr<Cache> cache, int key) {
    Cache::Handle* handle = cache->Lookup(EncodeKey(key));
    const int r = (handle == nullptr) ? -1 : DecodeValue(cache->Value(handle));
    if (handle != nullptr) {
      cache->Release(handle);
    }
    return r;
  }

  void Insert(shared_ptr<Cache> cache, int key, int value, int charge = 1) {
    cache->Release(cache->Insert(EncodeKey(key), EncodeValue(value), charge,
                                  &CacheTest::Deleter));
  }

  void Erase(shared_ptr<Cache> cache, int key) {
    cache->Erase(EncodeKey(key));
  }

  int Lookup(int key) {
    return Lookup(cache_, key);
  }

  void Insert(int key, int value, int charge = 1) {
    Insert(cache_, key, value, charge);
  }

  void Erase(int key) {
    Erase(cache_, key);
  }

  int Lookup2(int key) {
    return Lookup(cache2_, key);
  }

  void Insert2(int key, int value, int charge = 1) {
    Insert(cache2_, key, value, charge);
  }

  void Erase2(int key) {
    Erase(cache2_, key);
  }
};
CacheTest* CacheTest::current_;

namespace {
void dumbDeleter(const Slice& key, void* value) { }
}  // namespace

TEST(CacheTest, UsageTest) {
  // cache is shared_ptr and will be automatically cleaned up.
  const uint64_t kCapacity = 100000;
  auto cache = NewLRUCache(kCapacity, 8, 200);

  size_t usage = 0;
  const char* value = "abcdef";
  // make sure everything will be cached
  for (int i = 1; i < 100; ++i) {
    std::string key(i, 'a');
    auto kv_size = key.size() + 5;
    cache->Release(
        cache->Insert(key, (void*)value, kv_size, dumbDeleter)
    );
    usage += kv_size;
    ASSERT_EQ(usage, cache->GetUsage());
  }

  // make sure the cache will be overloaded
  for (uint64_t i = 1; i < kCapacity; ++i) {
    auto key = ToString(i);
    cache->Release(
        cache->Insert(key, (void*)value, key.size() + 5, dumbDeleter)
    );
  }

  // the usage should be close to the capacity
  ASSERT_GT(kCapacity, cache->GetUsage());
  ASSERT_LT(kCapacity * 0.95, cache->GetUsage());
}

TEST(CacheTest, HitAndMiss) {
  ASSERT_EQ(-1, Lookup(100));

  Insert(100, 101);
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(-1,  Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  Insert(200, 201);
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  Insert(100, 102);
  ASSERT_EQ(102, Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);
}

TEST(CacheTest, Erase) {
  Erase(200);
  ASSERT_EQ(0U, deleted_keys_.size());

  Insert(100, 101);
  Insert(200, 201);
  Erase(100);
  ASSERT_EQ(-1,  Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);

  Erase(100);
  ASSERT_EQ(-1,  Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(1U, deleted_keys_.size());
}

TEST(CacheTest, EntriesArePinned) {
  Insert(100, 101);
  Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
  ASSERT_EQ(1, cache_->GetUsage());

  Insert(100, 102);
  Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(102, DecodeValue(cache_->Value(h2)));
  ASSERT_EQ(0U, deleted_keys_.size());
  ASSERT_EQ(2, cache_->GetUsage());

  cache_->Release(h1);
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);
  ASSERT_EQ(1, cache_->GetUsage());

  Erase(100);
  ASSERT_EQ(-1, Lookup(100));
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(1, cache_->GetUsage());

  cache_->Release(h2);
  ASSERT_EQ(2U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[1]);
  ASSERT_EQ(102, deleted_values_[1]);
  ASSERT_EQ(0, cache_->GetUsage());
}

TEST(CacheTest, EvictionPolicy) {
  Insert(100, 101);
  Insert(200, 201);

  // Frequently used entry must be kept around
  for (int i = 0; i < kCacheSize + 100; i++) {
    Insert(1000+i, 2000+i);
    ASSERT_EQ(2000+i, Lookup(1000+i));
    ASSERT_EQ(101, Lookup(100));
  }
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(-1, Lookup(200));
}

TEST(CacheTest, EvictionPolicyRef) {
  Insert(100, 101);
  Insert(101, 102);
  Insert(102, 103);
  Insert(103, 104);
  Insert(200, 101);
  Insert(201, 102);
  Insert(202, 103);
  Insert(203, 104);
  Cache::Handle* h201 = cache_->Lookup(EncodeKey(200));
  Cache::Handle* h202 = cache_->Lookup(EncodeKey(201));
  Cache::Handle* h203 = cache_->Lookup(EncodeKey(202));
  Cache::Handle* h204 = cache_->Lookup(EncodeKey(203));
  Insert(300, 101);
  Insert(301, 102);
  Insert(302, 103);
  Insert(303, 104);

  // Insert entries much more than Cache capacity
  for (int i = 0; i < kCacheSize + 100; i++) {
    Insert(1000 + i, 2000 + i);
  }

  // Check whether the entries inserted in the beginning
  // are evicted. Ones without extra ref are evicted and
  // those with are not.
  ASSERT_EQ(-1, Lookup(100));
  ASSERT_EQ(-1, Lookup(101));
  ASSERT_EQ(-1, Lookup(102));
  ASSERT_EQ(-1, Lookup(103));

  ASSERT_EQ(-1, Lookup(300));
  ASSERT_EQ(-1, Lookup(301));
  ASSERT_EQ(-1, Lookup(302));
  ASSERT_EQ(-1, Lookup(303));

  ASSERT_EQ(101, Lookup(200));
  ASSERT_EQ(102, Lookup(201));
  ASSERT_EQ(103, Lookup(202));
  ASSERT_EQ(104, Lookup(203));

  // Cleaning up all the handles
  cache_->Release(h201);
  cache_->Release(h202);
  cache_->Release(h203);
  cache_->Release(h204);
}

TEST(CacheTest, ErasedHandleState) {
  // insert a key and get two handles
  Insert(100, 1000);
  Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
  Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(h1, h2);
  ASSERT_EQ(DecodeValue(cache_->Value(h1)), 1000);
  ASSERT_EQ(DecodeValue(cache_->Value(h2)), 1000);

  // delete the key from the cache
  Erase(100);
  // can no longer find in the cache
  ASSERT_EQ(-1, Lookup(100));

  // release one handle
  cache_->Release(h1);
  // still can't find in cache
  ASSERT_EQ(-1, Lookup(100));

  cache_->Release(h2);
}

TEST(CacheTest, HeavyEntries) {
  // Add a bunch of light and heavy entries and then count the combined
  // size of items still in the cache, which must be approximately the
  // same as the total capacity.
  const int kLight = 1;
  const int kHeavy = 10;
  int added = 0;
  int index = 0;
  while (added < 2*kCacheSize) {
    const int weight = (index & 1) ? kLight : kHeavy;
    Insert(index, 1000+index, weight);
    added += weight;
    index++;
  }

  int cached_weight = 0;
  for (int i = 0; i < index; i++) {
    const int weight = (i & 1 ? kLight : kHeavy);
    int r = Lookup(i);
    if (r >= 0) {
      cached_weight += weight;
      ASSERT_EQ(1000+i, r);
    }
  }
  ASSERT_LE(cached_weight, kCacheSize + kCacheSize/10);
}

TEST(CacheTest, NewId) {
  uint64_t a = cache_->NewId();
  uint64_t b = cache_->NewId();
  ASSERT_NE(a, b);
}

class Value {
 private:
  int v_;
 public:
  explicit Value(int v) : v_(v) { }

  ~Value() { std::cout << v_ << " is destructed\n"; }
};

namespace {
void deleter(const Slice& key, void* value) {
  delete static_cast<Value *>(value);
}
}  // namespace

TEST(CacheTest, OverCapacity) {
  int n = 10;

  // a LRUCache with n entries and one shard only
  std::shared_ptr<Cache> cache = NewLRUCache(n, 0);

  std::vector<Cache::Handle*> handles(n+1);

  // Insert n+1 entries, but not releasing.
  for (int i = 0; i < n+1; i++) {
    std::string key = ToString(i+1);
    handles[i] = cache->Insert(key, new Value(i+1), 1, &deleter);
  }

  // Guess what's in the cache now?
  for (int i = 0; i < n+1; i++) {
    std::string key = ToString(i+1);
    auto h = cache->Lookup(key);
    std::cout << key << (h?" found\n":" not found\n");
    ASSERT_TRUE(h != nullptr);
    if (h) cache->Release(h);
  }

  // the cache is over capacity since nothing could be evicted
  ASSERT_EQ(n + 1, cache->GetUsage());
  for (int i = 0; i < n+1; i++) {
    cache->Release(handles[i]);
  }

  // cache is under capacity now since elements were released
  ASSERT_EQ(n, cache->GetUsage());

  // element 0 is evicted and the rest is there
  // This is consistent with the LRU policy since the element 0
  // was released first
  for (int i = 0; i < n+1; i++) {
    std::string key = ToString(i+1);
    auto h = cache->Lookup(key);
    if (h) {
      ASSERT_NE(i, 0);
      cache->Release(h);
    } else {
      ASSERT_EQ(i, 0);
    }
  }
}

namespace {
std::vector<std::pair<int, int>> callback_state;
void callback(void* entry, size_t charge) {
  callback_state.push_back({DecodeValue(entry), static_cast<int>(charge)});
}
};

TEST(CacheTest, ApplyToAllCacheEntiresTest) {
  std::vector<std::pair<int, int>> inserted;
  callback_state.clear();

  for (int i = 0; i < 10; ++i) {
    Insert(i, i * 2, i + 1);
    inserted.push_back({i * 2, i + 1});
  }
  cache_->ApplyToAllCacheEntries(callback, true);

  sort(inserted.begin(), inserted.end());
  sort(callback_state.begin(), callback_state.end());
  ASSERT_TRUE(inserted == callback_state);
}

}  // namespace rocksdb

int main(int argc, char** argv) {
  return rocksdb::test::RunAllTests();
}
<commit_msg>Fix Mac compile errors on util/cache_test.cc<commit_after>//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include "rocksdb/cache.h"

#include <vector>
#include <string>
#include <iostream>
#include "util/coding.h"
#include "util/testharness.h"

namespace rocksdb {

// Conversions between numeric keys/values and the types expected by Cache.
static std::string EncodeKey(int k) {
  std::string result;
  PutFixed32(&result, k);
  return result;
}
static int DecodeKey(const Slice& k) {
  assert(k.size() == 4);
  return DecodeFixed32(k.data());
}
static void* EncodeValue(uintptr_t v) { return reinterpret_cast<void*>(v); }
static int DecodeValue(void* v) {
  return static_cast<int>(reinterpret_cast<uintptr_t>(v));
}

class CacheTest {
 public:
  static CacheTest* current_;

  static void Deleter(const Slice& key, void* v) {
    current_->deleted_keys_.push_back(DecodeKey(key));
    current_->deleted_values_.push_back(DecodeValue(v));
  }

  static const int kCacheSize = 1000;
  static const int kNumShardBits = 4;
  static const int kRemoveScanCountLimit = 16;

  static const int kCacheSize2 = 100;
  static const int kNumShardBits2 = 2;
  static const int kRemoveScanCountLimit2 = 200;

  std::vector<int> deleted_keys_;
  std::vector<int> deleted_values_;
  shared_ptr<Cache> cache_;
  shared_ptr<Cache> cache2_;

  CacheTest() :
      cache_(NewLRUCache(kCacheSize, kNumShardBits, kRemoveScanCountLimit)),
      cache2_(NewLRUCache(kCacheSize2, kNumShardBits2,
                          kRemoveScanCountLimit2)) {
    current_ = this;
  }

  ~CacheTest() {
  }

  int Lookup(shared_ptr<Cache> cache, int key) {
    Cache::Handle* handle = cache->Lookup(EncodeKey(key));
    const int r = (handle == nullptr) ? -1 : DecodeValue(cache->Value(handle));
    if (handle != nullptr) {
      cache->Release(handle);
    }
    return r;
  }

  void Insert(shared_ptr<Cache> cache, int key, int value, int charge = 1) {
    cache->Release(cache->Insert(EncodeKey(key), EncodeValue(value), charge,
                                  &CacheTest::Deleter));
  }

  void Erase(shared_ptr<Cache> cache, int key) {
    cache->Erase(EncodeKey(key));
  }

  int Lookup(int key) {
    return Lookup(cache_, key);
  }

  void Insert(int key, int value, int charge = 1) {
    Insert(cache_, key, value, charge);
  }

  void Erase(int key) {
    Erase(cache_, key);
  }

  int Lookup2(int key) {
    return Lookup(cache2_, key);
  }

  void Insert2(int key, int value, int charge = 1) {
    Insert(cache2_, key, value, charge);
  }

  void Erase2(int key) {
    Erase(cache2_, key);
  }
};
CacheTest* CacheTest::current_;

namespace {
void dumbDeleter(const Slice& key, void* value) { }
}  // namespace

TEST(CacheTest, UsageTest) {
  // cache is shared_ptr and will be automatically cleaned up.
  const uint64_t kCapacity = 100000;
  auto cache = NewLRUCache(kCapacity, 8, 200);

  size_t usage = 0;
  const char* value = "abcdef";
  // make sure everything will be cached
  for (int i = 1; i < 100; ++i) {
    std::string key(i, 'a');
    auto kv_size = key.size() + 5;
    cache->Release(
        cache->Insert(key, (void*)value, kv_size, dumbDeleter)
    );
    usage += kv_size;
    ASSERT_EQ(usage, cache->GetUsage());
  }

  // make sure the cache will be overloaded
  for (uint64_t i = 1; i < kCapacity; ++i) {
    auto key = ToString(i);
    cache->Release(
        cache->Insert(key, (void*)value, key.size() + 5, dumbDeleter)
    );
  }

  // the usage should be close to the capacity
  ASSERT_GT(kCapacity, cache->GetUsage());
  ASSERT_LT(kCapacity * 0.95, cache->GetUsage());
}

TEST(CacheTest, HitAndMiss) {
  ASSERT_EQ(-1, Lookup(100));

  Insert(100, 101);
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(-1,  Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  Insert(200, 201);
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  Insert(100, 102);
  ASSERT_EQ(102, Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(-1,  Lookup(300));

  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);
}

TEST(CacheTest, Erase) {
  Erase(200);
  ASSERT_EQ(0U, deleted_keys_.size());

  Insert(100, 101);
  Insert(200, 201);
  Erase(100);
  ASSERT_EQ(-1,  Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);

  Erase(100);
  ASSERT_EQ(-1,  Lookup(100));
  ASSERT_EQ(201, Lookup(200));
  ASSERT_EQ(1U, deleted_keys_.size());
}

TEST(CacheTest, EntriesArePinned) {
  Insert(100, 101);
  Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(101, DecodeValue(cache_->Value(h1)));
  ASSERT_EQ(1U, cache_->GetUsage());

  Insert(100, 102);
  Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(102, DecodeValue(cache_->Value(h2)));
  ASSERT_EQ(0U, deleted_keys_.size());
  ASSERT_EQ(2U, cache_->GetUsage());

  cache_->Release(h1);
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[0]);
  ASSERT_EQ(101, deleted_values_[0]);
  ASSERT_EQ(1U, cache_->GetUsage());

  Erase(100);
  ASSERT_EQ(-1, Lookup(100));
  ASSERT_EQ(1U, deleted_keys_.size());
  ASSERT_EQ(1U, cache_->GetUsage());

  cache_->Release(h2);
  ASSERT_EQ(2U, deleted_keys_.size());
  ASSERT_EQ(100, deleted_keys_[1]);
  ASSERT_EQ(102, deleted_values_[1]);
  ASSERT_EQ(0U, cache_->GetUsage());
}

TEST(CacheTest, EvictionPolicy) {
  Insert(100, 101);
  Insert(200, 201);

  // Frequently used entry must be kept around
  for (int i = 0; i < kCacheSize + 100; i++) {
    Insert(1000+i, 2000+i);
    ASSERT_EQ(2000+i, Lookup(1000+i));
    ASSERT_EQ(101, Lookup(100));
  }
  ASSERT_EQ(101, Lookup(100));
  ASSERT_EQ(-1, Lookup(200));
}

TEST(CacheTest, EvictionPolicyRef) {
  Insert(100, 101);
  Insert(101, 102);
  Insert(102, 103);
  Insert(103, 104);
  Insert(200, 101);
  Insert(201, 102);
  Insert(202, 103);
  Insert(203, 104);
  Cache::Handle* h201 = cache_->Lookup(EncodeKey(200));
  Cache::Handle* h202 = cache_->Lookup(EncodeKey(201));
  Cache::Handle* h203 = cache_->Lookup(EncodeKey(202));
  Cache::Handle* h204 = cache_->Lookup(EncodeKey(203));
  Insert(300, 101);
  Insert(301, 102);
  Insert(302, 103);
  Insert(303, 104);

  // Insert entries much more than Cache capacity
  for (int i = 0; i < kCacheSize + 100; i++) {
    Insert(1000 + i, 2000 + i);
  }

  // Check whether the entries inserted in the beginning
  // are evicted. Ones without extra ref are evicted and
  // those with are not.
  ASSERT_EQ(-1, Lookup(100));
  ASSERT_EQ(-1, Lookup(101));
  ASSERT_EQ(-1, Lookup(102));
  ASSERT_EQ(-1, Lookup(103));

  ASSERT_EQ(-1, Lookup(300));
  ASSERT_EQ(-1, Lookup(301));
  ASSERT_EQ(-1, Lookup(302));
  ASSERT_EQ(-1, Lookup(303));

  ASSERT_EQ(101, Lookup(200));
  ASSERT_EQ(102, Lookup(201));
  ASSERT_EQ(103, Lookup(202));
  ASSERT_EQ(104, Lookup(203));

  // Cleaning up all the handles
  cache_->Release(h201);
  cache_->Release(h202);
  cache_->Release(h203);
  cache_->Release(h204);
}

TEST(CacheTest, ErasedHandleState) {
  // insert a key and get two handles
  Insert(100, 1000);
  Cache::Handle* h1 = cache_->Lookup(EncodeKey(100));
  Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
  ASSERT_EQ(h1, h2);
  ASSERT_EQ(DecodeValue(cache_->Value(h1)), 1000);
  ASSERT_EQ(DecodeValue(cache_->Value(h2)), 1000);

  // delete the key from the cache
  Erase(100);
  // can no longer find in the cache
  ASSERT_EQ(-1, Lookup(100));

  // release one handle
  cache_->Release(h1);
  // still can't find in cache
  ASSERT_EQ(-1, Lookup(100));

  cache_->Release(h2);
}

TEST(CacheTest, HeavyEntries) {
  // Add a bunch of light and heavy entries and then count the combined
  // size of items still in the cache, which must be approximately the
  // same as the total capacity.
  const int kLight = 1;
  const int kHeavy = 10;
  int added = 0;
  int index = 0;
  while (added < 2*kCacheSize) {
    const int weight = (index & 1) ? kLight : kHeavy;
    Insert(index, 1000+index, weight);
    added += weight;
    index++;
  }

  int cached_weight = 0;
  for (int i = 0; i < index; i++) {
    const int weight = (i & 1 ? kLight : kHeavy);
    int r = Lookup(i);
    if (r >= 0) {
      cached_weight += weight;
      ASSERT_EQ(1000+i, r);
    }
  }
  ASSERT_LE(cached_weight, kCacheSize + kCacheSize/10);
}

TEST(CacheTest, NewId) {
  uint64_t a = cache_->NewId();
  uint64_t b = cache_->NewId();
  ASSERT_NE(a, b);
}

class Value {
 private:
  size_t v_;
 public:
  explicit Value(size_t v) : v_(v) { }

  ~Value() { std::cout << v_ << " is destructed\n"; }
};

namespace {
void deleter(const Slice& key, void* value) {
  delete static_cast<Value *>(value);
}
}  // namespace

TEST(CacheTest, OverCapacity) {
  size_t n = 10;

  // a LRUCache with n entries and one shard only
  std::shared_ptr<Cache> cache = NewLRUCache(n, 0);

  std::vector<Cache::Handle*> handles(n+1);

  // Insert n+1 entries, but not releasing.
  for (size_t i = 0; i < n + 1; i++) {
    std::string key = ToString(i+1);
    handles[i] = cache->Insert(key, new Value(i+1), 1, &deleter);
  }

  // Guess what's in the cache now?
  for (size_t i = 0; i < n + 1; i++) {
    std::string key = ToString(i+1);
    auto h = cache->Lookup(key);
    std::cout << key << (h?" found\n":" not found\n");
    ASSERT_TRUE(h != nullptr);
    if (h) cache->Release(h);
  }

  // the cache is over capacity since nothing could be evicted
  ASSERT_EQ(n + 1U, cache->GetUsage());
  for (size_t i = 0; i < n + 1; i++) {
    cache->Release(handles[i]);
  }

  // cache is under capacity now since elements were released
  ASSERT_EQ(n, cache->GetUsage());

  // element 0 is evicted and the rest is there
  // This is consistent with the LRU policy since the element 0
  // was released first
  for (size_t i = 0; i < n + 1; i++) {
    std::string key = ToString(i+1);
    auto h = cache->Lookup(key);
    if (h) {
      ASSERT_NE(i, 0U);
      cache->Release(h);
    } else {
      ASSERT_EQ(i, 0U);
    }
  }
}

namespace {
std::vector<std::pair<int, int>> callback_state;
void callback(void* entry, size_t charge) {
  callback_state.push_back({DecodeValue(entry), static_cast<int>(charge)});
}
};

TEST(CacheTest, ApplyToAllCacheEntiresTest) {
  std::vector<std::pair<int, int>> inserted;
  callback_state.clear();

  for (int i = 0; i < 10; ++i) {
    Insert(i, i * 2, i + 1);
    inserted.push_back({i * 2, i + 1});
  }
  cache_->ApplyToAllCacheEntries(callback, true);

  sort(inserted.begin(), inserted.end());
  sort(callback_state.begin(), callback_state.end());
  ASSERT_TRUE(inserted == callback_state);
}

}  // namespace rocksdb

int main(int argc, char** argv) {
  return rocksdb::test::RunAllTests();
}
<|endoftext|>


<commit_before>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "encryption.h"
#include "default.h"
#include "hex.h"
#include "base64.h"
#include "files.h"
#include "gzip.h"
#include "osrng.h"
#include "exception.h"
using namespace std;
using namespace GUtil;

int CryptoHelpers::DEFAULT_COMPRESSION_LEVEL = CryptoPP::Gzip::DEFAULT_DEFLATE_LEVEL;
int CryptoHelpers::MIN_COMPRESSION_LEVEL = CryptoPP::Gzip::MIN_DEFLATE_LEVEL;
int CryptoHelpers::MAX_COMPRESSION_LEVEL = CryptoPP::Gzip::MAX_DEFLATE_LEVEL;

string CryptoHelpers::encryptString(const string &instr, const string &passPhrase)
{
    string outstr;

    CryptoPP::DefaultEncryptorWithMAC encryptor(passPhrase.c_str(),
                                                new CryptoPP::StringSink(outstr));

    try
    {
        encryptor.Put((byte *)instr.c_str(), instr.length());
        encryptor.MessageEnd();
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return outstr;
}

string CryptoHelpers::decryptString(const string &instr, const string &passPhrase)
{
    string outstr;

    CryptoPP::DefaultDecryptorWithMAC decryptor(passPhrase.c_str(),
                                                new CryptoPP::StringSink(outstr));

    try
    {
        decryptor.Put((byte *)instr.c_str(), instr.length());
        decryptor.MessageEnd();
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return outstr;
}

void CryptoHelpers::encryptFile(const char *in, const char *out, const char *passPhrase)
{
    try
    {
        CryptoPP::FileSource f(in, true, new CryptoPP::DefaultEncryptorWithMAC(passPhrase, new CryptoPP::FileSink(out)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }
}

void CryptoHelpers::decryptFile(const char *in, const char *out, const char *passPhrase)
{
    try
    {
        CryptoPP::FileSource f(in, true, new CryptoPP::DefaultDecryptorWithMAC(passPhrase, new CryptoPP::FileSink(out)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }
}

string CryptoHelpers::compress(const string &instr, int level)
{
    string ret;

    if(level < MIN_COMPRESSION_LEVEL ||
       level > MAX_COMPRESSION_LEVEL)
        level = DEFAULT_COMPRESSION_LEVEL;

    try
    {
        CryptoPP::Gzip zipper(new CryptoPP::StringSink(ret), level);
        zipper.Put((byte*)instr.c_str(), instr.length());
        zipper.MessageEnd();
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return ret;
}

string CryptoHelpers::decompress(const string &instr)
{
    string tmp;

    try
    {
        CryptoPP::StringSource(instr, true, new CryptoPP::Gunzip(new CryptoPP::StringSink(tmp)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return tmp;
}

string CryptoHelpers::toBase64(const string &instr)
{
    string tmp;

    CryptoPP::Base64Encoder encoder(new CryptoPP::StringSink(tmp), false);
    encoder.Put((byte *)instr.c_str(), instr.length());
    encoder.MessageEnd();

    return tmp;
}

string CryptoHelpers::fromBase64(const string &instr)
{
    string tmp;

    try
    {
        CryptoPP::StringSource(instr, true,
                               new CryptoPP::Base64Decoder(new CryptoPP::StringSink(tmp)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return tmp;
}

string CryptoHelpers::toBase16(const string &instr)
{
    string tmp;

    CryptoPP::HexEncoder encoder(new CryptoPP::StringSink(tmp), true);
    encoder.Put((byte *)instr.c_str(), instr.length());
    encoder.MessageEnd();

    return tmp;
}

string CryptoHelpers::fromBase16(const string &instr)
{
    string tmp;

    try
    {
        CryptoPP::StringSource(instr, true,
                               new CryptoPP::HexDecoder(new CryptoPP::StringSink(tmp)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return tmp;
}

int CryptoHelpers::rand()
{
    CryptoPP::AutoSeededRandomPool rng;
    return rng.GenerateWord32();
}

string CryptoHelpers::randData(int size, int seed)
{
    CryptoPP::RandomPool *rng;
    if(seed == -1)
    {
        rng = new CryptoPP::AutoSeededRandomPool();
    }
    else
    {
        rng = new CryptoPP::RandomPool();

        // Seed the random pool
        rng->Put((byte*)(&seed), sizeof(int));
    }

    byte *output = new byte[size];
    rng->GenerateBlock(output, size);

    string ret = string((char*)output, size);
    delete output;
    delete rng;

    return ret;
}
<commit_msg>Now it doesn't compress if the file would get bigger<commit_after>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "encryption.h"
#include "default.h"
#include "hex.h"
#include "base64.h"
#include "files.h"
#include "gzip.h"
#include "osrng.h"
#include "exception.h"
using namespace std;
using namespace GUtil;

int CryptoHelpers::DEFAULT_COMPRESSION_LEVEL = CryptoPP::Gzip::DEFAULT_DEFLATE_LEVEL;
int CryptoHelpers::MIN_COMPRESSION_LEVEL = CryptoPP::Gzip::MIN_DEFLATE_LEVEL;
int CryptoHelpers::MAX_COMPRESSION_LEVEL = CryptoPP::Gzip::MAX_DEFLATE_LEVEL;

string CryptoHelpers::encryptString(const string &instr, const string &passPhrase)
{
    string outstr;

    CryptoPP::DefaultEncryptorWithMAC encryptor(passPhrase.c_str(),
                                                new CryptoPP::StringSink(outstr));

    try
    {
        encryptor.Put((byte *)instr.c_str(), instr.length());
        encryptor.MessageEnd();
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return outstr;
}

string CryptoHelpers::decryptString(const string &instr, const string &passPhrase)
{
    string outstr;

    CryptoPP::DefaultDecryptorWithMAC decryptor(passPhrase.c_str(),
                                                new CryptoPP::StringSink(outstr));

    try
    {
        decryptor.Put((byte *)instr.c_str(), instr.length());
        decryptor.MessageEnd();
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return outstr;
}

void CryptoHelpers::encryptFile(const char *in, const char *out, const char *passPhrase)
{
    try
    {
        CryptoPP::FileSource f(in, true, new CryptoPP::DefaultEncryptorWithMAC(passPhrase, new CryptoPP::FileSink(out)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }
}

void CryptoHelpers::decryptFile(const char *in, const char *out, const char *passPhrase)
{
    try
    {
        CryptoPP::FileSource f(in, true, new CryptoPP::DefaultDecryptorWithMAC(passPhrase, new CryptoPP::FileSink(out)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }
}

string CryptoHelpers::compress(const string &instr, int level)
{
    string ret;

    bool skip_compression = instr.length() > 10000000;

    if(!skip_compression)
    {
        if(level < MIN_COMPRESSION_LEVEL ||
           level > MAX_COMPRESSION_LEVEL)
            level = DEFAULT_COMPRESSION_LEVEL;

        try
        {
            CryptoPP::Gzip zipper(new CryptoPP::StringSink(ret), level);
            zipper.Put((byte*)instr.c_str(), instr.length());
            zipper.MessageEnd();
        }
        catch(CryptoPP::Exception ex)
        {
            throw GUtil::Exception(ex.GetWhat());
        }
    }

    if(skip_compression ||  ret.length() > instr.length())
    {
        // Leave it uncompressed, because we didn't gain anything by compression
        return "0" + instr;
    }

    return "1" + ret;
}

string CryptoHelpers::decompress(const string &instr)
{
    string tmp;

    if(instr.length() > 0)
    {
        bool is_compressed = false;
        char tmpc = instr.at(0);
        if(tmpc == '1')
            is_compressed = true;

        string newstr;
        if(tmpc == '0' || tmpc == '1')
            newstr = instr.substr(1);
        else
        {
            is_compressed = true;
            newstr = instr;
        }

        if(is_compressed)
        {
            try
            {
                CryptoPP::StringSource(newstr, true, new CryptoPP::Gunzip(new CryptoPP::StringSink(tmp)));
            }
            catch(CryptoPP::Exception ex)
            {
                throw GUtil::Exception(ex.GetWhat());
            }
        }
        else
            return newstr;
    }

    return tmp;
}

string CryptoHelpers::toBase64(const string &instr)
{
    string tmp;

    CryptoPP::Base64Encoder encoder(new CryptoPP::StringSink(tmp), false);
    encoder.Put((byte *)instr.c_str(), instr.length());
    encoder.MessageEnd();

    return tmp;
}

string CryptoHelpers::fromBase64(const string &instr)
{
    string tmp;

    try
    {
        CryptoPP::StringSource(instr, true,
                               new CryptoPP::Base64Decoder(new CryptoPP::StringSink(tmp)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return tmp;
}

string CryptoHelpers::toBase16(const string &instr)
{
    string tmp;

    CryptoPP::HexEncoder encoder(new CryptoPP::StringSink(tmp), true);
    encoder.Put((byte *)instr.c_str(), instr.length());
    encoder.MessageEnd();

    return tmp;
}

string CryptoHelpers::fromBase16(const string &instr)
{
    string tmp;

    try
    {
        CryptoPP::StringSource(instr, true,
                               new CryptoPP::HexDecoder(new CryptoPP::StringSink(tmp)));
    }
    catch(CryptoPP::Exception ex)
    {
        throw GUtil::Exception(ex.GetWhat());
    }

    return tmp;
}

int CryptoHelpers::rand()
{
    CryptoPP::AutoSeededRandomPool rng;
    return rng.GenerateWord32();
}

string CryptoHelpers::randData(int size, int seed)
{
    CryptoPP::RandomPool *rng;
    if(seed == -1)
    {
        rng = new CryptoPP::AutoSeededRandomPool();
    }
    else
    {
        rng = new CryptoPP::RandomPool();

        // Seed the random pool
        rng->Put((byte*)(&seed), sizeof(int));
    }

    byte *output = new byte[size];
    rng->GenerateBlock(output, size);

    string ret = string((char*)output, size);
    delete output;
    delete rng;

    return ret;
}
<|endoftext|>


<commit_before>/*
 * A Remote Debugger for SpiderMonkey Java Script engine.
 * Copyright (C) 2014-2015 Sławomir Wojtasiak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "encoding.hpp"
#include <langinfo.h>

#include <string>
#include <iostream>
#include <sstream>
#include <iconv.h>
#include <errno.h>
#include <limits.h>
#include <string.h>

#define MBS_ENC_LOCAL_ENCODING_BUFF_LEN         512

using namespace Utils;

EncodingFailedException::EncodingFailedException( const std::string& msg )
    : _msg(msg) {
}

EncodingFailedException::~EncodingFailedException() {
}

const std::string& EncodingFailedException::getMsg() const {
    return _msg;
}
<commit_msg>encoding.cpp: remove unused macro and includes<commit_after>/*
 * A Remote Debugger for SpiderMonkey Java Script engine.
 * Copyright (C) 2014-2015 Sławomir Wojtasiak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "encoding.hpp"

#include <string>

using namespace Utils;

EncodingFailedException::EncodingFailedException( const std::string& msg )
    : _msg(msg) {
}

EncodingFailedException::~EncodingFailedException() {
}

const std::string& EncodingFailedException::getMsg() const {
    return _msg;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3439
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3439 to 3440<commit_after>/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.

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

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

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

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3440
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include <boost/preprocessor.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/to_seq.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <silicium/to_unique.hpp>

#if SILICIUM_COMPILER_GENERATES_MOVES
#	define SILICIUM_MOVABLE_MEMBER(struct_name, member_name) \
	struct_name() = default; \
	SILICIUM_DEFAULT_MOVE(struct_name)
#else
#	define SILICIUM_MOVABLE_MEMBER(struct_name, member_name) \
	struct_name() : member_name() BOOST_NOEXCEPT {} \
	struct_name(struct_name &&other) BOOST_NOEXCEPT : member_name(std::move(other.member_name)) {} \
	struct_name &operator = (struct_name &&other) BOOST_NOEXCEPT { member_name = std::move(other.member_name); return *this; }
#endif

#define SILICIUM_DETAIL_MAKE_PARAMETER(z, n, array) BOOST_PP_COMMA_IF(n) BOOST_PP_ARRAY_ELEM(n, array) BOOST_PP_CAT(arg, n)
#define SILICIUM_DETAIL_MAKE_PARAMETERS(array) ( BOOST_PP_REPEAT(BOOST_PP_ARRAY_SIZE(array), SILICIUM_DETAIL_MAKE_PARAMETER, array) )

#define SILICIUM_DETAIL_MAKE_PURE_VIRTUAL_METHOD(r, data, elem) \
	virtual \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) \
	= 0;

#define SILICIUM_DETAIL_MAKE_INTERFACE(name, methods) struct name { \
	virtual ~name() {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_PURE_VIRTUAL_METHOD, _, methods) \
};

#define SILICIUM_DETAIL_ERASER_METHOD_ARGUMENT(z, n, text) , BOOST_PP_CAT(_, n)

#define SILICIUM_DETAIL_MAKE_ERASER_METHOD(r, data, elem) \
	virtual \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) \
	SILICIUM_OVERRIDE { \
		return original. BOOST_PP_TUPLE_ELEM(4, 0, elem) ( \
			BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_SIZE(BOOST_PP_TUPLE_ELEM(4, 1, elem)), arg) \
		); \
	}

#define SILICIUM_DETAIL_MAKE_BOX_METHOD(r, data, elem) \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) { \
		assert(original); \
		return original -> BOOST_PP_TUPLE_ELEM(4, 0, elem) ( \
			BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_SIZE(BOOST_PP_TUPLE_ELEM(4, 1, elem)), arg) \
		); \
	}

#define SILICIUM_DETAIL_MAKE_ERASER(name, methods) template <class Original> struct name : interface { \
	Original original; \
	SILICIUM_MOVABLE_MEMBER(name, original) \
	explicit name(Original original) : original(std::move(original)) {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_ERASER_METHOD, _, methods) \
};

#define SILICIUM_DETAIL_MAKE_BOX(name, methods) struct box { \
	std::unique_ptr<interface> original; \
	SILICIUM_MOVABLE_MEMBER(name, original) \
	explicit name(std::unique_ptr<interface> original) BOOST_NOEXCEPT : original(std::move(original)) {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_BOX_METHOD, _, methods) \
};

#define SILICIUM_SPECIALIZED_TRAIT(name, specialization, methods) struct name specialization { \
	SILICIUM_DETAIL_MAKE_INTERFACE(interface, methods) \
	SILICIUM_DETAIL_MAKE_ERASER(eraser, methods) \
	SILICIUM_DETAIL_MAKE_BOX(box, methods) \
	template <class Original> \
	static eraser<typename std::decay<Original>::type> erase(Original &&original) { \
		return eraser<typename std::decay<Original>::type>{std::forward<Original>(original)}; \
	} \
	template <class Original> \
	static box make_box(Original &&original) { \
		return box{Si::to_unique(erase(std::forward<Original>(original)))}; \
	} \
};

#define SILICIUM_TRAIT(name, methods) SILICIUM_SPECIALIZED_TRAIT(name, , methods)

typedef long element;

SILICIUM_TRAIT(
	Producer,
	((get, (0, ()), element))
)

struct test_producer
{
	element get()
	{
		return 42;
	}
};

BOOST_AUTO_TEST_CASE(trivial_trait)
{
	std::unique_ptr<Producer::interface> p = Si::to_unique(Producer::erase(test_producer{}));
	BOOST_REQUIRE(p);
	BOOST_CHECK_EQUAL(42, p->get());
}

template <class T>
SILICIUM_TRAIT(
	Container,
	((emplace_back, (1, (T)), void))
	((resize, (1, (size_t)), void))
	((resize, (2, (size_t, T const &)), void))
	((empty, (0, ()), bool, const))
	((size, (0, ()), size_t, const BOOST_NOEXCEPT))
)

BOOST_AUTO_TEST_CASE(templatized_trait)
{
	auto container = Container<int>::erase(std::vector<int>{});
	container.emplace_back(123);
	{
		std::vector<int> const expected{123};
		BOOST_CHECK(expected == container.original);
	}
	container.resize(2);
	{
		std::vector<int> const expected{123, 0};
		BOOST_CHECK(expected == container.original);
	}
	container.resize(3, 7);
	{
		std::vector<int> const expected{123, 0, 7};
		BOOST_CHECK(expected == container.original);
	}
}

BOOST_AUTO_TEST_CASE(trait_const_method)
{
	auto container = Container<int>::erase(std::vector<int>{});
	auto const &const_ref = container;
	BOOST_CHECK(const_ref.empty());
	container.original.resize(1);
	BOOST_CHECK(!const_ref.empty());
}

#if SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT
BOOST_AUTO_TEST_CASE(trait_noexcept_method)
{
	auto container = Container<int>::erase(std::vector<int>{});
	auto const &const_ref = container;
	BOOST_CHECK_EQUAL(0, const_ref.size());
	container.original.resize(3);
	BOOST_CHECK_EQUAL(3, const_ref.size());
	BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(const_ref.size()));
}
#endif

BOOST_AUTO_TEST_CASE(trait_box)
{
	//default constructor is available:
	Container<int>::box container;

	{
		//move construction is available:
		Container<int>::box container2 = Container<int>::make_box(std::vector<int>{});

		//move assignment is available:
		container = std::move(container2);

		BOOST_REQUIRE(container.original);
		BOOST_CHECK(!container2.original);
	}

	container.emplace_back(3);
	BOOST_CHECK(!container.empty());
	BOOST_CHECK_EQUAL(1u, container.size());
}

BOOST_AUTO_TEST_CASE(trait_eraser)
{
	//default constructor is available:
	Container<int>::eraser<std::vector<int>> container;

	{
		//move construction is available:
		Container<int>::eraser<std::vector<int>> container2 = Container<int>::erase(std::vector<int>{1, 2, 3});

		BOOST_CHECK_EQUAL(0, container.original.size());
		BOOST_CHECK_EQUAL(3, container2.original.size());

		//move assignment is available:
		container = std::move(container2);

		BOOST_CHECK_EQUAL(3, container.original.size());
		BOOST_CHECK_EQUAL(0, container2.original.size());
	}

	container.emplace_back(4);
	BOOST_CHECK(!container.empty());
	BOOST_CHECK_EQUAL(4, container.size());
}

template <class Signature>
struct Callable;

template <class Result, class A0>
SILICIUM_SPECIALIZED_TRAIT(
	Callable,
	<Result(A0)>,
	((operator(), (1, (A0)), Result))
)

BOOST_AUTO_TEST_CASE(trait_specialization)
{
	auto add_two = Callable<int(int)>::make_box([](int a) { return a + 2; });
	BOOST_CHECK_EQUAL(3, add_two(1));
}
<commit_msg>fix sign comparison warnings<commit_after>#include <boost/preprocessor.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/to_seq.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <silicium/to_unique.hpp>

#if SILICIUM_COMPILER_GENERATES_MOVES
#	define SILICIUM_MOVABLE_MEMBER(struct_name, member_name) \
	struct_name() = default; \
	SILICIUM_DEFAULT_MOVE(struct_name)
#else
#	define SILICIUM_MOVABLE_MEMBER(struct_name, member_name) \
	struct_name() : member_name() BOOST_NOEXCEPT {} \
	struct_name(struct_name &&other) BOOST_NOEXCEPT : member_name(std::move(other.member_name)) {} \
	struct_name &operator = (struct_name &&other) BOOST_NOEXCEPT { member_name = std::move(other.member_name); return *this; }
#endif

#define SILICIUM_DETAIL_MAKE_PARAMETER(z, n, array) BOOST_PP_COMMA_IF(n) BOOST_PP_ARRAY_ELEM(n, array) BOOST_PP_CAT(arg, n)
#define SILICIUM_DETAIL_MAKE_PARAMETERS(array) ( BOOST_PP_REPEAT(BOOST_PP_ARRAY_SIZE(array), SILICIUM_DETAIL_MAKE_PARAMETER, array) )

#define SILICIUM_DETAIL_MAKE_PURE_VIRTUAL_METHOD(r, data, elem) \
	virtual \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) \
	= 0;

#define SILICIUM_DETAIL_MAKE_INTERFACE(name, methods) struct name { \
	virtual ~name() {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_PURE_VIRTUAL_METHOD, _, methods) \
};

#define SILICIUM_DETAIL_ERASER_METHOD_ARGUMENT(z, n, text) , BOOST_PP_CAT(_, n)

#define SILICIUM_DETAIL_MAKE_ERASER_METHOD(r, data, elem) \
	virtual \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) \
	SILICIUM_OVERRIDE { \
		return original. BOOST_PP_TUPLE_ELEM(4, 0, elem) ( \
			BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_SIZE(BOOST_PP_TUPLE_ELEM(4, 1, elem)), arg) \
		); \
	}

#define SILICIUM_DETAIL_MAKE_BOX_METHOD(r, data, elem) \
	BOOST_PP_TUPLE_ELEM(4, 2, elem) \
	BOOST_PP_TUPLE_ELEM(4, 0, elem) \
	SILICIUM_DETAIL_MAKE_PARAMETERS(BOOST_PP_TUPLE_ELEM(4, 1, elem)) \
	BOOST_PP_TUPLE_ELEM(4, 3, elem) { \
		assert(original); \
		return original -> BOOST_PP_TUPLE_ELEM(4, 0, elem) ( \
			BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_SIZE(BOOST_PP_TUPLE_ELEM(4, 1, elem)), arg) \
		); \
	}

#define SILICIUM_DETAIL_MAKE_ERASER(name, methods) template <class Original> struct name : interface { \
	Original original; \
	SILICIUM_MOVABLE_MEMBER(name, original) \
	explicit name(Original original) : original(std::move(original)) {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_ERASER_METHOD, _, methods) \
};

#define SILICIUM_DETAIL_MAKE_BOX(name, methods) struct box { \
	std::unique_ptr<interface> original; \
	SILICIUM_MOVABLE_MEMBER(name, original) \
	explicit name(std::unique_ptr<interface> original) BOOST_NOEXCEPT : original(std::move(original)) {} \
	BOOST_PP_SEQ_FOR_EACH(SILICIUM_DETAIL_MAKE_BOX_METHOD, _, methods) \
};

#define SILICIUM_SPECIALIZED_TRAIT(name, specialization, methods) struct name specialization { \
	SILICIUM_DETAIL_MAKE_INTERFACE(interface, methods) \
	SILICIUM_DETAIL_MAKE_ERASER(eraser, methods) \
	SILICIUM_DETAIL_MAKE_BOX(box, methods) \
	template <class Original> \
	static eraser<typename std::decay<Original>::type> erase(Original &&original) { \
		return eraser<typename std::decay<Original>::type>{std::forward<Original>(original)}; \
	} \
	template <class Original> \
	static box make_box(Original &&original) { \
		return box{Si::to_unique(erase(std::forward<Original>(original)))}; \
	} \
};

#define SILICIUM_TRAIT(name, methods) SILICIUM_SPECIALIZED_TRAIT(name, , methods)

typedef long element;

SILICIUM_TRAIT(
	Producer,
	((get, (0, ()), element))
)

struct test_producer
{
	element get()
	{
		return 42;
	}
};

BOOST_AUTO_TEST_CASE(trivial_trait)
{
	std::unique_ptr<Producer::interface> p = Si::to_unique(Producer::erase(test_producer{}));
	BOOST_REQUIRE(p);
	BOOST_CHECK_EQUAL(42, p->get());
}

template <class T>
SILICIUM_TRAIT(
	Container,
	((emplace_back, (1, (T)), void))
	((resize, (1, (size_t)), void))
	((resize, (2, (size_t, T const &)), void))
	((empty, (0, ()), bool, const))
	((size, (0, ()), size_t, const BOOST_NOEXCEPT))
)

BOOST_AUTO_TEST_CASE(templatized_trait)
{
	auto container = Container<int>::erase(std::vector<int>{});
	container.emplace_back(123);
	{
		std::vector<int> const expected{123};
		BOOST_CHECK(expected == container.original);
	}
	container.resize(2);
	{
		std::vector<int> const expected{123, 0};
		BOOST_CHECK(expected == container.original);
	}
	container.resize(3, 7);
	{
		std::vector<int> const expected{123, 0, 7};
		BOOST_CHECK(expected == container.original);
	}
}

BOOST_AUTO_TEST_CASE(trait_const_method)
{
	auto container = Container<int>::erase(std::vector<int>{});
	auto const &const_ref = container;
	BOOST_CHECK(const_ref.empty());
	container.original.resize(1);
	BOOST_CHECK(!const_ref.empty());
}

#if SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT
BOOST_AUTO_TEST_CASE(trait_noexcept_method)
{
	auto container = Container<int>::erase(std::vector<int>{});
	auto const &const_ref = container;
	BOOST_CHECK_EQUAL(0, const_ref.size());
	container.original.resize(3);
	BOOST_CHECK_EQUAL(3, const_ref.size());
	BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(const_ref.size()));
}
#endif

BOOST_AUTO_TEST_CASE(trait_box)
{
	//default constructor is available:
	Container<int>::box container;

	{
		//move construction is available:
		Container<int>::box container2 = Container<int>::make_box(std::vector<int>{});

		//move assignment is available:
		container = std::move(container2);

		BOOST_REQUIRE(container.original);
		BOOST_CHECK(!container2.original);
	}

	container.emplace_back(3);
	BOOST_CHECK(!container.empty());
	BOOST_CHECK_EQUAL(1u, container.size());
}

BOOST_AUTO_TEST_CASE(trait_eraser)
{
	//default constructor is available:
	Container<int>::eraser<std::vector<int>> container;

	{
		//move construction is available:
		Container<int>::eraser<std::vector<int>> container2 = Container<int>::erase(std::vector<int>{1, 2, 3});

		BOOST_CHECK_EQUAL(0u, container.original.size());
		BOOST_CHECK_EQUAL(3u, container2.original.size());

		//move assignment is available:
		container = std::move(container2);

		BOOST_CHECK_EQUAL(3u, container.original.size());
		BOOST_CHECK_EQUAL(0u, container2.original.size());
	}

	container.emplace_back(4);
	BOOST_CHECK(!container.empty());
	BOOST_CHECK_EQUAL(4u, container.size());
}

template <class Signature>
struct Callable;

template <class Result, class A0>
SILICIUM_SPECIALIZED_TRAIT(
	Callable,
	<Result(A0)>,
	((operator(), (1, (A0)), Result))
)

BOOST_AUTO_TEST_CASE(trait_specialization)
{
	auto add_two = Callable<int(int)>::make_box([](int a) { return a + 2; });
	BOOST_CHECK_EQUAL(3, add_two(1));
}
<|endoftext|>


<commit_before>#include <map>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>

#include "boxer.h"
#include "stage.h"

#ifdef __ANDROID__
#include "jni.h"
#include <android/log.h>
#else
#include <pulse/simple.h>
#endif

extern int32_t _BOXER_FILES_SIZE;
extern char* _BOXER_FILES[];

int32_t cachedArgc = 0;
char argvStorage[1024];
char* cachedArgv[64];

namespace boxer
{

enum error: int32_t
{
    SUCCESS,
    FAILURE
};

stage* gStage = NULL;
int32_t gFrameDelay = 0;
std::map<int32_t, uint8_t*> gResourceMap;

struct audioParam
{
    int32_t id;
    int32_t delay;
    bool keepGoing;
};

pthread_mutex_t jAudioMutex;
audioParam* jAudioParam = NULL;

#define MAX_AUDIO_THREADS 16
pthread_t gAudioThread[MAX_AUDIO_THREADS];
audioParam gAudioThreadParam[MAX_AUDIO_THREADS];
int32_t gAudioThreadIndex = 0;

int32_t getArgc()
{
    return cachedArgc;
}

char** getArgv()
{
    return cachedArgv;
}

int32_t getFrameDelay()
{
    return gFrameDelay;
}

void setFrameDelay(int32_t ms)
{
    gFrameDelay = ms;
}

const uint8_t* getResource(int32_t id)
{
    auto found = gResourceMap.find(id);
    return found == gResourceMap.end() ? NULL: gResourceMap.find(id)->second;
}

void setStage(int32_t id)
{
    if(gStage != NULL)
    {
        gStage->~stage();
        free(gStage);
    }

    gStage = (stage*)malloc(sizeof(stage));
    gStage->init(id);
}

int32_t blockResource(int32_t id, int32_t x, int32_t y)
{
    int32_t code = FAILURE;

    if(gStage == NULL || (x > gStage->getWidth()) || (y > gStage->getHeight()))
        return code;

    const boxer::bmpStat* stat = (const boxer::bmpStat*)boxer::getResource(id);
    assert(stat != NULL);
    assert(stat->colorPlanes == 1);
    assert(stat->compression == 3); //BI_BITFIELDS

    if((x+stat->width) <= gStage->getWidth() && (y+stat->height) <= gStage->getHeight())
    {
        gStage->draw(boxer::getResource(id), x, y);
        code = SUCCESS;
    }

    return code;
}

void showStage()
{
    if(gStage != NULL)
    {
        gStage->show();
    }
    usleep(gFrameDelay*1000);
}

#define WAV_HEADER_SIZE 44
#ifdef __ANDROID__
#define AUDIO_BUFFER_SIZE 2048
#else
#define AUDIO_BUFFER_SIZE 1024
#endif
void* audioResourceThread(void* param)
{
    audioParam* desc = (audioParam*)param;
    while(true)
    {
#ifdef __ANDROID__
        pthread_mutex_lock(&jAudioMutex);
        while(jAudioParam != NULL && desc->keepGoing)
        {
            pthread_mutex_unlock(&jAudioMutex);
            sched_yield();
            pthread_mutex_lock(&jAudioMutex);
        }
        audioParam* jParam = new audioParam();
        jParam->id = desc->id;
        jParam->keepGoing = desc->keepGoing;
        jAudioParam = jParam;
        pthread_mutex_unlock(&jAudioMutex);
        while(jAudioParam != NULL && desc->keepGoing)
        {
            sched_yield();
        }
#else
        const boxer::wavStat* stat = (const boxer::wavStat*)boxer::getResource(desc->id);
        const uint8_t* data = (const uint8_t*)(boxer::getResource(desc->id) + WAV_HEADER_SIZE);
        static const pa_sample_spec spec = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 };
        pa_simple* stream = pa_simple_new(NULL, NULL, PA_STREAM_PLAYBACK, NULL, "boxer_track", &spec, NULL, NULL, NULL);
        if(stream != NULL)
        {
            int32_t i = 0;
            while((i+AUDIO_BUFFER_SIZE < stat->size) && desc->keepGoing)
            {
                if(pa_simple_write(stream, &data[i], AUDIO_BUFFER_SIZE, NULL) < 0)
                {
                    break;
                }
                i+=AUDIO_BUFFER_SIZE;
            }
            pa_simple_drain(stream, NULL);
            pa_simple_free(stream);
        }
#endif

        if(desc->keepGoing == false || desc->delay == -1)
            break;

        usleep(desc->delay*1000);
    }

    return NULL;
}

void startAudioResource(int32_t id, int32_t delay)
{
    waitAudioResource(id);
    gAudioThreadParam[gAudioThreadIndex].id = id;
    gAudioThreadParam[gAudioThreadIndex].delay = delay;
    gAudioThreadParam[gAudioThreadIndex].keepGoing = true;
    pthread_create(&gAudioThread[gAudioThreadIndex], NULL, audioResourceThread, &gAudioThreadParam[gAudioThreadIndex]);
    if(++gAudioThreadIndex == MAX_AUDIO_THREADS)
    {
        gAudioThreadIndex = 0;
    }
}

void stopAudioResource(int32_t id)
{
    int32_t i = MAX_AUDIO_THREADS;
    while(i--)
    {
        if(gAudioThreadParam[i].id == id)
        {
            gAudioThreadParam[i].keepGoing = false;
            pthread_mutex_lock(&jAudioMutex);
            if(jAudioParam != NULL && jAudioParam->id == id)
            {
                jAudioParam->keepGoing = false;
            }
            pthread_mutex_unlock(&jAudioMutex);
            waitAudioResource(id);
            break;
        }
    }
}

void waitAudioResource(int32_t id)
{
    int32_t i = MAX_AUDIO_THREADS;
    while(i--)
    {
        if(gAudioThreadParam[i].id == id)
        {
            pthread_join(gAudioThread[i], NULL);
            break;
        }
    }
}

struct _BUILDER
{
    _BUILDER()
    {
        pthread_mutex_init(&jAudioMutex, NULL);
    }
   ~_BUILDER()
    {
        int32_t count = 0;
        char buffer[PATH_MAX];
        while(count < _BOXER_FILES_SIZE)
        {
            free(gResourceMap.find(count++)->second);
        }
        if(gStage != NULL)
        {
            gStage->~stage();
            free(gStage);
        }
    }

};

static _BUILDER resourceBuilder;

}

void preload(const char* path)
{
    int32_t delay = 0;
#ifdef __ANDROID__
    delay = 48; //Empirical, but could be derived by checking CPU usage is less than max output of 2 threads
#else
    delay = 1000;
#endif

    boxer::setFrameDelay(delay);

    int32_t count = 0;
    char buffer[PATH_MAX];
    while(count < _BOXER_FILES_SIZE)
    {
        memset(buffer, '\0', PATH_MAX);
        memcpy(buffer, path, strlen(path));
        strcat(buffer, _BOXER_FILES[count]);
        FILE* temp = fopen(buffer, "r");
        if(temp)
        {
            fseek(temp, 0, SEEK_END);
            int32_t size = ftell(temp);
            rewind(temp);
            uint8_t* binary = (uint8_t*)malloc(size);
            size_t read = fread(binary, 1, size, temp);
            assert(read == size);
            boxer::gResourceMap.insert(std::pair<int32_t, uint8_t*>(count, binary));
            fclose(temp);
        }
        count++;
    }
}

int32_t main(int32_t argc, char** argv)
{
    cachedArgc = argc;
    char* storagePointer = argvStorage;
    while(argc--)
    {
        cachedArgv[argc] = storagePointer;
        int32_t length = strlen(argv[argc]);
        strcat(storagePointer, argv[argc]);
        storagePointer+=(length+1);
    }

    char buffer[PATH_MAX];
    memset(buffer, '\0', PATH_MAX);
    char* finalSlash = strrchr(cachedArgv[0], '/');
    memcpy(buffer, cachedArgv[0], (finalSlash - cachedArgv[0]) + 1);
    preload(buffer);
    boxerMain();

    return 0;
}

#ifdef __ANDROID__
JavaVM* jVM = NULL;
jclass jBoxerEngine = NULL;
jmethodID jShowStage = NULL;
char androidData[PATH_MAX];

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    jVM = vm;
    JNIEnv* env;
    if(vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
    {
        return -1;
    }

    return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_preload(JNIEnv* env, jobject obj, jstring pathString)
{
    const char* path = env->GetStringUTFChars(pathString, NULL);

    preload(path);

    memset(androidData, '\0', PATH_MAX);
    char* finalSlash = strrchr(path, '/');
    memcpy(androidData, path, (finalSlash - path) + 1);

    env->ReleaseStringUTFChars(pathString, path);
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_boxerMain(JNIEnv* env, jobject obj)
{
    jBoxerEngine = env->FindClass("org/starlo/boxer/BoxerEngine");
    jShowStage = env->GetStaticMethodID(jBoxerEngine, "showStage", "(Ljava/lang/String;)V");
    boxerMain();
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_audioResourceThread(JNIEnv* env, jobject obj)
{
    jclass engine = env->FindClass("org/starlo/boxer/BoxerEngine");
    jmethodID audioWrite = env->GetStaticMethodID(engine, "audioWrite", "([S)V");
    while(true)
    {
        if(boxer::jAudioParam != NULL)
        {
            int32_t i = 0;
            const boxer::wavStat* stat = (const boxer::wavStat*)boxer::getResource(boxer::jAudioParam->id);
            const uint8_t* data = (const uint8_t*)(boxer::getResource(boxer::jAudioParam->id) + WAV_HEADER_SIZE);
            jshortArray jData = env->NewShortArray(AUDIO_BUFFER_SIZE);
            while(i+AUDIO_BUFFER_SIZE < stat->size && boxer::jAudioParam->keepGoing)
            {
                env->SetShortArrayRegion(jData, 0, AUDIO_BUFFER_SIZE, (const short*)&data[i]);
                env->CallStaticVoidMethod(engine, audioWrite, jData);
                i+=AUDIO_BUFFER_SIZE;
            }
            env->DeleteLocalRef(jData);
            pthread_mutex_lock(&boxer::jAudioMutex);
            delete boxer::jAudioParam;
            boxer::jAudioParam = NULL;
            pthread_mutex_unlock(&boxer::jAudioMutex);
        }
        sched_yield();
    }
}

#endif
<commit_msg>Fix playback issue on Android<commit_after>#include <map>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>

#include "boxer.h"
#include "stage.h"

#ifdef __ANDROID__
#include "jni.h"
#include <android/log.h>
#else
#include <pulse/simple.h>
#endif

extern int32_t _BOXER_FILES_SIZE;
extern char* _BOXER_FILES[];

int32_t cachedArgc = 0;
char argvStorage[1024];
char* cachedArgv[64];

namespace boxer
{

enum error: int32_t
{
    SUCCESS,
    FAILURE
};

stage* gStage = NULL;
int32_t gFrameDelay = 0;
std::map<int32_t, uint8_t*> gResourceMap;

struct audioParam
{
    int32_t id;
    int32_t delay;
    bool keepGoing;
};

pthread_mutex_t jAudioMutex;
audioParam* jAudioParam = NULL;

#define MAX_AUDIO_THREADS 16
pthread_t gAudioThread[MAX_AUDIO_THREADS];
audioParam gAudioThreadParam[MAX_AUDIO_THREADS];
int32_t gAudioThreadIndex = 0;

int32_t getArgc()
{
    return cachedArgc;
}

char** getArgv()
{
    return cachedArgv;
}

int32_t getFrameDelay()
{
    return gFrameDelay;
}

void setFrameDelay(int32_t ms)
{
    gFrameDelay = ms;
}

const uint8_t* getResource(int32_t id)
{
    auto found = gResourceMap.find(id);
    return found == gResourceMap.end() ? NULL: gResourceMap.find(id)->second;
}

void setStage(int32_t id)
{
    if(gStage != NULL)
    {
        gStage->~stage();
        free(gStage);
    }

    gStage = (stage*)malloc(sizeof(stage));
    gStage->init(id);
}

int32_t blockResource(int32_t id, int32_t x, int32_t y)
{
    int32_t code = FAILURE;

    if(gStage == NULL || (x > gStage->getWidth()) || (y > gStage->getHeight()))
        return code;

    const boxer::bmpStat* stat = (const boxer::bmpStat*)boxer::getResource(id);
    assert(stat != NULL);
    assert(stat->colorPlanes == 1);
    assert(stat->compression == 3); //BI_BITFIELDS

    if((x+stat->width) <= gStage->getWidth() && (y+stat->height) <= gStage->getHeight())
    {
        gStage->draw(boxer::getResource(id), x, y);
        code = SUCCESS;
    }

    return code;
}

void showStage()
{
    if(gStage != NULL)
    {
        gStage->show();
    }
    usleep(gFrameDelay*1000);
}

#define WAV_HEADER_SIZE 44
#define AUDIO_BUFFER_SIZE 1024
void* audioResourceThread(void* param)
{
    audioParam* desc = (audioParam*)param;
    while(true)
    {
#ifdef __ANDROID__
        pthread_mutex_lock(&jAudioMutex);
        while(jAudioParam != NULL && desc->keepGoing)
        {
            pthread_mutex_unlock(&jAudioMutex);
            sched_yield();
            pthread_mutex_lock(&jAudioMutex);
        }
        audioParam* jParam = new audioParam();
        jParam->id = desc->id;
        jParam->keepGoing = desc->keepGoing;
        jAudioParam = jParam;
        pthread_mutex_unlock(&jAudioMutex);
        while(jAudioParam != NULL && desc->keepGoing)
        {
            sched_yield();
        }
#else
        const boxer::wavStat* stat = (const boxer::wavStat*)boxer::getResource(desc->id);
        const uint8_t* data = (const uint8_t*)(boxer::getResource(desc->id) + WAV_HEADER_SIZE);
        static const pa_sample_spec spec = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 };
        pa_simple* stream = pa_simple_new(NULL, NULL, PA_STREAM_PLAYBACK, NULL, "boxer_track", &spec, NULL, NULL, NULL);
        if(stream != NULL)
        {
            int32_t i = 0;
            while((i+AUDIO_BUFFER_SIZE < stat->size) && desc->keepGoing)
            {
                if(pa_simple_write(stream, &data[i], AUDIO_BUFFER_SIZE, NULL) < 0)
                {
                    break;
                }
                i+=AUDIO_BUFFER_SIZE;
            }
            pa_simple_drain(stream, NULL);
            pa_simple_free(stream);
        }
#endif

        if(desc->keepGoing == false || desc->delay == -1)
            break;

        usleep(desc->delay*1000);
    }

    return NULL;
}

void startAudioResource(int32_t id, int32_t delay)
{
    waitAudioResource(id);
    gAudioThreadParam[gAudioThreadIndex].id = id;
    gAudioThreadParam[gAudioThreadIndex].delay = delay;
    gAudioThreadParam[gAudioThreadIndex].keepGoing = true;
    pthread_create(&gAudioThread[gAudioThreadIndex], NULL, audioResourceThread, &gAudioThreadParam[gAudioThreadIndex]);
    if(++gAudioThreadIndex == MAX_AUDIO_THREADS)
    {
        gAudioThreadIndex = 0;
    }
}

void stopAudioResource(int32_t id)
{
    int32_t i = MAX_AUDIO_THREADS;
    while(i--)
    {
        if(gAudioThreadParam[i].id == id)
        {
            gAudioThreadParam[i].keepGoing = false;
            pthread_mutex_lock(&jAudioMutex);
            if(jAudioParam != NULL && jAudioParam->id == id)
            {
                jAudioParam->keepGoing = false;
            }
            pthread_mutex_unlock(&jAudioMutex);
            waitAudioResource(id);
            break;
        }
    }
}

void waitAudioResource(int32_t id)
{
    int32_t i = MAX_AUDIO_THREADS;
    while(i--)
    {
        if(gAudioThreadParam[i].id == id)
        {
            pthread_join(gAudioThread[i], NULL);
            break;
        }
    }
}

struct _BUILDER
{
    _BUILDER()
    {
        pthread_mutex_init(&jAudioMutex, NULL);
    }
   ~_BUILDER()
    {
        int32_t count = 0;
        char buffer[PATH_MAX];
        while(count < _BOXER_FILES_SIZE)
        {
            free(gResourceMap.find(count++)->second);
        }
        if(gStage != NULL)
        {
            gStage->~stage();
            free(gStage);
        }
    }

};

static _BUILDER resourceBuilder;

}

void preload(const char* path)
{
    int32_t delay = 0;
#ifdef __ANDROID__
    delay = 48; //Empirical, but could be derived by checking CPU usage is less than max output of 2 threads
#else
    delay = 1000;
#endif

    boxer::setFrameDelay(delay);

    int32_t count = 0;
    char buffer[PATH_MAX];
    while(count < _BOXER_FILES_SIZE)
    {
        memset(buffer, '\0', PATH_MAX);
        memcpy(buffer, path, strlen(path));
        strcat(buffer, _BOXER_FILES[count]);
        FILE* temp = fopen(buffer, "r");
        if(temp)
        {
            fseek(temp, 0, SEEK_END);
            int32_t size = ftell(temp);
            rewind(temp);
            uint8_t* binary = (uint8_t*)malloc(size);
            size_t read = fread(binary, 1, size, temp);
            assert(read == size);
            boxer::gResourceMap.insert(std::pair<int32_t, uint8_t*>(count, binary));
            fclose(temp);
        }
        count++;
    }
}

int32_t main(int32_t argc, char** argv)
{
    cachedArgc = argc;
    char* storagePointer = argvStorage;
    while(argc--)
    {
        cachedArgv[argc] = storagePointer;
        int32_t length = strlen(argv[argc]);
        strcat(storagePointer, argv[argc]);
        storagePointer+=(length+1);
    }

    char buffer[PATH_MAX];
    memset(buffer, '\0', PATH_MAX);
    char* finalSlash = strrchr(cachedArgv[0], '/');
    memcpy(buffer, cachedArgv[0], (finalSlash - cachedArgv[0]) + 1);
    preload(buffer);
    boxerMain();

    return 0;
}

#ifdef __ANDROID__
JavaVM* jVM = NULL;
jclass jBoxerEngine = NULL;
jmethodID jShowStage = NULL;
char androidData[PATH_MAX];

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    jVM = vm;
    JNIEnv* env;
    if(vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
    {
        return -1;
    }

    return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_preload(JNIEnv* env, jobject obj, jstring pathString)
{
    const char* path = env->GetStringUTFChars(pathString, NULL);

    preload(path);

    memset(androidData, '\0', PATH_MAX);
    char* finalSlash = strrchr(path, '/');
    memcpy(androidData, path, (finalSlash - path) + 1);

    env->ReleaseStringUTFChars(pathString, path);
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_boxerMain(JNIEnv* env, jobject obj)
{
    jBoxerEngine = env->FindClass("org/starlo/boxer/BoxerEngine");
    jShowStage = env->GetStaticMethodID(jBoxerEngine, "showStage", "(Ljava/lang/String;)V");
    boxerMain();
}

extern "C" JNIEXPORT void JNICALL Java_org_starlo_boxer_BoxerEngine_audioResourceThread(JNIEnv* env, jobject obj)
{
    jclass engine = env->FindClass("org/starlo/boxer/BoxerEngine");
    jmethodID audioWrite = env->GetStaticMethodID(engine, "audioWrite", "([S)V");
    while(true)
    {
        if(boxer::jAudioParam != NULL)
        {
            int32_t i = 0;
            const boxer::wavStat* stat = (const boxer::wavStat*)boxer::getResource(boxer::jAudioParam->id);
            const uint8_t* data = (const uint8_t*)(boxer::getResource(boxer::jAudioParam->id) + WAV_HEADER_SIZE);
            jshortArray jData = env->NewShortArray(AUDIO_BUFFER_SIZE/sizeof(short));
            while(i+AUDIO_BUFFER_SIZE < stat->size && boxer::jAudioParam->keepGoing)
            {
                env->SetShortArrayRegion(jData, 0, AUDIO_BUFFER_SIZE/sizeof(short), (const short*)&data[i]);
                env->CallStaticVoidMethod(engine, audioWrite, jData);
                i+=AUDIO_BUFFER_SIZE;
            }
            env->DeleteLocalRef(jData);
            pthread_mutex_lock(&boxer::jAudioMutex);
            delete boxer::jAudioParam;
            boxer::jAudioParam = NULL;
            pthread_mutex_unlock(&boxer::jAudioMutex);
        }
        sched_yield();
    }
}

#endif
<|endoftext|>


<commit_before>#include "BinaryTree.hpp"
#include <fstream>
#include <catch.hpp>

SCENARIO("default constructor")
{
	Tree<int> node;
	REQUIRE(node.root_() == nullptr);
}

SCENARIO("insert")
{
	Tree<int> tree;
	int newEl;
	tree.fIn("Tree.txt");
	std::ifstream("newEl.txt") >> newEl;
	tree.insert(newEl);
	REQUIRE(tree.right_() == 7);
}

SCENARIO("search")
{
	Tree<int> tree;
	Node<int> * node;
	tree.fIn("Tree+newEl.txt");
	node = tree.search(5);
	REQUIRE(tree.x_() == 5);
	REQUIRE(tree.left_() == 3);
	REQUIRE(tree.right_() == 7);
}

SCENARIO("fIn")
{
	Tree<int> tree;
	tree.fIn("Tree.txt");
	REQUIRE(tree.x_() == 5);
}
<commit_msg>Update init.cpp<commit_after>#include "BinaryTree.hpp"
#include <catch.hpp>

SCENARIO("default constructor")
{
	Tree<int> node;
	REQUIRE(node.root_() == nullptr);
}

SCENARIO("insert")
{
	Tree<int> tree;
	int newEl;
	tree.fIn("Tree.txt");
	std::ifstream("newEl.txt") >> newEl;
	tree.insert(newEl);
	REQUIRE(tree.right_() == 7);
}

SCENARIO("search")
{
	Tree<int> tree;
	Node<int> * node;
	tree.fIn("Tree+newEl.txt");
	node = tree.search(5);
	REQUIRE(tree.x_() == 5);
	REQUIRE(tree.left_() == 3);
	REQUIRE(tree.right_() == 7);
}

SCENARIO("fIn")
{
	Tree<int> tree;
	tree.fIn("Tree.txt");
	REQUIRE(tree.x_() == 5);
}
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

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

    Vc 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 Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <iostream>

using namespace Vc;

template<typename Vec> void checkAlignment()
{
    unsigned char i = 1;
    Vec a[10];
    unsigned long mask = VectorAlignment - 1;
    if (Vec::Size == 1 && sizeof(typename Vec::EntryType) != VectorAlignment) {
        mask = sizeof(typename Vec::EntryType) - 1;
    }
    for (i = 0; i < 10; ++i) {
        VERIFY((reinterpret_cast<unsigned long>(&a[i]) & mask) == 0);
    }
    const char *data = reinterpret_cast<const char *>(&a[0]);
    for (i = 0; i < 10; ++i) {
        VERIFY(&data[i * Vec::Size * sizeof(typename Vec::EntryType)] == reinterpret_cast<const char *>(&a[i]));
    }
}

template<typename Vec> void loadArray()
{
    typedef typename Vec::EntryType T;
    typedef typename Vec::IndexType I;

    const int count = 256 * 1024 / sizeof(T);
    T array[count];
    for (int i = 0; i < count; ++i) {
        array[i] = i;
    }

    const I indexesFromZero(IndexesFromZero);

    const Vec offsets(indexesFromZero);
    for (int i = 0; i < count; i += Vec::Size) {
        const T *const addr = &array[i];
        Vec ii(i);
        ii += offsets;

        Vec a(addr);
        COMPARE(a, ii);

        Vec b = Vec::Zero();
        b.load(addr);
        COMPARE(b, ii);
    }
}

template<typename Vec> void loadArrayShort()
{
    typedef typename Vec::EntryType T;

    const int count = 32 * 1024;
    T array[count];
    for (int i = 0; i < count; ++i) {
        array[i] = i;
    }

    const Vec &offsets = static_cast<Vec>(ushort_v::IndexesFromZero());
    for (int i = 0; i < count; i += Vec::Size) {
        const T *const addr = &array[i];
        Vec ii(i);
        ii += offsets;

        Vec a(addr);
        COMPARE(a, ii);

        Vec b = Vec::Zero();
        b.load(addr);
        COMPARE(b, ii);
    }
}

int main()
{
#if !VC_IMPL_LRBni && !defined(__LRB__)
    runTest(checkAlignment<int_v>);
    runTest(checkAlignment<uint_v>);
    runTest(checkAlignment<float_v>);
    runTest(checkAlignment<double_v>);
    runTest(checkAlignment<short_v>);
    runTest(checkAlignment<ushort_v>);
    runTest(checkAlignment<sfloat_v>);
#endif
    runTest(loadArray<int_v>);
    runTest(loadArray<uint_v>);
    runTest(loadArray<float_v>);
    runTest(loadArray<double_v>);
    runTest(loadArray<sfloat_v>);
    runTest(loadArrayShort<short_v>);
    runTest(loadArrayShort<ushort_v>);
    return 0;
}
<commit_msg>checkAlignment needs a special case for AVX (u)short_v<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

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

    Vc 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 Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "unittest.h"
#include <iostream>

using namespace Vc;

template<typename Vec> void checkAlignment()
{
    unsigned char i = 1;
    Vec a[10];
    unsigned long mask = VectorAlignment - 1;
    if (Vec::Size == 1 && sizeof(typename Vec::EntryType) != VectorAlignment) {
        mask = sizeof(typename Vec::EntryType) - 1;
    }
#ifdef VC_IMPL_AVX
    if (sizeof(typename Vec::EntryType) == 2) {
        mask = sizeof(Vec) - 1;
    }
#endif
    for (i = 0; i < 10; ++i) {
        VERIFY((reinterpret_cast<unsigned long>(&a[i]) & mask) == 0);
    }
    const char *data = reinterpret_cast<const char *>(&a[0]);
    for (i = 0; i < 10; ++i) {
        VERIFY(&data[i * Vec::Size * sizeof(typename Vec::EntryType)] == reinterpret_cast<const char *>(&a[i]));
    }
}

template<typename Vec> void loadArray()
{
    typedef typename Vec::EntryType T;
    typedef typename Vec::IndexType I;

    const int count = 256 * 1024 / sizeof(T);
    T array[count];
    for (int i = 0; i < count; ++i) {
        array[i] = i;
    }

    const I indexesFromZero(IndexesFromZero);

    const Vec offsets(indexesFromZero);
    for (int i = 0; i < count; i += Vec::Size) {
        const T *const addr = &array[i];
        Vec ii(i);
        ii += offsets;

        Vec a(addr);
        COMPARE(a, ii);

        Vec b = Vec::Zero();
        b.load(addr);
        COMPARE(b, ii);
    }
}

template<typename Vec> void loadArrayShort()
{
    typedef typename Vec::EntryType T;

    const int count = 32 * 1024;
    T array[count];
    for (int i = 0; i < count; ++i) {
        array[i] = i;
    }

    const Vec &offsets = static_cast<Vec>(ushort_v::IndexesFromZero());
    for (int i = 0; i < count; i += Vec::Size) {
        const T *const addr = &array[i];
        Vec ii(i);
        ii += offsets;

        Vec a(addr);
        COMPARE(a, ii);

        Vec b = Vec::Zero();
        b.load(addr);
        COMPARE(b, ii);
    }
}

int main()
{
#if !VC_IMPL_LRBni && !defined(__LRB__)
    runTest(checkAlignment<int_v>);
    runTest(checkAlignment<uint_v>);
    runTest(checkAlignment<float_v>);
    runTest(checkAlignment<double_v>);
    runTest(checkAlignment<short_v>);
    runTest(checkAlignment<ushort_v>);
    runTest(checkAlignment<sfloat_v>);
#endif
    runTest(loadArray<int_v>);
    runTest(loadArray<uint_v>);
    runTest(loadArray<float_v>);
    runTest(loadArray<double_v>);
    runTest(loadArray<sfloat_v>);
    runTest(loadArrayShort<short_v>);
    runTest(loadArrayShort<ushort_v>);
    return 0;
}
<|endoftext|>


<commit_before>#include "pch.h"

#include "LibFractal.h"

TEST(TestCaseName, CallExportedFunction) {
  EXPECT_EQ(1, 1);
  EXPECT_TRUE(true);
  EXPECT_EQ(2, functionToTest(1));
}

TEST(BasicTests, RunBenchMark) {
	EXPECT_EQ(0, runBenchmark(0, NULL));
}<commit_msg>test tweaks<commit_after>#include "pch.h"

#include "LibFractal.h"

TEST(BasicTests, CallExportedFunction) {
  EXPECT_EQ(2, functionToTest(1));
}

TEST(BasicTests, RunBenchMark) {
	EXPECT_EQ(0, runBenchmark(0, NULL));
}<|endoftext|>


<commit_before>#include "quadrature/angular/angular_quadrature_scalar.h"

#include "quadrature/angular/angular_quadrature_types.h"
#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

template <typename DimensionWrapper>
class AngularQuadratureScalarTests : public ::testing::Test {
 protected:
  static constexpr int dim = DimensionWrapper::value;
  // Tested object
  quadrature::angular::AngularQuadratureScalar<dim> test_scalar_quad_;
};

TYPED_TEST_CASE(AngularQuadratureScalarTests, bart::testing::AllDimensions);

TYPED_TEST(AngularQuadratureScalarTests, Constructor) {
  auto& test_scalar_quad_ = this->test_scalar_quad_;
  auto dim = this->dim;
  EXPECT_EQ(test_scalar_quad_.total_quadrature_points(), 1);
}

} // namespace<commit_msg>added test for quadrature points to tests for AngularQuadratureScalar<commit_after>#include "quadrature/angular/angular_quadrature_scalar.h"

#include <array>
#include <vector>

#include "quadrature/angular/angular_quadrature_types.h"
#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

using ::testing::ContainerEq;

template <typename DimensionWrapper>
class AngularQuadratureScalarTests : public ::testing::Test {
 protected:
  static constexpr int dim = DimensionWrapper::value;
  // Tested object
  quadrature::angular::AngularQuadratureScalar<dim> test_scalar_quad_;
};

TYPED_TEST_CASE(AngularQuadratureScalarTests, bart::testing::AllDimensions);

TYPED_TEST(AngularQuadratureScalarTests, Constructor) {
  auto& test_scalar_quad_ = this->test_scalar_quad_;
  constexpr int dim = this->dim;
  using QuadraturePoint = quadrature::angular::QuadraturePoint<dim>;
  using Ordinate = quadrature::angular::Ordinate<dim>;

  EXPECT_EQ(test_scalar_quad_.total_quadrature_points(), 1);

  Ordinate zero_ordinate;

  for (auto& angle_coordinate : zero_ordinate)
    angle_coordinate = 0;

  std::vector<QuadraturePoint> expected_quadrature_points{{1.0, zero_ordinate}};

  EXPECT_THAT(test_scalar_quad_.quadrature_points(),
              ContainerEq(expected_quadrature_points));
}

} // namespace<|endoftext|>