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

// TODO : Support NP_ASFILEONLY mode
// TODO : Support NP_SEEK mode
// TODO : Support SEEKABLE=true in NewStream

#include "webkit/glue/plugins/plugin_stream.h"

#include "base/string_util.h"
#include "base/message_loop.h"
#include "net/base/mime_util.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "googleurl/src/gurl.h"

namespace NPAPI {

PluginStream::~PluginStream() {
  // always close our temporary files.
  CloseTempFile();
  free(const_cast<char*>(stream_.url));
}

bool PluginStream::Open(const std::string &mime_type,
                        const std::string &headers,
                        uint32 length,
                        uint32 last_modified,
                        bool request_is_seekable) {
  headers_ = headers;
  NPP id = instance_->npp();
  stream_.end = length;
  stream_.lastmodified = last_modified;
  stream_.pdata = 0;
  stream_.ndata = id->ndata;
  stream_.notifyData = notify_data_;

  bool seekable_stream = false;
  if (request_is_seekable && !headers_.empty()) {
    stream_.headers = headers_.c_str();
    if (headers_.find("Accept-Ranges: bytes") != std::string::npos) {
      seekable_stream = true;
    }
  }

  const char *char_mime_type = "application/x-unknown-content-type";
  std::string temp_mime_type;
  if (!mime_type.empty()) {
    char_mime_type = mime_type.c_str();
  } else {
    GURL gurl(stream_.url);

#if defined(OS_WIN)
    FilePath path(UTF8ToWide(gurl.path()));
#elif defined(OS_POSIX)
    FilePath path(gurl.path());
#endif
    if (net::GetMimeTypeFromFile(path, &temp_mime_type))
      char_mime_type = temp_mime_type.c_str();
  }

  // Silverlight expects a valid mime type
  DCHECK(strlen(char_mime_type) != 0);
  NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type,
                                         &stream_, seekable_stream,
                                         &requested_plugin_mode_);
  if (err != NPERR_NO_ERROR) {
    Notify(err);
    return false;
  }

  opened_ = true;

  if (requested_plugin_mode_ == NP_SEEK) {
    seekable_stream_ = true;
  }
  // If the plugin has requested certain modes, then we need a copy
  // of this file on disk.  Open it and save it as we go.
  if (requested_plugin_mode_ == NP_ASFILEONLY ||
    requested_plugin_mode_ == NP_ASFILE) {
    if (OpenTempFile() == false)
      return false;
  }

  mime_type_ = char_mime_type;
  return true;
}

int PluginStream::Write(const char *buffer, const int length,
                        int data_offset) {
  // There may be two streams to write to - the plugin and the file.
  // It is unclear what to do if we cannot write to both.  The rules of
  // this function are that the plugin must consume at least as many
  // bytes as returned by the WriteReady call.  So, we will attempt to
  // write that many to both streams.  If we can't write that many bytes
  // to each stream, we'll return failure.

  DCHECK(opened_);
  if (WriteToFile(buffer, length) &&
      WriteToPlugin(buffer, length, data_offset))
    return length;

  return -1;
}

bool PluginStream::WriteToFile(const char *buf, size_t length) {
  // For ASFILEONLY, ASFILE, and SEEK modes, we need to write
  // to the disk
  if (TempFileIsValid() &&
      (requested_plugin_mode_ == NP_ASFILE ||
       requested_plugin_mode_ == NP_ASFILEONLY) ) {
    size_t totalBytesWritten = 0, bytes;
    do {
      bytes = WriteBytes(buf, length);
      totalBytesWritten += bytes;
    } while (bytes > 0U && totalBytesWritten < length);

    if (totalBytesWritten != length)
      return false;
  }

  return true;
}

bool PluginStream::WriteToPlugin(const char *buf, const int length,
                                 const int data_offset) {
  // For NORMAL and ASFILE modes, we send the data to the plugin now
  if (requested_plugin_mode_ != NP_NORMAL &&
      requested_plugin_mode_ != NP_ASFILE &&
      requested_plugin_mode_ != NP_SEEK)
    return true;

  int written = TryWriteToPlugin(buf, length, data_offset);
  if (written == -1)
      return false;

  if (written < length) {
    // Buffer the remaining data.
    size_t remaining = length - written;
    size_t previous_size = delivery_data_.size();
    delivery_data_.resize(previous_size + remaining);
    data_offset_ = data_offset;
    memcpy(&delivery_data_[previous_size], buf + written, remaining);
    MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
        this, &PluginStream::OnDelayDelivery));
  }

  return true;
}

void PluginStream::OnDelayDelivery() {
  // It is possible that the plugin stream may have closed before the task
  // was hit.
  if (!opened_) {
    return;
  }

  int size = static_cast<int>(delivery_data_.size());
  int written = TryWriteToPlugin(&delivery_data_.front(), size,
                                 data_offset_);
  if (written > 0) {
    // Remove the data that we already wrote.
    delivery_data_.erase(delivery_data_.begin(),
                         delivery_data_.begin() + written);
  }
}

int PluginStream::TryWriteToPlugin(const char *buf, const int length,
                                   const int data_offset) {
  int byte_offset = 0;

  if (data_offset > 0)
    data_offset_ = data_offset;

  while (byte_offset < length) {
    int bytes_remaining = length - byte_offset;
    int bytes_to_write = instance_->NPP_WriteReady(&stream_);
    if (bytes_to_write > bytes_remaining)
      bytes_to_write = bytes_remaining;

    if (bytes_to_write == 0)
      return byte_offset;

    int bytes_consumed = instance_->NPP_Write(
        &stream_, data_offset_, bytes_to_write,
        const_cast<char*>(buf + byte_offset));
    if (bytes_consumed < 0) {
      // The plugin failed, which means that we need to close the stream.
      Close(NPRES_NETWORK_ERR);
      return -1;
    }
    if (bytes_consumed == 0) {
      // The plugin couldn't take all of the data now.
      return byte_offset;
    }

    // The plugin might report more that we gave it.
    bytes_consumed = std::min(bytes_consumed, bytes_to_write);

    data_offset_ += bytes_consumed;
    byte_offset += bytes_consumed;
  }

  if (close_on_write_data_)
    Close(NPRES_DONE);

  return length;
}

bool PluginStream::Close(NPReason reason) {
  if (opened_ == true) {
    opened_ = false;

    if (delivery_data_.size()) {
      if (reason == NPRES_DONE) {
        // There is more data to be streamed, don't destroy the stream now.
        close_on_write_data_ = true;
        return true;
      } else {
        // Stop any pending data from being streamed
        delivery_data_.resize(0);
      }
    }

    // If we have a temp file, be sure to close it.
    // Also, allow the plugin to access it now.
    if (TempFileIsValid()) {
      CloseTempFile();
      if (reason == NPRES_DONE)
        WriteAsFile();
    }

    if (stream_.ndata != NULL) {
      // Stream hasn't been closed yet.
      NPError err = instance_->NPP_DestroyStream(&stream_, reason);
      DCHECK(err == NPERR_NO_ERROR);
    }
  }

  Notify(reason);
  return true;
}

void PluginStream::Notify(NPReason reason) {
  if (notify_needed_) {
    instance_->NPP_URLNotify(stream_.url, reason, notify_data_);
    notify_needed_ = false;
  }
}

}  // namespace NPAPI
<commit_msg>Always send the stream headers to the plugin, not just for seekable ones.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO : Support NP_ASFILEONLY mode
// TODO : Support NP_SEEK mode
// TODO : Support SEEKABLE=true in NewStream

#include "webkit/glue/plugins/plugin_stream.h"

#include "base/string_util.h"
#include "base/message_loop.h"
#include "net/base/mime_util.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "googleurl/src/gurl.h"

namespace NPAPI {

PluginStream::~PluginStream() {
  // always close our temporary files.
  CloseTempFile();
  free(const_cast<char*>(stream_.url));
}

bool PluginStream::Open(const std::string &mime_type,
                        const std::string &headers,
                        uint32 length,
                        uint32 last_modified,
                        bool request_is_seekable) {
  headers_ = headers;
  NPP id = instance_->npp();
  stream_.end = length;
  stream_.lastmodified = last_modified;
  stream_.pdata = 0;
  stream_.ndata = id->ndata;
  stream_.notifyData = notify_data_;
  if (!headers_.empty())
    stream_.headers = headers_.c_str();

  bool seekable_stream = false;
  if (request_is_seekable) {
    std::string headers_lc = StringToLowerASCII(headers);
    if (headers_lc.find("accept-ranges: bytes") != std::string::npos) {
      seekable_stream = true;
    }
  }

  const char *char_mime_type = "application/x-unknown-content-type";
  std::string temp_mime_type;
  if (!mime_type.empty()) {
    char_mime_type = mime_type.c_str();
  } else {
    GURL gurl(stream_.url);

#if defined(OS_WIN)
    FilePath path(UTF8ToWide(gurl.path()));
#elif defined(OS_POSIX)
    FilePath path(gurl.path());
#endif
    if (net::GetMimeTypeFromFile(path, &temp_mime_type))
      char_mime_type = temp_mime_type.c_str();
  }

  // Silverlight expects a valid mime type
  DCHECK(strlen(char_mime_type) != 0);
  NPError err = instance_->NPP_NewStream((NPMIMEType)char_mime_type,
                                         &stream_, seekable_stream,
                                         &requested_plugin_mode_);
  if (err != NPERR_NO_ERROR) {
    Notify(err);
    return false;
  }

  opened_ = true;

  if (requested_plugin_mode_ == NP_SEEK) {
    seekable_stream_ = true;
  }
  // If the plugin has requested certain modes, then we need a copy
  // of this file on disk.  Open it and save it as we go.
  if (requested_plugin_mode_ == NP_ASFILEONLY ||
    requested_plugin_mode_ == NP_ASFILE) {
    if (OpenTempFile() == false)
      return false;
  }

  mime_type_ = char_mime_type;
  return true;
}

int PluginStream::Write(const char *buffer, const int length,
                        int data_offset) {
  // There may be two streams to write to - the plugin and the file.
  // It is unclear what to do if we cannot write to both.  The rules of
  // this function are that the plugin must consume at least as many
  // bytes as returned by the WriteReady call.  So, we will attempt to
  // write that many to both streams.  If we can't write that many bytes
  // to each stream, we'll return failure.

  DCHECK(opened_);
  if (WriteToFile(buffer, length) &&
      WriteToPlugin(buffer, length, data_offset))
    return length;

  return -1;
}

bool PluginStream::WriteToFile(const char *buf, size_t length) {
  // For ASFILEONLY, ASFILE, and SEEK modes, we need to write
  // to the disk
  if (TempFileIsValid() &&
      (requested_plugin_mode_ == NP_ASFILE ||
       requested_plugin_mode_ == NP_ASFILEONLY) ) {
    size_t totalBytesWritten = 0, bytes;
    do {
      bytes = WriteBytes(buf, length);
      totalBytesWritten += bytes;
    } while (bytes > 0U && totalBytesWritten < length);

    if (totalBytesWritten != length)
      return false;
  }

  return true;
}

bool PluginStream::WriteToPlugin(const char *buf, const int length,
                                 const int data_offset) {
  // For NORMAL and ASFILE modes, we send the data to the plugin now
  if (requested_plugin_mode_ != NP_NORMAL &&
      requested_plugin_mode_ != NP_ASFILE &&
      requested_plugin_mode_ != NP_SEEK)
    return true;

  int written = TryWriteToPlugin(buf, length, data_offset);
  if (written == -1)
      return false;

  if (written < length) {
    // Buffer the remaining data.
    size_t remaining = length - written;
    size_t previous_size = delivery_data_.size();
    delivery_data_.resize(previous_size + remaining);
    data_offset_ = data_offset;
    memcpy(&delivery_data_[previous_size], buf + written, remaining);
    MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
        this, &PluginStream::OnDelayDelivery));
  }

  return true;
}

void PluginStream::OnDelayDelivery() {
  // It is possible that the plugin stream may have closed before the task
  // was hit.
  if (!opened_) {
    return;
  }

  int size = static_cast<int>(delivery_data_.size());
  int written = TryWriteToPlugin(&delivery_data_.front(), size,
                                 data_offset_);
  if (written > 0) {
    // Remove the data that we already wrote.
    delivery_data_.erase(delivery_data_.begin(),
                         delivery_data_.begin() + written);
  }
}

int PluginStream::TryWriteToPlugin(const char *buf, const int length,
                                   const int data_offset) {
  int byte_offset = 0;

  if (data_offset > 0)
    data_offset_ = data_offset;

  while (byte_offset < length) {
    int bytes_remaining = length - byte_offset;
    int bytes_to_write = instance_->NPP_WriteReady(&stream_);
    if (bytes_to_write > bytes_remaining)
      bytes_to_write = bytes_remaining;

    if (bytes_to_write == 0)
      return byte_offset;

    int bytes_consumed = instance_->NPP_Write(
        &stream_, data_offset_, bytes_to_write,
        const_cast<char*>(buf + byte_offset));
    if (bytes_consumed < 0) {
      // The plugin failed, which means that we need to close the stream.
      Close(NPRES_NETWORK_ERR);
      return -1;
    }
    if (bytes_consumed == 0) {
      // The plugin couldn't take all of the data now.
      return byte_offset;
    }

    // The plugin might report more that we gave it.
    bytes_consumed = std::min(bytes_consumed, bytes_to_write);

    data_offset_ += bytes_consumed;
    byte_offset += bytes_consumed;
  }

  if (close_on_write_data_)
    Close(NPRES_DONE);

  return length;
}

bool PluginStream::Close(NPReason reason) {
  if (opened_ == true) {
    opened_ = false;

    if (delivery_data_.size()) {
      if (reason == NPRES_DONE) {
        // There is more data to be streamed, don't destroy the stream now.
        close_on_write_data_ = true;
        return true;
      } else {
        // Stop any pending data from being streamed
        delivery_data_.resize(0);
      }
    }

    // If we have a temp file, be sure to close it.
    // Also, allow the plugin to access it now.
    if (TempFileIsValid()) {
      CloseTempFile();
      if (reason == NPRES_DONE)
        WriteAsFile();
    }

    if (stream_.ndata != NULL) {
      // Stream hasn't been closed yet.
      NPError err = instance_->NPP_DestroyStream(&stream_, reason);
      DCHECK(err == NPERR_NO_ERROR);
    }
  }

  Notify(reason);
  return true;
}

void PluginStream::Notify(NPReason reason) {
  if (notify_needed_) {
    instance_->NPP_URLNotify(stream_.url, reason, notify_data_);
    notify_needed_ = false;
  }
}

}  // namespace NPAPI
<|endoftext|>


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

#include "webkit/plugins/ppapi/ppb_pdf_impl.h"

#include "app/resource_bundle.h"
#include "base/metrics/histogram.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "grit/webkit_resources.h"
#include "grit/webkit_strings.h"
#include "skia/ext/platform_canvas.h"
#include "ppapi/c/pp_resource.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/icu/public/i18n/unicode/usearch.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
#include "webkit/plugins/ppapi/ppb_pdf.h"
#include "webkit/plugins/ppapi/var.h"

namespace webkit {
namespace ppapi {

#if defined(OS_LINUX)
class PrivateFontFile : public Resource {
 public:
  PrivateFontFile(PluginModule* module, int fd)
      : Resource(module),
        fd_(fd) {
  }
  virtual ~PrivateFontFile() {
  }

  // Resource overrides.
  PrivateFontFile* AsPrivateFontFile() { return this; }

  bool GetFontTable(uint32_t table,
                    void* output,
                    uint32_t* output_length);

 private:
  int fd_;
};
#endif

namespace {

struct ResourceImageInfo {
  PP_ResourceImage pp_id;
  int res_id;
};

static const ResourceImageInfo kResourceImageMap[] = {
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH, IDR_PDF_BUTTON_FTH },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER, IDR_PDF_BUTTON_FTH_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED, IDR_PDF_BUTTON_FTH_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED,
      IDR_PDF_BUTTON_ZOOMOUT_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND,
      IDR_PDF_THUMBNAIL_NUM_BACKGROUND },
};

PP_Var GetLocalizedString(PP_Module module_id, PP_ResourceString string_id) {
  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return PP_MakeUndefined();

  std::string rv;
  if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_NEED_PASSWORD));
  } else if (string_id == PP_RESOURCESTRING_PDFLOADING) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_PAGE_LOADING));
  } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_PAGE_LOAD_FAILED));
  } else {
    NOTREACHED();
  }

  return StringVar::StringToPPVar(module, rv);
}

PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) {
  int res_id = 0;
  for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) {
    if (kResourceImageMap[i].pp_id == image_id) {
      res_id = kResourceImageMap[i].res_id;
      break;
    }
  }
  if (res_id == 0)
    return 0;

  SkBitmap* res_bitmap =
      ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id);

  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return 0;
  scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl(module));
  if (!image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(),
                        res_bitmap->width(), res_bitmap->height(), false)) {
    return 0;
  }

  ImageDataAutoMapper mapper(image_data);
  if (!mapper.is_valid())
    return 0;

  skia::PlatformCanvas* canvas = image_data->mapped_canvas();
  SkBitmap& ret_bitmap =
      const_cast<SkBitmap&>(canvas->getTopPlatformDevice().accessBitmap(true));
  if (!res_bitmap->copyTo(&ret_bitmap, SkBitmap::kARGB_8888_Config, NULL)) {
    return 0;
  }

  return image_data->GetReference();
}

PP_Resource GetFontFileWithFallback(
    PP_Module module_id,
    const PP_FontDescription_Dev* description,
    PP_PrivateFontCharset charset) {
#if defined(OS_LINUX)
  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return 0;

  scoped_refptr<StringVar> face_name(StringVar::FromPPVar(description->face));
  if (!face_name)
    return 0;

  int fd = webkit_glue::MatchFontWithFallback(
      face_name->value().c_str(),
      description->weight >= PP_FONTWEIGHT_BOLD,
      description->italic,
      charset);
  if (fd == -1)
    return 0;

  scoped_refptr<PrivateFontFile> font(new PrivateFontFile(module, fd));

  return font->GetReference();
#else
  // For trusted PPAPI plugins, this is only needed in Linux since font loading
  // on Windows and Mac works through the renderer sandbox.
  return 0;
#endif
}

bool GetFontTableForPrivateFontFile(PP_Resource font_file,
                                    uint32_t table,
                                    void* output,
                                    uint32_t* output_length) {
#if defined(OS_LINUX)
  scoped_refptr<PrivateFontFile> font(
      Resource::GetAs<PrivateFontFile>(font_file));
  if (!font.get())
    return false;
  return font->GetFontTable(table, output, output_length);
#else
  return false;
#endif
}

void SearchString(PP_Module module,
                  const unsigned short* input_string,
                  const unsigned short* input_term,
                  bool case_sensitive,
                  PP_PrivateFindResult** results,
                  int* count) {
  const char16* string = reinterpret_cast<const char16*>(input_string);
  const char16* term = reinterpret_cast<const char16*>(input_term);

  UErrorCode status = U_ZERO_ERROR;
  UStringSearch* searcher = usearch_open(
      term, -1, string, -1, webkit_glue::GetWebKitLocale().c_str(), 0,
      &status);
  DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
         status == U_USING_DEFAULT_WARNING);
  UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY;

  UCollator* collator = usearch_getCollator(searcher);
  if (ucol_getStrength(collator) != strength) {
    ucol_setStrength(collator, strength);
    usearch_reset(searcher);
  }

  status = U_ZERO_ERROR;
  int match_start = usearch_first(searcher, &status);
  DCHECK(status == U_ZERO_ERROR);

  std::vector<PP_PrivateFindResult> pp_results;
  while (match_start != USEARCH_DONE) {
    size_t matched_length = usearch_getMatchedLength(searcher);
    PP_PrivateFindResult result;
    result.start_index = match_start;
    result.length = matched_length;
    pp_results.push_back(result);
    match_start = usearch_next(searcher, &status);
    DCHECK(status == U_ZERO_ERROR);
  }

  *count = pp_results.size();
  if (*count) {
    *results = reinterpret_cast<PP_PrivateFindResult*>(
        malloc(*count * sizeof(PP_PrivateFindResult)));
    memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult));
  } else {
    *results = NULL;
  }

  usearch_close(searcher);
}

void DidStartLoading(PP_Instance instance_id) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->DidStartLoading();
}

void DidStopLoading(PP_Instance instance_id) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->DidStopLoading();
}

void SetContentRestriction(PP_Instance instance_id, int restrictions) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->SetContentRestriction(restrictions);
}

void HistogramPDFPageCount(int count) {
  UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
}

void UserMetricsRecordAction(PP_Var action) {
  scoped_refptr<StringVar> action_str(StringVar::FromPPVar(action));
  if (action_str)
    webkit_glue::UserMetricsRecordAction(action_str->value());
}

const PPB_PDF ppb_pdf = {
  &GetLocalizedString,
  &GetResourceImage,
  &GetFontFileWithFallback,
  &GetFontTableForPrivateFontFile,
  &SearchString,
  &DidStartLoading,
  &DidStopLoading,
  &SetContentRestriction,
  &HistogramPDFPageCount,
  &UserMetricsRecordAction
};

}  // namespace

// static
const PPB_PDF* PPB_PDF_Impl::GetInterface() {
  return &ppb_pdf;
}

#if defined(OS_LINUX)
bool PrivateFontFile::GetFontTable(uint32_t table,
                                   void* output,
                                   uint32_t* output_length) {
  size_t temp_size = static_cast<size_t>(*output_length);
  bool rv = webkit_glue::GetFontTable(
      fd_, table, static_cast<uint8_t*>(output), &temp_size);
  *output_length = static_cast<uint32_t>(temp_size);
  return rv;
}
#endif

}  // namespace ppapi
}  // namespace webkit

<commit_msg>Modify inclusion to use system icu headers when -Duse_system_icu=1<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/plugins/ppapi/ppb_pdf_impl.h"

#include "app/resource_bundle.h"
#include "base/metrics/histogram.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "grit/webkit_resources.h"
#include "grit/webkit_strings.h"
#include "skia/ext/platform_canvas.h"
#include "ppapi/c/pp_resource.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "unicode/usearch.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
#include "webkit/plugins/ppapi/ppb_pdf.h"
#include "webkit/plugins/ppapi/var.h"

namespace webkit {
namespace ppapi {

#if defined(OS_LINUX)
class PrivateFontFile : public Resource {
 public:
  PrivateFontFile(PluginModule* module, int fd)
      : Resource(module),
        fd_(fd) {
  }
  virtual ~PrivateFontFile() {
  }

  // Resource overrides.
  PrivateFontFile* AsPrivateFontFile() { return this; }

  bool GetFontTable(uint32_t table,
                    void* output,
                    uint32_t* output_length);

 private:
  int fd_;
};
#endif

namespace {

struct ResourceImageInfo {
  PP_ResourceImage pp_id;
  int res_id;
};

static const ResourceImageInfo kResourceImageMap[] = {
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH, IDR_PDF_BUTTON_FTH },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_HOVER, IDR_PDF_BUTTON_FTH_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTH_PRESSED, IDR_PDF_BUTTON_FTH_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW, IDR_PDF_BUTTON_FTW },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER, IDR_PDF_BUTTON_FTW_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED, IDR_PDF_BUTTON_FTW_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN, IDR_PDF_BUTTON_ZOOMIN },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER, IDR_PDF_BUTTON_ZOOMIN_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED, IDR_PDF_BUTTON_ZOOMIN_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT, IDR_PDF_BUTTON_ZOOMOUT },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER, IDR_PDF_BUTTON_ZOOMOUT_HOVER },
  { PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED,
      IDR_PDF_BUTTON_ZOOMOUT_PRESSED },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0, IDR_PDF_THUMBNAIL_0 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1, IDR_PDF_THUMBNAIL_1 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2, IDR_PDF_THUMBNAIL_2 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3, IDR_PDF_THUMBNAIL_3 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4, IDR_PDF_THUMBNAIL_4 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5, IDR_PDF_THUMBNAIL_5 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6, IDR_PDF_THUMBNAIL_6 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7, IDR_PDF_THUMBNAIL_7 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8, IDR_PDF_THUMBNAIL_8 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9, IDR_PDF_THUMBNAIL_9 },
  { PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND,
      IDR_PDF_THUMBNAIL_NUM_BACKGROUND },
};

PP_Var GetLocalizedString(PP_Module module_id, PP_ResourceString string_id) {
  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return PP_MakeUndefined();

  std::string rv;
  if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_NEED_PASSWORD));
  } else if (string_id == PP_RESOURCESTRING_PDFLOADING) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_PAGE_LOADING));
  } else if (string_id == PP_RESOURCESTRING_PDFLOAD_FAILED) {
    rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_PAGE_LOAD_FAILED));
  } else {
    NOTREACHED();
  }

  return StringVar::StringToPPVar(module, rv);
}

PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) {
  int res_id = 0;
  for (size_t i = 0; i < arraysize(kResourceImageMap); ++i) {
    if (kResourceImageMap[i].pp_id == image_id) {
      res_id = kResourceImageMap[i].res_id;
      break;
    }
  }
  if (res_id == 0)
    return 0;

  SkBitmap* res_bitmap =
      ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id);

  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return 0;
  scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl(module));
  if (!image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(),
                        res_bitmap->width(), res_bitmap->height(), false)) {
    return 0;
  }

  ImageDataAutoMapper mapper(image_data);
  if (!mapper.is_valid())
    return 0;

  skia::PlatformCanvas* canvas = image_data->mapped_canvas();
  SkBitmap& ret_bitmap =
      const_cast<SkBitmap&>(canvas->getTopPlatformDevice().accessBitmap(true));
  if (!res_bitmap->copyTo(&ret_bitmap, SkBitmap::kARGB_8888_Config, NULL)) {
    return 0;
  }

  return image_data->GetReference();
}

PP_Resource GetFontFileWithFallback(
    PP_Module module_id,
    const PP_FontDescription_Dev* description,
    PP_PrivateFontCharset charset) {
#if defined(OS_LINUX)
  PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
  if (!module)
    return 0;

  scoped_refptr<StringVar> face_name(StringVar::FromPPVar(description->face));
  if (!face_name)
    return 0;

  int fd = webkit_glue::MatchFontWithFallback(
      face_name->value().c_str(),
      description->weight >= PP_FONTWEIGHT_BOLD,
      description->italic,
      charset);
  if (fd == -1)
    return 0;

  scoped_refptr<PrivateFontFile> font(new PrivateFontFile(module, fd));

  return font->GetReference();
#else
  // For trusted PPAPI plugins, this is only needed in Linux since font loading
  // on Windows and Mac works through the renderer sandbox.
  return 0;
#endif
}

bool GetFontTableForPrivateFontFile(PP_Resource font_file,
                                    uint32_t table,
                                    void* output,
                                    uint32_t* output_length) {
#if defined(OS_LINUX)
  scoped_refptr<PrivateFontFile> font(
      Resource::GetAs<PrivateFontFile>(font_file));
  if (!font.get())
    return false;
  return font->GetFontTable(table, output, output_length);
#else
  return false;
#endif
}

void SearchString(PP_Module module,
                  const unsigned short* input_string,
                  const unsigned short* input_term,
                  bool case_sensitive,
                  PP_PrivateFindResult** results,
                  int* count) {
  const char16* string = reinterpret_cast<const char16*>(input_string);
  const char16* term = reinterpret_cast<const char16*>(input_term);

  UErrorCode status = U_ZERO_ERROR;
  UStringSearch* searcher = usearch_open(
      term, -1, string, -1, webkit_glue::GetWebKitLocale().c_str(), 0,
      &status);
  DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
         status == U_USING_DEFAULT_WARNING);
  UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY;

  UCollator* collator = usearch_getCollator(searcher);
  if (ucol_getStrength(collator) != strength) {
    ucol_setStrength(collator, strength);
    usearch_reset(searcher);
  }

  status = U_ZERO_ERROR;
  int match_start = usearch_first(searcher, &status);
  DCHECK(status == U_ZERO_ERROR);

  std::vector<PP_PrivateFindResult> pp_results;
  while (match_start != USEARCH_DONE) {
    size_t matched_length = usearch_getMatchedLength(searcher);
    PP_PrivateFindResult result;
    result.start_index = match_start;
    result.length = matched_length;
    pp_results.push_back(result);
    match_start = usearch_next(searcher, &status);
    DCHECK(status == U_ZERO_ERROR);
  }

  *count = pp_results.size();
  if (*count) {
    *results = reinterpret_cast<PP_PrivateFindResult*>(
        malloc(*count * sizeof(PP_PrivateFindResult)));
    memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult));
  } else {
    *results = NULL;
  }

  usearch_close(searcher);
}

void DidStartLoading(PP_Instance instance_id) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->DidStartLoading();
}

void DidStopLoading(PP_Instance instance_id) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->DidStopLoading();
}

void SetContentRestriction(PP_Instance instance_id, int restrictions) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return;
  instance->delegate()->SetContentRestriction(restrictions);
}

void HistogramPDFPageCount(int count) {
  UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count);
}

void UserMetricsRecordAction(PP_Var action) {
  scoped_refptr<StringVar> action_str(StringVar::FromPPVar(action));
  if (action_str)
    webkit_glue::UserMetricsRecordAction(action_str->value());
}

const PPB_PDF ppb_pdf = {
  &GetLocalizedString,
  &GetResourceImage,
  &GetFontFileWithFallback,
  &GetFontTableForPrivateFontFile,
  &SearchString,
  &DidStartLoading,
  &DidStopLoading,
  &SetContentRestriction,
  &HistogramPDFPageCount,
  &UserMetricsRecordAction
};

}  // namespace

// static
const PPB_PDF* PPB_PDF_Impl::GetInterface() {
  return &ppb_pdf;
}

#if defined(OS_LINUX)
bool PrivateFontFile::GetFontTable(uint32_t table,
                                   void* output,
                                   uint32_t* output_length) {
  size_t temp_size = static_cast<size_t>(*output_length);
  bool rv = webkit_glue::GetFontTable(
      fd_, table, static_cast<uint8_t*>(output), &temp_size);
  *output_length = static_cast<uint32_t>(temp_size);
  return rv;
}
#endif

}  // namespace ppapi
}  // namespace webkit

<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  ツールス・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <string>
#include "utils/input.hpp"
#include "utils/format.hpp"
#include "utils/preference.hpp"
#include "widgets/widget_chip.hpp"

#include "interlock.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ツールス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct tools {

		static std::string limitf(const std::string& str, float min, float max, const char* form)
		{
			std::string newtext;
			float v;
			if((utils::input("%f", str.c_str()) % v).status()) {
				if(v < min) v = min;
				else if(v > max) v = max;
				char tmp[256];
				utils::format(form, tmp, sizeof(tmp)) % v;
				newtext = tmp;
			}
			return newtext;
		}

		static std::string limiti(const std::string& str, int min, int max, const char* form)
		{
			std::string newtext;
			int v;
			if((utils::input("%d", str.c_str()) % v).status()) {
				if(v < min) v = min;
				else if(v > max) v = max;
				char tmp[256];
				utils::format(form, tmp, sizeof(tmp)) % v;
				newtext = tmp;
			}
			return newtext;
		}

		static void set_help(gui::widget_chip* chip, gui::widget* src, const std::string& text)
		{
			chip->set_offset(src);
			chip->set_text(text);
		}

		static interlock::module get_module(int swn)
		{
			interlock::module md = interlock::module::N;
			switch(swn) {
			case 1:
				md = interlock::module::CRM;
				break;
			case 15:
				md = interlock::module::DC2;
				break;
			case 29:
				md = interlock::module::WDM;
				break;
			case 34:
				md = interlock::module::ICM;
				break;
			case 40:
				md = interlock::module::DC1;
				break;
			case 44:
				md = interlock::module::WGM;
				break;
			default:
				break;
			}
			return md;
		}

		static void init_sw(gui::widget_director& wd, gui::widget* root, interlock& ilc,
			int ofsx, int ofsy, gui::widget_check* out[], int num, int swn)
		{
			auto md = get_module(swn);
			for(int i = 0; i < num; ++i) {
				gui::widget::param wp(vtx::irect(ofsx, ofsy, 60, 40), root);
				gui::widget_check::param wp_((boost::format("%d") % swn).str());
				out[i] = wd.add_widget<gui::widget_check>(wp, wp_);
				ofsx += 60;
				ilc.install(md, static_cast<interlock::swtype>(swn), out[i]);
				++swn;
			}
		}

		static void load_sw(sys::preference& pre, gui::widget_check* sw[], uint32_t n)
		{
			for(uint32_t i = 0; i < n; ++i) {
				sw[i]->load(pre);
			}
		}

		static void save_sw(sys::preference& pre, gui::widget_check* sw[], uint32_t n)
		{
			for(uint32_t i = 0; i < n; ++i) {
				sw[i]->save(pre);
			}
		}

		static std::string double_to_str(double a)
		{
			std::string str;
			if(a >= 0.001) {
				str = (boost::format("%4.3f") % a).str();
			} else {
				str = (boost::format("%e") % a).str();
			}
			return str;
		}
	};
}
<commit_msg>update: chip location<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  ツールス・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <string>
#include "utils/input.hpp"
#include "utils/format.hpp"
#include "utils/preference.hpp"
#include "widgets/widget_chip.hpp"

#include "interlock.hpp"

namespace app {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ツールス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct tools {

		static std::string limitf(const std::string& str, float min, float max, const char* form)
		{
			std::string newtext;
			float v;
			if((utils::input("%f", str.c_str()) % v).status()) {
				if(v < min) v = min;
				else if(v > max) v = max;
				char tmp[256];
				utils::format(form, tmp, sizeof(tmp)) % v;
				newtext = tmp;
			}
			return newtext;
		}

		static std::string limiti(const std::string& str, int min, int max, const char* form)
		{
			std::string newtext;
			int v;
			if((utils::input("%d", str.c_str()) % v).status()) {
				if(v < min) v = min;
				else if(v > max) v = max;
				char tmp[256];
				utils::format(form, tmp, sizeof(tmp)) % v;
				newtext = tmp;
			}
			return newtext;
		}

		static void set_help(gui::widget_chip* chip, gui::widget* src, const std::string& text)
		{
			chip->set_offset(src, gui::widget_chip::offset_type::CENTER_UP);
			chip->set_text(text);
		}

		static interlock::module get_module(int swn)
		{
			interlock::module md = interlock::module::N;
			switch(swn) {
			case 1:
				md = interlock::module::CRM;
				break;
			case 15:
				md = interlock::module::DC2;
				break;
			case 29:
				md = interlock::module::WDM;
				break;
			case 34:
				md = interlock::module::ICM;
				break;
			case 40:
				md = interlock::module::DC1;
				break;
			case 44:
				md = interlock::module::WGM;
				break;
			default:
				break;
			}
			return md;
		}

		static void init_sw(gui::widget_director& wd, gui::widget* root, interlock& ilc,
			int ofsx, int ofsy, gui::widget_check* out[], int num, int swn)
		{
			auto md = get_module(swn);
			for(int i = 0; i < num; ++i) {
				gui::widget::param wp(vtx::irect(ofsx, ofsy, 60, 40), root);
				gui::widget_check::param wp_((boost::format("%d") % swn).str());
				out[i] = wd.add_widget<gui::widget_check>(wp, wp_);
				ofsx += 60;
				ilc.install(md, static_cast<interlock::swtype>(swn), out[i]);
				++swn;
			}
		}

		static void load_sw(sys::preference& pre, gui::widget_check* sw[], uint32_t n)
		{
			for(uint32_t i = 0; i < n; ++i) {
				sw[i]->load(pre);
			}
		}

		static void save_sw(sys::preference& pre, gui::widget_check* sw[], uint32_t n)
		{
			for(uint32_t i = 0; i < n; ++i) {
				sw[i]->save(pre);
			}
		}

		static std::string double_to_str(double a)
		{
			std::string str;
			if(a >= 0.001) {
				str = (boost::format("%4.3f") % a).str();
			} else {
				str = (boost::format("%e") % a).str();
			}
			return str;
		}
	};
}
<|endoftext|>


<commit_before>#include "whitted_integrator.h"
#include "diff_geom.h"
#include "light.h"
#include "brdf.h"

namespace pt {

WhittedIntegrator::WhittedIntegrator(const glm::vec3 &background, Scene scene)
	: background(background), scene(std::move(scene))
{}
IntersectionResult WhittedIntegrator::integrate(ActiveRay &ray) const {
	IntersectionResult result;

	const float dummy_samples[2] = {0};
	DifferentialGeometry dg;
	if (scene.intersect(ray.ray, dg)) {
		result.any_hit = true;
		glm::vec3 lighting(0);
		dg.orthonormalize();
		const glm::vec3 w_o = dg.to_shading(-ray.ray.dir);
		if (!(dg.brdf->bxdf_type() & BRDFType::Specular)) {
			for (const auto &l : scene.lights) {
				const LightSample light_sample = l->incident(dg.point);
				const glm::vec3 w_i = dg.to_shading(light_sample.dir);
				const glm::vec3 color = dg.brdf->eval(w_i, w_o) * light_sample.illum
					* std::max(glm::dot(light_sample.dir, dg.normal), 0.f);
				if (color != glm::vec3(0.f)) {
					result.shadow = std::unique_ptr<ActiveRay>(ActiveRay::shadow(light_sample.occlusion_ray, ray));
					for (size_t i = 0; i < 3; ++ i) {
						result.shadow->color[i] = color[i];
					}
				}
			}
		} else if (ray.ray.depth < 6) {
			// TODO: We actually need to create and ship off an ActiveRay as a secondary ray.
			if (dg.brdf->bxdf_type() & BRDFType::Reflection) {
				const BxDFSample f = dg.brdf->sample(w_o, dummy_samples);
				if (f.pdf != 0.f && f.color != glm::vec3(0.f)) {
					Ray refl_ray(dg.point, dg.from_shading(f.w_i), 0.001);
					refl_ray.depth = ray.ray.depth + 1;
					result.secondary = std::unique_ptr<ActiveRay>(ActiveRay::secondary(refl_ray, ray));
					for (size_t i = 0; i < 3; ++ i) {
						result.secondary->color[i] = f.color[i];
					}
				}
			}
			if (dg.brdf->bxdf_type() & BRDFType::Transmission) {
				// TODO
			}
		}
	}
	return result;
}
bool WhittedIntegrator::occluded(ActiveRay &ray) const {
	DifferentialGeometry dg;
	return scene.intersect(ray.ray, dg);
}

}

<commit_msg>Update the compositing depth value when we find a hit as well<commit_after>#include "whitted_integrator.h"
#include "diff_geom.h"
#include "light.h"
#include "brdf.h"

namespace pt {

WhittedIntegrator::WhittedIntegrator(const glm::vec3 &background, Scene scene)
	: background(background), scene(std::move(scene))
{}
IntersectionResult WhittedIntegrator::integrate(ActiveRay &ray) const {
	IntersectionResult result;

	const float dummy_samples[2] = {0};
	DifferentialGeometry dg;
	if (scene.intersect(ray.ray, dg)) {
		result.any_hit = true;
		ray.color.w = ray.ray.t_max;

		glm::vec3 lighting(0);
		dg.orthonormalize();
		const glm::vec3 w_o = dg.to_shading(-ray.ray.dir);
		if (!(dg.brdf->bxdf_type() & BRDFType::Specular)) {
			for (const auto &l : scene.lights) {
				const LightSample light_sample = l->incident(dg.point);
				const glm::vec3 w_i = dg.to_shading(light_sample.dir);
				const glm::vec3 color = dg.brdf->eval(w_i, w_o) * light_sample.illum
					* std::max(glm::dot(light_sample.dir, dg.normal), 0.f);
				if (color != glm::vec3(0.f)) {
					result.shadow = std::unique_ptr<ActiveRay>(ActiveRay::shadow(light_sample.occlusion_ray, ray));
					for (size_t i = 0; i < 3; ++ i) {
						result.shadow->color[i] = color[i];
					}
				}
			}
		} else if (ray.ray.depth < 6) {
			// TODO: We actually need to create and ship off an ActiveRay as a secondary ray.
			if (dg.brdf->bxdf_type() & BRDFType::Reflection) {
				const BxDFSample f = dg.brdf->sample(w_o, dummy_samples);
				if (f.pdf != 0.f && f.color != glm::vec3(0.f)) {
					Ray refl_ray(dg.point, dg.from_shading(f.w_i), 0.001);
					refl_ray.depth = ray.ray.depth + 1;
					result.secondary = std::unique_ptr<ActiveRay>(ActiveRay::secondary(refl_ray, ray));
					for (size_t i = 0; i < 3; ++ i) {
						result.secondary->color[i] = f.color[i];
					}
				}
			}
			if (dg.brdf->bxdf_type() & BRDFType::Transmission) {
				// TODO
			}
		}
	}
	return result;
}
bool WhittedIntegrator::occluded(ActiveRay &ray) const {
	DifferentialGeometry dg;
	return scene.intersect(ray.ray, dg);
}

}

<|endoftext|>


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

#ifndef _RECOVERYUI_HXX
#define _RECOVERYUI_HXX

//===============================================
// includes

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XSYNCHRONOUSDISPATCH_HPP_
#include <com/sun/star/frame/XSynchronousDispatch.hpp>
#endif

#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATORFACTORY_HPP_
#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif

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

#ifndef _SVX_DOCRECOVERY_HXX
#include "docrecovery.hxx"
#endif

//===============================================
// namespace

namespace svx
{

// Dont export this header ... Otherwise you have to remove this namespace alias!
namespace css   = ::com::sun::star;
namespace svxdr = ::svx::DocRecovery;

//===============================================
// declarations

class RecoveryUI : public ::cppu::WeakImplHelper2< css::lang::XServiceInfo        ,
                                                   css::frame::XSynchronousDispatch > // => XDispatch!
{
    //-------------------------------------------
    // const, types, etcpp.
    private:

        /** @short TODO */
        enum EJob
        {
            E_JOB_UNKNOWN,
            E_DO_EMERGENCY_SAVE,
            E_DO_RECOVERY,
            E_DO_CRASHREPORT
        };

    //-------------------------------------------
    // member
    private:

        /** @short TODO */
        css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;

        /** @short TODO */
        Window* m_pParentWindow;

        /** @short TODO */
        RecoveryUI::EJob m_eJob;

        /** @short TODO */
        css::uno::Reference< css::task::XStatusIndicatorFactory > m_xProgressFactory;

    //-------------------------------------------
    // interface
    public:

        //---------------------------------------
        /** @short  TODO */
        RecoveryUI(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);

        //---------------------------------------
        /** @short  TODO */
        virtual ~RecoveryUI();

        //---------------------------------------
        // css.lang.XServiceInfo

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

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

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

        //---------------------------------------
        virtual com::sun::star::uno::Any SAL_CALL dispatchWithReturnValue(const css::util::URL& aURL,
                                            const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
            throw(css::uno::RuntimeException);

        //---------------------------------------
        // css.frame.XDispatch

        virtual void SAL_CALL dispatch(const css::util::URL&                                  aURL      ,
                                       const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
            throw(css::uno::RuntimeException);

        virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                const css::util::URL&                                     aURL     )
            throw(css::uno::RuntimeException);
        virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                   const css::util::URL&                                     aURL     )
            throw(css::uno::RuntimeException);

        //---------------------------------------
        // XServiceInfo helper

        static ::rtl::OUString st_getImplementationName();
        static css::uno::Sequence< ::rtl::OUString > st_getSupportedServiceNames();
        static css::uno::Reference< css::uno::XInterface > SAL_CALL st_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);

    //-------------------------------------------
    // helper
    private:

        EJob impl_classifyJob(const css::util::URL& aURL);

        sal_Bool impl_doEmergencySave();

        void impl_doRecovery();

        void impl_showAllRecoveredDocs();

        void impl_doCrashReport();

};

} // namespace svx

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

#ifndef _RECOVERYUI_HXX
#define _RECOVERYUI_HXX

//===============================================
// includes

#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/frame/XSynchronousDispatch.hpp>
#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
#include <cppuhelper/implbase2.hxx>
#include <vcl/window.hxx>
#include "docrecovery.hxx"

//===============================================
// namespace

namespace svx
{

// Dont export this header ... Otherwise you have to remove this namespace alias!
namespace css   = ::com::sun::star;
namespace svxdr = ::svx::DocRecovery;

//===============================================
// declarations

class RecoveryUI : public ::cppu::WeakImplHelper2< css::lang::XServiceInfo        ,
                                                   css::frame::XSynchronousDispatch > // => XDispatch!
{
    //-------------------------------------------
    // const, types, etcpp.
    private:

        /** @short TODO */
        enum EJob
        {
            E_JOB_UNKNOWN,
            E_DO_EMERGENCY_SAVE,
            E_DO_RECOVERY,
            E_DO_CRASHREPORT
        };

    //-------------------------------------------
    // member
    private:

        /** @short TODO */
        css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;

        /** @short TODO */
        Window* m_pParentWindow;

        /** @short TODO */
        RecoveryUI::EJob m_eJob;

        /** @short TODO */
        css::uno::Reference< css::task::XStatusIndicatorFactory > m_xProgressFactory;

    //-------------------------------------------
    // interface
    public:

        //---------------------------------------
        /** @short  TODO */
        RecoveryUI(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);

        //---------------------------------------
        /** @short  TODO */
        virtual ~RecoveryUI();

        //---------------------------------------
        // css.lang.XServiceInfo

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

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

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

        //---------------------------------------
        virtual com::sun::star::uno::Any SAL_CALL dispatchWithReturnValue(const css::util::URL& aURL,
                                            const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
            throw(css::uno::RuntimeException);

        //---------------------------------------
        // css.frame.XDispatch

        virtual void SAL_CALL dispatch(const css::util::URL&                                  aURL      ,
                                       const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
            throw(css::uno::RuntimeException);

        virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                const css::util::URL&                                     aURL     )
            throw(css::uno::RuntimeException);
        virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
                                                   const css::util::URL&                                     aURL     )
            throw(css::uno::RuntimeException);

        //---------------------------------------
        // XServiceInfo helper

        static ::rtl::OUString st_getImplementationName();
        static css::uno::Sequence< ::rtl::OUString > st_getSupportedServiceNames();
        static css::uno::Reference< css::uno::XInterface > SAL_CALL st_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);

    //-------------------------------------------
    // helper
    private:

        EJob impl_classifyJob(const css::util::URL& aURL);

        sal_Bool impl_doEmergencySave();

        void impl_doRecovery();

        void impl_showAllRecoveredDocs();

        void impl_doCrashReport();

};

} // namespace svx

#endif // _RECOVERYUI_HXX
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    arrayParamIn(cp, section, base + ".data", data, length);
}
<commit_msg>Improve checkpointing of ethernet packets a bit.<commit_after>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    if (length)
        arrayParamIn(cp, section, base + ".data", data, length);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DEV_SINICREG_HH__
#define __DEV_SINICREG_HH__

#define __SINIC_REG32(NAME, VAL) static const uint32_t NAME = (VAL)
#define __SINIC_REG64(NAME, VAL) static const uint64_t NAME = (VAL)

#define __SINIC_VAL32(NAME, OFFSET, WIDTH) \
        static const uint32_t NAME##_width = WIDTH; \
        static const uint32_t NAME##_offset = OFFSET; \
        static const uint32_t NAME##_mask = (1 << WIDTH) - 1; \
        static const uint32_t NAME = ((1 << WIDTH) - 1) << OFFSET; \
        static inline uint32_t get_##NAME(uint32_t reg) \
        { return (reg & NAME) >> OFFSET; } \
        static inline uint32_t set_##NAME(uint32_t reg, uint32_t val) \
        { return (reg & ~NAME) | ((val << OFFSET) & NAME); }

#define __SINIC_VAL64(NAME, OFFSET, WIDTH) \
        static const uint64_t NAME##_width = WIDTH; \
        static const uint64_t NAME##_offset = OFFSET; \
        static const uint64_t NAME##_mask = (ULL(1) << WIDTH) - 1; \
        static const uint64_t NAME = ((ULL(1) << WIDTH) - 1) << OFFSET;	\
        static inline uint64_t get_##NAME(uint64_t reg) \
        { return (reg & NAME) >> OFFSET; } \
        static inline uint64_t set_##NAME(uint64_t reg, uint64_t val) \
        { return (reg & ~NAME) | ((val << OFFSET) & NAME); }

namespace Sinic {
namespace Regs {

static const int VirtualMask = 0xff;
static const int VirtualShift = 8;

// Registers
__SINIC_REG32(Config,      0x00); // 32: configuration register
__SINIC_REG32(Command,     0x04); // 32: command register
__SINIC_REG32(IntrStatus,  0x08); // 32: interrupt status
__SINIC_REG32(IntrMask,    0x0c); // 32: interrupt mask
__SINIC_REG32(RxMaxCopy,   0x10); // 32: max bytes per rx copy
__SINIC_REG32(TxMaxCopy,   0x14); // 32: max bytes per tx copy
__SINIC_REG32(RxMaxIntr,   0x18); // 32: max receives per interrupt
__SINIC_REG32(Reserved0,   0x1c); // 32: reserved
__SINIC_REG32(RxFifoSize,  0x20); // 32: rx fifo capacity in bytes
__SINIC_REG32(TxFifoSize,  0x24); // 32: tx fifo capacity in bytes
__SINIC_REG32(RxFifoMark,  0x28); // 32: rx fifo high watermark
__SINIC_REG32(TxFifoMark,  0x2c); // 32: tx fifo low watermark
__SINIC_REG32(RxData,      0x30); // 64: receive data
__SINIC_REG32(RxDone,      0x38); // 64: receive done
__SINIC_REG32(RxWait,      0x40); // 64: receive done (busy wait)
__SINIC_REG32(TxData,      0x48); // 64: transmit data
__SINIC_REG32(TxDone,      0x50); // 64: transmit done
__SINIC_REG32(TxWait,      0x58); // 64: transmit done (busy wait)
__SINIC_REG32(HwAddr,      0x60); // 64: mac address
__SINIC_REG32(Size,        0x68); // register addres space size

// Config register bits
__SINIC_VAL32(Config_RSS,      10, 1); // enable receive side scaling
__SINIC_VAL32(Config_RxThread,  9, 1); // enable receive threads
__SINIC_VAL32(Config_TxThread,  8, 1); // enable transmit thread
__SINIC_VAL32(Config_Filter,    7, 1); // enable receive filter
__SINIC_VAL32(Config_Vlan,      6, 1); // enable vlan tagging
__SINIC_VAL32(Config_Virtual,   5, 1); // enable virtual addressing
__SINIC_VAL32(Config_Desc,      4, 1); // enable tx/rx descriptors
__SINIC_VAL32(Config_Poll,      3, 1); // enable polling
__SINIC_VAL32(Config_IntEn,     2, 1); // enable interrupts
__SINIC_VAL32(Config_TxEn,      1, 1); // enable transmit
__SINIC_VAL32(Config_RxEn,      0, 1); // enable receive

// Command register bits
__SINIC_VAL32(Command_Intr,  1, 1); // software interrupt
__SINIC_VAL32(Command_Reset, 0, 1); // reset chip

// Interrupt register bits
__SINIC_VAL32(Intr_Soft,      8, 1); // software interrupt
__SINIC_VAL32(Intr_TxLow,     7, 1); // tx fifo dropped below watermark
__SINIC_VAL32(Intr_TxFull,    6, 1); // tx fifo full
__SINIC_VAL32(Intr_TxDMA,     5, 1); // tx dma completed w/ interrupt
__SINIC_VAL32(Intr_TxPacket,  4, 1); // packet transmitted
__SINIC_VAL32(Intr_RxHigh,    3, 1); // rx fifo above high watermark
__SINIC_VAL32(Intr_RxEmpty,   2, 1); // rx fifo empty
__SINIC_VAL32(Intr_RxDMA,     1, 1); // rx dma completed w/ interrupt
__SINIC_VAL32(Intr_RxPacket,  0, 1); // packet received
__SINIC_REG32(Intr_All,       0x01ff); // all valid interrupts
__SINIC_REG32(Intr_NoDelay,   0x01cc); // interrupts that aren't coalesced
__SINIC_REG32(Intr_Res,      ~0x01ff); // reserved interrupt bits

// RX Data Description
__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M
__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB

// TX Data Description
__SINIC_VAL64(TxData_More,     63,  1); // Packet not complete (will dma more)
__SINIC_VAL64(TxData_Checksum, 62,  1); // do checksum
__SINIC_VAL64(TxData_Len,      40, 20); // 0 - 1M
__SINIC_VAL64(TxData_Addr,      0, 40); // Address 1TB

// RX Done/Busy Information
__SINIC_VAL64(RxDone_Packets,   32, 16); // number of packets in rx fifo
__SINIC_VAL64(RxDone_Busy,      31,  1); // receive dma busy copying
__SINIC_VAL64(RxDone_Complete,  30,  1); // valid data (packet complete)
__SINIC_VAL64(RxDone_More,      29,  1); // Packet has more data (dma again)
__SINIC_VAL64(RxDone_Res0,      28,  1); // reserved
__SINIC_VAL64(RxDone_Res1,      27,  1); // reserved
__SINIC_VAL64(RxDone_Res2,      26,  1); // reserved
__SINIC_VAL64(RxDone_TcpError,  25,  1); // TCP packet error (bad checksum)
__SINIC_VAL64(RxDone_UdpError,  24,  1); // UDP packet error (bad checksum)
__SINIC_VAL64(RxDone_IpError,   23,  1); // IP packet error (bad checksum)
__SINIC_VAL64(RxDone_TcpPacket, 22,  1); // this is a TCP packet
__SINIC_VAL64(RxDone_UdpPacket, 21,  1); // this is a UDP packet
__SINIC_VAL64(RxDone_IpPacket,  20,  1); // this is an IP packet
__SINIC_VAL64(RxDone_CopyLen,    0, 20); // up to 256k

// TX Done/Busy Information
__SINIC_VAL64(TxDone_Packets,   32, 16); // number of packets in tx fifo
__SINIC_VAL64(TxDone_Busy,      31,  1); // transmit dma busy copying
__SINIC_VAL64(TxDone_Complete,  30,  1); // valid data (packet complete)
__SINIC_VAL64(TxDone_Full,      29,  1); // tx fifo is full
__SINIC_VAL64(TxDone_Low,       28,  1); // tx fifo is below the watermark
__SINIC_VAL64(TxDone_Res0,      27,  1); // reserved
__SINIC_VAL64(TxDone_Res1,      26,  1); // reserved
__SINIC_VAL64(TxDone_Res2,      25,  1); // reserved
__SINIC_VAL64(TxDone_Res3,      24,  1); // reserved
__SINIC_VAL64(TxDone_Res4,      23,  1); // reserved
__SINIC_VAL64(TxDone_Res5,      22,  1); // reserved
__SINIC_VAL64(TxDone_Res6,      21,  1); // reserved
__SINIC_VAL64(TxDone_Res7,      20,  1); // reserved
__SINIC_VAL64(TxDone_CopyLen,    0, 20); // up to 256k

struct Info
{
    uint8_t size;
    bool read;
    bool write;
    const char *name;
};

/* namespace Regs */ }

inline const Regs::Info&
regInfo(Addr daddr)
{
    static Regs::Info invalid = { 0, false, false, "invalid" };
    static Regs::Info info [] = {
        { 4, true,  true,  "Config"     },
        { 4, false, true,  "Command"    },
        { 4, true,  true,  "IntrStatus" },
        { 4, true,  true,  "IntrMask"   },
        { 4, true,  false, "RxMaxCopy"  },
        { 4, true,  false, "TxMaxCopy"  },
        { 4, true,  false, "RxMaxIntr"  },
        invalid,
        { 4, true,  false, "RxFifoSize" },
        { 4, true,  false, "TxFifoSize" },
        { 4, true,  false, "RxFifoMark" },
        { 4, true,  false, "TxFifoMark" },
        { 8, true,  true,  "RxData"     },
        invalid,
        { 8, true,  false, "RxDone"     },
        invalid,
        { 8, true,  false, "RxWait"     },
        invalid,
        { 8, true,  true,  "TxData"     },
        invalid,
        { 8, true,  false, "TxDone"     },
        invalid,
        { 8, true,  false, "TxWait"     },
        invalid,
        { 8, true,  false, "HwAddr"     },
        invalid,
    };

    return info[daddr / 4];
}

inline bool
regValid(Addr daddr)
{
    if (daddr > Regs::Size)
        return false;

    if (regInfo(daddr).size == 0)
        return false;

    return true;
}

/* namespace Sinic */ }

#endif // __DEV_SINICREG_HH__
<commit_msg>Bit of formatting for sinicreg.hh<commit_after>/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DEV_SINICREG_HH__
#define __DEV_SINICREG_HH__

#define __SINIC_REG32(NAME, VAL) static const uint32_t NAME = (VAL)
#define __SINIC_REG64(NAME, VAL) static const uint64_t NAME = (VAL)

#define __SINIC_VAL32(NAME, OFFSET, WIDTH) \
        static const uint32_t NAME##_width = WIDTH; \
        static const uint32_t NAME##_offset = OFFSET; \
        static const uint32_t NAME##_mask = (1 << WIDTH) - 1; \
        static const uint32_t NAME = ((1 << WIDTH) - 1) << OFFSET; \
        static inline uint32_t get_##NAME(uint32_t reg) \
        { return (reg & NAME) >> OFFSET; } \
        static inline uint32_t set_##NAME(uint32_t reg, uint32_t val) \
        { return (reg & ~NAME) | ((val << OFFSET) & NAME); }

#define __SINIC_VAL64(NAME, OFFSET, WIDTH) \
        static const uint64_t NAME##_width = WIDTH; \
        static const uint64_t NAME##_offset = OFFSET; \
        static const uint64_t NAME##_mask = (ULL(1) << WIDTH) - 1; \
        static const uint64_t NAME = ((ULL(1) << WIDTH) - 1) << OFFSET;	\
        static inline uint64_t get_##NAME(uint64_t reg) \
        { return (reg & NAME) >> OFFSET; } \
        static inline uint64_t set_##NAME(uint64_t reg, uint64_t val) \
        { return (reg & ~NAME) | ((val << OFFSET) & NAME); }

namespace Sinic {
namespace Regs {

static const int VirtualMask = 0xff;
static const int VirtualShift = 8;

// Registers
__SINIC_REG32(Config,        0x00); // 32: configuration register
__SINIC_REG32(Command,       0x04); // 32: command register
__SINIC_REG32(IntrStatus,    0x08); // 32: interrupt status
__SINIC_REG32(IntrMask,      0x0c); // 32: interrupt mask
__SINIC_REG32(RxMaxCopy,     0x10); // 32: max bytes per rx copy
__SINIC_REG32(TxMaxCopy,     0x14); // 32: max bytes per tx copy
__SINIC_REG32(RxMaxIntr,     0x18); // 32: max receives per interrupt
__SINIC_REG32(Reserved0,     0x1c); // 32: reserved
__SINIC_REG32(RxFifoSize,    0x20); // 32: rx fifo capacity in bytes
__SINIC_REG32(TxFifoSize,    0x24); // 32: tx fifo capacity in bytes
__SINIC_REG32(RxFifoMark,    0x28); // 32: rx fifo high watermark
__SINIC_REG32(TxFifoMark,    0x2c); // 32: tx fifo low watermark
__SINIC_REG32(RxData,        0x30); // 64: receive data
__SINIC_REG32(RxDone,        0x38); // 64: receive done
__SINIC_REG32(RxWait,        0x40); // 64: receive done (busy wait)
__SINIC_REG32(TxData,        0x48); // 64: transmit data
__SINIC_REG32(TxDone,        0x50); // 64: transmit done
__SINIC_REG32(TxWait,        0x58); // 64: transmit done (busy wait)
__SINIC_REG32(HwAddr,        0x60); // 64: mac address
__SINIC_REG32(Size,          0x68); // register addres space size

// Config register bits
__SINIC_VAL32(Config_RSS,      10, 1); // enable receive side scaling
__SINIC_VAL32(Config_RxThread,  9, 1); // enable receive threads
__SINIC_VAL32(Config_TxThread,  8, 1); // enable transmit thread
__SINIC_VAL32(Config_Filter,    7, 1); // enable receive filter
__SINIC_VAL32(Config_Vlan,      6, 1); // enable vlan tagging
__SINIC_VAL32(Config_Virtual,   5, 1); // enable virtual addressing
__SINIC_VAL32(Config_Desc,      4, 1); // enable tx/rx descriptors
__SINIC_VAL32(Config_Poll,      3, 1); // enable polling
__SINIC_VAL32(Config_IntEn,     2, 1); // enable interrupts
__SINIC_VAL32(Config_TxEn,      1, 1); // enable transmit
__SINIC_VAL32(Config_RxEn,      0, 1); // enable receive

// Command register bits
__SINIC_VAL32(Command_Intr,  1, 1); // software interrupt
__SINIC_VAL32(Command_Reset, 0, 1); // reset chip

// Interrupt register bits
__SINIC_VAL32(Intr_Soft,      8, 1); // software interrupt
__SINIC_VAL32(Intr_TxLow,     7, 1); // tx fifo dropped below watermark
__SINIC_VAL32(Intr_TxFull,    6, 1); // tx fifo full
__SINIC_VAL32(Intr_TxDMA,     5, 1); // tx dma completed w/ interrupt
__SINIC_VAL32(Intr_TxPacket,  4, 1); // packet transmitted
__SINIC_VAL32(Intr_RxHigh,    3, 1); // rx fifo above high watermark
__SINIC_VAL32(Intr_RxEmpty,   2, 1); // rx fifo empty
__SINIC_VAL32(Intr_RxDMA,     1, 1); // rx dma completed w/ interrupt
__SINIC_VAL32(Intr_RxPacket,  0, 1); // packet received
__SINIC_REG32(Intr_All,       0x01ff); // all valid interrupts
__SINIC_REG32(Intr_NoDelay,   0x01cc); // interrupts that aren't coalesced
__SINIC_REG32(Intr_Res,      ~0x01ff); // reserved interrupt bits

// RX Data Description
__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M
__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB

// TX Data Description
__SINIC_VAL64(TxData_More,     63,  1); // Packet not complete (will dma more)
__SINIC_VAL64(TxData_Checksum, 62,  1); // do checksum
__SINIC_VAL64(TxData_Len,      40, 20); // 0 - 1M
__SINIC_VAL64(TxData_Addr,      0, 40); // Address 1TB

// RX Done/Busy Information
__SINIC_VAL64(RxDone_Packets,   32, 16); // number of packets in rx fifo
__SINIC_VAL64(RxDone_Busy,      31,  1); // receive dma busy copying
__SINIC_VAL64(RxDone_Complete,  30,  1); // valid data (packet complete)
__SINIC_VAL64(RxDone_More,      29,  1); // Packet has more data (dma again)
__SINIC_VAL64(RxDone_Res0,      28,  1); // reserved
__SINIC_VAL64(RxDone_Res1,      27,  1); // reserved
__SINIC_VAL64(RxDone_Res2,      26,  1); // reserved
__SINIC_VAL64(RxDone_TcpError,  25,  1); // TCP packet error (bad checksum)
__SINIC_VAL64(RxDone_UdpError,  24,  1); // UDP packet error (bad checksum)
__SINIC_VAL64(RxDone_IpError,   23,  1); // IP packet error (bad checksum)
__SINIC_VAL64(RxDone_TcpPacket, 22,  1); // this is a TCP packet
__SINIC_VAL64(RxDone_UdpPacket, 21,  1); // this is a UDP packet
__SINIC_VAL64(RxDone_IpPacket,  20,  1); // this is an IP packet
__SINIC_VAL64(RxDone_CopyLen,    0, 20); // up to 256k

// TX Done/Busy Information
__SINIC_VAL64(TxDone_Packets,   32, 16); // number of packets in tx fifo
__SINIC_VAL64(TxDone_Busy,      31,  1); // transmit dma busy copying
__SINIC_VAL64(TxDone_Complete,  30,  1); // valid data (packet complete)
__SINIC_VAL64(TxDone_Full,      29,  1); // tx fifo is full
__SINIC_VAL64(TxDone_Low,       28,  1); // tx fifo is below the watermark
__SINIC_VAL64(TxDone_Res0,      27,  1); // reserved
__SINIC_VAL64(TxDone_Res1,      26,  1); // reserved
__SINIC_VAL64(TxDone_Res2,      25,  1); // reserved
__SINIC_VAL64(TxDone_Res3,      24,  1); // reserved
__SINIC_VAL64(TxDone_Res4,      23,  1); // reserved
__SINIC_VAL64(TxDone_Res5,      22,  1); // reserved
__SINIC_VAL64(TxDone_Res6,      21,  1); // reserved
__SINIC_VAL64(TxDone_Res7,      20,  1); // reserved
__SINIC_VAL64(TxDone_CopyLen,    0, 20); // up to 256k

struct Info
{
    uint8_t size;
    bool read;
    bool write;
    const char *name;
};

/* namespace Regs */ }

inline const Regs::Info&
regInfo(Addr daddr)
{
    static Regs::Info invalid = { 0, false, false, "invalid" };
    static Regs::Info info [] = {
        { 4, true,  true,  "Config"     },
        { 4, false, true,  "Command"    },
        { 4, true,  true,  "IntrStatus" },
        { 4, true,  true,  "IntrMask"   },
        { 4, true,  false, "RxMaxCopy"  },
        { 4, true,  false, "TxMaxCopy"  },
        { 4, true,  false, "RxMaxIntr"  },
        invalid,
        { 4, true,  false, "RxFifoSize" },
        { 4, true,  false, "TxFifoSize" },
        { 4, true,  false, "RxFifoMark" },
        { 4, true,  false, "TxFifoMark" },
        { 8, true,  true,  "RxData"     },
        invalid,
        { 8, true,  false, "RxDone"     },
        invalid,
        { 8, true,  false, "RxWait"     },
        invalid,
        { 8, true,  true,  "TxData"     },
        invalid,
        { 8, true,  false, "TxDone"     },
        invalid,
        { 8, true,  false, "TxWait"     },
        invalid,
        { 8, true,  false, "HwAddr"     },
        invalid,
    };

    return info[daddr / 4];
}

inline bool
regValid(Addr daddr)
{
    if (daddr > Regs::Size)
        return false;

    if (regInfo(daddr).size == 0)
        return false;

    return true;
}

/* namespace Sinic */ }

#endif // __DEV_SINICREG_HH__
<|endoftext|>