<commit_before>#pragma once
// generic (non-architecture-specific) implementations of gemmBitserial
// and other related functions

static GEMMContext allocGEMMContext_generic(
  uint64_t lhsRows, uint64_t depth, uint64_t rhsRows,
  uint64_t lhsBits, uint64_t rhsBits,
  bool lhsSigned, bool rhsSigned
) {
  const uint64_t regblock_lhs = 2;
  const uint64_t regblock_d = 1;
  const uint64_t regblock_rhs = 2;
  const uint64_t cacheBits = 32*1024*8;

  return allocGEMMContext_base(
    lhsRows, depth, rhsRows, lhsBits, rhsBits, lhsSigned, rhsSigned,
    regblock_lhs, regblock_d, regblock_rhs, cacheBits
  );
};

/* Multiply a lhs_block x rhs_block chunk of the given matrices, starting at
  (bA, bBT) using 2x1x2 register tiling. For internal use.
*/
inline void gemmBinary_generic_chunk_tile2x1x2(
  uint64_t * A, uint64_t * BT, int32_t * CT,
  int32_t alpha,
  uint64_t rowsA, uint64_t depth_words, uint64_t rowsBT,
  uint64_t bA, uint64_t bBT,
  uint64_t lhs_block, uint64_t rhs_block,
  uint64_t rowsA_orig, uint64_t rowsBT_orig) {
  const uint64_t Atile = 2, DepthTile = 1, BTtile = 2;
  const size_t num_acc = Atile*BTtile;

  for(uint64_t rBT = bBT; rBT < bBT + rhs_block; rBT += BTtile) {
    uint64_t * BTptr = &BT[rBT * depth_words];
    for(uint64_t rA = bA; rA < bA + lhs_block; rA += Atile) {
      uint64_t * Aptr = &A[rA * depth_words];
      int32_t acc[num_acc] = {0};
      for(uint64_t d = 0; d < depth_words; d += DepthTile) {
        const uint64_t a0 = Aptr[d], a1 = Aptr[d + depth_words];
        const uint64_t b0 = BTptr[d], b1 = BTptr[d + depth_words];
        acc[0] += __builtin_popcountll(a0 & b0);
        acc[1] += __builtin_popcountll(a0 & b1);
        acc[2] += __builtin_popcountll(a1 & b0);
        acc[3] += __builtin_popcountll(a1 & b1);
      }
      for(uint64_t at = 0; at < Atile; at++) {
        for(uint64_t bt = 0; bt < BTtile; bt++) {
          if(((rBT + bt) < rowsBT_orig) && ((rA + at) < rowsA_orig)) {
            CT[(rBT + bt) * rowsA_orig + (rA + at)] += acc[at * BTtile + bt] * alpha;
          }
        }
      }
    }
  }
}

/* CT = A * BT using cache blocking and 2x1x2 register blocking where possible.
   For internal use.
*/
static void gemmBinary_generic_L1_tile2x1x2(
  uint64_t * A, uint64_t * BT, int32_t * CT, int32_t alpha,
  uint64_t rowsA, uint64_t depth_words, uint64_t rowsBT,
  uint64_t rowsA_orig, uint64_t rowsBT_orig,
  uint64_t lhsBlock, uint64_t rhsBlock
  ) {
  const uint64_t Atile = 2, DepthTile = 1, BTtile = 2;
  assert(rowsBT % rhsBlock == 0);
  assert(rowsA % lhsBlock == 0);
  assert(lhsBlock % Atile == 0);
  assert(rhsBlock % BTtile == 0);

  for(uint64_t bBT = 0; bBT < rowsBT; bBT += rhsBlock) {
    for(uint64_t bA = 0; bA < rowsA; bA += lhsBlock) {
      gemmBinary_generic_chunk_tile2x1x2(
        A, BT, CT, alpha, rowsA, depth_words, rowsBT, bA, bBT,
        lhsBlock, rhsBlock, rowsA_orig, rowsBT_orig
      );
    }
  }
}

/* Bit-serial GEMM via a series of calls to gemmBinary.
   Note that rhs must be given in transposed form, and the result is also
   produced transposed.
*/

static void gemmBitSerial_generic_usingBinary(GEMMContext ctx) {
  // ensure that matrix shapes are compatible
  assert(ctx.lhs.ncols == ctx.rhs.ncols);
  const uint64_t lhsbits = ctx.lhs.nbits;
  const uint64_t rhsbits = ctx.rhs.nbits;
  // clear contents of result matrix by setting everything to zero
  memset(ctx.res, 0, ctx.lhs.nrows*ctx.rhs.nrows*sizeof(int32_t));
  // call binary GEMM for each bit position
  for(uint64_t lbit = 0; lbit < lhsbits; lbit++) {
    bool neg_lhs = ctx.lhs.issigned && (lbit == lhsbits-1);
    for(uint64_t rbit = 0; rbit < rhsbits; rbit++) {
      bool neg_rhs = ctx.rhs.issigned && (rbit == rhsbits-1);
      bool neg = neg_rhs ^ neg_lhs;
      int32_t alpha = neg ? -(1 << (lbit+rbit)) : (1 << (lbit+rbit));
      gemmBinary_generic_L1_tile2x1x2(
        ctx.lhs.bitplaneptr(lbit), ctx.rhs.bitplaneptr(rbit), ctx.res, alpha,
        ctx.lhs.nrows_a, ctx.lhs.wordsPerRow(), ctx.rhs.nrows_a,
        ctx.lhs.nrows, ctx.rhs.nrows, ctx.lhsBlock, ctx.rhsBlock
      );
    }
  }
}
<commit_msg>bring back naive gemmBitSerial, useful for verification<commit_after>#pragma once
// generic (non-architecture-specific) implementations of gemmBitserial
// and other related functions

static GEMMContext allocGEMMContext_generic(
  uint64_t lhsRows, uint64_t depth, uint64_t rhsRows,
  uint64_t lhsBits, uint64_t rhsBits,
  bool lhsSigned, bool rhsSigned
) {
  const uint64_t regblock_lhs = 2;
  const uint64_t regblock_d = 1;
  const uint64_t regblock_rhs = 2;
  const uint64_t cacheBits = 32*1024*8;

  return allocGEMMContext_base(
    lhsRows, depth, rhsRows, lhsBits, rhsBits, lhsSigned, rhsSigned,
    regblock_lhs, regblock_d, regblock_rhs, cacheBits
  );
};

/* Multiply a lhs_block x rhs_block chunk of the given matrices, starting at
  (bA, bBT) using 2x1x2 register tiling. For internal use.
*/
inline void gemmBinary_generic_chunk_tile2x1x2(
  uint64_t * A, uint64_t * BT, int32_t * CT,
  int32_t alpha,
  uint64_t rowsA, uint64_t depth_words, uint64_t rowsBT,
  uint64_t bA, uint64_t bBT,
  uint64_t lhs_block, uint64_t rhs_block,
  uint64_t rowsA_orig, uint64_t rowsBT_orig) {
  const uint64_t Atile = 2, DepthTile = 1, BTtile = 2;
  const size_t num_acc = Atile*BTtile;

  for(uint64_t rBT = bBT; rBT < bBT + rhs_block; rBT += BTtile) {
    uint64_t * BTptr = &BT[rBT * depth_words];
    for(uint64_t rA = bA; rA < bA + lhs_block; rA += Atile) {
      uint64_t * Aptr = &A[rA * depth_words];
      int32_t acc[num_acc] = {0};
      for(uint64_t d = 0; d < depth_words; d += DepthTile) {
        const uint64_t a0 = Aptr[d], a1 = Aptr[d + depth_words];
        const uint64_t b0 = BTptr[d], b1 = BTptr[d + depth_words];
        acc[0] += __builtin_popcountll(a0 & b0);
        acc[1] += __builtin_popcountll(a0 & b1);
        acc[2] += __builtin_popcountll(a1 & b0);
        acc[3] += __builtin_popcountll(a1 & b1);
      }
      for(uint64_t at = 0; at < Atile; at++) {
        for(uint64_t bt = 0; bt < BTtile; bt++) {
          if(((rBT + bt) < rowsBT_orig) && ((rA + at) < rowsA_orig)) {
            CT[(rBT + bt) * rowsA_orig + (rA + at)] += acc[at * BTtile + bt] * alpha;
          }
        }
      }
    }
  }
}

/* CT = A * BT using cache blocking and 2x1x2 register blocking where possible.
   For internal use.
*/
static void gemmBinary_generic_L1_tile2x1x2(
  uint64_t * A, uint64_t * BT, int32_t * CT, int32_t alpha,
  uint64_t rowsA, uint64_t depth_words, uint64_t rowsBT,
  uint64_t rowsA_orig, uint64_t rowsBT_orig,
  uint64_t lhsBlock, uint64_t rhsBlock
  ) {
  const uint64_t Atile = 2, DepthTile = 1, BTtile = 2;
  assert(rowsBT % rhsBlock == 0);
  assert(rowsA % lhsBlock == 0);
  assert(lhsBlock % Atile == 0);
  assert(rhsBlock % BTtile == 0);

  for(uint64_t bBT = 0; bBT < rowsBT; bBT += rhsBlock) {
    for(uint64_t bA = 0; bA < rowsA; bA += lhsBlock) {
      gemmBinary_generic_chunk_tile2x1x2(
        A, BT, CT, alpha, rowsA, depth_words, rowsBT, bA, bBT,
        lhsBlock, rhsBlock, rowsA_orig, rowsBT_orig
      );
    }
  }
}

/* Bit-serial GEMM via a series of calls to gemmBinary.
   Note that rhs must be given in transposed form, and the result is also
   produced transposed.
*/
static void gemmBitSerial_generic_usingBinary(GEMMContext ctx) {
  // ensure that matrix shapes are compatible
  assert(ctx.lhs.ncols == ctx.rhs.ncols);
  const uint64_t lhsbits = ctx.lhs.nbits;
  const uint64_t rhsbits = ctx.rhs.nbits;
  // clear contents of result matrix by setting everything to zero
  memset(ctx.res, 0, ctx.lhs.nrows*ctx.rhs.nrows*sizeof(int32_t));
  // call binary GEMM for each bit position
  for(uint64_t lbit = 0; lbit < lhsbits; lbit++) {
    bool neg_lhs = ctx.lhs.issigned && (lbit == lhsbits-1);
    for(uint64_t rbit = 0; rbit < rhsbits; rbit++) {
      bool neg_rhs = ctx.rhs.issigned && (rbit == rhsbits-1);
      bool neg = neg_rhs ^ neg_lhs;
      int32_t alpha = neg ? -(1 << (lbit+rbit)) : (1 << (lbit+rbit));
      gemmBinary_generic_L1_tile2x1x2(
        ctx.lhs.bitplaneptr(lbit), ctx.rhs.bitplaneptr(rbit), ctx.res, alpha,
        ctx.lhs.nrows_a, ctx.lhs.wordsPerRow(), ctx.rhs.nrows_a,
        ctx.lhs.nrows, ctx.rhs.nrows, ctx.lhsBlock, ctx.rhsBlock
      );
    }
  }
}

/* Standalone bit-serial GEMM. Note that rhs must be given in transposed
   form, and the result is also produced transposed.
*/
static void gemmBitSerial_generic_naive(GEMMContext ctx) {
  // ensure that matrix shapes are compatible
  assert(ctx.lhs.ncols == ctx.rhs.ncols);
  const uint64_t lhsbits = ctx.lhs.nbits;
  const uint64_t rhsbits = ctx.rhs.nbits;
  const uint64_t out_rows = ctx.lhs.nrows;
  const uint64_t out_cols = ctx.rhs.nrows;
  const uint64_t depth = ctx.lhs.wordsPerRow();

  for(uint64_t i = 0; i < out_cols; i++) {
    for(uint64_t j = 0; j < out_rows; j++) {
      int32_t rowres = 0;
      for(uint64_t lbit = 0; lbit < lhsbits; lbit++) {
        bool neg_lhs = ctx.lhs.issigned && (lbit == lhsbits-1);
        for(uint64_t rbit = 0; rbit < rhsbits; rbit++) {
          bool neg_rhs = ctx.rhs.issigned && (rbit == rhsbits-1);
          uint64_t * ldata = ctx.lhs.rowptr(lbit, j);
          uint64_t * rdata = ctx.rhs.rowptr(rbit, i);
          uint64_t andcard = 0;
          // AND-popcount-accumulate over row pair
          for(uint64_t k = 0; k < depth; k++) {
            andcard += __builtin_popcountll(ldata[k] & rdata[k]);
          }
          // scale
          andcard = andcard << (lbit + rbit);
          // negate if needed
          rowres += (neg_lhs ^ neg_rhs) ? -andcard : andcard;
        }
      }
      ctx.res[i * ctx.lhs.nrows + j] = rowres;
    }
  }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDashedStreamLine.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDashedStreamLine - generate constant-time dashed streamline in arbitrary dataset
// .SECTION Description
// vtkDashedStreamLine is a filter that generates a "dashed" streamline for
// an arbitrary dataset. The streamline consists of a series of dashes, each
// of which represents (approximately) a constant time increment. Thus in the
// resulting visual representation, relatively long dashes represent areas of
// high velocity, and small dashes represent areas of low velocity.
//
// vtkDashedStreamLine introduces the instance variable DashFactor.
// DashFactor interacts with its superclass' instance variable StepLength to
// create the dashes. DashFactor is the percentage of the StepLength line
// segment that is visible. Thus if DashFactor=0.75, the dashes will be
// "three-quarters on" and "one-quarter off".
// .SECTION See Also
// vtkStreamer, vtkStreamLine, vtkStreamPoints

#ifndef __vtkDashedStreamLine_h
#define __vtkDashedStreamLine_h

#include "vtkStreamLine.hh"

class vtkDashedStreamLine : public vtkStreamLine
{
public:
  vtkDashedStreamLine();
  char *GetClassName() {return "vtkDashedStreamLine";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // For each dash, specify the fraction of the dash that is "on". A factor
  // of 1.0 will result in a continuous line, a factor of 0.5 will result in
  // dashed that are half on and half off.
  vtkSetClampMacro(DashFactor,float,0.01,1.0);
  vtkGetMacro(DashFactor,float);

protected:
  // Convert streamer array into vtkPolyData
  void Execute();

  // the fraction of on versus off in dash
  float DashFactor;

};

#endif

<commit_msg>ENH: Fixed comments<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDashedStreamLine.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDashedStreamLine - generate constant-time dashed streamline in arbitrary dataset
// .SECTION Description
// vtkDashedStreamLine is a filter that generates a "dashed" streamline for
// an arbitrary dataset. The streamline consists of a series of dashes, each
// of which represents (approximately) a constant time increment. Thus in the
// resulting visual representation, relatively long dashes represent areas of
// high velocity, and small dashes represent areas of low velocity.
//
// vtkDashedStreamLine introduces the instance variable DashFactor.
// DashFactor interacts with its superclass' instance variable StepLength to
// create the dashes. DashFactor is the percentage of the StepLength line
// segment that is visible. Thus if DashFactor=0.75, the dashes will be
// "three-quarters on" and "one-quarter off".
// .SECTION See Also
// vtkStreamer vtkStreamLine vtkStreamPoints

#ifndef __vtkDashedStreamLine_h
#define __vtkDashedStreamLine_h

#include "vtkStreamLine.hh"

class vtkDashedStreamLine : public vtkStreamLine
{
public:
  vtkDashedStreamLine();
  char *GetClassName() {return "vtkDashedStreamLine";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // For each dash, specify the fraction of the dash that is "on". A factor
  // of 1.0 will result in a continuous line, a factor of 0.5 will result in
  // dashed that are half on and half off.
  vtkSetClampMacro(DashFactor,float,0.01,1.0);
  vtkGetMacro(DashFactor,float);

protected:
  // Convert streamer array into vtkPolyData
  void Execute();

  // the fraction of on versus off in dash
  float DashFactor;

};

#endif

<|endoftext|>


<commit_before>/*~
 * Copyright (C) 2013 - 2016 George Makrydakis <george@irrequietus.eu>
 *
 * This file is part of 'clause', a highly generic C++ meta-programming library,
 * subject to the terms and conditions of the Mozilla Public License v 2.0. If
 * a copy of the MPLv2 license text was not distributed with this file, you can
 * obtain it at: http://mozilla.org/MPL/2.0/.
 *
 * The 'clause' library is an experimental library in active development with
 * a source code repository at: https://github.com/irrequietus/clause.git and
 * issue tracker at https://github.com/irrequietus/clause/issues.
 *
 */

#ifndef CLAUSE_PPMPF_ALGORITHMS_MAP_HH
#define CLAUSE_PPMPF_ALGORITHMS_MAP_HH

#include <clause/ppmpf/collections/tuple.hh>
#include <clause/ppmpf/collections/sequence.hh>

/*~
 * @desc A high order function applying a given function to each element of a
 *       a given ppmpf collection (sequences, safe and unsafe ppmpf tuples),
 *       also supporting closures with a particular syntax and expanding to
 *       a ppmpf collection of the same typeclause.
 * @pfrg fexp: a plain function or a ppmpf closure.
 * @pfrg tycl: a ppmpf typeclause.
 * @pexp Application of fexp over a ppmpf collection as the latter is described
 *       in the typeclause enclosing it.
 */
#define PPMPF_MAP(fexp,tycl) \
        PPMPF_TYPEFY( PPMPF_PFLD1 \
                    , PPMPF_MHD \
                    , PPMPF_MAP_MHD \
                    , fexp \
                    , PPMPF_IFELSE( PPMPF_IS(PPMPF_TYPEOF(tycl), 2) \
                                  , \
                                  , () )\
                    , tycl )

#endif /* CLAUSE_PPMPF_ALGORITHMS_MAP_HH */
<commit_msg>Using <clause/ppmpf/algorithms/map.hh> includes vxpp fmap too now.<commit_after>/*~
 * Copyright (C) 2013 - 2016 George Makrydakis <george@irrequietus.eu>
 *
 * This file is part of 'clause', a highly generic C++ meta-programming library,
 * subject to the terms and conditions of the Mozilla Public License v 2.0. If
 * a copy of the MPLv2 license text was not distributed with this file, you can
 * obtain it at: http://mozilla.org/MPL/2.0/.
 *
 * The 'clause' library is an experimental library in active development with
 * a source code repository at: https://github.com/irrequietus/clause.git and
 * issue tracker at https://github.com/irrequietus/clause/issues.
 *
 */

#ifndef CLAUSE_PPMPF_ALGORITHMS_MAP_HH
#define CLAUSE_PPMPF_ALGORITHMS_MAP_HH

#include <clause/ppmpf/collections/tuple.hh>
#include <clause/ppmpf/collections/sequence.hh>
#include <clause/ppmpf/vxpp.hh>

/*~
 * @desc A high order function applying a given function to each element of a
 *       a given ppmpf collection (sequences, safe and unsafe ppmpf tuples),
 *       also supporting closures with a particular syntax and expanding to
 *       a ppmpf collection of the same typeclause.
 * @pfrg fexp: a plain function or a ppmpf closure.
 * @pfrg tycl: a ppmpf typeclause.
 * @pexp Application of fexp over a ppmpf collection as the latter is described
 *       in the typeclause enclosing it.
 */
#define PPMPF_MAP(fexp,tycl) \
        PPMPF_TYPEFY( PPMPF_PFLD1 \
                    , PPMPF_MHD \
                    , PPMPF_MAP_MHD \
                    , fexp \
                    , PPMPF_IFELSE( PPMPF_IS(PPMPF_TYPEOF(tycl), 2) \
                                  , \
                                  , () )\
                    , tycl )

#endif /* CLAUSE_PPMPF_ALGORITHMS_MAP_HH */
<|endoftext|>


<commit_before>/*
 @ 0xCCCCCCCC
*/

#include <iostream>

#include "signals.h"

void foo(int i, const int& j, int&& k)
{
    std::cout << "foo" << std::endl;
}

struct Foo {
    static void foo(int i, const int& j, int&& k)
    {
        std::cout << "Foo::foo" << std::endl;
    }
};

int main()
{
    Signal<int, const int&, int&&> s;
    std::function<void(int, const int&, int&&)> f(&foo);
    Slot slot = s.Connect(&foo);
    s.Connect(&Foo::foo);
    s.Connect(f);
    s.Emit(1, 3, 5);

    slot.Disconnect();
    s.Emit(5, 3, 1);
    s.DisconnectAll();
    s.Emit(3, 2, 1);
    return 0;
}<commit_msg>Signal-Slot: update test code<commit_after>/*
 @ 0xCCCCCCCC
*/

#include <iostream>
#include <functional>

#include "signals.h"

void foo(int i, const int& j, int&& k)
{
    std::cout << "foo" << std::endl;
}

struct Foo {
    static void sfoo(int i, const int& j, int&& k)
    {
        std::cout << "Foo::sfoo" << std::endl;
    }

    void foo(int i, const int& j, int&& k)
    {
        s = "world";
        std::cout << "Foo::foo" << std::endl;
    }

    std::string s = "hello";
};

int main()
{
    Signal<int, const int&, int&&> s;
    Slot slot = s.Connect(&foo);
    s.Connect(&Foo::sfoo);
    auto foo = std::make_shared<Foo>();
    auto pf = foo.get();
    using namespace std::placeholders;
    s.Connect(std::bind(&Foo::foo, pf, _1, _2, _3), foo);
    s.Emit(1, 3, 5);
    slot.Disconnect();
    s.Emit(5, 3, 1);
    foo.reset();
    s.Emit(5, 3, 1);
    s.DisconnectAll();
    s.Emit(3, 2, 1);
    return 0;
}<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

struct BmodP {
	long long index;
	long long value;
}mod1[10000000];

bool cmp(BmodP tmp1, BmodP tmp2) {
	if(tmp1.value<tmp2.value || (tmp1.value==tmp2.value&&tmp1.index<tmp2.index))  return true;
	return false;
}

long long* extendEuclid(long long a, long long b) {
	long long *sol = new long long[2];
	if(b==0) {
		sol[0] = 1;
		sol[1] = 0;
		return sol;
	} else {
		long long *tmp = extendEuclid(b, a%b);
		sol[0] = tmp[1];
		sol[1] = tmp[0]-(long long)floor(a/b)*tmp[1];
		return sol;
	}
}

// a^n%p
long long pow_mod(long long a, long long n, long long p) {
	if(n==0) return 1;
	long long x = pow_mod(a, n/2, p);
	long long ans = ((x%p) * (x %p))%p;
	if(n%2==1) ans = ((ans%p)*(a%p))%p;
	return ans;
}

long long bi_search(long long m, long long x) {
	long long low = 0;
	long long high = m-1;

	while(low<=high) {
		long long mid = (low+high)/2;
		if(mod1[mid].value==x) {
			return mod1[mid].index;
		} else if(mod1[mid].value<x) {
			low = mid+1;
		} else {
			high = mid-1;
		}
	}
	return -1;
}

int main()
{
	long long P, B, N;
	while(scanf("%lld%lld%lld", &P, &B, &N)!=EOF) {
		bool is_find = false;
		long long m = (long long)ceil(sqrt((double)(P)));
		//calculate B^j%p, j=0,1,...,m-1

		for(long long j=0; j<m; j++) {
			mod1[j].index = j;
			mod1[j].value = pow_mod(B, j, P);
		}
		//sort array mod1, later used for binary search
		sort(mod1, mod1+m, cmp);
		//binary search mod1, need to delete repeated mod[j].value
		for(long long i=0; i<m-1; i++) {
			if(mod1[i+1].value==mod1[i].value) {
				mod1[i+1].index = mod1[i].index;
			}
		}

		//calculate N*inv(B^{im})%P, i=0,1,...,m-1

		long long *invB = extendEuclid(B, P);

		while(invB[0] <0) invB[0]+=P;

		//long long bm = pow_mod(invB[0], m, P);
		for(long long i=0; i<m; i++) {
			long long tmp = pow_mod(invB[0], i*m, P);
			long long res = ((tmp%P) * (N % P))%P;
			//serach res in mod1
			long long j = bi_search(m, res);

			if(j!=-1) {
				long long L = i*m + j;
				cout  << L << endl;
				is_find = true;
				break;
			}
		}
		if(!is_find) cout << "no solution" << endl;
	}
	return 0;
}
<commit_msg>update discrete logarithm<commit_after>#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

struct BmodP {
	long long index;
	long long value;
}mod1[10000000];

bool cmp(BmodP tmp1, BmodP tmp2) {
	if(tmp1.value<tmp2.value || (tmp1.value==tmp2.value&&tmp1.index<tmp2.index))  return true;
	return false;
}

long long* extendEuclid(long long a, long long b) {
	long long *sol = new long long[2];
	if(b==0) {
		sol[0] = 1;
		sol[1] = 0;
		return sol;
	} else {
		long long *tmp = extendEuclid(b, a%b);
		sol[0] = tmp[1];
		sol[1] = tmp[0]-(long long)floor(a/b)*tmp[1];
		return sol;
	}
}

// a^n%p
long long pow_mod(long long a, long long n, long long p) {
	if(n==0) return 1;
	long long x = pow_mod(a, n/2, p);
	long long ans = ((x%p) * (x %p))%p;
	if(n%2==1) ans = ((ans%p)*(a%p))%p;
	return ans;
}

long long bi_search(long long m, long long x) {
	long long low = 0;
	long long high = m-1;

	while(low<=high) {
		long long mid = (low+high)/2;
		if(mod1[mid].value==x) {
			return mod1[mid].index;
		} else if(mod1[mid].value<x) {
			low = mid+1;
		} else {
			high = mid-1;
		}
	}
	return -1;
}

int main()
{
	long long P, B, N;
	while(scanf("%lld%lld%lld", &P, &B, &N)!=EOF) {
		bool is_find = false;
		long long m = (long long)ceil(sqrt((double)(P)));
		//calculate B^j%p, j=0,1,...,m-1

		for(long long j=0; j<m; j++) {
			mod1[j].index = j;
			mod1[j].value = pow_mod(B, j, P);
		}
		//sort array mod1, later used for binary search
		sort(mod1, mod1+m, cmp);
		//There may exist same value with different index, let the big index be the small index
		//otherwise, binary search may find the bigger index
		for(long long i=0; i<m-1; i++) {
			if(mod1[i+1].value==mod1[i].value) {
				mod1[i+1].index = mod1[i].index;
			}
		}

		//calculate N*inv(B^{im})%P, i=0,1,...,m-1

		long long *invB = extendEuclid(B, P);

		while(invB[0] <0) invB[0]+=P;

		//long long bm = pow_mod(invB[0], m, P);
		for(long long i=0; i<m; i++) {
			long long tmp = pow_mod(invB[0], i*m, P);
			long long res = ((tmp%P) * (N % P))%P;
			//serach res in mod1
			long long j = bi_search(m, res);

			if(j!=-1) {
				long long L = i*m + j;
				cout  << L << endl;
				is_find = true;
				break;
			}
		}
		if(!is_find) cout << "no solution" << endl;
	}
	return 0;
}
<|endoftext|>


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

#include "flutter/shell/platform/android/android_surface_gl.h"

#include <utility>

#include "flutter/fml/logging.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/shell/platform/android/android_shell_holder.h"

namespace flutter {

AndroidSurfaceGL::AndroidSurfaceGL(
    std::shared_ptr<AndroidContext> android_context,
    std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
    const AndroidSurface::Factory& surface_factory)
    : external_view_embedder_(
          std::make_unique<AndroidExternalViewEmbedder>(android_context,
                                                        jni_facade,
                                                        surface_factory)),
      android_context_(
          std::static_pointer_cast<AndroidContextGL>(android_context)),
      native_window_(nullptr),
      onscreen_surface_(nullptr),
      offscreen_surface_(nullptr) {
  // Acquire the offscreen surface.
  offscreen_surface_ = android_context_->CreateOffscreenSurface();
  if (!offscreen_surface_->IsValid()) {
    offscreen_surface_ = nullptr;
  }
}

AndroidSurfaceGL::~AndroidSurfaceGL() = default;

void AndroidSurfaceGL::TeardownOnScreenContext() {
  // When the onscreen surface is destroyed, the context and the surface
  // instance should be deleted. Issue:
  // https://github.com/flutter/flutter/issues/64414
  android_context_->ClearCurrent();
  onscreen_surface_ = nullptr;
}

bool AndroidSurfaceGL::IsValid() const {
  return offscreen_surface_ && android_context_->IsValid();
}

std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
    GrDirectContext* gr_context) {
  if (gr_context) {
    return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
  }
  return std::make_unique<GPUSurfaceGL>(this, true);
}

bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  FML_DCHECK(native_window_);

  if (size == onscreen_surface_->GetSize()) {
    return true;
  }

  android_context_->ClearCurrent();

  // Ensure the destructor is called since it destroys the `EGLSurface` before
  // creating a new onscreen surface.
  onscreen_surface_ = nullptr;
  onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_);
  if (!onscreen_surface_->IsValid()) {
    FML_LOG(ERROR) << "Unable to create EGL window surface on resize.";
    return false;
  }
  onscreen_surface_->MakeCurrent();
  return true;
}

bool AndroidSurfaceGL::ResourceContextMakeCurrent() {
  FML_DCHECK(IsValid());
  return offscreen_surface_->MakeCurrent();
}

bool AndroidSurfaceGL::ResourceContextClearCurrent() {
  FML_DCHECK(IsValid());
  return android_context_->ClearCurrent();
}

bool AndroidSurfaceGL::SetNativeWindow(
    fml::RefPtr<AndroidNativeWindow> window) {
  FML_DCHECK(IsValid());
  FML_DCHECK(window);
  native_window_ = window;
  // Create the onscreen surface.
  onscreen_surface_ = android_context_->CreateOnscreenSurface(window);
  if (!onscreen_surface_->IsValid()) {
    return false;
  }
  return true;
}

std::unique_ptr<GLContextResult> AndroidSurfaceGL::GLContextMakeCurrent() {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  auto default_context_result = std::make_unique<GLContextDefaultResult>(
      onscreen_surface_->MakeCurrent());
  return std::move(default_context_result);
}

bool AndroidSurfaceGL::GLContextClearCurrent() {
  FML_DCHECK(IsValid());
  return android_context_->ClearCurrent();
}

bool AndroidSurfaceGL::GLContextPresent(uint32_t fbo_id) {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  return onscreen_surface_->SwapBuffers();
}

intptr_t AndroidSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
  FML_DCHECK(IsValid());
  // The default window bound framebuffer on Android.
  return 0;
}

// |GPUSurfaceGLDelegate|
ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() {
  return external_view_embedder_.get();
}

}  // namespace flutter
<commit_msg>Ensure the destructor is called since it destroys the `EGLSurface` before creating a new onscreen surface. (#20916)<commit_after>// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/android/android_surface_gl.h"

#include <utility>

#include "flutter/fml/logging.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/shell/platform/android/android_shell_holder.h"

namespace flutter {

AndroidSurfaceGL::AndroidSurfaceGL(
    std::shared_ptr<AndroidContext> android_context,
    std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
    const AndroidSurface::Factory& surface_factory)
    : external_view_embedder_(
          std::make_unique<AndroidExternalViewEmbedder>(android_context,
                                                        jni_facade,
                                                        surface_factory)),
      android_context_(
          std::static_pointer_cast<AndroidContextGL>(android_context)),
      native_window_(nullptr),
      onscreen_surface_(nullptr),
      offscreen_surface_(nullptr) {
  // Acquire the offscreen surface.
  offscreen_surface_ = android_context_->CreateOffscreenSurface();
  if (!offscreen_surface_->IsValid()) {
    offscreen_surface_ = nullptr;
  }
}

AndroidSurfaceGL::~AndroidSurfaceGL() = default;

void AndroidSurfaceGL::TeardownOnScreenContext() {
  // When the onscreen surface is destroyed, the context and the surface
  // instance should be deleted. Issue:
  // https://github.com/flutter/flutter/issues/64414
  android_context_->ClearCurrent();
  onscreen_surface_ = nullptr;
}

bool AndroidSurfaceGL::IsValid() const {
  return offscreen_surface_ && android_context_->IsValid();
}

std::unique_ptr<Surface> AndroidSurfaceGL::CreateGPUSurface(
    GrDirectContext* gr_context) {
  if (gr_context) {
    return std::make_unique<GPUSurfaceGL>(sk_ref_sp(gr_context), this, true);
  }
  return std::make_unique<GPUSurfaceGL>(this, true);
}

bool AndroidSurfaceGL::OnScreenSurfaceResize(const SkISize& size) {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  FML_DCHECK(native_window_);

  if (size == onscreen_surface_->GetSize()) {
    return true;
  }

  android_context_->ClearCurrent();

  // Ensure the destructor is called since it destroys the `EGLSurface` before
  // creating a new onscreen surface.
  onscreen_surface_ = nullptr;
  onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_);
  if (!onscreen_surface_->IsValid()) {
    FML_LOG(ERROR) << "Unable to create EGL window surface on resize.";
    return false;
  }
  onscreen_surface_->MakeCurrent();
  return true;
}

bool AndroidSurfaceGL::ResourceContextMakeCurrent() {
  FML_DCHECK(IsValid());
  return offscreen_surface_->MakeCurrent();
}

bool AndroidSurfaceGL::ResourceContextClearCurrent() {
  FML_DCHECK(IsValid());
  return android_context_->ClearCurrent();
}

bool AndroidSurfaceGL::SetNativeWindow(
    fml::RefPtr<AndroidNativeWindow> window) {
  FML_DCHECK(IsValid());
  FML_DCHECK(window);
  native_window_ = window;
  // Ensure the destructor is called since it destroys the `EGLSurface` before
  // creating a new onscreen surface.
  onscreen_surface_ = nullptr;
  // Create the onscreen surface.
  onscreen_surface_ = android_context_->CreateOnscreenSurface(window);
  if (!onscreen_surface_->IsValid()) {
    return false;
  }
  return true;
}

std::unique_ptr<GLContextResult> AndroidSurfaceGL::GLContextMakeCurrent() {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  auto default_context_result = std::make_unique<GLContextDefaultResult>(
      onscreen_surface_->MakeCurrent());
  return std::move(default_context_result);
}

bool AndroidSurfaceGL::GLContextClearCurrent() {
  FML_DCHECK(IsValid());
  return android_context_->ClearCurrent();
}

bool AndroidSurfaceGL::GLContextPresent(uint32_t fbo_id) {
  FML_DCHECK(IsValid());
  FML_DCHECK(onscreen_surface_);
  return onscreen_surface_->SwapBuffers();
}

intptr_t AndroidSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const {
  FML_DCHECK(IsValid());
  // The default window bound framebuffer on Android.
  return 0;
}

// |GPUSurfaceGLDelegate|
ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() {
  return external_view_embedder_.get();
}

}  // namespace flutter
<|endoftext|>


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

#ifndef INCLUDED_SIMPLEMAPI_HXX
#define INCLUDED_SIMPLEMAPI_HXX

#define WIN32_LEAN_AND_MEAN
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#include <mapi.h>
#ifndef __MINGW32__
#include <mapix.h>
#endif
#if defined _MSC_VER
#pragma warning(pop)
#endif

class CSimpleMapi
{
public:
    /**
        @throws std::runtime_error
        if either the mapi32.dll could not be loaded at all
        or necessary function exports are missing
    */
    CSimpleMapi(); // throws std::runtime_error;

    ~CSimpleMapi();

    ULONG MAPILogon(
        ULONG ulUIParam,
        LPTSTR lpszProfileName,
        LPTSTR lpszPassword,
        FLAGS flFlags,
        ULONG ulReserved,
        LPLHANDLE lplhSession );

    ULONG MAPILogoff(
        LHANDLE lhSession,
        ULONG ulUIParam,
        FLAGS flFlags,
        ULONG ulReserved );

    ULONG MAPISendMail(
        LHANDLE lhSession,
        ULONG ulUIParam,
        lpMapiMessage lpMessage,
        FLAGS flFlags,
        ULONG ulReserved );

private:
    HMODULE         m_hMapiDll;
    LPMAPILOGON     m_lpfnMapiLogon;
    LPMAPILOGOFF    m_lpfnMapiLogoff;
    LPMAPISENDMAIL  m_lpfnMapiSendMail;
};

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

#ifndef INCLUDED_SIMPLEMAPI_HXX
#define INCLUDED_SIMPLEMAPI_HXX

#define WIN32_LEAN_AND_MEAN
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#include <mapi.h>
#ifndef __MINGW32__
#include <mapix.h>
#endif
#if defined _MSC_VER
#pragma warning(pop)
#endif

class CSimpleMapi
{
public:
    /**
        @throws std::runtime_error
        if either the mapi32.dll could not be loaded at all
        or necessary function exports are missing
    */
    CSimpleMapi(); // throws std::runtime_error;

    ~CSimpleMapi();

    ULONG MAPILogon(
        ULONG ulUIParam,
        LPTSTR lpszProfileName,
        LPTSTR lpszPassword,
        FLAGS flFlags,
        ULONG ulReserved,
        LPLHANDLE lplhSession );

    ULONG MAPILogoff(
        LHANDLE lhSession,
        ULONG ulUIParam,
        FLAGS flFlags,
        ULONG ulReserved );

    ULONG MAPISendMail(
        LHANDLE lhSession,
        ULONG ulUIParam,
        lpMapiMessage lpMessage,
        FLAGS flFlags,
        ULONG ulReserved );

private:
    HMODULE         m_hMapiDll;
    LPMAPILOGON     m_lpfnMapiLogon;
    LPMAPILOGOFF    m_lpfnMapiLogoff;
    LPMAPISENDMAIL  m_lpfnMapiSendMail;
};

#endif
<|endoftext|>


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

#include "dom_node_impl.h"
#include "browser_impl.h"
#include "cef_thread.h"
#include "dom_document_impl.h"
#include "dom_event_impl.h"
#include "tracker.h"

#include "base/logging.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEventListener.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"

using WebKit::WebAttribute;
using WebKit::WebDocument;
using WebKit::WebDOMEvent;
using WebKit::WebDOMEventListener;
using WebKit::WebElement;
using WebKit::WebFrame;
using WebKit::WebNamedNodeMap;
using WebKit::WebNode;
using WebKit::WebString;

namespace {

// Wrapper implementation for WebDOMEventListener.
class CefDOMEventListenerWrapper : public WebDOMEventListener,
                                   public CefTrackObject
{
public:
  CefDOMEventListenerWrapper(CefBrowserImpl* browser, WebFrame* frame,
                             CefRefPtr<CefDOMEventListener> listener)
    : browser_(browser), frame_(frame), listener_(listener)
  {
    // Cause this object to be deleted immediately before the frame is closed.
    browser->UIT_AddFrameObject(frame, this);
  }
  virtual ~CefDOMEventListenerWrapper()
  {
    REQUIRE_UIT();
  }

  virtual void handleEvent(const WebDOMEvent& event)
  {
    CefRefPtr<CefDOMDocumentImpl> documentImpl;
    CefRefPtr<CefDOMEventImpl> eventImpl;

    if (!event.isNull()) {
      // Create CefDOMDocumentImpl and CefDOMEventImpl objects that are valid
      // only for the scope of this method.
      const WebDocument& document = frame_->document();
      if (!document.isNull()) {
        documentImpl = new CefDOMDocumentImpl(browser_, frame_);
        eventImpl = new CefDOMEventImpl(documentImpl, event);
      }
    }

    listener_->HandleEvent(eventImpl.get());

    if(eventImpl.get())
      eventImpl->Detach();
    if (documentImpl.get())
      documentImpl->Detach();
  }

protected:
  CefBrowserImpl* browser_;
  WebFrame* frame_;
  CefRefPtr<CefDOMEventListener> listener_;
};

} // namespace

CefDOMNodeImpl::CefDOMNodeImpl(CefRefPtr<CefDOMDocumentImpl> document,
                               const WebKit::WebNode& node)
    : document_(document), node_(node)
{
}

CefDOMNodeImpl::~CefDOMNodeImpl()
{
  REQUIRE_UIT();

  if (document_.get() && !node_.isNull()) {
    // Remove the node from the document.
    document_->RemoveNode(node_);
  }
}

CefDOMNodeImpl::Type CefDOMNodeImpl::GetType()
{
  if (!VerifyContext())
    return DOM_NODE_TYPE_UNSUPPORTED;

  switch (node_.nodeType()) {
    case WebNode::ElementNode:
      return DOM_NODE_TYPE_ELEMENT;
    case WebNode::AttributeNode:
      return DOM_NODE_TYPE_ATTRIBUTE;
    case WebNode::TextNode:
      return DOM_NODE_TYPE_TEXT;
    case WebNode::CDataSectionNode:
      return DOM_NODE_TYPE_CDATA_SECTION;
    case WebNode::EntityReferenceNode:
      return DOM_NODE_TYPE_ENTITY_REFERENCE;
    case WebNode::EntityNode:
      return DOM_NODE_TYPE_ENTITY;
    case WebNode::ProcessingInstructionsNode:
      return DOM_NODE_TYPE_PROCESSING_INSTRUCTIONS;
    case WebNode::CommentNode:
      return DOM_NODE_TYPE_COMMENT;
    case WebNode::DocumentNode:
      return DOM_NODE_TYPE_DOCUMENT;
    case WebNode::DocumentTypeNode:
      return DOM_NODE_TYPE_DOCUMENT_TYPE;
    case WebNode::DocumentFragmentNode:
      return DOM_NODE_TYPE_DOCUMENT_FRAGMENT;
    case WebNode::NotationNode:
      return DOM_NODE_TYPE_NOTATION;
    case WebNode::XPathNamespaceNode:
      return DOM_NODE_TYPE_XPATH_NAMESPACE;
    default:
      return DOM_NODE_TYPE_UNSUPPORTED;
  }
}

bool CefDOMNodeImpl::IsText()
{
  if (!VerifyContext())
    return false;

  return node_.isTextNode();
}

bool CefDOMNodeImpl::IsElement()
{
  if (!VerifyContext())
    return false;

  return node_.isElementNode();
}

CefString CefDOMNodeImpl::GetName()
{
  CefString str;
  if (!VerifyContext())
    return str;

  const WebString& name = node_.nodeName();
  if (!name.isNull())
    str = name;

  return str;
}

CefString CefDOMNodeImpl::GetValue()
{
  CefString str;
  if (!VerifyContext())
    return str;

  const WebString& value = node_.nodeValue();
  if (!value.isNull())
    str = value;

  return str;
}

bool CefDOMNodeImpl::SetValue(const CefString& value)
{
  if (!VerifyContext())
    return false;

  if (node_.isElementNode())
    return false;

  return node_.setNodeValue(string16(value));
}

CefString CefDOMNodeImpl::GetAsMarkup()
{
  CefString str;
  if (!VerifyContext())
    return str;

  const WebString& markup = node_.createMarkup();
  if (!markup.isNull())
    str = markup;

  return str;
}

CefRefPtr<CefDOMDocument> CefDOMNodeImpl::GetDocument()
{
  if (!VerifyContext())
    return NULL;

  return document_.get();
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetParent()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.parentNode());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetPreviousSibling()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.previousSibling());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetNextSibling()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.nextSibling());
}

bool CefDOMNodeImpl::HasChildren()
{
  if (!VerifyContext())
    return false;

  return node_.hasChildNodes();
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetFirstChild()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.firstChild());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetLastChild()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.lastChild());
}

void CefDOMNodeImpl::AddEventListener(const CefString& eventType,
                                      CefRefPtr<CefDOMEventListener> listener,
                                      bool useCapture)
{
  if (!VerifyContext())
    return;

  node_.addEventListener(string16(eventType),
      new CefDOMEventListenerWrapper(document_->GetBrowser(),
          document_->GetFrame(), listener),
      useCapture);
}

CefString CefDOMNodeImpl::GetElementTagName()
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& tagname = element.tagName();
  if (!tagname.isNull())
    str = tagname;

  return str;
}

bool CefDOMNodeImpl::HasElementAttributes()
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  return (element.attributes().length() > 0);
}

bool CefDOMNodeImpl::HasElementAttribute(const CefString& attrName)
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  return element.hasAttribute(string16(attrName));
}

CefString CefDOMNodeImpl::GetElementAttribute(const CefString& attrName)
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& attr = element.getAttribute(string16(attrName));
  if (!attr.isNull())
    str = attr;

  return str;
}

void CefDOMNodeImpl::GetElementAttributes(AttributeMap& attrMap)
{
  if (!VerifyContext())
    return;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebNamedNodeMap& map = element.attributes();
  unsigned int len = map.length();
  if (len == 0)
    return;

  string16 nameStr, valueStr;

  for (unsigned int i = 0; i < len; ++i) {
    const WebAttribute& attrib = map.attributeItem(i);
    string16 nameStr, valueStr;
    const WebString& name = attrib.localName();
    if (!name.isNull())
      nameStr = name;
    const WebString& value = attrib.value();
    if (!value.isNull())
      valueStr = value;

    attrMap.insert(std::make_pair(nameStr, valueStr));
  }
}

bool CefDOMNodeImpl::SetElementAttribute(const CefString& attrName,
                                         const CefString& value)
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  WebElement element = node_.to<WebKit::WebElement>();
  return element.setAttribute(string16(attrName), string16(value));
}

CefString CefDOMNodeImpl::GetElementInnerText()
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& text = element.innerText();
  if (!text.isNull())
    str = text;

  return str;
}

void CefDOMNodeImpl::Detach()
{
  document_ = NULL;
  node_.assign(WebNode());
}

bool CefDOMNodeImpl::VerifyContext()
{
  if (!document_.get()) {
    NOTREACHED();
    return false;
  }
  if (!document_->VerifyContext())
    return false;
  if(node_.isNull()) {
    NOTREACHED();
    return false;
  }
  return true;
}
<commit_msg>Add support for retrieving values from DOM form elements.<commit_after>// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "dom_node_impl.h"
#include "browser_impl.h"
#include "cef_thread.h"
#include "dom_document_impl.h"
#include "dom_event_impl.h"
#include "tracker.h"

#include "base/logging.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEventListener.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
#include "webkit/glue/form_field.h"

using WebKit::WebAttribute;
using WebKit::WebDocument;
using WebKit::WebDOMEvent;
using WebKit::WebDOMEventListener;
using WebKit::WebElement;
using WebKit::WebFrame;
using WebKit::WebFormControlElement;
using WebKit::WebNamedNodeMap;
using WebKit::WebNode;
using WebKit::WebString;

namespace {

// Wrapper implementation for WebDOMEventListener.
class CefDOMEventListenerWrapper : public WebDOMEventListener,
                                   public CefTrackObject
{
public:
  CefDOMEventListenerWrapper(CefBrowserImpl* browser, WebFrame* frame,
                             CefRefPtr<CefDOMEventListener> listener)
    : browser_(browser), frame_(frame), listener_(listener)
  {
    // Cause this object to be deleted immediately before the frame is closed.
    browser->UIT_AddFrameObject(frame, this);
  }
  virtual ~CefDOMEventListenerWrapper()
  {
    REQUIRE_UIT();
  }

  virtual void handleEvent(const WebDOMEvent& event)
  {
    CefRefPtr<CefDOMDocumentImpl> documentImpl;
    CefRefPtr<CefDOMEventImpl> eventImpl;

    if (!event.isNull()) {
      // Create CefDOMDocumentImpl and CefDOMEventImpl objects that are valid
      // only for the scope of this method.
      const WebDocument& document = frame_->document();
      if (!document.isNull()) {
        documentImpl = new CefDOMDocumentImpl(browser_, frame_);
        eventImpl = new CefDOMEventImpl(documentImpl, event);
      }
    }

    listener_->HandleEvent(eventImpl.get());

    if(eventImpl.get())
      eventImpl->Detach();
    if (documentImpl.get())
      documentImpl->Detach();
  }

protected:
  CefBrowserImpl* browser_;
  WebFrame* frame_;
  CefRefPtr<CefDOMEventListener> listener_;
};

} // namespace

CefDOMNodeImpl::CefDOMNodeImpl(CefRefPtr<CefDOMDocumentImpl> document,
                               const WebKit::WebNode& node)
    : document_(document), node_(node)
{
}

CefDOMNodeImpl::~CefDOMNodeImpl()
{
  REQUIRE_UIT();

  if (document_.get() && !node_.isNull()) {
    // Remove the node from the document.
    document_->RemoveNode(node_);
  }
}

CefDOMNodeImpl::Type CefDOMNodeImpl::GetType()
{
  if (!VerifyContext())
    return DOM_NODE_TYPE_UNSUPPORTED;

  switch (node_.nodeType()) {
    case WebNode::ElementNode:
      return DOM_NODE_TYPE_ELEMENT;
    case WebNode::AttributeNode:
      return DOM_NODE_TYPE_ATTRIBUTE;
    case WebNode::TextNode:
      return DOM_NODE_TYPE_TEXT;
    case WebNode::CDataSectionNode:
      return DOM_NODE_TYPE_CDATA_SECTION;
    case WebNode::EntityReferenceNode:
      return DOM_NODE_TYPE_ENTITY_REFERENCE;
    case WebNode::EntityNode:
      return DOM_NODE_TYPE_ENTITY;
    case WebNode::ProcessingInstructionsNode:
      return DOM_NODE_TYPE_PROCESSING_INSTRUCTIONS;
    case WebNode::CommentNode:
      return DOM_NODE_TYPE_COMMENT;
    case WebNode::DocumentNode:
      return DOM_NODE_TYPE_DOCUMENT;
    case WebNode::DocumentTypeNode:
      return DOM_NODE_TYPE_DOCUMENT_TYPE;
    case WebNode::DocumentFragmentNode:
      return DOM_NODE_TYPE_DOCUMENT_FRAGMENT;
    case WebNode::NotationNode:
      return DOM_NODE_TYPE_NOTATION;
    case WebNode::XPathNamespaceNode:
      return DOM_NODE_TYPE_XPATH_NAMESPACE;
    default:
      return DOM_NODE_TYPE_UNSUPPORTED;
  }
}

bool CefDOMNodeImpl::IsText()
{
  if (!VerifyContext())
    return false;

  return node_.isTextNode();
}

bool CefDOMNodeImpl::IsElement()
{
  if (!VerifyContext())
    return false;

  return node_.isElementNode();
}

CefString CefDOMNodeImpl::GetName()
{
  CefString str;
  if (!VerifyContext())
    return str;

  const WebString& name = node_.nodeName();
  if (!name.isNull())
    str = name;

  return str;
}

CefString CefDOMNodeImpl::GetValue()
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (node_.isElementNode()) {
    const WebElement& element = node_.to<WebKit::WebElement>();
    if (element.isFormControlElement()) {
      // Retrieve the value from the form control element.
      const WebFormControlElement& formElement =
          node_.to<WebKit::WebFormControlElement>();

      webkit_glue::FormField formField(formElement);
      str = formField.value();
    }
  }

  if (str.empty()) {
    const WebString& value = node_.nodeValue();
    if (!value.isNull())
      str = value;
  }

  return str;
}

bool CefDOMNodeImpl::SetValue(const CefString& value)
{
  if (!VerifyContext())
    return false;

  if (node_.isElementNode())
    return false;

  return node_.setNodeValue(string16(value));
}

CefString CefDOMNodeImpl::GetAsMarkup()
{
  CefString str;
  if (!VerifyContext())
    return str;

  const WebString& markup = node_.createMarkup();
  if (!markup.isNull())
    str = markup;

  return str;
}

CefRefPtr<CefDOMDocument> CefDOMNodeImpl::GetDocument()
{
  if (!VerifyContext())
    return NULL;

  return document_.get();
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetParent()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.parentNode());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetPreviousSibling()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.previousSibling());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetNextSibling()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.nextSibling());
}

bool CefDOMNodeImpl::HasChildren()
{
  if (!VerifyContext())
    return false;

  return node_.hasChildNodes();
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetFirstChild()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.firstChild());
}

CefRefPtr<CefDOMNode> CefDOMNodeImpl::GetLastChild()
{
  if (!VerifyContext())
    return NULL;

  return document_->GetOrCreateNode(node_.lastChild());
}

void CefDOMNodeImpl::AddEventListener(const CefString& eventType,
                                      CefRefPtr<CefDOMEventListener> listener,
                                      bool useCapture)
{
  if (!VerifyContext())
    return;

  node_.addEventListener(string16(eventType),
      new CefDOMEventListenerWrapper(document_->GetBrowser(),
          document_->GetFrame(), listener),
      useCapture);
}

CefString CefDOMNodeImpl::GetElementTagName()
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& tagname = element.tagName();
  if (!tagname.isNull())
    str = tagname;

  return str;
}

bool CefDOMNodeImpl::HasElementAttributes()
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  return (element.attributes().length() > 0);
}

bool CefDOMNodeImpl::HasElementAttribute(const CefString& attrName)
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  return element.hasAttribute(string16(attrName));
}

CefString CefDOMNodeImpl::GetElementAttribute(const CefString& attrName)
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& attr = element.getAttribute(string16(attrName));
  if (!attr.isNull())
    str = attr;

  return str;
}

void CefDOMNodeImpl::GetElementAttributes(AttributeMap& attrMap)
{
  if (!VerifyContext())
    return;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebNamedNodeMap& map = element.attributes();
  unsigned int len = map.length();
  if (len == 0)
    return;

  string16 nameStr, valueStr;

  for (unsigned int i = 0; i < len; ++i) {
    const WebAttribute& attrib = map.attributeItem(i);
    string16 nameStr, valueStr;
    const WebString& name = attrib.localName();
    if (!name.isNull())
      nameStr = name;
    const WebString& value = attrib.value();
    if (!value.isNull())
      valueStr = value;

    attrMap.insert(std::make_pair(nameStr, valueStr));
  }
}

bool CefDOMNodeImpl::SetElementAttribute(const CefString& attrName,
                                         const CefString& value)
{
  if (!VerifyContext())
    return false;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return false;
  }

  WebElement element = node_.to<WebKit::WebElement>();
  return element.setAttribute(string16(attrName), string16(value));
}

CefString CefDOMNodeImpl::GetElementInnerText()
{
  CefString str;
  if (!VerifyContext())
    return str;

  if (!node_.isElementNode()) {
    NOTREACHED();
    return str;
  }

  const WebElement& element = node_.to<WebKit::WebElement>();
  const WebString& text = element.innerText();
  if (!text.isNull())
    str = text;

  return str;
}

void CefDOMNodeImpl::Detach()
{
  document_ = NULL;
  node_.assign(WebNode());
}

bool CefDOMNodeImpl::VerifyContext()
{
  if (!document_.get()) {
    NOTREACHED();
    return false;
  }
  if (!document_->VerifyContext())
    return false;
  if(node_.isNull()) {
    NOTREACHED();
    return false;
  }
  return true;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:17:26 $
 *
 *  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
 *
 ************************************************************************/

#include "UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx"

#include "UriReference.hxx"
#include "supportsService.hxx"

#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "com/sun/star/uri/XUriReference.hpp"
#include "com/sun/star/uri/XUriSchemeParser.hpp"
#include "com/sun/star/uri/XVndSunStarScriptUrlReference.hpp"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/implbase2.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/mutex.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"

#include <new>

namespace css = com::sun::star;

namespace {

int getHexWeight(sal_Unicode c) {
    return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
        : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
        : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
        : -1;
}

int parseEscaped(rtl::OUString const & part, sal_Int32 * index) {
    if (part.getLength() - *index < 3 || part[*index] != '%') {
        return -1;
    }
    int n1 = getHexWeight(part[*index + 1]);
    int n2 = getHexWeight(part[*index + 2]);
    if (n1 < 0 || n2 < 0) {
        return -1;
    }
    *index += 3;
    return (n1 << 4) | n2;
}

rtl::OUString parsePart(
    rtl::OUString const & part, bool namePart, sal_Int32 * index)
{
    rtl::OUStringBuffer buf;
    while (*index < part.getLength()) {
        sal_Unicode c = part[*index];
        if (namePart ? c == '?' : c == '&' || c == '=') {
            break;
        } else if (c == '%') {
            sal_Int32 i = *index;
            int n = parseEscaped(part, &i);
            if (n >= 0 && n <= 0x7F) {
                buf.append(static_cast< sal_Unicode >(n));
            } else if (n >= 0xC0 && n <= 0xFC) {
                sal_Int32 encoded;
                int shift;
                sal_Int32 min;
                if (n <= 0xDF) {
                    encoded = (n & 0x1F) << 6;
                    shift = 0;
                    min = 0x80;
                } else if (n <= 0xEF) {
                    encoded = (n & 0x0F) << 12;
                    shift = 6;
                    min = 0x800;
                } else if (n <= 0xF7) {
                    encoded = (n & 0x07) << 18;
                    shift = 12;
                    min = 0x10000;
                } else if (n <= 0xFB) {
                    encoded = (n & 0x03) << 24;
                    shift = 18;
                    min = 0x200000;
                } else {
                    encoded = 0;
                    shift = 24;
                    min = 0x4000000;
                }
                bool utf8 = true;
                for (; shift >= 0; shift -= 6) {
                    n = parseEscaped(part, &i);
                    if (n < 0x80 || n > 0xBF) {
                        utf8 = false;
                        break;
                    }
                    encoded |= (n & 0x3F) << shift;
                }
                if (!utf8 || encoded < min
                    || encoded >= 0xD800 && encoded <= 0xDFFF
                    || encoded > 0x10FFFF)
                {
                    break;
                }
                if (encoded <= 0xFFFF) {
                    buf.append(static_cast< sal_Unicode >(encoded));
                } else {
                    buf.append(static_cast< sal_Unicode >(
                        (encoded >> 10) | 0xD800));
                    buf.append(static_cast< sal_Unicode >(
                        (encoded & 0x3FF) | 0xDC00));
                }
            } else {
                break;
            }
            *index = i;
        } else {
            buf.append(c);
            ++*index;
        }
    }
    return buf.makeStringAndClear();
}

bool parseSchemeSpecificPart(rtl::OUString const & part) {
    sal_Int32 len = part.getLength();
    sal_Int32 i = 0;
    if (parsePart(part, true, &i).getLength() == 0 || part[0] == '/') {
        return false;
    }
    if (i == len) {
        return true;
    }
    for (;;) {
        ++i; // skip '?' or '&'
        if (parsePart(part, false, &i).getLength() == 0 || i == len
            || part[i] != '=')
        {
            return false;
        }
        ++i;
        parsePart(part, false, &i);
        if (i == len) {
            return true;
        }
        if (part[i] != '&') {
            return false;
        }
    }
}

class UrlReference:
    public cppu::WeakImplHelper1< css::uri::XVndSunStarScriptUrlReference >
{
public:
    UrlReference(rtl::OUString const & scheme, rtl::OUString const & path):
        m_base(
            scheme, false, false, rtl::OUString(), path, false, rtl::OUString())
    {}

    virtual rtl::OUString SAL_CALL getUriReference()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getUriReference(); }

    virtual sal_Bool SAL_CALL isAbsolute()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.isAbsolute(); }

    virtual rtl::OUString SAL_CALL getScheme()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getScheme(); }

    virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getSchemeSpecificPart(); }

    virtual sal_Bool SAL_CALL isHierarchical()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.isHierarchical(); }

    virtual sal_Bool SAL_CALL hasAuthority()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasAuthority(); }

    virtual rtl::OUString SAL_CALL getAuthority()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getAuthority(); }

    virtual rtl::OUString SAL_CALL getPath()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPath(); }

    virtual sal_Bool SAL_CALL hasRelativePath()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasRelativePath(); }

    virtual sal_Int32 SAL_CALL getPathSegmentCount()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPathSegmentCount(); }

    virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPathSegment(index); }

    virtual sal_Bool SAL_CALL hasQuery()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasQuery(); }

    virtual rtl::OUString SAL_CALL getQuery()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getQuery(); }

    virtual sal_Bool SAL_CALL hasFragment()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasFragment(); }

    virtual rtl::OUString SAL_CALL getFragment()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getFragment(); }

    virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
        throw (com::sun::star::uno::RuntimeException)
    { m_base.setFragment(fragment); }

    virtual void SAL_CALL clearFragment()
        throw (com::sun::star::uno::RuntimeException)
    { m_base.clearFragment(); }

    virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);

    virtual sal_Bool SAL_CALL hasParameter(rtl::OUString const & key)
        throw (css::uno::RuntimeException);

    virtual rtl::OUString SAL_CALL getParameter(rtl::OUString const & key)
        throw (css::uno::RuntimeException);

private:
    UrlReference(UrlReference &); // not implemented
    void operator =(UrlReference); // not implemented

    virtual ~UrlReference() {}

    sal_Int32 findParameter(rtl::OUString const & key);

    stoc::uriproc::UriReference m_base;
};

rtl::OUString UrlReference::getName() throw (css::uno::RuntimeException) {
    osl::MutexGuard g(m_base.m_mutex);
    sal_Int32 i = 0;
    return parsePart(m_base.m_path, true, &i);
}

sal_Bool UrlReference::hasParameter(rtl::OUString const & key)
    throw (css::uno::RuntimeException)
{
    osl::MutexGuard g(m_base.m_mutex);
    return findParameter(key) >= 0;
}

rtl::OUString UrlReference::getParameter(rtl::OUString const & key)
    throw (css::uno::RuntimeException)
{
    osl::MutexGuard g(m_base.m_mutex);
    sal_Int32 i = findParameter(key);
    return i >= 0 ? parsePart(m_base.m_path, false, &i) : rtl::OUString();
}

sal_Int32 UrlReference::findParameter(rtl::OUString const & key) {
    sal_Int32 i = 0;
    parsePart(m_base.m_path, true, &i); // skip name
    for (;;) {
        if (i == m_base.m_path.getLength()) {
            return -1;
        }
        ++i; // skip '?' or '&'
        rtl::OUString k = parsePart(m_base.m_path, false, &i);
        ++i; // skip '='
        if (k == key) {
            return i;
        }
        parsePart(m_base.m_path, false, &i); // skip value
    }
}

class Parser: public cppu::WeakImplHelper2<
    css::lang::XServiceInfo, css::uri::XUriSchemeParser >
{
public:
    Parser() {}

    virtual rtl::OUString SAL_CALL getImplementationName()
        throw (css::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
        throw (css::uno::RuntimeException);

    virtual css::uno::Sequence< rtl::OUString > SAL_CALL
    getSupportedServiceNames() throw (css::uno::RuntimeException);

    virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
    parse(
        rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
        throw (css::uno::RuntimeException);

private:
    Parser(Parser &); // not implemented
    void operator =(Parser); // not implemented

    virtual ~Parser() {}
};

rtl::OUString Parser::getImplementationName()
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::UriSchemeParser_vndDOTsunDOTstarDOTscript::
        getImplementationName();
}

sal_Bool Parser::supportsService(rtl::OUString const & serviceName)
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::supportsService(
        getSupportedServiceNames(), serviceName);
}

css::uno::Sequence< rtl::OUString > Parser::getSupportedServiceNames()
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::UriSchemeParser_vndDOTsunDOTstarDOTscript::
        getSupportedServiceNames();
}

css::uno::Reference< css::uri::XUriReference >
Parser::parse(
    rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
    throw (css::uno::RuntimeException)
{
    if (!parseSchemeSpecificPart(schemeSpecificPart)) {
        return 0;
    }
    try {
        return new UrlReference(scheme, schemeSpecificPart);
    } catch (std::bad_alloc &) {
        throw css::uno::RuntimeException(
            rtl::OUString::createFromAscii("std::bad_alloc"), 0);
    }
}

}

namespace stoc { namespace uriproc {
namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {

css::uno::Reference< css::uno::XInterface > create(
    css::uno::Reference< css::uno::XComponentContext > const &)
    SAL_THROW((css::uno::Exception))
{
    //TODO: single instance
    try {
        return static_cast< cppu::OWeakObject * >(new Parser);
    } catch (std::bad_alloc &) {
        throw css::uno::RuntimeException(
            rtl::OUString::createFromAscii("std::bad_alloc"), 0);
    }
}

rtl::OUString getImplementationName() {
    return rtl::OUString::createFromAscii(
        "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
}

css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
    css::uno::Sequence< rtl::OUString > s(1);
    s[0] = rtl::OUString::createFromAscii(
        "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
    return s;
}

} } }
<commit_msg>INTEGRATION: CWS pchfix02 (1.4.36); FILE MERGED 2006/09/01 17:41:19 kaib 1.4.36.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 17:38:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx"

#include "UriReference.hxx"
#include "supportsService.hxx"

#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "com/sun/star/uri/XUriReference.hpp"
#include "com/sun/star/uri/XUriSchemeParser.hpp"
#include "com/sun/star/uri/XVndSunStarScriptUrlReference.hpp"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/implbase2.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/mutex.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"

#include <new>

namespace css = com::sun::star;

namespace {

int getHexWeight(sal_Unicode c) {
    return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
        : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
        : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
        : -1;
}

int parseEscaped(rtl::OUString const & part, sal_Int32 * index) {
    if (part.getLength() - *index < 3 || part[*index] != '%') {
        return -1;
    }
    int n1 = getHexWeight(part[*index + 1]);
    int n2 = getHexWeight(part[*index + 2]);
    if (n1 < 0 || n2 < 0) {
        return -1;
    }
    *index += 3;
    return (n1 << 4) | n2;
}

rtl::OUString parsePart(
    rtl::OUString const & part, bool namePart, sal_Int32 * index)
{
    rtl::OUStringBuffer buf;
    while (*index < part.getLength()) {
        sal_Unicode c = part[*index];
        if (namePart ? c == '?' : c == '&' || c == '=') {
            break;
        } else if (c == '%') {
            sal_Int32 i = *index;
            int n = parseEscaped(part, &i);
            if (n >= 0 && n <= 0x7F) {
                buf.append(static_cast< sal_Unicode >(n));
            } else if (n >= 0xC0 && n <= 0xFC) {
                sal_Int32 encoded;
                int shift;
                sal_Int32 min;
                if (n <= 0xDF) {
                    encoded = (n & 0x1F) << 6;
                    shift = 0;
                    min = 0x80;
                } else if (n <= 0xEF) {
                    encoded = (n & 0x0F) << 12;
                    shift = 6;
                    min = 0x800;
                } else if (n <= 0xF7) {
                    encoded = (n & 0x07) << 18;
                    shift = 12;
                    min = 0x10000;
                } else if (n <= 0xFB) {
                    encoded = (n & 0x03) << 24;
                    shift = 18;
                    min = 0x200000;
                } else {
                    encoded = 0;
                    shift = 24;
                    min = 0x4000000;
                }
                bool utf8 = true;
                for (; shift >= 0; shift -= 6) {
                    n = parseEscaped(part, &i);
                    if (n < 0x80 || n > 0xBF) {
                        utf8 = false;
                        break;
                    }
                    encoded |= (n & 0x3F) << shift;
                }
                if (!utf8 || encoded < min
                    || encoded >= 0xD800 && encoded <= 0xDFFF
                    || encoded > 0x10FFFF)
                {
                    break;
                }
                if (encoded <= 0xFFFF) {
                    buf.append(static_cast< sal_Unicode >(encoded));
                } else {
                    buf.append(static_cast< sal_Unicode >(
                        (encoded >> 10) | 0xD800));
                    buf.append(static_cast< sal_Unicode >(
                        (encoded & 0x3FF) | 0xDC00));
                }
            } else {
                break;
            }
            *index = i;
        } else {
            buf.append(c);
            ++*index;
        }
    }
    return buf.makeStringAndClear();
}

bool parseSchemeSpecificPart(rtl::OUString const & part) {
    sal_Int32 len = part.getLength();
    sal_Int32 i = 0;
    if (parsePart(part, true, &i).getLength() == 0 || part[0] == '/') {
        return false;
    }
    if (i == len) {
        return true;
    }
    for (;;) {
        ++i; // skip '?' or '&'
        if (parsePart(part, false, &i).getLength() == 0 || i == len
            || part[i] != '=')
        {
            return false;
        }
        ++i;
        parsePart(part, false, &i);
        if (i == len) {
            return true;
        }
        if (part[i] != '&') {
            return false;
        }
    }
}

class UrlReference:
    public cppu::WeakImplHelper1< css::uri::XVndSunStarScriptUrlReference >
{
public:
    UrlReference(rtl::OUString const & scheme, rtl::OUString const & path):
        m_base(
            scheme, false, false, rtl::OUString(), path, false, rtl::OUString())
    {}

    virtual rtl::OUString SAL_CALL getUriReference()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getUriReference(); }

    virtual sal_Bool SAL_CALL isAbsolute()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.isAbsolute(); }

    virtual rtl::OUString SAL_CALL getScheme()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getScheme(); }

    virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getSchemeSpecificPart(); }

    virtual sal_Bool SAL_CALL isHierarchical()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.isHierarchical(); }

    virtual sal_Bool SAL_CALL hasAuthority()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasAuthority(); }

    virtual rtl::OUString SAL_CALL getAuthority()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getAuthority(); }

    virtual rtl::OUString SAL_CALL getPath()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPath(); }

    virtual sal_Bool SAL_CALL hasRelativePath()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasRelativePath(); }

    virtual sal_Int32 SAL_CALL getPathSegmentCount()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPathSegmentCount(); }

    virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getPathSegment(index); }

    virtual sal_Bool SAL_CALL hasQuery()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasQuery(); }

    virtual rtl::OUString SAL_CALL getQuery()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getQuery(); }

    virtual sal_Bool SAL_CALL hasFragment()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.hasFragment(); }

    virtual rtl::OUString SAL_CALL getFragment()
        throw (com::sun::star::uno::RuntimeException)
    { return m_base.getFragment(); }

    virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
        throw (com::sun::star::uno::RuntimeException)
    { m_base.setFragment(fragment); }

    virtual void SAL_CALL clearFragment()
        throw (com::sun::star::uno::RuntimeException)
    { m_base.clearFragment(); }

    virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);

    virtual sal_Bool SAL_CALL hasParameter(rtl::OUString const & key)
        throw (css::uno::RuntimeException);

    virtual rtl::OUString SAL_CALL getParameter(rtl::OUString const & key)
        throw (css::uno::RuntimeException);

private:
    UrlReference(UrlReference &); // not implemented
    void operator =(UrlReference); // not implemented

    virtual ~UrlReference() {}

    sal_Int32 findParameter(rtl::OUString const & key);

    stoc::uriproc::UriReference m_base;
};

rtl::OUString UrlReference::getName() throw (css::uno::RuntimeException) {
    osl::MutexGuard g(m_base.m_mutex);
    sal_Int32 i = 0;
    return parsePart(m_base.m_path, true, &i);
}

sal_Bool UrlReference::hasParameter(rtl::OUString const & key)
    throw (css::uno::RuntimeException)
{
    osl::MutexGuard g(m_base.m_mutex);
    return findParameter(key) >= 0;
}

rtl::OUString UrlReference::getParameter(rtl::OUString const & key)
    throw (css::uno::RuntimeException)
{
    osl::MutexGuard g(m_base.m_mutex);
    sal_Int32 i = findParameter(key);
    return i >= 0 ? parsePart(m_base.m_path, false, &i) : rtl::OUString();
}

sal_Int32 UrlReference::findParameter(rtl::OUString const & key) {
    sal_Int32 i = 0;
    parsePart(m_base.m_path, true, &i); // skip name
    for (;;) {
        if (i == m_base.m_path.getLength()) {
            return -1;
        }
        ++i; // skip '?' or '&'
        rtl::OUString k = parsePart(m_base.m_path, false, &i);
        ++i; // skip '='
        if (k == key) {
            return i;
        }
        parsePart(m_base.m_path, false, &i); // skip value
    }
}

class Parser: public cppu::WeakImplHelper2<
    css::lang::XServiceInfo, css::uri::XUriSchemeParser >
{
public:
    Parser() {}

    virtual rtl::OUString SAL_CALL getImplementationName()
        throw (css::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
        throw (css::uno::RuntimeException);

    virtual css::uno::Sequence< rtl::OUString > SAL_CALL
    getSupportedServiceNames() throw (css::uno::RuntimeException);

    virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
    parse(
        rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
        throw (css::uno::RuntimeException);

private:
    Parser(Parser &); // not implemented
    void operator =(Parser); // not implemented

    virtual ~Parser() {}
};

rtl::OUString Parser::getImplementationName()
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::UriSchemeParser_vndDOTsunDOTstarDOTscript::
        getImplementationName();
}

sal_Bool Parser::supportsService(rtl::OUString const & serviceName)
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::supportsService(
        getSupportedServiceNames(), serviceName);
}

css::uno::Sequence< rtl::OUString > Parser::getSupportedServiceNames()
    throw (css::uno::RuntimeException)
{
    return stoc::uriproc::UriSchemeParser_vndDOTsunDOTstarDOTscript::
        getSupportedServiceNames();
}

css::uno::Reference< css::uri::XUriReference >
Parser::parse(
    rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
    throw (css::uno::RuntimeException)
{
    if (!parseSchemeSpecificPart(schemeSpecificPart)) {
        return 0;
    }
    try {
        return new UrlReference(scheme, schemeSpecificPart);
    } catch (std::bad_alloc &) {
        throw css::uno::RuntimeException(
            rtl::OUString::createFromAscii("std::bad_alloc"), 0);
    }
}

}

namespace stoc { namespace uriproc {
namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {

css::uno::Reference< css::uno::XInterface > create(
    css::uno::Reference< css::uno::XComponentContext > const &)
    SAL_THROW((css::uno::Exception))
{
    //TODO: single instance
    try {
        return static_cast< cppu::OWeakObject * >(new Parser);
    } catch (std::bad_alloc &) {
        throw css::uno::RuntimeException(
            rtl::OUString::createFromAscii("std::bad_alloc"), 0);
    }
}

rtl::OUString getImplementationName() {
    return rtl::OUString::createFromAscii(
        "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
}

css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
    css::uno::Sequence< rtl::OUString > s(1);
    s[0] = rtl::OUString::createFromAscii(
        "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
    return s;
}

} } }
<|endoftext|>