<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#include "rustllvm.h"

#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"

using namespace llvm;
using namespace llvm::object;

struct LLVMRustArchiveMember {
  const char *filename;
  const char *name;
  Archive::Child child;

  LLVMRustArchiveMember(): filename(NULL), name(NULL),
#if LLVM_VERSION_MINOR >= 8
    child(NULL, NULL, NULL)
#else
    child(NULL, NULL)
#endif
  {}
  ~LLVMRustArchiveMember() {}
};

typedef OwningBinary<Archive> RustArchive;

extern "C" void*
LLVMRustOpenArchive(char *path) {
    ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
                                                                          -1,
                                                                          false);
    if (!buf_or) {
        LLVMRustSetLastError(buf_or.getError().message().c_str());
        return nullptr;
    }

    ErrorOr<std::unique_ptr<Archive>> archive_or =
        Archive::create(buf_or.get()->getMemBufferRef());

    if (!archive_or) {
        LLVMRustSetLastError(archive_or.getError().message().c_str());
        return nullptr;
    }

    OwningBinary<Archive> *ret = new OwningBinary<Archive>(
            std::move(archive_or.get()), std::move(buf_or.get()));

    return ret;
}

extern "C" void
LLVMRustDestroyArchive(RustArchive *ar) {
    delete ar;
}

struct RustArchiveIterator {
    Archive::child_iterator cur;
    Archive::child_iterator end;
};

extern "C" RustArchiveIterator*
LLVMRustArchiveIteratorNew(RustArchive *ra) {
    Archive *ar = ra->getBinary();
    RustArchiveIterator *rai = new RustArchiveIterator();
    rai->cur = ar->child_begin();
    rai->end = ar->child_end();
    return rai;
}

extern "C" const Archive::Child*
LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
    if (rai->cur == rai->end)
        return NULL;
#if LLVM_VERSION_MINOR >= 8
    const ErrorOr<Archive::Child>* cur = rai->cur.operator->();
    if (!*cur) {
        LLVMRustSetLastError(cur->getError().message().c_str());
        return NULL;
    }
    const Archive::Child &child = cur->get();
#else
    const Archive::Child &child = *rai->cur.operator->();
#endif
    Archive::Child *ret = new Archive::Child(child);

    ++rai->cur;
    return ret;
}

extern "C" void
LLVMRustArchiveChildFree(Archive::Child *child) {
    delete child;
}

extern "C" void
LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
    delete rai;
}

extern "C" const char*
LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
    ErrorOr<StringRef> name_or_err = child->getName();
    if (name_or_err.getError())
        return NULL;
    StringRef name = name_or_err.get();
    *size = name.size();
    return name.data();
}

extern "C" const char*
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
    StringRef buf;
    ErrorOr<StringRef> buf_or_err = child->getBuffer();
    if (buf_or_err.getError()) {
      LLVMRustSetLastError(buf_or_err.getError().message().c_str());
      return NULL;
    }
    buf = buf_or_err.get();
    *size = buf.size();
    return buf.data();
}

extern "C" LLVMRustArchiveMember*
LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
    LLVMRustArchiveMember *Member = new LLVMRustArchiveMember;
    Member->filename = Filename;
    Member->name = Name;
    if (child)
        Member->child = *child;
    return Member;
}

extern "C" void
LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) {
    delete Member;
}

extern "C" int
LLVMRustWriteArchive(char *Dst,
                     size_t NumMembers,
                     const LLVMRustArchiveMember **NewMembers,
                     bool WriteSymbtab,
                     Archive::Kind Kind) {
  std::vector<NewArchiveMember> Members;

  for (size_t i = 0; i < NumMembers; i++) {
    auto Member = NewMembers[i];
    assert(Member->name);
    if (Member->filename) {
#if LLVM_VERSION_MINOR >= 9
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return -1;
      }
      Members.push_back(std::move(*MOrErr));
#else
      Members.push_back(NewArchiveIterator(Member->filename, Member->name));
#endif
    } else {
#if LLVM_VERSION_MINOR >= 9
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return -1;
      }
      Members.push_back(std::move(*MOrErr));
#else
      Members.push_back(NewArchiveIterator(Member->child, Member->name));
#endif
    }
  }
#if LLVM_VERSION_MINOR >= 8
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
#else
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
#endif
  if (!pair.second)
    return 0;
  LLVMRustSetLastError(pair.second.message().c_str());
  return -1;
}
<commit_msg>[LLVM-3.9] Update return type for Archive::create<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#include "rustllvm.h"

#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"

using namespace llvm;
using namespace llvm::object;

struct LLVMRustArchiveMember {
  const char *filename;
  const char *name;
  Archive::Child child;

  LLVMRustArchiveMember(): filename(NULL), name(NULL),
#if LLVM_VERSION_MINOR >= 8
    child(NULL, NULL, NULL)
#else
    child(NULL, NULL)
#endif
  {}
  ~LLVMRustArchiveMember() {}
};

typedef OwningBinary<Archive> RustArchive;

extern "C" void*
LLVMRustOpenArchive(char *path) {
    ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
                                                                          -1,
                                                                          false);
    if (!buf_or) {
        LLVMRustSetLastError(buf_or.getError().message().c_str());
        return nullptr;
    }

#if LLVM_VERSION_MINOR <= 8
    ErrorOr<std::unique_ptr<Archive>> archive_or =
#else
    Expected<std::unique_ptr<Archive>> archive_or =
#endif
        Archive::create(buf_or.get()->getMemBufferRef());

    if (!archive_or) {
#if LLVM_VERSION_MINOR <= 8
        LLVMRustSetLastError(archive_or.getError().message().c_str());
#else
        LLVMRustSetLastError(toString(archive_or.takeError()).c_str());
#endif
        return nullptr;
    }

    OwningBinary<Archive> *ret = new OwningBinary<Archive>(
            std::move(archive_or.get()), std::move(buf_or.get()));

    return ret;
}

extern "C" void
LLVMRustDestroyArchive(RustArchive *ar) {
    delete ar;
}

struct RustArchiveIterator {
    Archive::child_iterator cur;
    Archive::child_iterator end;
};

extern "C" RustArchiveIterator*
LLVMRustArchiveIteratorNew(RustArchive *ra) {
    Archive *ar = ra->getBinary();
    RustArchiveIterator *rai = new RustArchiveIterator();
    rai->cur = ar->child_begin();
    rai->end = ar->child_end();
    return rai;
}

extern "C" const Archive::Child*
LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
    if (rai->cur == rai->end)
        return NULL;
#if LLVM_VERSION_MINOR >= 8
    const ErrorOr<Archive::Child>* cur = rai->cur.operator->();
    if (!*cur) {
        LLVMRustSetLastError(cur->getError().message().c_str());
        return NULL;
    }
    const Archive::Child &child = cur->get();
#else
    const Archive::Child &child = *rai->cur.operator->();
#endif
    Archive::Child *ret = new Archive::Child(child);

    ++rai->cur;
    return ret;
}

extern "C" void
LLVMRustArchiveChildFree(Archive::Child *child) {
    delete child;
}

extern "C" void
LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
    delete rai;
}

extern "C" const char*
LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
    ErrorOr<StringRef> name_or_err = child->getName();
    if (name_or_err.getError())
        return NULL;
    StringRef name = name_or_err.get();
    *size = name.size();
    return name.data();
}

extern "C" const char*
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
    StringRef buf;
    ErrorOr<StringRef> buf_or_err = child->getBuffer();
    if (buf_or_err.getError()) {
      LLVMRustSetLastError(buf_or_err.getError().message().c_str());
      return NULL;
    }
    buf = buf_or_err.get();
    *size = buf.size();
    return buf.data();
}

extern "C" LLVMRustArchiveMember*
LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
    LLVMRustArchiveMember *Member = new LLVMRustArchiveMember;
    Member->filename = Filename;
    Member->name = Name;
    if (child)
        Member->child = *child;
    return Member;
}

extern "C" void
LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) {
    delete Member;
}

extern "C" int
LLVMRustWriteArchive(char *Dst,
                     size_t NumMembers,
                     const LLVMRustArchiveMember **NewMembers,
                     bool WriteSymbtab,
                     Archive::Kind Kind) {
  std::vector<NewArchiveMember> Members;

  for (size_t i = 0; i < NumMembers; i++) {
    auto Member = NewMembers[i];
    assert(Member->name);
    if (Member->filename) {
#if LLVM_VERSION_MINOR >= 9
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return -1;
      }
      Members.push_back(std::move(*MOrErr));
#else
      Members.push_back(NewArchiveIterator(Member->filename, Member->name));
#endif
    } else {
#if LLVM_VERSION_MINOR >= 9
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return -1;
      }
      Members.push_back(std::move(*MOrErr));
#else
      Members.push_back(NewArchiveIterator(Member->child, Member->name));
#endif
    }
  }
#if LLVM_VERSION_MINOR >= 8
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
#else
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
#endif
  if (!pair.second)
    return 0;
  LLVMRustSetLastError(pair.second.message().c_str());
  return -1;
}
<|endoftext|>


<commit_before>#include "src/s3_cmds/zgw_s3_object.h"

#include <vector>

#include <glog/logging.h>
#include "slash/include/env.h"
#include "slash/include/slash_string.h"

bool GetObjectCmd::DoInitial() {
  block_buffer_.clear();
  data_size_ = 0;
  range_result_.clear();
  std::queue<std::tuple<uint64_t, uint64_t, uint64_t>> empty;
  std::swap(blocks_, empty);
  need_partial_ = req_headers_.count("range");

  return TryAuth();
}

int GetObjectCmd::ParseRange(const std::string& range, uint64_t data_size,
                             uint64_t* range_start, uint64_t* range_end) {
  // Check whether range is valid
  // Support sigle range for only
  if (range.find("bytes=") == std::string::npos) {
    return 400;
  }
  std::string range_header = range.substr(6);
  int start = 0;
  int end = INT32_MAX;
  int res = sscanf(range_header.c_str(), "%d-%d", &start, &end);
  end = std::min(data_size - 1, static_cast<uint64_t>(end));
  if (res == 1 && start < 0) {
    start = data_size + start;
    end = data_size - 1;
  }

  if (res > 0 &&
      start <= end) {
    // Valid range
    LOG(INFO) << "Get range: " << start << "-" << end;
    *range_start = start;
    *range_end = end;
    return 206;
  }
  return 416;
}

void GetObjectCmd::ParseBlocksFrom(const std::vector<std::string>& block_indexes) {
  if (data_size_ == 0) {
    if (need_partial_) {
      http_ret_code_ = 416;
      GenerateErrorXml(kInvalidRange, object_name_);
      return;
    } else {
      return;
    }
  }
  assert(data_size_ > 0);
  uint64_t range_start = 0;
  uint64_t range_end = data_size_ - 1;
  if (need_partial_) {
    http_ret_code_ = ParseRange(req_headers_.at("range"), data_size_,
                                &range_start, &range_end);
    if (http_ret_code_ == 400) {
      GenerateErrorXml(kInvalidArgument, "range");
    } else if (http_ret_code_ == 416) {
      GenerateErrorXml(kInvalidRange, object_name_);
    } else if (http_ret_code_ == 206) {
      // Success partial
      char buf[100];
      sprintf(buf, "bytes %lu-%lu/%lu", range_start, range_end, object_.size);
      http_ret_code_ = 206;
      range_result_.assign(buf);
      data_size_ = range_end - range_start + 1;
    } else {
      // Can't reach here
    }
  }
  uint64_t needed_size = range_end - range_start + 1;
  for (size_t i = 0; i < block_indexes.size(); i++) {
    // Parse all block needed
    uint64_t start_block, end_block, start_byte, data_size;
    int ret = sscanf(block_indexes[i].c_str(), "%lu-%lu(%lu,%lu)",
                     &start_block, &end_block, &start_byte, &data_size);

    // Select block interval index
    if (range_start >= (data_size - start_byte)) {
      range_start -= (data_size - start_byte);
      start_byte = 0;
      // Next block group
      continue;
    }

    for (uint64_t b = start_block; b <= end_block; b++) {
      uint64_t cur_bsize = std::min(data_size, zgwstore::kZgwBlockSize) - start_byte;
      // Select block
      if (range_start >= cur_bsize) {
        range_start -= cur_bsize;
        start_byte = 0;
        // Next block
        continue;
      }

      uint64_t remain = std::min(needed_size,
                                 zgwstore::kZgwBlockSize - range_start);
      remain = std::min(remain, data_size);

      blocks_.push(std::make_tuple(b, start_byte + range_start, remain));
      needed_size -= remain;
      start_byte = 0;

      if (needed_size == 0) {
        return;
      }

      range_start = 0;
    }
  }
}

void GetObjectCmd::SortBlockIndexes(std::vector<std::string>* block_indexes) {
  std::sort(block_indexes->begin(), block_indexes->end(),
            [](const std::string& a, const std::string& b) {
              return std::atoi(a.substr(0, 5).c_str()) <
                      std::atoi(b.substr(0, 5).c_str());
            });
  std::vector<std::string> tmp(*block_indexes);
  block_indexes->clear();
  for (auto& b : tmp) {
    // Trim sort sign e.g. 00012(3-9)(0,12) -> (3-9)(0,12)
    b = b.substr(5);
    std::vector<std::string> items;
    slash::StringSplit(b, '|', items);
    for (auto& i : items) {
      block_indexes->push_back(i);
    }
  }
}

void GetObjectCmd::DoAndResponse(pink::HttpResponse* resp) {
  if (http_ret_code_ == 200) {
    // Get object_ meta
    Status s = store_->GetObject(user_name_, bucket_name_, object_name_,
                                 &object_);
    if (!s.ok()) {
      if (s.ToString().find("Bucket Doesn't Belong To This User") !=
          std::string::npos) {
        http_ret_code_ = 404;
        GenerateErrorXml(kNoSuchBucket, bucket_name_);
      } else if (s.ToString().find("Object Not Found") != std::string::npos) {
        http_ret_code_ = 404;
        GenerateErrorXml(kNoSuchKey, object_name_);
      }
    } else {
      data_size_ = object_.size;

      std::vector<std::string> sorted_block_indexes;
      if (object_.upload_id != "_") {
        s = store_->GetMultiBlockSet(bucket_name_, object_name_,
                                     object_.upload_id, &sorted_block_indexes);
        if (s.IsIOError()) {
          http_ret_code_ = 500;
        }
        // Sort block indexes load from redis set
        SortBlockIndexes(&sorted_block_indexes);
      } else {
        // Sigle block index needn't sorting
        sorted_block_indexes.push_back(object_.data_block);
      }
      ParseBlocksFrom(sorted_block_indexes);
    }

    if (http_ret_code_ == 200 ||
        http_ret_code_ == 206) {
      // Success
      if (http_ret_code_ == 206) {
        resp->SetHeaders("Content-Range", range_result_);
      }
      resp->SetHeaders("ETag", "\"" + object_.etag + "\"");
      resp->SetHeaders("Last-Modified", http_nowtime(object_.last_modified));
      resp->SetContentLength(data_size_);
    }
  }
  if (http_ret_code_ != 206 &&
      http_ret_code_ != 200) {
    // Response error xml
    resp->SetContentLength(http_response_xml_.size());
  }
  resp->SetStatusCode(http_ret_code_);
}

int GetObjectCmd::DoResponseBody(char* buf, size_t max_size) {
  if (http_ret_code_ != 200 &&
      http_ret_code_ != 206 &&
      !http_response_xml_.empty()) {
    // Error happend, response error xml
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  }
  // Response object data
  if (data_size_ == 0) {
    return 0;
  }

  uint64_t block_size = std::get<2>(blocks_.front());
  if (block_size > max_size) {
    // Waiting for enough buffer
    return 0;
  }
  std::string block_index = std::to_string(std::get<0>(blocks_.front()));
  uint64_t start_byte = std::get<1>(blocks_.front());
  blocks_.pop();
  Status s = store_->BlockGet(block_index, &block_buffer_);
  if (!s.ok()) {
    // Zeppelin error, close the http connection
    return -1;
  }
  memcpy(buf, block_buffer_.data() + start_byte, block_size);
  data_size_ -= block_size; // Has written
  return block_size;
}
<commit_msg>Bugfix of get object copied<commit_after>#include "src/s3_cmds/zgw_s3_object.h"

#include <vector>

#include <glog/logging.h>
#include "slash/include/env.h"
#include "slash/include/slash_string.h"

bool GetObjectCmd::DoInitial() {
  block_buffer_.clear();
  data_size_ = 0;
  range_result_.clear();
  std::queue<std::tuple<uint64_t, uint64_t, uint64_t>> empty;
  std::swap(blocks_, empty);
  need_partial_ = req_headers_.count("range");

  return TryAuth();
}

int GetObjectCmd::ParseRange(const std::string& range, uint64_t data_size,
                             uint64_t* range_start, uint64_t* range_end) {
  // Check whether range is valid
  // Support sigle range for only
  if (range.find("bytes=") == std::string::npos) {
    return 400;
  }
  std::string range_header = range.substr(6);
  int start = 0;
  int end = INT32_MAX;
  int res = sscanf(range_header.c_str(), "%d-%d", &start, &end);
  end = std::min(data_size - 1, static_cast<uint64_t>(end));
  if (res == 1 && start < 0) {
    start = data_size + start;
    end = data_size - 1;
  }

  if (res > 0 &&
      start <= end) {
    // Valid range
    LOG(INFO) << "Get range: " << start << "-" << end;
    *range_start = start;
    *range_end = end;
    return 206;
  }
  return 416;
}

void GetObjectCmd::ParseBlocksFrom(const std::vector<std::string>& block_indexes) {
  if (data_size_ == 0) {
    if (need_partial_) {
      http_ret_code_ = 416;
      GenerateErrorXml(kInvalidRange, object_name_);
      return;
    } else {
      return;
    }
  }
  assert(data_size_ > 0);
  uint64_t range_start = 0;
  uint64_t range_end = data_size_ - 1;
  if (need_partial_) {
    http_ret_code_ = ParseRange(req_headers_.at("range"), data_size_,
                                &range_start, &range_end);
    if (http_ret_code_ == 400) {
      GenerateErrorXml(kInvalidArgument, "range");
    } else if (http_ret_code_ == 416) {
      GenerateErrorXml(kInvalidRange, object_name_);
    } else if (http_ret_code_ == 206) {
      // Success partial
      char buf[100];
      sprintf(buf, "bytes %lu-%lu/%lu", range_start, range_end, object_.size);
      http_ret_code_ = 206;
      range_result_.assign(buf);
      data_size_ = range_end - range_start + 1;
    } else {
      // Can't reach here
    }
  }
  uint64_t needed_size = range_end - range_start + 1;
  for (size_t i = 0; i < block_indexes.size(); i++) {
    // Parse all block needed
    uint64_t start_block, end_block, start_byte, data_size;
    int ret = sscanf(block_indexes[i].c_str(), "%lu-%lu(%lu,%lu)",
                     &start_block, &end_block, &start_byte, &data_size);

    // Select block interval index
    if (range_start >= (data_size - start_byte)) {
      range_start -= (data_size - start_byte);
      start_byte = 0;
      // Next block group
      continue;
    }

    for (uint64_t b = start_block; b <= end_block; b++) {
      uint64_t cur_bsize = std::min(data_size, zgwstore::kZgwBlockSize) - start_byte;
      // Select block
      if (range_start >= cur_bsize) {
        range_start -= cur_bsize;
        start_byte = 0;
        // Next block
        continue;
      }

      uint64_t remain = std::min(needed_size,
                                 zgwstore::kZgwBlockSize - range_start);
      remain = std::min(remain, data_size);

      blocks_.push(std::make_tuple(b, start_byte + range_start, remain));
      needed_size -= remain;
      start_byte = 0;

      if (needed_size == 0) {
        return;
      }

      range_start = 0;
    }
  }
}

void GetObjectCmd::SortBlockIndexes(std::vector<std::string>* block_indexes) {
  std::sort(block_indexes->begin(), block_indexes->end(),
            [](const std::string& a, const std::string& b) {
              return std::atoi(a.substr(0, 5).c_str()) <
                      std::atoi(b.substr(0, 5).c_str());
            });
  std::vector<std::string> tmp(*block_indexes);
  block_indexes->clear();
  for (auto& b : tmp) {
    // Trim sort sign e.g. 00012(3-9)(0,12) -> (3-9)(0,12)
    b = b.substr(5);
    std::vector<std::string> items;
    slash::StringSplit(b, '|', items);
    for (auto& i : items) {
      block_indexes->push_back(i);
    }
  }
}

void GetObjectCmd::DoAndResponse(pink::HttpResponse* resp) {
  if (http_ret_code_ == 200) {
    // Get object_ meta
    Status s = store_->GetObject(user_name_, bucket_name_, object_name_,
                                 &object_);
    if (!s.ok()) {
      if (s.ToString().find("Bucket Doesn't Belong To This User") !=
          std::string::npos) {
        http_ret_code_ = 404;
        GenerateErrorXml(kNoSuchBucket, bucket_name_);
      } else if (s.ToString().find("Object Not Found") != std::string::npos) {
        http_ret_code_ = 404;
        GenerateErrorXml(kNoSuchKey, object_name_);
      }
    } else {
      data_size_ = object_.size;

      std::vector<std::string> sorted_block_indexes;
      if (object_.upload_id != "_") {
        std::string data_block = object_.data_block;
        size_t pos = data_block.find("|");
        assert(pos != std::string::npos);
        std::string bkname = data_block.substr(32, pos - 32);
        std::string obname = data_block.substr(pos + 1);
        s = store_->GetMultiBlockSet(bkname, obname,
                                     object_.upload_id, &sorted_block_indexes);
        if (s.IsIOError()) {
          http_ret_code_ = 500;
        }
        // Sort block indexes load from redis set
        SortBlockIndexes(&sorted_block_indexes);
      } else {
        // Sigle block index needn't sorting
        sorted_block_indexes.push_back(object_.data_block);
      }
      ParseBlocksFrom(sorted_block_indexes);
    }

    if (http_ret_code_ == 200 ||
        http_ret_code_ == 206) {
      // Success
      if (http_ret_code_ == 206) {
        resp->SetHeaders("Content-Range", range_result_);
      }
      resp->SetHeaders("ETag", "\"" + object_.etag + "\"");
      resp->SetHeaders("Last-Modified", http_nowtime(object_.last_modified));
      resp->SetContentLength(data_size_);
    }
  }
  if (http_ret_code_ != 206 &&
      http_ret_code_ != 200) {
    // Response error xml
    resp->SetContentLength(http_response_xml_.size());
  }
  resp->SetStatusCode(http_ret_code_);
}

int GetObjectCmd::DoResponseBody(char* buf, size_t max_size) {
  if (http_ret_code_ != 200 &&
      http_ret_code_ != 206 &&
      !http_response_xml_.empty()) {
    // Error happend, response error xml
    if (max_size < http_response_xml_.size()) {
      memcpy(buf, http_response_xml_.data(), max_size);
      http_response_xml_.assign(http_response_xml_.substr(max_size));
    } else {
      memcpy(buf, http_response_xml_.data(), http_response_xml_.size());
    }
    return std::min(max_size, http_response_xml_.size());
  }
  // Response object data
  if (data_size_ == 0) {
    return 0;
  }

  uint64_t block_size = std::get<2>(blocks_.front());
  if (block_size > max_size) {
    // Waiting for enough buffer
    return 0;
  }
  std::string block_index = std::to_string(std::get<0>(blocks_.front()));
  uint64_t start_byte = std::get<1>(blocks_.front());
  blocks_.pop();
  Status s = store_->BlockGet(block_index, &block_buffer_);
  if (!s.ok()) {
    // Zeppelin error, close the http connection
    return -1;
  }
  memcpy(buf, block_buffer_.data() + start_byte, block_size);
  data_size_ -= block_size; // Has written
  return block_size;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <tools/resid.hxx>
#include <vcl/msgbox.hxx>
#include <osl/file.hxx>

#include "xmlfilterdialogstrings.hrc"
#include "xmlfiltertabdialog.hxx"
#include "xmlfiltertabdialog.hrc"
#include "xmlfiltertabpagebasic.hrc"
#include "xmlfiltertabpagexslt.hrc"
#include "xmlfiltertabpagebasic.hxx"
#include "xmlfiltertabpagexslt.hxx"
#include "xmlfiltersettingsdialog.hxx"
#include "xmlfilterhelpids.hrc"

using namespace com::sun::star::uno;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;
using namespace com::sun::star::lang;

XMLFilterTabDialog::XMLFilterTabDialog( Window *pParent, ResMgr& rResMgr, const Reference< XMultiServiceFactory >& rxMSF, const filter_info_impl* pInfo ) :
    TabDialog( pParent, ResId( DLG_XML_FILTER_TABDIALOG, rResMgr ) ),
    mxMSF( rxMSF ),
    mrResMgr( rResMgr ),
    maTabCtrl( this, ResId( 1, rResMgr ) ),
    maOKBtn( this ),
    maCancelBtn( this ),
    maHelpBtn( this )
{
    FreeResource();

    maTabCtrl.SetHelpId( HID_XML_FILTER_TABPAGE_CTRL );

    mpOldInfo = pInfo;
    mpNewInfo = new filter_info_impl( *mpOldInfo );

    OUString aTitle( GetText() );
    aTitle.replaceAll("%s", mpNewInfo->maFilterName);
    SetText( aTitle );

    maTabCtrl.Show();
    maOKBtn.Show();
    maCancelBtn.Show();
    maHelpBtn.Show();

    maOKBtn.SetClickHdl( LINK( this, XMLFilterTabDialog, OkHdl ) );

    maTabCtrl.SetActivatePageHdl( LINK( this, XMLFilterTabDialog, ActivatePageHdl ) );
    maTabCtrl.SetDeactivatePageHdl( LINK( this, XMLFilterTabDialog, DeactivatePageHdl ) );

    mpBasicPage = new XMLFilterTabPageBasic( &maTabCtrl, mrResMgr );
    mpBasicPage->SetInfo( mpNewInfo );

    maTabCtrl.SetTabPage( RID_XML_FILTER_TABPAGE_BASIC, mpBasicPage );

    Size aSiz = mpBasicPage->GetSizePixel();
    Size aCtrlSiz = maTabCtrl.GetTabPageSizePixel();
    // set size on TabControl only if smaller than TabPage
    if ( aCtrlSiz.Width() < aSiz.Width() || aCtrlSiz.Height() < aSiz.Height() )
    {
        maTabCtrl.SetTabPageSizePixel( aSiz );
        aCtrlSiz = aSiz;
    }

    mpXSLTPage = new XMLFilterTabPageXSLT( &maTabCtrl, mrResMgr, mxMSF );
    mpXSLTPage->SetInfo( mpNewInfo );

    maTabCtrl.SetTabPage( RID_XML_FILTER_TABPAGE_XSLT, mpXSLTPage );

    aSiz = mpXSLTPage->GetSizePixel();
    if ( aCtrlSiz.Width() < aSiz.Width() || aCtrlSiz.Height() < aSiz.Height() )
    {
        maTabCtrl.SetTabPageSizePixel( aSiz );
        aCtrlSiz = aSiz;
    }

    ActivatePageHdl( &maTabCtrl );

    AdjustLayout();
}

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

XMLFilterTabDialog::~XMLFilterTabDialog()
{
    delete mpBasicPage;
    delete mpXSLTPage;
    delete mpNewInfo;
}

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

bool XMLFilterTabDialog::onOk()
{
    mpXSLTPage->FillInfo( mpNewInfo );
    mpBasicPage->FillInfo( mpNewInfo );

    sal_uInt16 nErrorPage = 0;
    sal_uInt16 nErrorId = 0;
    Window* pFocusWindow = NULL;
    OUString aReplace1;
    OUString aReplace2;

    // 1. see if the filter name is ok
    if( (mpNewInfo->maFilterName.isEmpty()) || (mpNewInfo->maFilterName != mpOldInfo->maFilterName) )
    {
        // if the user deleted the filter name, we reset the original filter name
        if( mpNewInfo->maFilterName.isEmpty() )
        {
            mpNewInfo->maFilterName = mpOldInfo->maFilterName;
        }
        else
        {
            try
            {
                Reference< XNameAccess > xFilterContainer( mxMSF->createInstance( "com.sun.star.document.FilterFactory" ), UNO_QUERY );
                if( xFilterContainer.is() )
                {
                    if( xFilterContainer->hasByName( mpNewInfo->maFilterName ) )
                    {
                        nErrorPage = RID_XML_FILTER_TABPAGE_BASIC;
                        nErrorId = STR_ERROR_FILTER_NAME_EXISTS;
                        pFocusWindow = &(mpBasicPage->maEDFilterName);
                        aReplace1 = mpNewInfo->maFilterName;
                    }

                }
            }
            catch( const Exception& )
            {
                OSL_FAIL( "XMLFilterTabDialog::onOk exception catched!" );
            }
        }
    }

    // 2. see if the interface name is ok
    if( (mpNewInfo->maInterfaceName.isEmpty()) || (mpNewInfo->maInterfaceName != mpOldInfo->maInterfaceName) )
    {
        // if the user deleted the interface name, we reset the original filter name
        if( mpNewInfo->maInterfaceName.isEmpty() )
        {
            mpNewInfo->maInterfaceName = mpOldInfo->maInterfaceName;
        }
        else
        {
            try
            {
                Reference< XNameAccess > xFilterContainer( mxMSF->createInstance( "com.sun.star.document.FilterFactory" ), UNO_QUERY );
                if( xFilterContainer.is() )
                {
                    Sequence< OUString > aFilterNames( xFilterContainer->getElementNames() );
                    OUString* pFilterName = aFilterNames.getArray();

                    const sal_Int32 nCount = aFilterNames.getLength();
                    sal_Int32 nFilter;

                    Sequence< PropertyValue > aValues;
                    for( nFilter = 0; (nFilter < nCount) && (nErrorId == 0); nFilter++, pFilterName++ )
                    {
                        Any aAny( xFilterContainer->getByName( *pFilterName ) );
                        if( !(aAny >>= aValues) )
                            continue;

                        const sal_Int32 nValueCount( aValues.getLength() );
                        PropertyValue* pValues = aValues.getArray();
                        sal_Int32 nValue;

                        for( nValue = 0; (nValue < nValueCount) && (nErrorId == 0); nValue++, pValues++ )
                        {
                            if ( pValues->Name == "UIName" )
                            {
                                OUString aInterfaceName;
                                pValues->Value >>= aInterfaceName;
                                if( aInterfaceName == mpNewInfo->maInterfaceName )
                                {
                                    nErrorPage = RID_XML_FILTER_TABPAGE_BASIC;
                                    nErrorId = STR_ERROR_TYPE_NAME_EXISTS;
                                    pFocusWindow = &(mpBasicPage->maEDInterfaceName);
                                    aReplace1 = mpNewInfo->maInterfaceName;
                                    aReplace2 = *pFilterName;
                                }
                            }
                        }
                    }
                }
            }
            catch( const Exception& )
            {
                OSL_FAIL( "XMLFilterTabDialog::onOk exception catched!" );
            }
        }
    }

    if( 0 == nErrorId )
    {
        // 4. see if the export xslt is valid
        if( (mpNewInfo->maExportXSLT != mpOldInfo->maExportXSLT) && isFileURL( mpNewInfo->maExportXSLT ) )
        {
            osl::File aFile( mpNewInfo->maExportXSLT );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_EXPORT_XSLT_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDExportXSLT);
            }
        }
    }

    if( 0 == nErrorId )
    {
        // 5. see if the import xslt is valid
        if( (mpNewInfo->maImportXSLT != mpOldInfo->maImportXSLT) && isFileURL( mpNewInfo->maImportXSLT ) )
        {
            osl::File aFile( mpNewInfo->maImportXSLT );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_IMPORT_XSLT_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDImportTemplate);
            }
        }
    }

    // see if we have at least an import or an export xslt
    if((mpNewInfo->maImportXSLT.isEmpty()) && (mpNewInfo->maExportXSLT.isEmpty()) )
    {
        nErrorId = STR_ERROR_EXPORT_XSLT_NOT_FOUND;
        nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
        pFocusWindow = &(mpXSLTPage->maEDExportXSLT);
    }

    if( 0 == nErrorId )
    {
        // 6. see if the import template is valid
        if( (mpNewInfo->maImportTemplate != mpOldInfo->maImportTemplate) && isFileURL( mpNewInfo->maImportTemplate ) )
        {
            osl::File aFile( mpNewInfo->maImportTemplate );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_IMPORT_TEMPLATE_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDImportTemplate);
            }
        }
    }

    if( 0 != nErrorId )
    {
        maTabCtrl.SetCurPageId( (sal_uInt16)nErrorPage );
        ActivatePageHdl( &maTabCtrl );

        ResId aResId( nErrorId, mrResMgr );
        OUString aMessage( aResId );

        if( aReplace2.getLength() )
        {
            aMessage.replaceAll( "%s1", aReplace1 );
            aMessage.replaceAll( "%s2", aReplace2 );
        }
        else if( aReplace1.getLength() )
        {
            aMessage.replaceAll( "%s", aReplace1 );
        }

        ErrorBox aBox(this, (WinBits)(WB_OK), aMessage );
        aBox.Execute();

        if( pFocusWindow )
            pFocusWindow->GrabFocus();

        return false;
    }
    else
    {
        return true;
    }
}

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

filter_info_impl* XMLFilterTabDialog::getNewFilterInfo() const
{
    return mpNewInfo;
}

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

IMPL_LINK_NOARG(XMLFilterTabDialog, OkHdl)
{
    if( onOk() )
        EndDialog(1);

    return 0;
}

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

IMPL_LINK( XMLFilterTabDialog, ActivatePageHdl, TabControl *, pTabCtrl )
{
    const sal_uInt16 nId = pTabCtrl->GetCurPageId();
    TabPage* pTabPage = pTabCtrl->GetTabPage( nId );
    pTabPage->Show();

    return 0;
}

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

IMPL_LINK( XMLFilterTabDialog, DeactivatePageHdl, TabControl *, /* pTabCtrl */ )
{
    return sal_True;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>OUString::replaceAll unused results<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <tools/resid.hxx>
#include <vcl/msgbox.hxx>
#include <osl/file.hxx>

#include "xmlfilterdialogstrings.hrc"
#include "xmlfiltertabdialog.hxx"
#include "xmlfiltertabdialog.hrc"
#include "xmlfiltertabpagebasic.hrc"
#include "xmlfiltertabpagexslt.hrc"
#include "xmlfiltertabpagebasic.hxx"
#include "xmlfiltertabpagexslt.hxx"
#include "xmlfiltersettingsdialog.hxx"
#include "xmlfilterhelpids.hrc"

using namespace com::sun::star::uno;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;
using namespace com::sun::star::lang;

XMLFilterTabDialog::XMLFilterTabDialog( Window *pParent, ResMgr& rResMgr, const Reference< XMultiServiceFactory >& rxMSF, const filter_info_impl* pInfo ) :
    TabDialog( pParent, ResId( DLG_XML_FILTER_TABDIALOG, rResMgr ) ),
    mxMSF( rxMSF ),
    mrResMgr( rResMgr ),
    maTabCtrl( this, ResId( 1, rResMgr ) ),
    maOKBtn( this ),
    maCancelBtn( this ),
    maHelpBtn( this )
{
    FreeResource();

    maTabCtrl.SetHelpId( HID_XML_FILTER_TABPAGE_CTRL );

    mpOldInfo = pInfo;
    mpNewInfo = new filter_info_impl( *mpOldInfo );

    OUString aTitle( GetText() );
    aTitle = aTitle.replaceAll("%s", mpNewInfo->maFilterName);
    SetText( aTitle );

    maTabCtrl.Show();
    maOKBtn.Show();
    maCancelBtn.Show();
    maHelpBtn.Show();

    maOKBtn.SetClickHdl( LINK( this, XMLFilterTabDialog, OkHdl ) );

    maTabCtrl.SetActivatePageHdl( LINK( this, XMLFilterTabDialog, ActivatePageHdl ) );
    maTabCtrl.SetDeactivatePageHdl( LINK( this, XMLFilterTabDialog, DeactivatePageHdl ) );

    mpBasicPage = new XMLFilterTabPageBasic( &maTabCtrl, mrResMgr );
    mpBasicPage->SetInfo( mpNewInfo );

    maTabCtrl.SetTabPage( RID_XML_FILTER_TABPAGE_BASIC, mpBasicPage );

    Size aSiz = mpBasicPage->GetSizePixel();
    Size aCtrlSiz = maTabCtrl.GetTabPageSizePixel();
    // set size on TabControl only if smaller than TabPage
    if ( aCtrlSiz.Width() < aSiz.Width() || aCtrlSiz.Height() < aSiz.Height() )
    {
        maTabCtrl.SetTabPageSizePixel( aSiz );
        aCtrlSiz = aSiz;
    }

    mpXSLTPage = new XMLFilterTabPageXSLT( &maTabCtrl, mrResMgr, mxMSF );
    mpXSLTPage->SetInfo( mpNewInfo );

    maTabCtrl.SetTabPage( RID_XML_FILTER_TABPAGE_XSLT, mpXSLTPage );

    aSiz = mpXSLTPage->GetSizePixel();
    if ( aCtrlSiz.Width() < aSiz.Width() || aCtrlSiz.Height() < aSiz.Height() )
    {
        maTabCtrl.SetTabPageSizePixel( aSiz );
        aCtrlSiz = aSiz;
    }

    ActivatePageHdl( &maTabCtrl );

    AdjustLayout();
}

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

XMLFilterTabDialog::~XMLFilterTabDialog()
{
    delete mpBasicPage;
    delete mpXSLTPage;
    delete mpNewInfo;
}

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

bool XMLFilterTabDialog::onOk()
{
    mpXSLTPage->FillInfo( mpNewInfo );
    mpBasicPage->FillInfo( mpNewInfo );

    sal_uInt16 nErrorPage = 0;
    sal_uInt16 nErrorId = 0;
    Window* pFocusWindow = NULL;
    OUString aReplace1;
    OUString aReplace2;

    // 1. see if the filter name is ok
    if( (mpNewInfo->maFilterName.isEmpty()) || (mpNewInfo->maFilterName != mpOldInfo->maFilterName) )
    {
        // if the user deleted the filter name, we reset the original filter name
        if( mpNewInfo->maFilterName.isEmpty() )
        {
            mpNewInfo->maFilterName = mpOldInfo->maFilterName;
        }
        else
        {
            try
            {
                Reference< XNameAccess > xFilterContainer( mxMSF->createInstance( "com.sun.star.document.FilterFactory" ), UNO_QUERY );
                if( xFilterContainer.is() )
                {
                    if( xFilterContainer->hasByName( mpNewInfo->maFilterName ) )
                    {
                        nErrorPage = RID_XML_FILTER_TABPAGE_BASIC;
                        nErrorId = STR_ERROR_FILTER_NAME_EXISTS;
                        pFocusWindow = &(mpBasicPage->maEDFilterName);
                        aReplace1 = mpNewInfo->maFilterName;
                    }

                }
            }
            catch( const Exception& )
            {
                OSL_FAIL( "XMLFilterTabDialog::onOk exception catched!" );
            }
        }
    }

    // 2. see if the interface name is ok
    if( (mpNewInfo->maInterfaceName.isEmpty()) || (mpNewInfo->maInterfaceName != mpOldInfo->maInterfaceName) )
    {
        // if the user deleted the interface name, we reset the original filter name
        if( mpNewInfo->maInterfaceName.isEmpty() )
        {
            mpNewInfo->maInterfaceName = mpOldInfo->maInterfaceName;
        }
        else
        {
            try
            {
                Reference< XNameAccess > xFilterContainer( mxMSF->createInstance( "com.sun.star.document.FilterFactory" ), UNO_QUERY );
                if( xFilterContainer.is() )
                {
                    Sequence< OUString > aFilterNames( xFilterContainer->getElementNames() );
                    OUString* pFilterName = aFilterNames.getArray();

                    const sal_Int32 nCount = aFilterNames.getLength();
                    sal_Int32 nFilter;

                    Sequence< PropertyValue > aValues;
                    for( nFilter = 0; (nFilter < nCount) && (nErrorId == 0); nFilter++, pFilterName++ )
                    {
                        Any aAny( xFilterContainer->getByName( *pFilterName ) );
                        if( !(aAny >>= aValues) )
                            continue;

                        const sal_Int32 nValueCount( aValues.getLength() );
                        PropertyValue* pValues = aValues.getArray();
                        sal_Int32 nValue;

                        for( nValue = 0; (nValue < nValueCount) && (nErrorId == 0); nValue++, pValues++ )
                        {
                            if ( pValues->Name == "UIName" )
                            {
                                OUString aInterfaceName;
                                pValues->Value >>= aInterfaceName;
                                if( aInterfaceName == mpNewInfo->maInterfaceName )
                                {
                                    nErrorPage = RID_XML_FILTER_TABPAGE_BASIC;
                                    nErrorId = STR_ERROR_TYPE_NAME_EXISTS;
                                    pFocusWindow = &(mpBasicPage->maEDInterfaceName);
                                    aReplace1 = mpNewInfo->maInterfaceName;
                                    aReplace2 = *pFilterName;
                                }
                            }
                        }
                    }
                }
            }
            catch( const Exception& )
            {
                OSL_FAIL( "XMLFilterTabDialog::onOk exception catched!" );
            }
        }
    }

    if( 0 == nErrorId )
    {
        // 4. see if the export xslt is valid
        if( (mpNewInfo->maExportXSLT != mpOldInfo->maExportXSLT) && isFileURL( mpNewInfo->maExportXSLT ) )
        {
            osl::File aFile( mpNewInfo->maExportXSLT );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_EXPORT_XSLT_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDExportXSLT);
            }
        }
    }

    if( 0 == nErrorId )
    {
        // 5. see if the import xslt is valid
        if( (mpNewInfo->maImportXSLT != mpOldInfo->maImportXSLT) && isFileURL( mpNewInfo->maImportXSLT ) )
        {
            osl::File aFile( mpNewInfo->maImportXSLT );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_IMPORT_XSLT_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDImportTemplate);
            }
        }
    }

    // see if we have at least an import or an export xslt
    if((mpNewInfo->maImportXSLT.isEmpty()) && (mpNewInfo->maExportXSLT.isEmpty()) )
    {
        nErrorId = STR_ERROR_EXPORT_XSLT_NOT_FOUND;
        nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
        pFocusWindow = &(mpXSLTPage->maEDExportXSLT);
    }

    if( 0 == nErrorId )
    {
        // 6. see if the import template is valid
        if( (mpNewInfo->maImportTemplate != mpOldInfo->maImportTemplate) && isFileURL( mpNewInfo->maImportTemplate ) )
        {
            osl::File aFile( mpNewInfo->maImportTemplate );
            osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
            if( aRC != osl::File::E_None )
            {
                nErrorId = STR_ERROR_IMPORT_TEMPLATE_NOT_FOUND;
                nErrorPage = RID_XML_FILTER_TABPAGE_XSLT;
                pFocusWindow = &(mpXSLTPage->maEDImportTemplate);
            }
        }
    }

    if( 0 != nErrorId )
    {
        maTabCtrl.SetCurPageId( (sal_uInt16)nErrorPage );
        ActivatePageHdl( &maTabCtrl );

        ResId aResId( nErrorId, mrResMgr );
        OUString aMessage( aResId );

        if( aReplace2.getLength() )
        {
            aMessage = aMessage.replaceAll( "%s1", aReplace1 );
            aMessage = aMessage.replaceAll( "%s2", aReplace2 );
        }
        else if( aReplace1.getLength() )
        {
            aMessage = aMessage.replaceAll( "%s", aReplace1 );
        }

        ErrorBox aBox(this, (WinBits)(WB_OK), aMessage );
        aBox.Execute();

        if( pFocusWindow )
            pFocusWindow->GrabFocus();

        return false;
    }
    else
    {
        return true;
    }
}

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

filter_info_impl* XMLFilterTabDialog::getNewFilterInfo() const
{
    return mpNewInfo;
}

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

IMPL_LINK_NOARG(XMLFilterTabDialog, OkHdl)
{
    if( onOk() )
        EndDialog(1);

    return 0;
}

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

IMPL_LINK( XMLFilterTabDialog, ActivatePageHdl, TabControl *, pTabCtrl )
{
    const sal_uInt16 nId = pTabCtrl->GetCurPageId();
    TabPage* pTabPage = pTabCtrl->GetTabPage( nId );
    pTabPage->Show();

    return 0;
}

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

IMPL_LINK( XMLFilterTabDialog, DeactivatePageHdl, TabControl *, /* pTabCtrl */ )
{
    return sal_True;
}

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


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       [ Peter Jentsch <pjotr@guineapics.de> ]
 * Portions created by the Initial Developer are Copyright (C) 2010 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Peter Jentsch <pjotr@guineapics.de>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

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

#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <vector>
#include <iostream>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlIO.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include <libxslt/variables.h>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/implbase4.hxx>
#include <cppuhelper/implbase.hxx>
#include <osl/module.h>
#include <osl/file.hxx>
#include <osl/process.h>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XStreamListener.hpp>

#include <LibXSLTTransformer.hxx>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::osl;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using ::std::list;
using ::std::map;
using ::std::pair;

#define _INPUT_BUFFER_SIZE 4096
#define _OUTPUT_BUFFER_SIZE 4096

namespace XSLT
{
    const char* const LibXSLTTransformer::PARAM_SOURCE_URL = "sourceURL";
    const char* const LibXSLTTransformer::PARAM_SOURCE_BASE_URL =
            "sourceBaseURL";
    const char* const LibXSLTTransformer::PARAM_TARGET_URL = "targetURL";
    const char* const LibXSLTTransformer::PARAM_TARGET_BASE_URL =
            "targetBaseURL";
    const char* const LibXSLTTransformer::PARAM_DOCTYPE_SYSTEM = "sytemType";
    const char* const LibXSLTTransformer::PARAM_DOCTYPE_PUBLIC = "publicType";

    const sal_Int32 Reader::OUTPUT_BUFFER_SIZE = _OUTPUT_BUFFER_SIZE;

    const sal_Int32 Reader::INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;

    struct ParserInputBufferCallback
    {
        static int
        on_read(void * context, char * buffer, int len)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->read(buffer, len);
        }
        static int
        on_close(void * context)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->closeInput();
        }
    };
    struct ParserOutputBufferCallback
    {
        static int
        on_write(void * context, const char * buffer, int len)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->write(buffer, len);
        }
        static int
        on_close(void * context)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->closeOutput();
        }
    };

    Reader::Reader(LibXSLTTransformer* transformer) :
        m_transformer(transformer), m_terminated(false), m_readBuf(
                INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE)
    {
        LIBXML_TEST_VERSION;
    }
    ;

    int
    Reader::read(char * buffer, int len)
    {
        //        const char *ptr = (const char *) context;
        if (buffer == NULL || len < 0)
            return (-1);
        sal_Int32 n;
        Reference<XInputStream> xis = this->m_transformer->getInputStream();
        n = xis.get()->readBytes(m_readBuf, len);
        if (n > 0)
            {
                memcpy(buffer, m_readBuf.getArray(), n);
            }
        return n;
    }

    int
    Reader::write(const char * buffer, int len)
    {
        if (buffer == NULL || len < 0)
            return -1;
        if (len > 0)
            {
                Reference<XOutputStream> xos = m_transformer->getOutputStream();
                sal_Int32 writeLen = len;
                sal_Int32 bufLen = ::std::min(writeLen,
                        this->OUTPUT_BUFFER_SIZE);
                const sal_uInt8* memPtr =
                        reinterpret_cast<const sal_uInt8*> (buffer);
                while (writeLen > 0)
                    {
                        sal_Int32 n = ::std::min(writeLen, bufLen);
                        m_writeBuf.realloc(n);
                        memcpy(m_writeBuf.getArray(), memPtr,
                                static_cast<size_t> (n));
                        xos.get()->writeBytes(m_writeBuf);
                        memPtr += n;
                        writeLen -= n;
                    }
            }
        return len;
    }

    int
    Reader::closeInput()
    {
        return 0;
    }

    int
    Reader::closeOutput()
    {
        Reference<XOutputStream> xos = m_transformer->getOutputStream();
        if (xos.is())
            {
                xos.get()->flush();
                xos.get()->closeOutput();
            }
        m_transformer->done();
        return 0;
    }

    void
    Reader::run()
    {
        OSL_ASSERT(m_transformer != NULL);
        OSL_ASSERT(m_transformer->getInputStream().is());
        OSL_ASSERT(m_transformer->getOutputStream().is());
        OSL_ASSERT(m_transformer->getStyleSheetURL());
        ::std::map<const char*, OString>::iterator pit;
        ::std::map<const char*, OString> pmap = m_transformer->getParameters();
        ::std::vector< const char* > params( pmap.size() * 2 + 1 ); // build parameters
        int paramIndex = 0;
        for (pit = pmap.begin(); pit != pmap.end(); pit++)
            {
                params[paramIndex++] = (*pit).first;
                params[paramIndex++] = (*pit).second.getStr();
            }
        params[paramIndex] = NULL;
        xmlDocPtr doc = xmlReadIO(&ParserInputBufferCallback::on_read,
                &ParserInputBufferCallback::on_close,
                static_cast<void*> (this), NULL, NULL, 0);
        xsltStylesheetPtr styleSheet = xsltParseStylesheetFile(
                (const xmlChar *) m_transformer->getStyleSheetURL().getStr());
        xmlDocPtr result = NULL;
        xsltTransformContextPtr tcontext = NULL;
        if (styleSheet)
            {
                tcontext = xsltNewTransformContext(styleSheet, doc);
                xsltQuoteUserParams(tcontext, &params[0]);
                result = xsltApplyStylesheetUser(styleSheet, doc, 0, 0, 0,
                        tcontext);
            }

        if (result)
            {
                xmlCharEncodingHandlerPtr encoder = xmlGetCharEncodingHandler(
                        XML_CHAR_ENCODING_UTF8);
                xmlOutputBufferPtr outBuf = xmlAllocOutputBuffer(encoder);
                outBuf->context = static_cast<void *> (this);
                outBuf->writecallback = &ParserOutputBufferCallback::on_write;
                outBuf->closecallback = &ParserOutputBufferCallback::on_close;
                xsltSaveResultTo(outBuf, result, styleSheet);
            }
        else
            {
                xmlErrorPtr lastErr = xmlGetLastError();
                OUString msg;
                if (lastErr)
                    msg = OUString::createFromAscii(lastErr->message);
                else
                    msg = OUString::createFromAscii(
                            "Unknown XSLT transformation error");

                m_transformer->error(msg);
            }
        closeOutput();
        xsltFreeStylesheet(styleSheet);
        xsltFreeTransformContext(tcontext);
        xmlFreeDoc(doc);
        xmlFreeDoc(result);
    }
    ;

    void
    Reader::onTerminated()
    {
        m_terminated = true;
    }
    ;

    Reader::~Reader()
    {
    }

    LibXSLTTransformer::LibXSLTTransformer(
            const Reference<XMultiServiceFactory> &r) :
        m_rServiceFactory(r)
    {
    }

    void
    LibXSLTTransformer::setInputStream(
            const Reference<XInputStream>& inputStream)
            throw (RuntimeException)
    {
        m_rInputStream = inputStream;
    }

    Reference<XInputStream>
    LibXSLTTransformer::getInputStream() throw (RuntimeException)
    {
        return m_rInputStream;
    }

    void
    LibXSLTTransformer::setOutputStream(
            const Reference<XOutputStream>& outputStream)
            throw (RuntimeException)
    {
        m_rOutputStream = outputStream;
    }

    Reference<XOutputStream>
    LibXSLTTransformer::getOutputStream() throw (RuntimeException)
    {
        return m_rOutputStream;
    }

    void
    LibXSLTTransformer::addListener(const Reference<XStreamListener>& listener)
            throw (RuntimeException)
    {
        m_listeners.insert(m_listeners.begin(), listener);
    }

    void
    LibXSLTTransformer::removeListener(
            const Reference<XStreamListener>& listener)
            throw (RuntimeException)
    {
        m_listeners.remove(listener);
    }

    void
    LibXSLTTransformer::start() throw (RuntimeException)
    {
        ListenerList::iterator it;
        ListenerList* l = &m_listeners;
        for (it = l->begin(); it != l->end(); it++)
            {
                Reference<XStreamListener> xl = *it;
                xl.get()->started();
            }
        Reader* r = new Reader(this);
        r->create();
    }

    void
    LibXSLTTransformer::error(const OUString& msg)
    {
        ListenerList* l = &m_listeners;
        Any arg;
        arg <<= Exception(msg, *this);
        for (ListenerList::iterator it = l->begin(); it != l->end(); it++)
            {
                Reference<XStreamListener> xl = *it;
                if (xl.is())
                    {
                        xl.get()->error(arg);
                    }
            }
    }

    void
    LibXSLTTransformer::done()
    {
        ListenerList* l = &m_listeners;
        for (ListenerList::iterator it = l->begin(); it != l->end(); it++)
            {
                Reference<XStreamListener> xl = *it;
                if (xl.is())
                    {
                        xl.get()->closed();
                    }
            }
    }

    void
    LibXSLTTransformer::terminate() throw (RuntimeException)
    {
        m_parameters.clear();
    }

    void
    LibXSLTTransformer::initialize(const Sequence<Any>& params)
            throw (RuntimeException)
    {
        xmlSubstituteEntitiesDefault(0);
        m_parameters.clear();
        for (int i = 0; i < params.getLength(); i++)
            {
                NamedValue nv;
                params[i] >>= nv;
                OString nameUTF8 = OUStringToOString(nv.Name,
                        RTL_TEXTENCODING_UTF8);
                OUString value;
                OString valueUTF8;
                if (nv.Value >>= value)
                    {
                        valueUTF8 = OUStringToOString(value,
                                RTL_TEXTENCODING_UTF8);
                    }
                else
                    {
                        // ignore non-string parameters
                        continue;
                    }
                if (nameUTF8.equals("StylesheetURL"))
                    {
                        m_styleSheetURL = valueUTF8;
                    }
                else if (nameUTF8.equals("SourceURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_SOURCE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("SourceBaseURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_SOURCE_BASE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("TargetURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_TARGET_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("TargetBaseURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_TARGET_BASE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("DoctypeSystem"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_DOCTYPE_SYSTEM, valueUTF8));
                    }
                else if (nameUTF8.equals("DoctypePublic"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_DOCTYPE_PUBLIC, valueUTF8));
                    }
            }
    }

    const OString
    LibXSLTTransformer::getStyleSheetURL()
    {
        return m_styleSheetURL;
    }

    ::std::map<const char*, OString>
    LibXSLTTransformer::getParameters()
    {
        return m_parameters;
    }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

<commit_msg>cppcheck: post- to pre- *crement change<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *       [ Peter Jentsch <pjotr@guineapics.de> ]
 * Portions created by the Initial Developer are Copyright (C) 2010 the
 * Initial Developer. All Rights Reserved.
 *
 * Contributor(s): Peter Jentsch <pjotr@guineapics.de>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

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

#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <vector>
#include <iostream>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlIO.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include <libxslt/variables.h>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/implbase4.hxx>
#include <cppuhelper/implbase.hxx>
#include <osl/module.h>
#include <osl/file.hxx>
#include <osl/process.h>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XStreamListener.hpp>

#include <LibXSLTTransformer.hxx>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::osl;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using ::std::list;
using ::std::map;
using ::std::pair;

#define _INPUT_BUFFER_SIZE 4096
#define _OUTPUT_BUFFER_SIZE 4096

namespace XSLT
{
    const char* const LibXSLTTransformer::PARAM_SOURCE_URL = "sourceURL";
    const char* const LibXSLTTransformer::PARAM_SOURCE_BASE_URL =
            "sourceBaseURL";
    const char* const LibXSLTTransformer::PARAM_TARGET_URL = "targetURL";
    const char* const LibXSLTTransformer::PARAM_TARGET_BASE_URL =
            "targetBaseURL";
    const char* const LibXSLTTransformer::PARAM_DOCTYPE_SYSTEM = "sytemType";
    const char* const LibXSLTTransformer::PARAM_DOCTYPE_PUBLIC = "publicType";

    const sal_Int32 Reader::OUTPUT_BUFFER_SIZE = _OUTPUT_BUFFER_SIZE;

    const sal_Int32 Reader::INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;

    struct ParserInputBufferCallback
    {
        static int
        on_read(void * context, char * buffer, int len)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->read(buffer, len);
        }
        static int
        on_close(void * context)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->closeInput();
        }
    };
    struct ParserOutputBufferCallback
    {
        static int
        on_write(void * context, const char * buffer, int len)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->write(buffer, len);
        }
        static int
        on_close(void * context)
        {
            Reader * tmp = static_cast<Reader*> (context);
            return tmp->closeOutput();
        }
    };

    Reader::Reader(LibXSLTTransformer* transformer) :
        m_transformer(transformer), m_terminated(false), m_readBuf(
                INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE)
    {
        LIBXML_TEST_VERSION;
    }
    ;

    int
    Reader::read(char * buffer, int len)
    {
        //        const char *ptr = (const char *) context;
        if (buffer == NULL || len < 0)
            return (-1);
        sal_Int32 n;
        Reference<XInputStream> xis = this->m_transformer->getInputStream();
        n = xis.get()->readBytes(m_readBuf, len);
        if (n > 0)
            {
                memcpy(buffer, m_readBuf.getArray(), n);
            }
        return n;
    }

    int
    Reader::write(const char * buffer, int len)
    {
        if (buffer == NULL || len < 0)
            return -1;
        if (len > 0)
            {
                Reference<XOutputStream> xos = m_transformer->getOutputStream();
                sal_Int32 writeLen = len;
                sal_Int32 bufLen = ::std::min(writeLen,
                        this->OUTPUT_BUFFER_SIZE);
                const sal_uInt8* memPtr =
                        reinterpret_cast<const sal_uInt8*> (buffer);
                while (writeLen > 0)
                    {
                        sal_Int32 n = ::std::min(writeLen, bufLen);
                        m_writeBuf.realloc(n);
                        memcpy(m_writeBuf.getArray(), memPtr,
                                static_cast<size_t> (n));
                        xos.get()->writeBytes(m_writeBuf);
                        memPtr += n;
                        writeLen -= n;
                    }
            }
        return len;
    }

    int
    Reader::closeInput()
    {
        return 0;
    }

    int
    Reader::closeOutput()
    {
        Reference<XOutputStream> xos = m_transformer->getOutputStream();
        if (xos.is())
            {
                xos.get()->flush();
                xos.get()->closeOutput();
            }
        m_transformer->done();
        return 0;
    }

    void
    Reader::run()
    {
        OSL_ASSERT(m_transformer != NULL);
        OSL_ASSERT(m_transformer->getInputStream().is());
        OSL_ASSERT(m_transformer->getOutputStream().is());
        OSL_ASSERT(m_transformer->getStyleSheetURL());
        ::std::map<const char*, OString>::iterator pit;
        ::std::map<const char*, OString> pmap = m_transformer->getParameters();
        ::std::vector< const char* > params( pmap.size() * 2 + 1 ); // build parameters
        int paramIndex = 0;
        for (pit = pmap.begin(); pit != pmap.end(); pit++)
            {
                params[paramIndex++] = (*pit).first;
                params[paramIndex++] = (*pit).second.getStr();
            }
        params[paramIndex] = NULL;
        xmlDocPtr doc = xmlReadIO(&ParserInputBufferCallback::on_read,
                &ParserInputBufferCallback::on_close,
                static_cast<void*> (this), NULL, NULL, 0);
        xsltStylesheetPtr styleSheet = xsltParseStylesheetFile(
                (const xmlChar *) m_transformer->getStyleSheetURL().getStr());
        xmlDocPtr result = NULL;
        xsltTransformContextPtr tcontext = NULL;
        if (styleSheet)
            {
                tcontext = xsltNewTransformContext(styleSheet, doc);
                xsltQuoteUserParams(tcontext, &params[0]);
                result = xsltApplyStylesheetUser(styleSheet, doc, 0, 0, 0,
                        tcontext);
            }

        if (result)
            {
                xmlCharEncodingHandlerPtr encoder = xmlGetCharEncodingHandler(
                        XML_CHAR_ENCODING_UTF8);
                xmlOutputBufferPtr outBuf = xmlAllocOutputBuffer(encoder);
                outBuf->context = static_cast<void *> (this);
                outBuf->writecallback = &ParserOutputBufferCallback::on_write;
                outBuf->closecallback = &ParserOutputBufferCallback::on_close;
                xsltSaveResultTo(outBuf, result, styleSheet);
            }
        else
            {
                xmlErrorPtr lastErr = xmlGetLastError();
                OUString msg;
                if (lastErr)
                    msg = OUString::createFromAscii(lastErr->message);
                else
                    msg = OUString::createFromAscii(
                            "Unknown XSLT transformation error");

                m_transformer->error(msg);
            }
        closeOutput();
        xsltFreeStylesheet(styleSheet);
        xsltFreeTransformContext(tcontext);
        xmlFreeDoc(doc);
        xmlFreeDoc(result);
    }
    ;

    void
    Reader::onTerminated()
    {
        m_terminated = true;
    }
    ;

    Reader::~Reader()
    {
    }

    LibXSLTTransformer::LibXSLTTransformer(
            const Reference<XMultiServiceFactory> &r) :
        m_rServiceFactory(r)
    {
    }

    void
    LibXSLTTransformer::setInputStream(
            const Reference<XInputStream>& inputStream)
            throw (RuntimeException)
    {
        m_rInputStream = inputStream;
    }

    Reference<XInputStream>
    LibXSLTTransformer::getInputStream() throw (RuntimeException)
    {
        return m_rInputStream;
    }

    void
    LibXSLTTransformer::setOutputStream(
            const Reference<XOutputStream>& outputStream)
            throw (RuntimeException)
    {
        m_rOutputStream = outputStream;
    }

    Reference<XOutputStream>
    LibXSLTTransformer::getOutputStream() throw (RuntimeException)
    {
        return m_rOutputStream;
    }

    void
    LibXSLTTransformer::addListener(const Reference<XStreamListener>& listener)
            throw (RuntimeException)
    {
        m_listeners.insert(m_listeners.begin(), listener);
    }

    void
    LibXSLTTransformer::removeListener(
            const Reference<XStreamListener>& listener)
            throw (RuntimeException)
    {
        m_listeners.remove(listener);
    }

    void
    LibXSLTTransformer::start() throw (RuntimeException)
    {
        ListenerList::iterator it;
        ListenerList* l = &m_listeners;
        for (it = l->begin(); it != l->end(); ++it)
            {
                Reference<XStreamListener> xl = *it;
                xl.get()->started();
            }
        Reader* r = new Reader(this);
        r->create();
    }

    void
    LibXSLTTransformer::error(const OUString& msg)
    {
        ListenerList* l = &m_listeners;
        Any arg;
        arg <<= Exception(msg, *this);
        for (ListenerList::iterator it = l->begin(); it != l->end(); ++it)
            {
                Reference<XStreamListener> xl = *it;
                if (xl.is())
                    {
                        xl.get()->error(arg);
                    }
            }
    }

    void
    LibXSLTTransformer::done()
    {
        ListenerList* l = &m_listeners;
        for (ListenerList::iterator it = l->begin(); it != l->end(); ++it)
            {
                Reference<XStreamListener> xl = *it;
                if (xl.is())
                    {
                        xl.get()->closed();
                    }
            }
    }

    void
    LibXSLTTransformer::terminate() throw (RuntimeException)
    {
        m_parameters.clear();
    }

    void
    LibXSLTTransformer::initialize(const Sequence<Any>& params)
            throw (RuntimeException)
    {
        xmlSubstituteEntitiesDefault(0);
        m_parameters.clear();
        for (int i = 0; i < params.getLength(); i++)
            {
                NamedValue nv;
                params[i] >>= nv;
                OString nameUTF8 = OUStringToOString(nv.Name,
                        RTL_TEXTENCODING_UTF8);
                OUString value;
                OString valueUTF8;
                if (nv.Value >>= value)
                    {
                        valueUTF8 = OUStringToOString(value,
                                RTL_TEXTENCODING_UTF8);
                    }
                else
                    {
                        // ignore non-string parameters
                        continue;
                    }
                if (nameUTF8.equals("StylesheetURL"))
                    {
                        m_styleSheetURL = valueUTF8;
                    }
                else if (nameUTF8.equals("SourceURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_SOURCE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("SourceBaseURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_SOURCE_BASE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("TargetURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_TARGET_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("TargetBaseURL"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_TARGET_BASE_URL, valueUTF8));
                    }
                else if (nameUTF8.equals("DoctypeSystem"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_DOCTYPE_SYSTEM, valueUTF8));
                    }
                else if (nameUTF8.equals("DoctypePublic"))
                    {
                        m_parameters.insert(pair<const char*, OString> (
                                PARAM_DOCTYPE_PUBLIC, valueUTF8));
                    }
            }
    }

    const OString
    LibXSLTTransformer::getStyleSheetURL()
    {
        return m_styleSheetURL;
    }

    ::std::map<const char*, OString>
    LibXSLTTransformer::getParameters()
    {
        return m_parameters;
    }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

<|endoftext|>


<commit_before>//===--- History.cpp - Previously Entered Lines -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for setting and retrieving previously
//  entered input, with a persistent backend (i.e. a history file).
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#include "textinput/History.h"
#include <iostream>
#include <fstream>

#ifdef WIN32
# include <stdio.h>
#else
# include <unistd.h>
#endif

namespace textinput {
  History::History(const char* filename):
    fHistFileName(filename ? filename : ""), fMaxDepth((size_t) -1),
    fPruneLength(0), fNumHistFileLines(0) {
    // Create a history object, initialize from filename if the file
    // exists. Append new lines to filename taking into account the
    // maximal number of lines allowed by SetMaxDepth().
    if (filename) ReadFile(filename);
  }

  History::~History() {}

  void
  History::AddLine(const std::string& line) {
    // Add a line to entries and file.
    if (line.empty()) return;
    fEntries.push_back(line);
    AppendToFile();
  }

  void
  History::ReadFile(const char* FileName) {
    // Inject all lines of FileName.
    // Intentionally ignore fMaxDepth
    std::ifstream InHistFile(FileName);
    if (!InHistFile) return;
    std::string line;
    while (std::getline(InHistFile, line)) {
      while (!line.empty()) {
        size_t len = line.length();
        char c = line[len - 1];
        if (c != '\n' && c != '\r') break;
        line.erase(len - 1);
      }
      if (!line.empty()) {
        fEntries.push_back(line);
      }
    }
    fNumHistFileLines = fEntries.size();
  }

  void
  History::AppendToFile() {
    // Write last entry to hist file.
    // Prune if needed.
    if (fHistFileName.empty() || !fMaxDepth) return;

    // Calculate prune length to use
    size_t nPrune = fPruneLength;
    if (nPrune == (size_t)kPruneLengthDefault) {
      nPrune = (size_t)(fMaxDepth * 0.8);
    } else if (nPrune > fMaxDepth) {
      nPrune = fMaxDepth - 1; // fMaxDepth is guaranteed to be > 0.
    }

    // Don't check for the actual line count of the history file after every
    // single line. Once every 50% on the way between nPrune and fMaxDepth is
    // enough.
    if (fNumHistFileLines < fMaxDepth
        && (fNumHistFileLines % (fMaxDepth - nPrune)) == 0) {
      fNumHistFileLines = 0;
      std::string line;
      std::ifstream in(fHistFileName.c_str());
      while (std::getline(in, line))
        ++fNumHistFileLines;
    }

    size_t numLines = fNumHistFileLines;
    if (numLines >= fMaxDepth) {
      // Prune! But don't simply write our lines - other processes might have
      // added their own.
      std::string line;
      std::ifstream in(fHistFileName.c_str());
      std::string pruneFileName = fHistFileName + "_prune";
      std::ofstream out(pruneFileName.c_str());
      if (out) {
        if (in) {
          while (numLines >= nPrune && std::getline(in, line)) {
            // skip
            --numLines;
          }
          while (std::getline(in, line)) {
            out << line << '\n';
          }
        }
        out << fEntries.back() << '\n';
        in.close();
        out.close();
#ifdef WIN32
        ::_unlink(fHistFileName.c_str());
#else
        ::unlink(fHistFileName.c_str());
#endif
        if (::rename(pruneFileName.c_str(), fHistFileName.c_str()) == -1) {
           std::cerr << "ERROR in textinput::History::AppendToFile(): "
              "cannot rename " << pruneFileName << " to " << fHistFileName;
        }
        fNumHistFileLines = nPrune;
      }
    } else {
      std::ofstream out(fHistFileName.c_str(), std::ios_base::app);
      out << fEntries.back() << '\n';
      ++fNumHistFileLines;
    }
  }
}
<commit_msg>Make tmp prune files process-unique (ROOT-6539).<commit_after>//===--- History.cpp - Previously Entered Lines -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the interface for setting and retrieving previously
//  entered input, with a persistent backend (i.e. a history file).
//
//  Axel Naumann <axel@cern.ch>, 2011-05-12
//===----------------------------------------------------------------------===//

#include "textinput/History.h"
#include <iostream>
#include <fstream>
#include <sstream>

#ifdef WIN32
# include <stdio.h>
extern "C" unsigned int GetCurrentProcessId();
#else
# include <unistd.h>
#endif

namespace textinput {
  History::History(const char* filename):
    fHistFileName(filename ? filename : ""), fMaxDepth((size_t) -1),
    fPruneLength(0), fNumHistFileLines(0) {
    // Create a history object, initialize from filename if the file
    // exists. Append new lines to filename taking into account the
    // maximal number of lines allowed by SetMaxDepth().
    if (filename) ReadFile(filename);
  }

  History::~History() {}

  void
  History::AddLine(const std::string& line) {
    // Add a line to entries and file.
    if (line.empty()) return;
    fEntries.push_back(line);
    AppendToFile();
  }

  void
  History::ReadFile(const char* FileName) {
    // Inject all lines of FileName.
    // Intentionally ignore fMaxDepth
    std::ifstream InHistFile(FileName);
    if (!InHistFile) return;
    std::string line;
    while (std::getline(InHistFile, line)) {
      while (!line.empty()) {
        size_t len = line.length();
        char c = line[len - 1];
        if (c != '\n' && c != '\r') break;
        line.erase(len - 1);
      }
      if (!line.empty()) {
        fEntries.push_back(line);
      }
    }
    fNumHistFileLines = fEntries.size();
  }

  void
  History::AppendToFile() {
    // Write last entry to hist file.
    // Prune if needed.
    if (fHistFileName.empty() || !fMaxDepth) return;

    // Calculate prune length to use
    size_t nPrune = fPruneLength;
    if (nPrune == (size_t)kPruneLengthDefault) {
      nPrune = (size_t)(fMaxDepth * 0.8);
    } else if (nPrune > fMaxDepth) {
      nPrune = fMaxDepth - 1; // fMaxDepth is guaranteed to be > 0.
    }

    // Don't check for the actual line count of the history file after every
    // single line. Once every 50% on the way between nPrune and fMaxDepth is
    // enough.
    if (fNumHistFileLines < fMaxDepth
        && (fNumHistFileLines % (fMaxDepth - nPrune)) == 0) {
      fNumHistFileLines = 0;
      std::string line;
      std::ifstream in(fHistFileName.c_str());
      while (std::getline(in, line))
        ++fNumHistFileLines;
    }

    size_t numLines = fNumHistFileLines;
    if (numLines >= fMaxDepth) {
      // Prune! But don't simply write our lines - other processes might have
      // added their own.
      std::string line;
      std::ifstream in(fHistFileName.c_str());
      std::stringstream pruneFileNameStream;
      pruneFileNameStream << fHistFileName + "_prune"
#if _WIN32
                          << ::GetCurrentProcessId();
#else
                          << ::getpid();
#endif
      std::ofstream out(pruneFileNameStream.str().c_str());
      if (out) {
        if (in) {
          while (numLines >= nPrune && std::getline(in, line)) {
            // skip
            --numLines;
          }
          while (std::getline(in, line)) {
            out << line << '\n';
          }
        }
        out << fEntries.back() << '\n';
        in.close();
        out.close();
#ifdef WIN32
        ::_unlink(fHistFileName.c_str());
#else
        ::unlink(fHistFileName.c_str());
#endif
        if (::rename(pruneFileNameStream.str().c_str(), fHistFileName.c_str()) == -1){
           std::cerr << "ERROR in textinput::History::AppendToFile(): "
              "cannot rename " << pruneFileNameStream.str() << " to " << fHistFileName;
        }
        fNumHistFileLines = nPrune;
      }
    } else {
      std::ofstream out(fHistFileName.c_str(), std::ios_base::app);
      out << fEntries.back() << '\n';
      ++fNumHistFileLines;
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "core/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h"

#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/IntRect.h"
#include "core/platform/graphics/transforms/AffineTransform.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebRect.h"

using WebKit::WebFloatRect;
using WebKit::WebRect;

namespace WebCore {

OpaqueRectTrackingContentLayerDelegate::OpaqueRectTrackingContentLayerDelegate(GraphicsContextPainter* painter)
    : m_painter(painter)
    , m_opaque(false)
{
}

OpaqueRectTrackingContentLayerDelegate::~OpaqueRectTrackingContentLayerDelegate()
{
}

void OpaqueRectTrackingContentLayerDelegate::paintContents(SkCanvas* canvas, const WebRect& clip, bool canPaintLCDText, WebFloatRect& opaque)
{
    GraphicsContext context(canvas);
    context.setTrackOpaqueRegion(!m_opaque);
    context.setCertainlyOpaque(m_opaque);
    context.setShouldSmoothFonts(canPaintLCDText);

    // Record transform prior to painting, as all opaque tracking will be
    // relative to this current value.
    AffineTransform canvasToContentTransform = context.getCTM().inverse();

    m_painter->paint(context, clip);

    // Transform tracked opaque paints back to our layer's content space.
    ASSERT(canvasToContentTransform.isInvertible());
    ASSERT(canvasToContentTransform.preservesAxisAlignment());
    opaque = canvasToContentTransform.mapRect(context.opaqueRegion().asRect());
}

}
<commit_msg>Turn on GraphicsContext annotations when tracing.<commit_after>/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "core/platform/graphics/chromium/OpaqueRectTrackingContentLayerDelegate.h"

#include "core/platform/EventTracer.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/IntRect.h"
#include "core/platform/graphics/transforms/AffineTransform.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebRect.h"

using WebKit::WebFloatRect;
using WebKit::WebRect;

namespace WebCore {

OpaqueRectTrackingContentLayerDelegate::OpaqueRectTrackingContentLayerDelegate(GraphicsContextPainter* painter)
    : m_painter(painter)
    , m_opaque(false)
{
}

OpaqueRectTrackingContentLayerDelegate::~OpaqueRectTrackingContentLayerDelegate()
{
}

void OpaqueRectTrackingContentLayerDelegate::paintContents(SkCanvas* canvas, const WebRect& clip, bool canPaintLCDText, WebFloatRect& opaque)
{
    GraphicsContext context(canvas);
    context.setTrackOpaqueRegion(!m_opaque);
    context.setCertainlyOpaque(m_opaque);
    context.setShouldSmoothFonts(canPaintLCDText);

    if (*EventTracer::getTraceCategoryEnabledFlag("blink.graphics_context_annotations"))
        context.setAnnotationMode(AnnotateAll);

    // Record transform prior to painting, as all opaque tracking will be
    // relative to this current value.
    AffineTransform canvasToContentTransform = context.getCTM().inverse();

    m_painter->paint(context, clip);

    // Transform tracked opaque paints back to our layer's content space.
    ASSERT(canvasToContentTransform.isInvertible());
    ASSERT(canvasToContentTransform.preservesAxisAlignment());
    opaque = canvasToContentTransform.mapRect(context.opaqueRegion().asRect());
}

}
<|endoftext|>