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

#include "augmenter/augmenter.h"

#include "gtest/gtest.h"
#include "protocol_buffer/document.pb.h"
#include "protocol_buffer/documents.pb.h"

namespace augmenter {

bert_annotator::Documents construct_test_document() {
  bert_annotator::Documents documents;
  bert_annotator::Document* document = documents.add_documents();
  document->set_text("Text with some InterWordCapitalization");
  bert_annotator::Token* token;
  token = document->add_token();
  token->set_start(0);
  token->set_end(3);
  token->set_word("Text");
  token = document->add_token();
  token->set_start(5);
  token->set_end(8);
  token->set_word("with");
  token = document->add_token();
  token->set_start(10);
  token->set_end(13);
  token->set_word("some");
  token = document->add_token();
  token->set_start(15);
  token->set_end(37);
  token->set_word("InterWordCapitalization");

  return documents;
}

TEST(AugmenterTest, AugmentsAreAdded) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_EQ(augmenter.get_documents().documents_size(), 2);
}

TEST(AugmenterTest, NoLowercasingForZeroPercent) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(0.0);

  ASSERT_STREQ(augmenter.get_documents().documents(0).text().c_str(),
               "Text with some InterWordCapitalization");
}

TEST(AugmenterTest, CompleteLowercasingForHundretPercent) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_STREQ(augmenter.get_documents().documents(1).text().c_str(),
               "text with some interwordcapitalization");
}

TEST(AugmenterTest, DontLowercaseNonTokens) {
  bert_annotator::Documents documents;
  bert_annotator::Document* document = documents.add_documents();
  document->set_text("[BOS] Text with some InterWordCapitalization [EOS]");
  bert_annotator::Token* token;
  token = document->add_token();
  token->set_start(6);
  token->set_end(9);
  token->set_word("Text");
  token = document->add_token();
  token->set_start(11);
  token->set_end(14);
  token->set_word("with");
  token = document->add_token();
  token->set_start(16);
  token->set_end(19);
  token->set_word("some");
  token = document->add_token();
  token->set_start(21);
  token->set_end(43);
  token->set_word("InterWordCapitalization");
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_STREQ(augmenter.get_documents().documents(1).text().c_str(),
               "[BOS] text with some interwordcapitalization [EOS]");
}

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

#include "augmenter/augmenter.h"

#include "gtest/gtest.h"
#include "protocol_buffer/document.pb.h"
#include "protocol_buffer/documents.pb.h"

namespace augmenter {

bert_annotator::Documents construct_test_document() {
  bert_annotator::Documents documents;
  bert_annotator::Document* document = documents.add_documents();
  document->set_text("Text with some InterWordCapitalization");
  bert_annotator::Token* token;
  token = document->add_token();
  token->set_start(0);
  token->set_end(3);
  token->set_word("Text");
  token = document->add_token();
  token->set_start(5);
  token->set_end(8);
  token->set_word("with");
  token = document->add_token();
  token->set_start(10);
  token->set_end(13);
  token->set_word("some");
  token = document->add_token();
  token->set_start(15);
  token->set_end(37);
  token->set_word("InterWordCapitalization");

  return documents;
}

TEST(AugmenterTest, AugmentsAreAdded) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_EQ(augmenter.get_documents().documents_size(), 2);
}

TEST(AugmenterTest, NoLowercasingForZeroPercent) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(0.0);

  ASSERT_STREQ(augmenter.get_documents().documents(0).text().c_str(),
               "Text with some InterWordCapitalization");
}

TEST(AugmenterTest, CompleteLowercasingForHundredPercent) {
  bert_annotator::Documents documents = construct_test_document();
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_STREQ(augmenter.get_documents().documents(1).text().c_str(),
               "text with some interwordcapitalization");
}

TEST(AugmenterTest, DontLowercaseNonTokens) {
  bert_annotator::Documents documents;
  bert_annotator::Document* document = documents.add_documents();
  document->set_text("[BOS] Text with some InterWordCapitalization [EOS]");
  bert_annotator::Token* token;
  token = document->add_token();
  token->set_start(6);
  token->set_end(9);
  token->set_word("Text");
  token = document->add_token();
  token->set_start(11);
  token->set_end(14);
  token->set_word("with");
  token = document->add_token();
  token->set_start(16);
  token->set_end(19);
  token->set_word("some");
  token = document->add_token();
  token->set_start(21);
  token->set_end(43);
  token->set_word("InterWordCapitalization");
  Augmenter augmenter = Augmenter(documents);

  augmenter.lowercase(1.0);

  ASSERT_STREQ(augmenter.get_documents().documents(1).text().c_str(),
               "[BOS] text with some interwordcapitalization [EOS]");
}

}  // namespace augmenter
<|endoftext|>


<commit_before>///
/// Copyright 2017 Matt Kaes All Rights Reserved.
///
// 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.
//

#pragma once
#include "immintrin.h" // AVX Intrinsics
#include <cstring> // memset
#include <intrin.h> // _BitScanForward

// Make sure we are able to use AVX2
#ifndef __AVX2__
#ifdef _MSC_VER
#warning "AVX2 is not enabled. Please compile with /arch:AVX2"
#else
#error "AVX2 is not enabled. Please compile with -mavx"
#endif
#endif // !__AVX2__

// This is important to make sure magic AVX alignment works
static_assert(sizeof(int) == 4, "unsigned != 4 bytes! Alignment issues for buckets will occur.");

// Turn Intel warnings into errors
#pragma warning (error: 4752)

#define _m_256i_IntPack(a) _mm256_set_epi32(a,a,a,a,a,a,a,a)
#define AVX_Or(a, b)

// Linear probing Vector Table for unsigned four byte words
// Non-distructing variant
template <typename Value>
class VectorizedTable {
public:
  VectorizedTable()
  {
    m_valueHeap = nullptr;
    m_mm_keyHeap = nullptr;
    m_mm_statesHeap = nullptr;

    grow(MinCapacity);
  }

  ~VectorizedTable()
  {
    // Would just be faster to leak &| segfault
    delete[] m_valueHeap;
    _mm_free(m_mm_keyHeap);
    _mm_free(m_mm_statesHeap);
  }

  Value& add(int index, const Value& value)
  {
    // Catch the issue with repeat adds
    int slot = slotOf(hash(index));
    if (slot != -1)
      return m_valueHeap[slot] = value;

    return insert(hash(index), value);
  }

  bool containsKey(int index) const
  {
    return slotOf(hash(index)) != -1;
  }

  Value& at(int index)
  {
    int slot = slotOf(hash(index));

    if (slot != -1)
      return m_valueHeap[slot];
    else
      return insert(hash(index), Value());
  }

  const Value& operator[](int index) const
  {
    int slot = slotOf(hash(index));

    if (slot != -1)
      return m_valueHeap[slot];
    else
      return Value();
  }

  Value& operator[](int index)
  {
    return at(index);
  }

  void clear()
  {
    memset(m_mm_keyHeap, 0, m_capacity * sizeof(int));
    memset(m_mm_statesHeap, 0, m_capacity * sizeof(int));
  }

  int size()
  {
    return m_size;
  }

  int capacity()
  {
    return m_capacity;
  }

private:
  int hash(int x) const {
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = (x >> 16) ^ x;
    return x;
  }

  Value& insert(int hashIndex, const Value& value)
  {
    if (m_size >= m_capacity / GrowFactor)
      grow(m_capacity * GrowFactor);
    m_size++;

    int slot = openSlot(hashIndex);
    m_mm_keyHeap[slot] = hashIndex;
    m_mm_statesHeap[slot] = BucketState::InUse;
    return m_valueHeap[slot] = value;
  }

  int openSlot(int hashedIndex) const
  {
    // Create an InUse mask to see if a bucket is full
    const __m256i inuseMask = _m_256i_IntPack((int)BucketState::InUse);
    int bucketId = ((hashedIndex  % m_capacity) / sizeof(__m256i) * sizeof(int)) / sizeof(int);
    const int bucketCount = m_capacity * sizeof(int) / sizeof(__m256i);
    const int bucketCountBits = bucketCount - 1;

    while (true)
    {
      // life finding
      const __m256i stateMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], inuseMask));
      const __m256i stateMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], inuseMask));
      const __m256i stateMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], inuseMask));
      const __m256i stateMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], inuseMask));
      const int stateMap = ~_mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(stateMask1, stateMask2), stateMask3), stateMask4));

      unsigned long lowestIndex;
      const long slotFound = _BitScanForward(&lowestIndex, stateMap);

      if (slotFound)
        return (bucketId << 3) + ((lowestIndex & 3) << 3) + (lowestIndex >> 2);

      // Next bucket.
      bucketId = (bucketId + 4) & (bucketCountBits);
    }
  }

  int slotOf(int hashedIndex) const
  {
    // Create an Empty mask to see if we can stop
    const __m256i emptyMask = _m_256i_IntPack((int)BucketState::Empty);
    const __m256i inuseMask = _m_256i_IntPack((int)BucketState::InUse);
    const __m256i indexMask = _m_256i_IntPack(hashedIndex);

    int bucketId = ((hashedIndex  % m_capacity) / sizeof(__m256i) * sizeof(int)) / sizeof(int);
    const int bucketCount = m_capacity * sizeof(int) / sizeof(__m256i);
    const int bucketCountBits = bucketCount - 1;
    int emptyBucket = 0;

    while (true)
    {
      // Value finding
      const __m256i valueMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId], indexMask));
      const __m256i valueMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 1], indexMask));
      const __m256i valueMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 2], indexMask));
      const __m256i valueMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 3], indexMask));

      // life finding
      const __m256i stateMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], inuseMask));
      const __m256i stateMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], inuseMask));
      const __m256i stateMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], inuseMask));
      const __m256i stateMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], inuseMask));

      // Back to scaler mode
      int valueMap = _mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(valueMask1, valueMask2), valueMask3), valueMask4));
      const int stateMap = _mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(stateMask1, stateMask2), stateMask3), stateMask4));

      // Wipe empty cells
      valueMap &= stateMap;

      unsigned long lowestIndex;
      const long foundValue = _BitScanForward(&lowestIndex, valueMap);

      if (foundValue)
        return (bucketId << 3) + ((lowestIndex & 3) << 3) + (lowestIndex >> 2);

      // Empty block found
      __m256i empty = _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], emptyMask);
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], emptyMask));
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], emptyMask));
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], emptyMask));

      if (_mm256_movemask_epi8(empty))
        return -1;

      bucketId = (bucketId + 4) & (bucketCountBits);
    }
  }

  void grow(int capacity)
  {
    // Keep a reference to the old pointers
    Value* oldValueHeap = m_valueHeap;
    int* oldKeyHeap = m_mm_keyHeap;
    BucketState* oldStatesHeap = m_mm_statesHeap;
    int oldCapacity = m_capacity;

    // Creating all of the objects
    m_size = 0;
    m_capacity = capacity;
    m_valueHeap = new Value[m_capacity];
    m_mm_keyHeap = (int*)_mm_malloc(m_capacity * sizeof(*m_mm_keyHeap), AVXAlignment);
    m_mm_statesHeap = (BucketState*)_mm_malloc(m_capacity * sizeof(*m_mm_statesHeap), AVXAlignment);

    clear();

    if (oldStatesHeap)
    {
      for (int i = 0; i < oldCapacity; i++)
        if (oldStatesHeap[i] == BucketState::InUse)
          insert(oldKeyHeap[i], oldValueHeap[i]);

      delete[] oldValueHeap;
      _mm_free(oldKeyHeap);
      _mm_free(oldStatesHeap);
    }
  }

  enum class BucketState : int
  {
    Empty = 0,
    InUse = 1,
    Dead = 2
  };

  Value* m_valueHeap;
  int* m_mm_keyHeap;
  BucketState* m_mm_statesHeap;

  int m_size;
  int m_capacity;

  const int AVXAlignment = 16;
  const int MinCapacity = 64;
  const int GrowFactor = 4;

  const __m256i byte1Mask = _m_256i_IntPack(0x000000FF);
  const __m256i byte2Mask = _m_256i_IntPack(0x0000FF00);
  const __m256i byte3Mask = _m_256i_IntPack(0x00FF0000);
  const __m256i byte4Mask = _m_256i_IntPack(0xFF000000);
};<commit_msg>Clear Fix<commit_after>///
/// Copyright 2017 Matt Kaes All Rights Reserved.
///
// 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.
//

#pragma once
#include "immintrin.h" // AVX Intrinsics
#include <cstring> // memset
#include <intrin.h> // _BitScanForward

// Make sure we are able to use AVX2
#ifndef __AVX2__
#ifdef _MSC_VER
#warning "AVX2 is not enabled. Please compile with /arch:AVX2"
#else
#error "AVX2 is not enabled. Please compile with -mavx"
#endif
#endif // !__AVX2__

// This is important to make sure magic AVX alignment works
static_assert(sizeof(int) == 4, "unsigned != 4 bytes! Alignment issues for buckets will occur.");

// Turn Intel warnings into errors
#pragma warning (error: 4752)

#define _m_256i_IntPack(a) _mm256_set_epi32(a,a,a,a,a,a,a,a)
#define AVX_Or(a, b)

// Linear probing Vector Table for unsigned four byte words
// Non-distructing variant
template <typename Value>
class VectorizedTable {
public:
  VectorizedTable()
  {
    m_valueHeap = nullptr;
    m_mm_keyHeap = nullptr;
    m_mm_statesHeap = nullptr;

    grow(MinCapacity);
  }

  ~VectorizedTable()
  {
    delete[] m_valueHeap;
    _mm_free(m_mm_keyHeap);
    _mm_free(m_mm_statesHeap);
  }

  Value& add(int index, const Value& value)
  {
    // Catch the issue with repeat adds
    int slot = slotOf(hash(index));
    if (slot != -1)
      return m_valueHeap[slot] = value;

    return insert(hash(index), value);
  }

  bool containsKey(int index) const
  {
    return slotOf(hash(index)) != -1;
  }

  Value& at(int index)
  {
    int slot = slotOf(hash(index));

    if (slot != -1)
      return m_valueHeap[slot];
    else
      return insert(hash(index), Value());
  }

  const Value& operator[](int index) const
  {
    int slot = slotOf(hash(index));

    if (slot != -1)
      return m_valueHeap[slot];
    else
      return Value();
  }

  Value& operator[](int index)
  {
    return at(index);
  }

  void clear()
  {
    m_size = 0;
    memset(m_mm_keyHeap, 0, m_capacity * sizeof(int));
    memset(m_mm_statesHeap, 0, m_capacity * sizeof(int));
  }

  int size()
  {
    return m_size;
  }

  int capacity()
  {
    return m_capacity;
  }

private:
  int hash(int x) const {
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = ((x >> 16) ^ x) * 0x45d9f3b;
    x = (x >> 16) ^ x;
    return x;
  }

  Value& insert(int hashIndex, const Value& value)
  {
    if (m_size >= m_capacity / GrowFactor)
      grow(m_capacity * GrowFactor);
    m_size++;

    int slot = openSlot(hashIndex);
    m_mm_keyHeap[slot] = hashIndex;
    m_mm_statesHeap[slot] = BucketState::InUse;
    return m_valueHeap[slot] = value;
  }

  int openSlot(int hashedIndex) const
  {
    // Create an InUse mask to see if a bucket is full
    const __m256i inuseMask = _m_256i_IntPack((int)BucketState::InUse);
    int bucketId = ((hashedIndex  % m_capacity) / sizeof(__m256i) * sizeof(int)) / sizeof(int);
    const int bucketCount = m_capacity * sizeof(int) / sizeof(__m256i);
    const int bucketCountBits = bucketCount - 1;

    while (true)
    {
      // life finding
      const __m256i stateMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], inuseMask));
      const __m256i stateMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], inuseMask));
      const __m256i stateMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], inuseMask));
      const __m256i stateMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], inuseMask));
      const int stateMap = ~_mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(stateMask1, stateMask2), stateMask3), stateMask4));

      unsigned long lowestIndex;
      const long slotFound = _BitScanForward(&lowestIndex, stateMap);

      if (slotFound)
        return (bucketId << 3) + ((lowestIndex & 3) << 3) + (lowestIndex >> 2);

      // Next bucket.
      bucketId = (bucketId + 4) & (bucketCountBits);
    }
  }

  int slotOf(int hashedIndex) const
  {
    // Create an Empty mask to see if we can stop
    const __m256i emptyMask = _m_256i_IntPack((int)BucketState::Empty);
    const __m256i inuseMask = _m_256i_IntPack((int)BucketState::InUse);
    const __m256i indexMask = _m_256i_IntPack(hashedIndex);

    int bucketId = ((hashedIndex  % m_capacity) / sizeof(__m256i) * sizeof(int)) / sizeof(int);
    const int bucketCount = m_capacity * sizeof(int) / sizeof(__m256i);
    const int bucketCountBits = bucketCount - 1;
    int emptyBucket = 0;

    while (true)
    {
      // Value finding
      const __m256i valueMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId], indexMask));
      const __m256i valueMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 1], indexMask));
      const __m256i valueMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 2], indexMask));
      const __m256i valueMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_keyHeap)[bucketId + 3], indexMask));

      // life finding
      const __m256i stateMask1 = _mm256_and_si256(byte1Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], inuseMask));
      const __m256i stateMask2 = _mm256_and_si256(byte2Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], inuseMask));
      const __m256i stateMask3 = _mm256_and_si256(byte3Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], inuseMask));
      const __m256i stateMask4 = _mm256_and_si256(byte4Mask, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], inuseMask));

      // Back to scaler mode
      int valueMap = _mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(valueMask1, valueMask2), valueMask3), valueMask4));
      const int stateMap = _mm256_movemask_epi8(_mm256_or_si256(_mm256_or_si256(_mm256_or_si256(stateMask1, stateMask2), stateMask3), stateMask4));

      // Wipe empty cells
      valueMap &= stateMap;

      unsigned long lowestIndex;
      const long foundValue = _BitScanForward(&lowestIndex, valueMap);

      if (foundValue)
        return (bucketId << 3) + ((lowestIndex & 3) << 3) + (lowestIndex >> 2);

      // Empty block found
      __m256i empty = _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId], emptyMask);
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 1], emptyMask));
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 2], emptyMask));
      empty = _mm256_or_si256(empty, _mm256_cmpeq_epi32(((__m256i*)m_mm_statesHeap)[bucketId + 3], emptyMask));

      if (_mm256_movemask_epi8(empty))
        return -1;

      bucketId = (bucketId + 4) & (bucketCountBits);
    }
  }

  void grow(int capacity)
  {
    // Keep a reference to the old pointers
    Value* oldValueHeap = m_valueHeap;
    int* oldKeyHeap = m_mm_keyHeap;
    BucketState* oldStatesHeap = m_mm_statesHeap;
    int oldCapacity = m_capacity;

    // Creating all of the objects
    m_capacity = capacity;
    m_valueHeap = new Value[m_capacity];
    m_mm_keyHeap = (int*)_mm_malloc(m_capacity * sizeof(*m_mm_keyHeap), AVXAlignment);
    m_mm_statesHeap = (BucketState*)_mm_malloc(m_capacity * sizeof(*m_mm_statesHeap), AVXAlignment);

    clear();

    if (oldStatesHeap)
    {
      for (int i = 0; i < oldCapacity; i++)
        if (oldStatesHeap[i] == BucketState::InUse)
          insert(oldKeyHeap[i], oldValueHeap[i]);

      delete[] oldValueHeap;
      _mm_free(oldKeyHeap);
      _mm_free(oldStatesHeap);
    }
  }

  enum class BucketState : int
  {
    Empty = 0,
    InUse = 1,
    Dead = 2
  };

  Value* m_valueHeap;
  int* m_mm_keyHeap;
  BucketState* m_mm_statesHeap;

  int m_size;
  int m_capacity;

  const int AVXAlignment = 16;
  const int MinCapacity = 64;
  const int GrowFactor = 4;

  const __m256i byte1Mask = _m_256i_IntPack(0x000000FF);
  const __m256i byte2Mask = _m_256i_IntPack(0x0000FF00);
  const __m256i byte3Mask = _m_256i_IntPack(0x00FF0000);
  const __m256i byte4Mask = _m_256i_IntPack(0xFF000000);
};<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlmeta.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 22:31:14 $
 *
 *  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_sw.hxx"

#include <hintids.hxx>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTINFOSUPPLIER_HPP_
#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXTDOCUMENT_HPP_
#include <com/sun/star/text/XTextDocument.hpp>
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif

#ifndef _XMLOFF_XMLMETAI_HXX
#include <xmloff/xmlmetai.hxx>
#endif

#ifndef _XMLOFF_XMLMETAE_HXX
#include <xmloff/xmlmetae.hxx>
#endif
#ifndef _SVX_LANGITEM_HXX
#include <svx/langitem.hxx>
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _DOCSTAT_HXX
#include "docstat.hxx"
#endif
#ifndef _SWDOCSH_HXX
#include "docsh.hxx"
#endif
#ifndef _DOC_HXX //autogen wg. SwDoc
#include <doc.hxx>
#endif
#ifndef _UNOOBJ_HXX
#include <unoobj.hxx>
#endif

#ifndef _XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLEXP_HXX
#include "xmlexp.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

// ---------------------------------------------------------------------

SvXMLImportContext *SwXMLImport::CreateMetaContext(
                                       const OUString& rLocalName )
{
    SvXMLImportContext *pContext = 0;

    if( !(IsStylesOnlyMode() || IsInsertMode()) )
    {
        pContext = new SfxXMLMetaContext( *this,
                                    XML_NAMESPACE_OFFICE, rLocalName,
                                    GetModel() );
    }

    if( !pContext )
        pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE,
                                              rLocalName );

    return pContext;
}

// ---------------------------------------------------------------------

enum SvXMLTokenMapAttrs
{
    XML_TOK_META_STAT_TABLE = 1,
    XML_TOK_META_STAT_IMAGE = 2,
    XML_TOK_META_STAT_OLE = 4,
    XML_TOK_META_STAT_PAGE = 8,
    XML_TOK_META_STAT_PARA = 16,
    XML_TOK_META_STAT_WORD = 32,
    XML_TOK_META_STAT_CHAR = 64,
    XML_TOK_META_STAT_END=XML_TOK_UNKNOWN
};

static __FAR_DATA SvXMLTokenMapEntry aMetaStatAttrTokenMap[] =
{
    { XML_NAMESPACE_META, XML_TABLE_COUNT,      XML_TOK_META_STAT_TABLE },
    { XML_NAMESPACE_META, XML_IMAGE_COUNT,      XML_TOK_META_STAT_IMAGE },
    { XML_NAMESPACE_META, XML_OBJECT_COUNT,     XML_TOK_META_STAT_OLE   },
    { XML_NAMESPACE_META, XML_PARAGRAPH_COUNT,  XML_TOK_META_STAT_PARA  },
    { XML_NAMESPACE_META, XML_PAGE_COUNT,       XML_TOK_META_STAT_PAGE  },
    { XML_NAMESPACE_META, XML_WORD_COUNT,       XML_TOK_META_STAT_WORD  },
    { XML_NAMESPACE_META, XML_CHARACTER_COUNT,  XML_TOK_META_STAT_CHAR  },
    XML_TOKEN_MAP_END
};
void SwXMLImport::SetStatisticAttributes(
        const Reference< xml::sax::XAttributeList > & xAttrList)
{
    if( IsStylesOnlyMode() || IsInsertMode() )
        return;

    SvXMLImport::SetStatisticAttributes(xAttrList);

    Reference<XUnoTunnel> xCrsrTunnel( GetTextImport()->GetCursor(),
                                       UNO_QUERY);
    ASSERT( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
    OTextCursorHelper *pTxtCrsr = (OTextCursorHelper*)xCrsrTunnel->getSomething(
                                        OTextCursorHelper::getUnoTunnelId() );
    ASSERT( pTxtCrsr, "SwXTextCursor missing" );
    SwDoc *pDoc = pTxtCrsr->GetDoc();
    SwDocStat aDocStat( pDoc->GetDocStat() );

    SvXMLTokenMap aTokenMap( aMetaStatAttrTokenMap );

    sal_uInt32 nTokens = 0;
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rValue = xAttrList->getValueByIndex( i );
        sal_Int32 nValue;
        if( !GetMM100UnitConverter().convertNumber( nValue, rValue ) )
            continue;

        const OUString& rAttrName = xAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );

        sal_uInt32 nToken = aTokenMap.Get( nPrefix, aLocalName );
        switch( nToken )
        {
        case XML_TOK_META_STAT_TABLE:
            aDocStat.nTbl = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_IMAGE:
            aDocStat.nGrf = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_OLE:
            aDocStat.nOLE = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_PAGE:
            aDocStat.nPage = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_PARA:
            aDocStat.nPara = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_WORD:
            aDocStat.nWord = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_CHAR:
            aDocStat.nChar = (sal_uInt32)nValue;
            break;
        default:
            nToken = 0;
        }
        nTokens |= nToken;
    }

    if( 127 == nTokens )
        aDocStat.bModified = sal_False;
    if( nTokens )
        pDoc->SetDocStat( aDocStat );

    // set progress bar reference to #paragraphs. If not available,
    // use #pages*10, or guesstimate 250 paragraphs. Additionally
    // guesstimate PROGRESS_BAR_STEPS each for meta+settings, styles,
    // and autostyles.
    sal_Int32 nProgressReference = 250;
    if( nTokens & XML_TOK_META_STAT_PARA )
        nProgressReference = (sal_Int32)aDocStat.nPara;
    else if ( nTokens & XML_TOK_META_STAT_PAGE )
        nProgressReference = 10 * (sal_Int32)aDocStat.nPage;
    ProgressBarHelper* pProgress = GetProgressBarHelper();
    pProgress->SetReference( nProgressReference + 3*PROGRESS_BAR_STEP );
    pProgress->SetValue( 0 );
}

// ---------------------------------------------------------------------

void SwXMLExport::_ExportMeta()
{
    SvXMLExport::_ExportMeta();

    if( !IsBlockMode() )
    {
        OUStringBuffer aOut(16);

        Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY );
        Reference < XText > xText = xTextDoc->getText();
        Reference<XUnoTunnel> xTextTunnel( xText, UNO_QUERY);
        ASSERT( xTextTunnel.is(), "missing XUnoTunnel for Cursor" );
        if( !xTextTunnel.is() )
            return;

        SwXText *pText = (SwXText *)xTextTunnel->getSomething(
                                            SwXText::getUnoTunnelId() );
        ASSERT( pText, "SwXText missing" );
        if( !pText )
            return;

        SwDocStat aDocStat( pText->GetDoc()->GetDocStat() );
        aOut.append( (sal_Int32)aDocStat.nTbl );
        AddAttribute( XML_NAMESPACE_META, XML_TABLE_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nGrf );
        AddAttribute( XML_NAMESPACE_META, XML_IMAGE_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nOLE );
        AddAttribute( XML_NAMESPACE_META, XML_OBJECT_COUNT,
                      aOut.makeStringAndClear() );
        if( aDocStat.nPage )
        {
            aOut.append( (sal_Int32)aDocStat.nPage );
            AddAttribute( XML_NAMESPACE_META, XML_PAGE_COUNT,
                          aOut.makeStringAndClear() );
        }
        aOut.append( (sal_Int32)aDocStat.nPara );
        AddAttribute( XML_NAMESPACE_META, XML_PARAGRAPH_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nWord );
        AddAttribute( XML_NAMESPACE_META, XML_WORD_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nChar );
        AddAttribute( XML_NAMESPACE_META, XML_CHARACTER_COUNT,
                      aOut.makeStringAndClear() );
        SvXMLElementExport aElem( *this, XML_NAMESPACE_META,
                                  XML_DOCUMENT_STATISTIC,
                                  sal_True, sal_True );

        if( IsShowProgress() )
        {
            ProgressBarHelper *pProgress = GetProgressBarHelper();
            pProgress->SetValue( pProgress->GetValue() + 2 );
        }
    }
}

<commit_msg>INTEGRATION: CWS rpt23fix01 (1.15.386); FILE MERGED 2007/07/13 10:03:57 ama 1.15.386.1: Fix #i78827#: DocFromModel instead from TxtCrsr<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlmeta.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: hr $ $Date: 2007-08-02 14:22:03 $
 *
 *  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_sw.hxx"

#include <hintids.hxx>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTINFOSUPPLIER_HPP_
#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXTDOCUMENT_HPP_
#include <com/sun/star/text/XTextDocument.hpp>
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif

#ifndef _XMLOFF_XMLMETAI_HXX
#include <xmloff/xmlmetai.hxx>
#endif

#ifndef _XMLOFF_XMLMETAE_HXX
#include <xmloff/xmlmetae.hxx>
#endif
#ifndef _SVX_LANGITEM_HXX
#include <svx/langitem.hxx>
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _DOCSTAT_HXX
#include "docstat.hxx"
#endif
#ifndef _SWDOCSH_HXX
#include "docsh.hxx"
#endif
#ifndef _DOC_HXX //autogen wg. SwDoc
#include <doc.hxx>
#endif
#ifndef _UNOOBJ_HXX
#include <unoobj.hxx>
#endif

#ifndef _XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLEXP_HXX
#include "xmlexp.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

// ---------------------------------------------------------------------

SvXMLImportContext *SwXMLImport::CreateMetaContext(
                                       const OUString& rLocalName )
{
    SvXMLImportContext *pContext = 0;

    if( !(IsStylesOnlyMode() || IsInsertMode()) )
    {
        pContext = new SfxXMLMetaContext( *this,
                                    XML_NAMESPACE_OFFICE, rLocalName,
                                    GetModel() );
    }

    if( !pContext )
        pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE,
                                              rLocalName );

    return pContext;
}

// ---------------------------------------------------------------------

enum SvXMLTokenMapAttrs
{
    XML_TOK_META_STAT_TABLE = 1,
    XML_TOK_META_STAT_IMAGE = 2,
    XML_TOK_META_STAT_OLE = 4,
    XML_TOK_META_STAT_PAGE = 8,
    XML_TOK_META_STAT_PARA = 16,
    XML_TOK_META_STAT_WORD = 32,
    XML_TOK_META_STAT_CHAR = 64,
    XML_TOK_META_STAT_END=XML_TOK_UNKNOWN
};

static __FAR_DATA SvXMLTokenMapEntry aMetaStatAttrTokenMap[] =
{
    { XML_NAMESPACE_META, XML_TABLE_COUNT,      XML_TOK_META_STAT_TABLE },
    { XML_NAMESPACE_META, XML_IMAGE_COUNT,      XML_TOK_META_STAT_IMAGE },
    { XML_NAMESPACE_META, XML_OBJECT_COUNT,     XML_TOK_META_STAT_OLE   },
    { XML_NAMESPACE_META, XML_PARAGRAPH_COUNT,  XML_TOK_META_STAT_PARA  },
    { XML_NAMESPACE_META, XML_PAGE_COUNT,       XML_TOK_META_STAT_PAGE  },
    { XML_NAMESPACE_META, XML_WORD_COUNT,       XML_TOK_META_STAT_WORD  },
    { XML_NAMESPACE_META, XML_CHARACTER_COUNT,  XML_TOK_META_STAT_CHAR  },
    XML_TOKEN_MAP_END
};
void SwXMLImport::SetStatisticAttributes(
        const Reference< xml::sax::XAttributeList > & xAttrList)
{
    if( IsStylesOnlyMode() || IsInsertMode() )
        return;

    SvXMLImport::SetStatisticAttributes(xAttrList);

    SwDoc *pDoc = SwImport::GetDocFromXMLImport( *this );
    SwDocStat aDocStat( pDoc->GetDocStat() );

    SvXMLTokenMap aTokenMap( aMetaStatAttrTokenMap );

    sal_uInt32 nTokens = 0;
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rValue = xAttrList->getValueByIndex( i );
        sal_Int32 nValue;
        if( !GetMM100UnitConverter().convertNumber( nValue, rValue ) )
            continue;

        const OUString& rAttrName = xAttrList->getNameByIndex( i );
        OUString aLocalName;
        sal_uInt16 nPrefix =
            GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );

        sal_uInt32 nToken = aTokenMap.Get( nPrefix, aLocalName );
        switch( nToken )
        {
        case XML_TOK_META_STAT_TABLE:
            aDocStat.nTbl = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_IMAGE:
            aDocStat.nGrf = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_OLE:
            aDocStat.nOLE = (sal_uInt16)nValue;
            break;
        case XML_TOK_META_STAT_PAGE:
            aDocStat.nPage = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_PARA:
            aDocStat.nPara = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_WORD:
            aDocStat.nWord = (sal_uInt32)nValue;
            break;
        case XML_TOK_META_STAT_CHAR:
            aDocStat.nChar = (sal_uInt32)nValue;
            break;
        default:
            nToken = 0;
        }
        nTokens |= nToken;
    }

    if( 127 == nTokens )
        aDocStat.bModified = sal_False;
    if( nTokens )
        pDoc->SetDocStat( aDocStat );

    // set progress bar reference to #paragraphs. If not available,
    // use #pages*10, or guesstimate 250 paragraphs. Additionally
    // guesstimate PROGRESS_BAR_STEPS each for meta+settings, styles,
    // and autostyles.
    sal_Int32 nProgressReference = 250;
    if( nTokens & XML_TOK_META_STAT_PARA )
        nProgressReference = (sal_Int32)aDocStat.nPara;
    else if ( nTokens & XML_TOK_META_STAT_PAGE )
        nProgressReference = 10 * (sal_Int32)aDocStat.nPage;
    ProgressBarHelper* pProgress = GetProgressBarHelper();
    pProgress->SetReference( nProgressReference + 3*PROGRESS_BAR_STEP );
    pProgress->SetValue( 0 );
}

// ---------------------------------------------------------------------

void SwXMLExport::_ExportMeta()
{
    SvXMLExport::_ExportMeta();

    if( !IsBlockMode() )
    {
        OUStringBuffer aOut(16);

        Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY );
        Reference < XText > xText = xTextDoc->getText();
        Reference<XUnoTunnel> xTextTunnel( xText, UNO_QUERY);
        ASSERT( xTextTunnel.is(), "missing XUnoTunnel for Cursor" );
        if( !xTextTunnel.is() )
            return;

        SwXText *pText = (SwXText *)xTextTunnel->getSomething(
                                            SwXText::getUnoTunnelId() );
        ASSERT( pText, "SwXText missing" );
        if( !pText )
            return;

        SwDocStat aDocStat( pText->GetDoc()->GetDocStat() );
        aOut.append( (sal_Int32)aDocStat.nTbl );
        AddAttribute( XML_NAMESPACE_META, XML_TABLE_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nGrf );
        AddAttribute( XML_NAMESPACE_META, XML_IMAGE_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nOLE );
        AddAttribute( XML_NAMESPACE_META, XML_OBJECT_COUNT,
                      aOut.makeStringAndClear() );
        if( aDocStat.nPage )
        {
            aOut.append( (sal_Int32)aDocStat.nPage );
            AddAttribute( XML_NAMESPACE_META, XML_PAGE_COUNT,
                          aOut.makeStringAndClear() );
        }
        aOut.append( (sal_Int32)aDocStat.nPara );
        AddAttribute( XML_NAMESPACE_META, XML_PARAGRAPH_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nWord );
        AddAttribute( XML_NAMESPACE_META, XML_WORD_COUNT,
                      aOut.makeStringAndClear() );
        aOut.append( (sal_Int32)aDocStat.nChar );
        AddAttribute( XML_NAMESPACE_META, XML_CHARACTER_COUNT,
                      aOut.makeStringAndClear() );
        SvXMLElementExport aElem( *this, XML_NAMESPACE_META,
                                  XML_DOCUMENT_STATISTIC,
                                  sal_True, sal_True );

        if( IsShowProgress() )
        {
            ProgressBarHelper *pProgress = GetProgressBarHelper();
            pProgress->SetValue( pProgress->GetValue() + 2 );
        }
    }
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drformsh.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 12:27:14 $
 *
 *  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_sw.hxx"

#include <hintids.hxx>
#ifndef _SVX_HLNKITEM_HXX //autogen
#include <svx/hlnkitem.hxx>
#endif
#ifndef _SVDVIEW_HXX //autogen
#include <svx/svdview.hxx>
#endif
#ifndef _SFX_WHITER_HXX //autogen
#include <svtools/whiter.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXOBJFACE_HXX //autogen
#include <sfx2/objface.hxx>
#endif
#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SFXDISPATCH_HXX
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SVX_FMGLOB_HXX
#include <svx/fmglob.hxx>
#endif
#ifndef _SVDOUNO_HXX //autogen
#include <svx/svdouno.hxx>
#endif
#ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
#include <com/sun/star/form/FormButtonType.hpp>
#endif
#ifndef _SVX_HTMLMODE_HXX
#include <svx/htmlmode.hxx>
#endif
#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif

#include "viewopt.hxx"
#include "swmodule.hxx"
#include "wrtsh.hxx"
#include "cmdid.h"
#include "globals.hrc"
#include "helpid.h"
#include "popup.hrc"
#include "shells.hrc"
#include "drwbassh.hxx"
#include "drformsh.hxx"
#ifndef SVTOOLS_URIHELPER_HXX
#include <svtools/urihelper.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _SFXDOCFILE_HXX
#include <sfx2/docfile.hxx>
#endif
#ifndef _SWDOCSH_HXX
#include <docsh.hxx>
#endif

#define SwDrawFormShell
#include "itemdef.hxx"
#include "swslots.hxx"

#include <unomid.h>

using namespace ::com::sun::star;
using namespace ::rtl;

SFX_IMPL_INTERFACE(SwDrawFormShell, SwDrawBaseShell, SW_RES(STR_SHELLNAME_DRAWFORM))
{
    SFX_POPUPMENU_REGISTRATION(SW_RES(MN_DRAWFORM_POPUPMENU));
    SFX_OBJECTBAR_REGISTRATION(SFX_OBJECTBAR_OBJECT, SW_RES(RID_TEXT_TOOLBOX));
}

TYPEINIT1(SwDrawFormShell, SwDrawBaseShell)

void SwDrawFormShell::Execute(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    const SfxPoolItem* pItem = 0;
    const SfxItemSet *pArgs = rReq.GetArgs();

    switch ( rReq.GetSlot() )
    {
        case SID_HYPERLINK_SETLINK:
        {
        if(pArgs)
            pArgs->GetItemState(SID_HYPERLINK_SETLINK, sal_False, &pItem);
        if(pItem)
        {
            SdrView *pSdrView = rSh.GetDrawView();
            const SvxHyperlinkItem& rHLinkItem = *(const SvxHyperlinkItem *)pItem;
            bool bConvertToText = rHLinkItem.GetInsertMode() == HLINK_DEFAULT ||
                            rHLinkItem.GetInsertMode() == HLINK_FIELD;
            const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
            if (rMarkList.GetMark(0))
            {
                SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, rMarkList.GetMark(0)->GetMarkedSdrObj());
                if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
                {
                    if(bConvertToText)
                    {
                        //remove object -> results in destruction of this!
                        SwView& rTempView = GetView();
                        rTempView.GetViewFrame()->GetDispatcher()->Execute(SID_DELETE, SFX_CALLMODE_SYNCHRON );
                        rTempView.StopShellTimer();
                        //issue a new command to insert the link
                        rTempView.GetViewFrame()->GetDispatcher()->Execute(
                                SID_HYPERLINK_SETLINK, SFX_CALLMODE_ASYNCHRON, &rHLinkItem, 0);
                    }
                    else
                    {
                        uno::Reference< awt::XControlModel >  xControlModel = pUnoCtrl->GetUnoControlModel();

                        ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
                        if( !xControlModel.is() )
                            return;

                        uno::Reference< beans::XPropertySet >  xPropSet(xControlModel, uno::UNO_QUERY);

                        // Darf man eine URL an dem Objekt setzen?
                        OUString sTargetURL( C2U( "TargetURL" ));
                        uno::Reference< beans::XPropertySetInfo >  xPropInfoSet = xPropSet->getPropertySetInfo();
                        if( xPropInfoSet->hasPropertyByName( sTargetURL ))
                        {
                            beans::Property aProp = xPropInfoSet->getPropertyByName( sTargetURL );
                            if( aProp.Name.getLength() )
                            {
                                uno::Any aTmp;
                                // Ja!
                                aTmp <<= OUString(rHLinkItem.GetName());
                                xPropSet->setPropertyValue(C2U("Label"), aTmp );

                                SfxMedium* pMedium = GetView().GetDocShell()->GetMedium();
                                INetURLObject aAbs;
                                if( pMedium )
                                    aAbs = pMedium->GetURLObject();
                                aTmp <<=  OUString(URIHelper::SmartRel2Abs(aAbs, rHLinkItem.GetURL()));
                                xPropSet->setPropertyValue( sTargetURL, aTmp );

                                if( rHLinkItem.GetTargetFrame().Len() )
                                {
                                    aTmp <<=  OUString(rHLinkItem.GetTargetFrame());
                                    xPropSet->setPropertyValue( C2U("TargetFrame"), aTmp );
                                }

                                form::FormButtonType eButtonType = form::FormButtonType_URL;
                                aTmp.setValue( &eButtonType, ::getCppuType((const form::FormButtonType*)0));
                                xPropSet->setPropertyValue( C2U("ButtonType"), aTmp );
                            }
                        }
                    }
                }
            }
        }
        }
        break;

        default:
            DBG_ASSERT(!this, "falscher Dispatcher");
            return;
    }
}

void SwDrawFormShell::GetState(SfxItemSet& rSet)
{
    SwWrtShell &rSh = GetShell();
    SfxWhichIter aIter( rSet );
    sal_uInt16 nWhich = aIter.FirstWhich();

    while( nWhich )
    {
        switch( nWhich )
        {
            case SID_HYPERLINK_GETLINK:
            {
                SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
                const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
                SvxHyperlinkItem aHLinkItem;
                if (rMarkList.GetMark(0))
                {
                    SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, rMarkList.GetMark(0)->GetMarkedSdrObj());
                    if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
                    {
                        uno::Reference< awt::XControlModel >  xControlModel = pUnoCtrl->GetUnoControlModel();

                        ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
                        if( !xControlModel.is() )
                            return;

                        uno::Reference< beans::XPropertySet >  xPropSet(xControlModel, uno::UNO_QUERY);

                        uno::Any aTmp;
                        uno::Reference< beans::XPropertySetInfo >  xInfo = xPropSet->getPropertySetInfo();
                        if(xInfo->hasPropertyByName(C2U("ButtonType" )))
                        {
                             form::FormButtonType eButtonType = form::FormButtonType_URL;
                            aTmp = xPropSet->getPropertyValue( C2U("ButtonType") );
                            if( aTmp >>= eButtonType )
                            {
                                // Label
                                if(xInfo->hasPropertyByName( C2U("Label") ))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("Label") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetName(sTmp);
                                    }
                                }

                                // URL
                                if(xInfo->hasPropertyByName( C2U("TargetURL" )))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("TargetURL") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetURL(sTmp);
                                    }
                                }

                                // Target
                                if(xInfo->hasPropertyByName( C2U("TargetFrame") ))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("TargetFrame") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetTargetFrame(sTmp);
                                    }
                                }
                                aHLinkItem.SetInsertMode(HLINK_BUTTON);
                            }
                        }
                    }
                }
                sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
                aHLinkItem.SetInsertMode((SvxLinkInsertMode)(aHLinkItem.GetInsertMode() |
                    ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0)));

                rSet.Put(aHLinkItem);
            }
            break;
        }
        nWhich = aIter.NextWhich();
    }
}

SwDrawFormShell::SwDrawFormShell(SwView &_rView) :
    SwDrawBaseShell(_rView)
{
    SetHelpId(SW_DRAWFORMSHELL);
    GetShell().NoEdit(sal_True);
    SetName(String::CreateFromAscii("DrawForm"));
}

SwDrawFormShell::~SwDrawFormShell()
{
}

<commit_msg>INTEGRATION: CWS impresstables2 (1.14.82); FILE MERGED 2007/10/12 00:23:49 cl 1.14.82.2: RESYNC: (1.14-1.15); FILE MERGED 2007/10/11 14:18:39 cl 1.14.82.1: #i68103# fixed namespace issues<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drformsh.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 12:53:55 $
 *
 *  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_sw.hxx"

#include <hintids.hxx>
#ifndef _SVX_HLNKITEM_HXX //autogen
#include <svx/hlnkitem.hxx>
#endif
#ifndef _SVDVIEW_HXX //autogen
#include <svx/svdview.hxx>
#endif
#ifndef _SFX_WHITER_HXX //autogen
#include <svtools/whiter.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXOBJFACE_HXX //autogen
#include <sfx2/objface.hxx>
#endif
#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SFXDISPATCH_HXX
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SVX_FMGLOB_HXX
#include <svx/fmglob.hxx>
#endif
#ifndef _SVDOUNO_HXX //autogen
#include <svx/svdouno.hxx>
#endif
#ifndef _COM_SUN_STAR_FORM_FORMBUTTONTYPE_HPP_
#include <com/sun/star/form/FormButtonType.hpp>
#endif
#ifndef _SVX_HTMLMODE_HXX
#include <svx/htmlmode.hxx>
#endif
#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif

#include "viewopt.hxx"
#include "swmodule.hxx"
#include "wrtsh.hxx"
#include "cmdid.h"
#include "globals.hrc"
#include "helpid.h"
#include "popup.hrc"
#include "shells.hrc"
#include "drwbassh.hxx"
#include "drformsh.hxx"
#ifndef SVTOOLS_URIHELPER_HXX
#include <svtools/urihelper.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _SFXDOCFILE_HXX
#include <sfx2/docfile.hxx>
#endif
#ifndef _SWDOCSH_HXX
#include <docsh.hxx>
#endif

#define SwDrawFormShell
#include "itemdef.hxx"
#include "swslots.hxx"

#include <unomid.h>

using namespace ::com::sun::star;
using ::rtl::OUString;

SFX_IMPL_INTERFACE(SwDrawFormShell, SwDrawBaseShell, SW_RES(STR_SHELLNAME_DRAWFORM))
{
    SFX_POPUPMENU_REGISTRATION(SW_RES(MN_DRAWFORM_POPUPMENU));
    SFX_OBJECTBAR_REGISTRATION(SFX_OBJECTBAR_OBJECT, SW_RES(RID_TEXT_TOOLBOX));
}

TYPEINIT1(SwDrawFormShell, SwDrawBaseShell)

void SwDrawFormShell::Execute(SfxRequest &rReq)
{
    SwWrtShell &rSh = GetShell();
    const SfxPoolItem* pItem = 0;
    const SfxItemSet *pArgs = rReq.GetArgs();

    switch ( rReq.GetSlot() )
    {
        case SID_HYPERLINK_SETLINK:
        {
        if(pArgs)
            pArgs->GetItemState(SID_HYPERLINK_SETLINK, sal_False, &pItem);
        if(pItem)
        {
            SdrView *pSdrView = rSh.GetDrawView();
            const SvxHyperlinkItem& rHLinkItem = *(const SvxHyperlinkItem *)pItem;
            bool bConvertToText = rHLinkItem.GetInsertMode() == HLINK_DEFAULT ||
                            rHLinkItem.GetInsertMode() == HLINK_FIELD;
            const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
            if (rMarkList.GetMark(0))
            {
                SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, rMarkList.GetMark(0)->GetMarkedSdrObj());
                if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
                {
                    if(bConvertToText)
                    {
                        //remove object -> results in destruction of this!
                        SwView& rTempView = GetView();
                        rTempView.GetViewFrame()->GetDispatcher()->Execute(SID_DELETE, SFX_CALLMODE_SYNCHRON );
                        rTempView.StopShellTimer();
                        //issue a new command to insert the link
                        rTempView.GetViewFrame()->GetDispatcher()->Execute(
                                SID_HYPERLINK_SETLINK, SFX_CALLMODE_ASYNCHRON, &rHLinkItem, 0);
                    }
                    else
                    {
                        uno::Reference< awt::XControlModel >  xControlModel = pUnoCtrl->GetUnoControlModel();

                        ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
                        if( !xControlModel.is() )
                            return;

                        uno::Reference< beans::XPropertySet >  xPropSet(xControlModel, uno::UNO_QUERY);

                        // Darf man eine URL an dem Objekt setzen?
                        OUString sTargetURL( C2U( "TargetURL" ));
                        uno::Reference< beans::XPropertySetInfo >  xPropInfoSet = xPropSet->getPropertySetInfo();
                        if( xPropInfoSet->hasPropertyByName( sTargetURL ))
                        {
                            beans::Property aProp = xPropInfoSet->getPropertyByName( sTargetURL );
                            if( aProp.Name.getLength() )
                            {
                                uno::Any aTmp;
                                // Ja!
                                aTmp <<= OUString(rHLinkItem.GetName());
                                xPropSet->setPropertyValue(C2U("Label"), aTmp );

                                SfxMedium* pMedium = GetView().GetDocShell()->GetMedium();
                                INetURLObject aAbs;
                                if( pMedium )
                                    aAbs = pMedium->GetURLObject();
                                aTmp <<=  OUString(URIHelper::SmartRel2Abs(aAbs, rHLinkItem.GetURL()));
                                xPropSet->setPropertyValue( sTargetURL, aTmp );

                                if( rHLinkItem.GetTargetFrame().Len() )
                                {
                                    aTmp <<=  OUString(rHLinkItem.GetTargetFrame());
                                    xPropSet->setPropertyValue( C2U("TargetFrame"), aTmp );
                                }

                                form::FormButtonType eButtonType = form::FormButtonType_URL;
                                aTmp.setValue( &eButtonType, ::getCppuType((const form::FormButtonType*)0));
                                xPropSet->setPropertyValue( C2U("ButtonType"), aTmp );
                            }
                        }
                    }
                }
            }
        }
        }
        break;

        default:
            DBG_ASSERT(!this, "falscher Dispatcher");
            return;
    }
}

void SwDrawFormShell::GetState(SfxItemSet& rSet)
{
    SwWrtShell &rSh = GetShell();
    SfxWhichIter aIter( rSet );
    sal_uInt16 nWhich = aIter.FirstWhich();

    while( nWhich )
    {
        switch( nWhich )
        {
            case SID_HYPERLINK_GETLINK:
            {
                SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
                const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
                SvxHyperlinkItem aHLinkItem;
                if (rMarkList.GetMark(0))
                {
                    SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, rMarkList.GetMark(0)->GetMarkedSdrObj());
                    if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
                    {
                        uno::Reference< awt::XControlModel >  xControlModel = pUnoCtrl->GetUnoControlModel();

                        ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
                        if( !xControlModel.is() )
                            return;

                        uno::Reference< beans::XPropertySet >  xPropSet(xControlModel, uno::UNO_QUERY);

                        uno::Any aTmp;
                        uno::Reference< beans::XPropertySetInfo >  xInfo = xPropSet->getPropertySetInfo();
                        if(xInfo->hasPropertyByName(C2U("ButtonType" )))
                        {
                             form::FormButtonType eButtonType = form::FormButtonType_URL;
                            aTmp = xPropSet->getPropertyValue( C2U("ButtonType") );
                            if( aTmp >>= eButtonType )
                            {
                                // Label
                                if(xInfo->hasPropertyByName( C2U("Label") ))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("Label") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetName(sTmp);
                                    }
                                }

                                // URL
                                if(xInfo->hasPropertyByName( C2U("TargetURL" )))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("TargetURL") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetURL(sTmp);
                                    }
                                }

                                // Target
                                if(xInfo->hasPropertyByName( C2U("TargetFrame") ))
                                {
                                    aTmp = xPropSet->getPropertyValue( C2U("TargetFrame") );
                                    OUString sTmp;
                                    if( (aTmp >>= sTmp) && sTmp.getLength())
                                    {
                                        aHLinkItem.SetTargetFrame(sTmp);
                                    }
                                }
                                aHLinkItem.SetInsertMode(HLINK_BUTTON);
                            }
                        }
                    }
                }
                sal_uInt16 nHtmlMode = ::GetHtmlMode(GetView().GetDocShell());
                aHLinkItem.SetInsertMode((SvxLinkInsertMode)(aHLinkItem.GetInsertMode() |
                    ((nHtmlMode & HTMLMODE_ON) != 0 ? HLINK_HTMLMODE : 0)));

                rSet.Put(aHLinkItem);
            }
            break;
        }
        nWhich = aIter.NextWhich();
    }
}

SwDrawFormShell::SwDrawFormShell(SwView &_rView) :
    SwDrawBaseShell(_rView)
{
    SetHelpId(SW_DRAWFORMSHELL);
    GetShell().NoEdit(sal_True);
    SetName(String::CreateFromAscii("DrawForm"));
}

SwDrawFormShell::~SwDrawFormShell()
{
}

<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright 2009-2015 Jörg Müller
 *
 * 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 "Exception.h"
#include "IReader.h"
#include "file/File.h"
#include "respec/ChannelMapper.h"
#include "fx/Lowpass.h"
#include "fx/Highpass.h"
#include "fx/Envelope.h"
#include "respec/LinearResample.h"
#include "fx/Threshold.h"
#include "fx/Accumulator.h"
#include "fx/Sum.h"
#include "generator/Silence.h"
#include "fx/Limiter.h"
#include "devices/DeviceManager.h"
#include "sequence/Sequence.h"
#include "file/FileWriter.h"
#include "devices/ReadDevice.h"
#include "plugin/PluginManager.h"
#include "devices/DeviceManager.h"
#include "devices/IDeviceFactory.h"
#include "devices/NULLDevice.h"

#include <cassert>
#include <cstring>
#include <cmath>
#include <sstream>

using namespace aud;

#define AUD_CAPI_IMPLEMENTATION
#include "AUD_Special.h"

static inline AUD_Specs convSpecToC(aud::Specs specs)
{
	AUD_Specs s;
	s.channels = static_cast<AUD_Channels>(specs.channels);
	s.rate = static_cast<AUD_SampleRate>(specs.rate);
	return s;
}

static inline aud::Specs convCToSpec(AUD_Specs specs)
{
	aud::Specs s;
	s.channels = static_cast<Channels>(specs.channels);
	s.rate = static_cast<SampleRate>(specs.rate);
	return s;
}

static inline AUD_DeviceSpecs convDSpecToC(aud::DeviceSpecs specs)
{
	AUD_DeviceSpecs s;
	s.specs = convSpecToC(specs.specs);
	s.format = static_cast<AUD_SampleFormat>(specs.format);
	return s;
}

static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
{
	aud::DeviceSpecs s;
	s.specs = convCToSpec(specs.specs);
	s.format = static_cast<SampleFormat>(specs.format);
	return s;
}

AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
{
	assert(sound);

	AUD_SoundInfo info;
	info.specs.channels = AUD_CHANNELS_INVALID;
	info.specs.rate = AUD_RATE_INVALID;
	info.length = 0.0f;

	try
	{
		std::shared_ptr<IReader> reader = (*sound)->createReader();

		if(reader.get())
		{
			info.specs = convSpecToC(reader->getSpecs());
			info.length = reader->getLength() / (float) info.specs.rate;
		}
	}
	catch(Exception&)
	{
	}

	return info;
}

AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
						   float attack, float release, float threshold,
						   int accumulate, int additive, int square,
						   float sthreshold, double samplerate, int* length)
{
	Buffer buffer;
	DeviceSpecs specs;
	specs.channels = CHANNELS_MONO;
	specs.rate = (SampleRate)samplerate;
	std::shared_ptr<ISound> sound;

	std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename));

	int position = 0;

	try
	{
		std::shared_ptr<IReader> reader = file->createReader();

		SampleRate rate = reader->getSpecs().rate;

		sound = std::shared_ptr<ISound>(new ChannelMapper(file, specs));

		if(high < rate)
			sound = std::shared_ptr<ISound>(new Lowpass(sound, high));
		if(low > 0)
			sound = std::shared_ptr<ISound>(new Highpass(sound, low));

		sound = std::shared_ptr<ISound>(new Envelope(sound, attack, release, threshold, 0.1f));
		sound = std::shared_ptr<ISound>(new LinearResample(sound, specs));

		if(square)
			sound = std::shared_ptr<ISound>(new Threshold(sound, sthreshold));

		if(accumulate)
			sound = std::shared_ptr<ISound>(new Accumulator(sound, additive));
		else if(additive)
			sound = std::shared_ptr<ISound>(new Sum(sound));

		reader = sound->createReader();

		if(!reader.get())
			return nullptr;

		int len;
		bool eos;
		do
		{
			len = samplerate;
			buffer.resize((position + len) * sizeof(float), true);
			reader->read(len, eos, buffer.getBuffer() + position);
			position += len;
		} while(!eos);
	}
	catch(Exception&)
	{
		return nullptr;
	}

	float * result = (float *)malloc(position * sizeof(float));
	std::memcpy(result, buffer.getBuffer(), position * sizeof(float));
	*length = position;
	return result;
}

static void pauseSound(AUD_Handle* handle)
{
	assert(handle);
	(*handle)->pause();
}

AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
{
	std::shared_ptr<ISound> silence = std::shared_ptr<ISound>(new Silence);
	std::shared_ptr<ISound> limiter = std::shared_ptr<ISound>(new Limiter(silence, 0, seconds));

	auto device = DeviceManager::getDevice();

	std::lock_guard<ILockable> lock(*device);

	try
	{
		AUD_Handle handle2 = device->play(limiter);
		if(handle2.get())
		{
			handle2->setStopCallback((stopCallback)pauseSound, handle);
			return new AUD_Handle(handle2);
		}
	}
	catch(Exception&)
	{
	}

	return nullptr;
}

AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt)
{
	DeviceSpecs specs;
	float* buf;
	Buffer aBuffer;

	specs.rate = RATE_INVALID;
	specs.channels = CHANNELS_MONO;
	specs.format = FORMAT_INVALID;

	std::shared_ptr<IReader> reader = ChannelMapper(*sound, specs).createReader();

	specs.specs = reader->getSpecs();
	int len;
	float samplejump = specs.rate / samples_per_second;
	float min, max, power, overallmax;
	bool eos;

	overallmax = 0;

	for(int i = 0; i < length; i++)
	{
		len = floor(samplejump * (i+1)) - floor(samplejump * i);

		if (*interrupt)
			return 0;

		aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
		buf = aBuffer.getBuffer();

		reader->read(len, eos, buf);

		max = min = *buf;
		power = *buf * *buf;
		for(int j = 1; j < len; j++)
		{
			if(buf[j] < min)
				min = buf[j];
			if(buf[j] > max)
				max = buf[j];
			power += buf[j] * buf[j];
		}

		buffer[i * 3] = min;
		buffer[i * 3 + 1] = max;
		buffer[i * 3 + 2] = sqrt(power) / len;

		if(overallmax < max)
			overallmax = max;
		if(overallmax < -min)
			overallmax = -min;

		if(eos)
		{
			length = i;
			break;
		}
	}

	if(overallmax > 1.0f)
	{
		for(int i = 0; i < length * 3; i++)
		{
			buffer[i] /= overallmax;
		}
	}

	return length;
}

AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
	try
	{
		Sequence* f = dynamic_cast<Sequence *>(sound->get());

		f->setSpecs(convCToSpec(specs.specs));
		std::shared_ptr<IReader> reader = f->createQualityReader();
		reader->seek(start);
		std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate);
		FileWriter::writeReader(reader, writer, length, buffersize);

		return nullptr;
	}
	catch(Exception& e)
	{
		return e.getMessage().c_str();
	}
}

AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
	try
	{
		Sequence* f = dynamic_cast<Sequence *>(sound->get());

		f->setSpecs(convCToSpec(specs.specs));

		std::vector<std::shared_ptr<IWriter> > writers;

		int channels = specs.channels;
		specs.channels = AUD_CHANNELS_MONO;

		for(int i = 0; i < channels; i++)
		{
			std::stringstream stream;
			std::string fn = filename;
			size_t index = fn.find_last_of('.');
			size_t index_slash = fn.find_last_of('/');
			size_t index_backslash = fn.find_last_of('\\');

			if((index == std::string::npos) ||
				((index < index_slash) && (index_slash != std::string::npos)) ||
				((index < index_backslash) && (index_backslash != std::string::npos)))
			{
				stream << filename << "_" << (i + 1);
			}
			else
			{
				stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
			}
			writers.push_back(FileWriter::createWriter(stream.str(), convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate));
		}

		std::shared_ptr<IReader> reader = f->createQualityReader();
		reader->seek(start);
		FileWriter::writeReader(reader, writers, length, buffersize);

		return nullptr;
	}
	catch(Exception& e)
	{
		return e.getMessage().c_str();
	}
}

AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
{
	try
	{
		ReadDevice* device = new ReadDevice(convCToDSpec(specs));
		device->setQuality(true);
		device->setVolume(volume);

		dynamic_cast<Sequence *>(sequencer->get())->setSpecs(convCToSpec(specs.specs));

		AUD_Handle handle = device->play(*sequencer);
		if(handle.get())
		{
			handle->seek(start);
		}

		return new AUD_Device(device);
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API void AUD_initOnce()
{
	PluginManager::loadPlugins();
	NULLDevice::registerPlugin();
}

AUD_API void AUD_exitOnce()
{
}

AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
{
	try
	{
		std::shared_ptr<IDeviceFactory> factory = DeviceManager::getDeviceFactory(device);

		if(factory)
		{
			factory->setName(name);
			factory->setBufferSize(buffersize);
			factory->setSpecs(convCToDSpec(specs));
			auto device = factory->openDevice();
			DeviceManager::setDevice(device);

			return new AUD_Device(device);
		}
	}
	catch(Exception&)
	{
	}
	return nullptr;
}

AUD_API void AUD_exit(AUD_Device* device)
{
	delete device;
	DeviceManager::releaseDevice();
}

AUD_API char** AUD_getDeviceNames()
{
	std::vector<std::string> v_names = DeviceManager::getAvailableDeviceNames();
	char** names = (char**) malloc(sizeof(char*) * (v_names.size() + 1));

	for(int i = 0; i < v_names.size(); i++)
	{
		std::string name = v_names[i];
		names[i] = (char*) malloc(sizeof(char) * (name.length() + 1));
		strcpy(names[i], name.c_str());
	}

	return names;
}
<commit_msg>Fixing error in last commit.<commit_after>/*******************************************************************************
 * Copyright 2009-2015 Jörg Müller
 *
 * 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 "Exception.h"
#include "IReader.h"
#include "file/File.h"
#include "respec/ChannelMapper.h"
#include "fx/Lowpass.h"
#include "fx/Highpass.h"
#include "fx/Envelope.h"
#include "respec/LinearResample.h"
#include "fx/Threshold.h"
#include "fx/Accumulator.h"
#include "fx/Sum.h"
#include "generator/Silence.h"
#include "fx/Limiter.h"
#include "devices/DeviceManager.h"
#include "sequence/Sequence.h"
#include "file/FileWriter.h"
#include "devices/ReadDevice.h"
#include "plugin/PluginManager.h"
#include "devices/DeviceManager.h"
#include "devices/IDeviceFactory.h"
#include "devices/NULLDevice.h"

#include <cassert>
#include <cstring>
#include <cmath>
#include <sstream>

using namespace aud;

#define AUD_CAPI_IMPLEMENTATION
#include "AUD_Special.h"

static inline AUD_Specs convSpecToC(aud::Specs specs)
{
	AUD_Specs s;
	s.channels = static_cast<AUD_Channels>(specs.channels);
	s.rate = static_cast<AUD_SampleRate>(specs.rate);
	return s;
}

static inline aud::Specs convCToSpec(AUD_Specs specs)
{
	aud::Specs s;
	s.channels = static_cast<Channels>(specs.channels);
	s.rate = static_cast<SampleRate>(specs.rate);
	return s;
}

static inline AUD_DeviceSpecs convDSpecToC(aud::DeviceSpecs specs)
{
	AUD_DeviceSpecs s;
	s.specs = convSpecToC(specs.specs);
	s.format = static_cast<AUD_SampleFormat>(specs.format);
	return s;
}

static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
{
	aud::DeviceSpecs s;
	s.specs = convCToSpec(specs.specs);
	s.format = static_cast<SampleFormat>(specs.format);
	return s;
}

AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
{
	assert(sound);

	AUD_SoundInfo info;
	info.specs.channels = AUD_CHANNELS_INVALID;
	info.specs.rate = AUD_RATE_INVALID;
	info.length = 0.0f;

	try
	{
		std::shared_ptr<IReader> reader = (*sound)->createReader();

		if(reader.get())
		{
			info.specs = convSpecToC(reader->getSpecs());
			info.length = reader->getLength() / (float) info.specs.rate;
		}
	}
	catch(Exception&)
	{
	}

	return info;
}

AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
						   float attack, float release, float threshold,
						   int accumulate, int additive, int square,
						   float sthreshold, double samplerate, int* length)
{
	Buffer buffer;
	DeviceSpecs specs;
	specs.channels = CHANNELS_MONO;
	specs.rate = (SampleRate)samplerate;
	std::shared_ptr<ISound> sound;

	std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename));

	int position = 0;

	try
	{
		std::shared_ptr<IReader> reader = file->createReader();

		SampleRate rate = reader->getSpecs().rate;

		sound = std::shared_ptr<ISound>(new ChannelMapper(file, specs));

		if(high < rate)
			sound = std::shared_ptr<ISound>(new Lowpass(sound, high));
		if(low > 0)
			sound = std::shared_ptr<ISound>(new Highpass(sound, low));

		sound = std::shared_ptr<ISound>(new Envelope(sound, attack, release, threshold, 0.1f));
		sound = std::shared_ptr<ISound>(new LinearResample(sound, specs));

		if(square)
			sound = std::shared_ptr<ISound>(new Threshold(sound, sthreshold));

		if(accumulate)
			sound = std::shared_ptr<ISound>(new Accumulator(sound, additive));
		else if(additive)
			sound = std::shared_ptr<ISound>(new Sum(sound));

		reader = sound->createReader();

		if(!reader.get())
			return nullptr;

		int len;
		bool eos;
		do
		{
			len = samplerate;
			buffer.resize((position + len) * sizeof(float), true);
			reader->read(len, eos, buffer.getBuffer() + position);
			position += len;
		} while(!eos);
	}
	catch(Exception&)
	{
		return nullptr;
	}

	float * result = (float *)malloc(position * sizeof(float));
	std::memcpy(result, buffer.getBuffer(), position * sizeof(float));
	*length = position;
	return result;
}

static void pauseSound(AUD_Handle* handle)
{
	assert(handle);
	(*handle)->pause();
}

AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
{
	std::shared_ptr<ISound> silence = std::shared_ptr<ISound>(new Silence);
	std::shared_ptr<ISound> limiter = std::shared_ptr<ISound>(new Limiter(silence, 0, seconds));

	auto device = DeviceManager::getDevice();

	std::lock_guard<ILockable> lock(*device);

	try
	{
		AUD_Handle handle2 = device->play(limiter);
		if(handle2.get())
		{
			handle2->setStopCallback((stopCallback)pauseSound, handle);
			return new AUD_Handle(handle2);
		}
	}
	catch(Exception&)
	{
	}

	return nullptr;
}

AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt)
{
	DeviceSpecs specs;
	float* buf;
	Buffer aBuffer;

	specs.rate = RATE_INVALID;
	specs.channels = CHANNELS_MONO;
	specs.format = FORMAT_INVALID;

	std::shared_ptr<IReader> reader = ChannelMapper(*sound, specs).createReader();

	specs.specs = reader->getSpecs();
	int len;
	float samplejump = specs.rate / samples_per_second;
	float min, max, power, overallmax;
	bool eos;

	overallmax = 0;

	for(int i = 0; i < length; i++)
	{
		len = floor(samplejump * (i+1)) - floor(samplejump * i);

		if (*interrupt)
			return 0;

		aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
		buf = aBuffer.getBuffer();

		reader->read(len, eos, buf);

		max = min = *buf;
		power = *buf * *buf;
		for(int j = 1; j < len; j++)
		{
			if(buf[j] < min)
				min = buf[j];
			if(buf[j] > max)
				max = buf[j];
			power += buf[j] * buf[j];
		}

		buffer[i * 3] = min;
		buffer[i * 3 + 1] = max;
		buffer[i * 3 + 2] = sqrt(power) / len;

		if(overallmax < max)
			overallmax = max;
		if(overallmax < -min)
			overallmax = -min;

		if(eos)
		{
			length = i;
			break;
		}
	}

	if(overallmax > 1.0f)
	{
		for(int i = 0; i < length * 3; i++)
		{
			buffer[i] /= overallmax;
		}
	}

	return length;
}

AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
	try
	{
		Sequence* f = dynamic_cast<Sequence *>(sound->get());

		f->setSpecs(convCToSpec(specs.specs));
		std::shared_ptr<IReader> reader = f->createQualityReader();
		reader->seek(start);
		std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate);
		FileWriter::writeReader(reader, writer, length, buffersize);

		return nullptr;
	}
	catch(Exception& e)
	{
		return e.getMessage().c_str();
	}
}

AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
	try
	{
		Sequence* f = dynamic_cast<Sequence *>(sound->get());

		f->setSpecs(convCToSpec(specs.specs));

		std::vector<std::shared_ptr<IWriter> > writers;

		int channels = specs.channels;
		specs.channels = AUD_CHANNELS_MONO;

		for(int i = 0; i < channels; i++)
		{
			std::stringstream stream;
			std::string fn = filename;
			size_t index = fn.find_last_of('.');
			size_t index_slash = fn.find_last_of('/');
			size_t index_backslash = fn.find_last_of('\\');

			if((index == std::string::npos) ||
				((index < index_slash) && (index_slash != std::string::npos)) ||
				((index < index_backslash) && (index_backslash != std::string::npos)))
			{
				stream << filename << "_" << (i + 1);
			}
			else
			{
				stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
			}
			writers.push_back(FileWriter::createWriter(stream.str(), convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate));
		}

		std::shared_ptr<IReader> reader = f->createQualityReader();
		reader->seek(start);
		FileWriter::writeReader(reader, writers, length, buffersize);

		return nullptr;
	}
	catch(Exception& e)
	{
		return e.getMessage().c_str();
	}
}

AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
{
	try
	{
		ReadDevice* device = new ReadDevice(convCToDSpec(specs));
		device->setQuality(true);
		device->setVolume(volume);

		dynamic_cast<Sequence *>(sequencer->get())->setSpecs(convCToSpec(specs.specs));

		AUD_Handle handle = device->play(*sequencer);
		if(handle.get())
		{
			handle->seek(start);
		}

		return new AUD_Device(device);
	}
	catch(Exception&)
	{
		return nullptr;
	}
}

AUD_API void AUD_initOnce()
{
	PluginManager::loadPlugins();
	NULLDevice::registerPlugin();
}

AUD_API void AUD_exitOnce()
{
}

AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
{
	try
	{
		std::shared_ptr<IDeviceFactory> factory = DeviceManager::getDeviceFactory(device);

		if(factory)
		{
			factory->setName(name);
			factory->setBufferSize(buffersize);
			factory->setSpecs(convCToDSpec(specs));
			auto device = factory->openDevice();
			DeviceManager::setDevice(device);

			return new AUD_Device(device);
		}
	}
	catch(Exception&)
	{
	}
	return nullptr;
}

AUD_API void AUD_exit(AUD_Device* device)
{
	delete device;
	DeviceManager::releaseDevice();
}

AUD_API char** AUD_getDeviceNames()
{
	std::vector<std::string> v_names = DeviceManager::getAvailableDeviceNames();
	char** names = (char**) malloc(sizeof(char*) * (v_names.size() + 1));

	for(int i = 0; i < v_names.size(); i++)
	{
		std::string name = v_names[i];
		names[i] = (char*) malloc(sizeof(char) * (name.length() + 1));
		strcpy(names[i], name.c_str());
	}

	names[v_names.size()] = nullptr;

	return names;
}
<|endoftext|>