<commit_before>#include "evas_common.h"
#include "evas_engine.h"

int
evas_software_ddraw_init (HWND    window,
                          int     depth,
                          int     fullscreen,
                          Outbuf *buf)
{
   DDSURFACEDESC  surface_desc;
   DDPIXELFORMAT  pixel_format;
   HRESULT        res;
   int            width;
   int            height;

   if (!buf)
     return 0;

   buf->priv.dd.window = window;

   res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
   if (FAILED(res))
     return 0;

   if (buf->priv.dd.fullscreen)
     {
        DDSCAPS caps;

        res = buf->priv.dd.object->SetCooperativeLevel(window,
                                                       DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
        if (FAILED(res))
          goto release_object;

        width = GetSystemMetrics(SM_CXSCREEN);
        height = GetSystemMetrics(SM_CYSCREEN);

        ZeroMemory(&pixel_format, sizeof(pixel_format));
        pixel_format.dwSize = sizeof(pixel_format);
        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);

        if (pixel_format.dwRGBBitCount != depth)
          goto release_object;

        buf->priv.dd.depth = depth;

        res = buf->priv.dd.object->SetDisplayMode(width, height, depth);
        if (FAILED(res))
          goto release_object;

        memset(&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
        surface_desc.dwBackBufferCount = 1;

        res = buf->priv.dd.object->CreateSurface(&surface_desc,
                                                 &buf->priv.dd.surface_primary, NULL);
        if (FAILED(res))
          goto release_object;

        caps.dwCaps = DDSCAPS_BACKBUFFER;
        res = buf->priv.dd.surface_primary->GetAttachedSurface(&caps,
                                                               &buf->priv.dd.surface_back);
        if (FAILED(res))
          goto release_surface_primary;
     }
   else
     {
        RECT           rect;

        if (!GetClientRect(window, &rect))
          goto release_object;

        width = rect.right - rect.left;
        height = rect.bottom - rect.top;

        res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
        if (FAILED(res))
          goto release_object;

        res = buf->priv.dd.object->CreateClipper(0, &buf->priv.dd.clipper, NULL);
        if (FAILED(res))
          goto release_object;

        res = buf->priv.dd.clipper->SetHWnd(0, window);
        if (FAILED(res))
          goto release_clipper;

        memset(&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_primary, NULL);
        if (FAILED(res))
          goto release_clipper;

        res = buf->priv.dd.surface_primary->SetClipper(buf->priv.dd.clipper);
        if (FAILED(res))
          goto release_surface_primary;

        memset (&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
        surface_desc.dwWidth = width;
        surface_desc.dwHeight = height;

        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_back, NULL);
        if (FAILED(res))
          goto release_surface_primary;

        ZeroMemory(&pixel_format, sizeof(pixel_format));
        pixel_format.dwSize = sizeof(pixel_format);
        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);

        if (pixel_format.dwRGBBitCount != depth)
          goto release_surface_back;

        buf->priv.dd.depth = depth;
     }

   return 1;

 release_surface_back:
   buf->priv.dd.surface_back->Release();
 release_surface_primary:
   buf->priv.dd.surface_primary->Release();
 release_clipper:
   if (buf->priv.dd.fullscreen)
     buf->priv.dd.clipper->Release();
 release_object:
   buf->priv.dd.object->Release();

   return 0;
}

void
evas_software_ddraw_shutdown(Outbuf *buf)
{
   if (!buf)
     return;

   if (buf->priv.dd.fullscreen)
     if (buf->priv.dd.surface_back)
       buf->priv.dd.surface_back->Release();
   if (buf->priv.dd.surface_primary)
     buf->priv.dd.surface_primary->Release();
   if (buf->priv.dd.fullscreen)
     if (buf->priv.dd.clipper)
       buf->priv.dd.clipper->Release();
   if (buf->priv.dd.object)
     buf->priv.dd.object->Release();
}

int
evas_software_ddraw_masks_get(Outbuf *buf)
{
   DDPIXELFORMAT pixel_format;

   ZeroMemory(&pixel_format, sizeof(pixel_format));
   pixel_format.dwSize = sizeof(pixel_format);

   if (FAILED(buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format)))
     return 0;

   buf->priv.mask.r = pixel_format.dwRBitMask;
   buf->priv.mask.g = pixel_format.dwGBitMask;
   buf->priv.mask.b = pixel_format.dwBBitMask;

   return 1;
}

void *
evas_software_ddraw_lock(Outbuf *buf,
                         int    *ddraw_width,
                         int    *ddraw_height,
                         int    *ddraw_pitch,
                         int    *ddraw_depth)
{
   DDSURFACEDESC surface_desc;

   ZeroMemory(&surface_desc, sizeof(surface_desc));
   surface_desc.dwSize = sizeof(surface_desc);

   if (FAILED(buf->priv.dd.surface_back->Lock(NULL,
                                              &surface_desc,
                                              DDLOCK_WAIT | DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK,
                                              NULL)))
     return NULL;

   *ddraw_width = surface_desc.dwWidth;
   *ddraw_height = surface_desc.dwHeight;
   *ddraw_pitch = surface_desc.lPitch;
   *ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;

   return surface_desc.lpSurface;
}

void
evas_software_ddraw_unlock_and_flip(Outbuf *buf)
{
   RECT    dst_rect;
   RECT    src_rect;
   POINT   p;

   if (FAILED(buf->priv.dd.surface_back->Unlock(NULL)))
     return;

   /* we figure out where on the primary surface our window lives */
   p.x = 0;
   p.y = 0;
   ClientToScreen(buf->priv.dd.window, &p);
   GetClientRect(buf->priv.dd.window, &dst_rect);
   OffsetRect(&dst_rect, p.x, p.y);
   SetRect(&src_rect, 0, 0, buf->width, buf->height);

   /* nothing to do if the function fails, so we don't check the result */
   buf->priv.dd.surface_primary->Blt(&dst_rect,
                                     buf->priv.dd.surface_back,
                                     &src_rect,
                                     DDBLT_WAIT, NULL);
}

void
evas_software_ddraw_surface_resize(Outbuf *buf)
{
   DDSURFACEDESC surface_desc;

   buf->priv.dd.surface_back->Release();
   memset (&surface_desc, 0, sizeof (surface_desc));
   surface_desc.dwSize = sizeof (surface_desc);
   /* FIXME: that code does not compile. Must know why */
#if 0
   surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
   surface_desc.dwWidth = width;
   surface_desc.dwHeight = height;
   buf->priv.dd.surface_back->SetSurfaceDesc(&surface_desc, NULL);
#else
   surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
   surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
   surface_desc.dwWidth = buf->width;
   surface_desc.dwHeight = buf->height;
   buf->priv.dd.object->CreateSurface(&surface_desc,
                                      &buf->priv.dd.surface_back,
                                      NULL);
#endif
}
<commit_msg>release the clipper only it has been created, that is in windowed mode<commit_after>#include "evas_common.h"
#include "evas_engine.h"

int
evas_software_ddraw_init (HWND    window,
                          int     depth,
                          int     fullscreen,
                          Outbuf *buf)
{
   DDSURFACEDESC  surface_desc;
   DDPIXELFORMAT  pixel_format;
   HRESULT        res;
   int            width;
   int            height;

   if (!buf)
     return 0;

   buf->priv.dd.window = window;

   res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
   if (FAILED(res))
     return 0;

   if (buf->priv.dd.fullscreen)
     {
        DDSCAPS caps;

        res = buf->priv.dd.object->SetCooperativeLevel(window,
                                                       DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
        if (FAILED(res))
          goto release_object;

        width = GetSystemMetrics(SM_CXSCREEN);
        height = GetSystemMetrics(SM_CYSCREEN);

        ZeroMemory(&pixel_format, sizeof(pixel_format));
        pixel_format.dwSize = sizeof(pixel_format);
        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);

        if (pixel_format.dwRGBBitCount != depth)
          goto release_object;

        buf->priv.dd.depth = depth;

        res = buf->priv.dd.object->SetDisplayMode(width, height, depth);
        if (FAILED(res))
          goto release_object;

        memset(&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
        surface_desc.dwBackBufferCount = 1;

        res = buf->priv.dd.object->CreateSurface(&surface_desc,
                                                 &buf->priv.dd.surface_primary, NULL);
        if (FAILED(res))
          goto release_object;

        caps.dwCaps = DDSCAPS_BACKBUFFER;
        res = buf->priv.dd.surface_primary->GetAttachedSurface(&caps,
                                                               &buf->priv.dd.surface_back);
        if (FAILED(res))
          goto release_surface_primary;
     }
   else
     {
        RECT           rect;

        if (!GetClientRect(window, &rect))
          goto release_object;

        width = rect.right - rect.left;
        height = rect.bottom - rect.top;

        res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
        if (FAILED(res))
          goto release_object;

        res = buf->priv.dd.object->CreateClipper(0, &buf->priv.dd.clipper, NULL);
        if (FAILED(res))
          goto release_object;

        res = buf->priv.dd.clipper->SetHWnd(0, window);
        if (FAILED(res))
          goto release_clipper;

        memset(&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_primary, NULL);
        if (FAILED(res))
          goto release_clipper;

        res = buf->priv.dd.surface_primary->SetClipper(buf->priv.dd.clipper);
        if (FAILED(res))
          goto release_surface_primary;

        memset (&surface_desc, 0, sizeof(surface_desc));
        surface_desc.dwSize = sizeof(surface_desc);
        surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
        surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
        surface_desc.dwWidth = width;
        surface_desc.dwHeight = height;

        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_back, NULL);
        if (FAILED(res))
          goto release_surface_primary;

        ZeroMemory(&pixel_format, sizeof(pixel_format));
        pixel_format.dwSize = sizeof(pixel_format);
        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);

        if (pixel_format.dwRGBBitCount != depth)
          goto release_surface_back;

        buf->priv.dd.depth = depth;
     }

   return 1;

 release_surface_back:
   buf->priv.dd.surface_back->Release();
 release_surface_primary:
   buf->priv.dd.surface_primary->Release();
 release_clipper:
   if (!buf->priv.dd.fullscreen)
     buf->priv.dd.clipper->Release();
 release_object:
   buf->priv.dd.object->Release();

   return 0;
}

void
evas_software_ddraw_shutdown(Outbuf *buf)
{
   if (!buf)
     return;

   if (buf->priv.dd.fullscreen)
     if (buf->priv.dd.surface_back)
       buf->priv.dd.surface_back->Release();
   if (buf->priv.dd.surface_primary)
     buf->priv.dd.surface_primary->Release();
   if (!buf->priv.dd.fullscreen)
     if (buf->priv.dd.clipper)
       buf->priv.dd.clipper->Release();
   if (buf->priv.dd.object)
     buf->priv.dd.object->Release();
}

int
evas_software_ddraw_masks_get(Outbuf *buf)
{
   DDPIXELFORMAT pixel_format;

   ZeroMemory(&pixel_format, sizeof(pixel_format));
   pixel_format.dwSize = sizeof(pixel_format);

   if (FAILED(buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format)))
     return 0;

   buf->priv.mask.r = pixel_format.dwRBitMask;
   buf->priv.mask.g = pixel_format.dwGBitMask;
   buf->priv.mask.b = pixel_format.dwBBitMask;

   return 1;
}

void *
evas_software_ddraw_lock(Outbuf *buf,
                         int    *ddraw_width,
                         int    *ddraw_height,
                         int    *ddraw_pitch,
                         int    *ddraw_depth)
{
   DDSURFACEDESC surface_desc;

   ZeroMemory(&surface_desc, sizeof(surface_desc));
   surface_desc.dwSize = sizeof(surface_desc);

   if (FAILED(buf->priv.dd.surface_back->Lock(NULL,
                                              &surface_desc,
                                              DDLOCK_WAIT | DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK,
                                              NULL)))
     return NULL;

   *ddraw_width = surface_desc.dwWidth;
   *ddraw_height = surface_desc.dwHeight;
   *ddraw_pitch = surface_desc.lPitch;
   *ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;

   return surface_desc.lpSurface;
}

void
evas_software_ddraw_unlock_and_flip(Outbuf *buf)
{
   RECT    dst_rect;
   RECT    src_rect;
   POINT   p;

   if (FAILED(buf->priv.dd.surface_back->Unlock(NULL)))
     return;

   /* we figure out where on the primary surface our window lives */
   p.x = 0;
   p.y = 0;
   ClientToScreen(buf->priv.dd.window, &p);
   GetClientRect(buf->priv.dd.window, &dst_rect);
   OffsetRect(&dst_rect, p.x, p.y);
   SetRect(&src_rect, 0, 0, buf->width, buf->height);

   /* nothing to do if the function fails, so we don't check the result */
   buf->priv.dd.surface_primary->Blt(&dst_rect,
                                     buf->priv.dd.surface_back,
                                     &src_rect,
                                     DDBLT_WAIT, NULL);
}

void
evas_software_ddraw_surface_resize(Outbuf *buf)
{
   DDSURFACEDESC surface_desc;

   buf->priv.dd.surface_back->Release();
   memset (&surface_desc, 0, sizeof (surface_desc));
   surface_desc.dwSize = sizeof (surface_desc);
   /* FIXME: that code does not compile. Must know why */
#if 0
   surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
   surface_desc.dwWidth = width;
   surface_desc.dwHeight = height;
   buf->priv.dd.surface_back->SetSurfaceDesc(&surface_desc, NULL);
#else
   surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
   surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
   surface_desc.dwWidth = buf->width;
   surface_desc.dwHeight = buf->height;
   buf->priv.dd.object->CreateSurface(&surface_desc,
                                      &buf->priv.dd.surface_back,
                                      NULL);
#endif
}
<|endoftext|>


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

// Author: guptaa@google.com (Ashish Gupta)

#include "net/instaweb/rewriter/public/static_javascript_manager.h"

#include <utility>
#include "base/logging.h"
#include "net/instaweb/htmlparse/public/doctype.h"
#include "net/instaweb/htmlparse/public/html_element.h"
#include "net/instaweb/htmlparse/public/html_name.h"
#include "net/instaweb/htmlparse/public/html_node.h"
#include "net/instaweb/http/public/meta_data.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/url_namer.h"
#include "net/instaweb/util/public/hasher.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/stl_util.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"

namespace net_instaweb {

extern const char* JS_add_instrumentation;
extern const char* JS_add_instrumentation_opt;
extern const char* JS_client_domain_rewriter;
extern const char* JS_client_domain_rewriter_opt;
extern const char* JS_critical_images_beacon;
extern const char* JS_critical_images_beacon_opt;
extern const char* JS_defer_iframe;
extern const char* JS_defer_iframe_opt;
extern const char* JS_delay_images;
extern const char* JS_delay_images_opt;
extern const char* JS_delay_images_inline;
extern const char* JS_delay_images_inline_opt;
extern const char* JS_js_defer;
extern const char* JS_js_defer_opt;
extern const char* JS_lazyload_images;
extern const char* JS_lazyload_images_opt;
extern const char* JS_deterministic;
extern const char* JS_deterministic_opt;
extern const char* JS_detect_reflow;
extern const char* JS_detect_reflow_opt;
extern const char* JS_local_storage_cache;
extern const char* JS_local_storage_cache_opt;

// The generated files(blink.js, js_defer.js) are named in "<hash>-<fileName>"
// format.
const char StaticJavascriptManager::kGStaticBase[] =
    "http://www.gstatic.com/psa/static/";

const char StaticJavascriptManager::kDefaultLibraryUrlPrefix[] = "/psajs/";
const char StaticJavascriptManager::kJsExtension[] = ".js";

struct StaticJavascriptManager::Asset {
  const char* file_name;
  const char* js_optimized;
  const char* js_debug;
  GoogleString js_opt_hash;
  GoogleString js_debug_hash;
  GoogleString opt_url;
  GoogleString debug_url;
};

StaticJavascriptManager::StaticJavascriptManager(
    UrlNamer* url_namer,
    Hasher* hasher,
    MessageHandler* message_handler)
    : url_namer_(url_namer),
      hasher_(hasher),
      message_handler_(message_handler),
      serve_js_from_gstatic_(false),
      library_url_prefix_(kDefaultLibraryUrlPrefix) {
  InitializeJsStrings();

  ResponseHeaders header;
  // TODO(ksimbili): Define a new constant kShortCacheTtlForMismatchedContentMs
  // in ServerContext for 5min.
  header.SetDateAndCaching(0, ResponseHeaders::kImplicitCacheTtlMs);
  cache_header_with_private_ttl_ = StrCat(
      header.Lookup1(HttpAttributes::kCacheControl),
      ",private");

  header.Clear();
  header.SetDateAndCaching(0, ServerContext::kGeneratedMaxAgeMs);
  cache_header_with_long_ttl_ = header.Lookup1(HttpAttributes::kCacheControl);
}

StaticJavascriptManager::~StaticJavascriptManager() {
  STLDeleteElements(&assets_);
}

const GoogleString& StaticJavascriptManager::GetJsUrl(
    const JsModule& module, const RewriteOptions* options) const {
  return options->Enabled(RewriteOptions::kDebug) ?
      assets_[module]->debug_url :
      assets_[module]->opt_url;
}

void StaticJavascriptManager::set_gstatic_hash(const JsModule& module,
                                               const GoogleString& hash) {
  if (serve_js_from_gstatic_) {
    CHECK(!hash.empty());
    assets_[module]->opt_url =
        StrCat(kGStaticBase, hash, "-", assets_[module]->file_name,
               kJsExtension);
  }
}

void StaticJavascriptManager::InitializeJsStrings() {
  assets_.resize(kEndOfModules);
  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    *it = new Asset;
  }
  // Initialize file names.
  assets_[kAddInstrumentationJs]->file_name = "add_instrumentation";
  assets_[kBlinkJs]->file_name = "blink";
  assets_[kClientDomainRewriter]->file_name = "client_domain_rewriter";
  assets_[kCriticalImagesBeaconJs]->file_name = "critical_images_beacon";
  assets_[kDeferIframe]->file_name = "defer_iframe";
  assets_[kDeferJs]->file_name = "js_defer";
  assets_[kDelayImagesJs]->file_name = "delay_images";
  assets_[kDelayImagesInlineJs]->file_name = "delay_images_inline";
  assets_[kLazyloadImagesJs]->file_name = "lazyload_images";
  assets_[kDetectReflowJs]->file_name = "detect_reflow";
  assets_[kDeterministicJs]->file_name = "deterministic";
  assets_[kLocalStorageCacheJs]->file_name = "local_storage_cache";

  // Initialize compiled javascript strings->
  assets_[kAddInstrumentationJs]->js_optimized = JS_add_instrumentation_opt;
  // Fetching the blink JS is not currently supported->
  assets_[kBlinkJs]->js_optimized = "// Unsupported";
  assets_[kClientDomainRewriter]->js_optimized =
      JS_client_domain_rewriter_opt;
  assets_[kCriticalImagesBeaconJs]->js_optimized =
      JS_critical_images_beacon_opt;
  assets_[kDeferIframe]->js_optimized = JS_defer_iframe_opt;
  assets_[kDeferJs]->js_optimized = JS_js_defer_opt;
  assets_[kDelayImagesJs]->js_optimized = JS_delay_images_opt;
  assets_[kDelayImagesInlineJs]->js_optimized = JS_delay_images_inline_opt;
  assets_[kLazyloadImagesJs]->js_optimized = JS_lazyload_images_opt;
  assets_[kDetectReflowJs]->js_optimized = JS_detect_reflow_opt;
  assets_[kDeterministicJs]->js_optimized = JS_deterministic_opt;
  assets_[kLocalStorageCacheJs]->js_optimized = JS_local_storage_cache_opt;

  // Initialize cleartext javascript strings->
  assets_[kAddInstrumentationJs]->js_debug = JS_add_instrumentation;
  // Fetching the blink JS is not currently supported-> Add a comment in as the
  // unit test expects debug code to include comments->
  assets_[kBlinkJs]->js_debug = "/* Unsupported */";
  assets_[kClientDomainRewriter]->js_debug = JS_client_domain_rewriter;
  assets_[kCriticalImagesBeaconJs]->js_debug = JS_critical_images_beacon;
  assets_[kDeferIframe]->js_debug = JS_defer_iframe;
  assets_[kDeferJs]->js_debug = JS_js_defer;
  assets_[kDelayImagesJs]->js_debug = JS_delay_images;
  assets_[kDelayImagesInlineJs]->js_debug = JS_delay_images_inline;
  assets_[kLazyloadImagesJs]->js_debug = JS_lazyload_images;
  assets_[kDetectReflowJs]->js_debug = JS_detect_reflow;
  assets_[kDeterministicJs]->js_debug = JS_deterministic;
  assets_[kLocalStorageCacheJs]->js_debug = JS_local_storage_cache;

  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    Asset* asset = *it;
    asset->js_opt_hash = hasher_->Hash(asset->js_optimized);
    asset->js_debug_hash = hasher_->Hash(asset->js_debug);

    // Setup a map of file name to the corresponding index in assets_ to
    // allow easier lookup in GetJsSnippet.
    file_name_to_module_map_[asset->file_name] =
        static_cast<JsModule>(it - assets_.begin());
  }
  InitializeJsUrls();
}

void StaticJavascriptManager::InitializeJsUrls() {
  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    Asset* asset = *it;
    // Generated urls are in the format "<filename>.<md5>.js".
    asset->opt_url = StrCat(url_namer_->get_proxy_domain(),
                            library_url_prefix_,
                            asset->file_name,
                            ".", asset->js_opt_hash,
                            kJsExtension);

    // Generated debug urls are in the format "<fileName>_debug.<md5>.js".
    asset->debug_url = StrCat(url_namer_->get_proxy_domain(),
                              library_url_prefix_,
                              asset->file_name,
                              "_debug.", asset->js_debug_hash,
                              kJsExtension);
  }

  // Blink does not currently use the hash in the URL, so it is special cased
  // here.
  GoogleString blink_js_url = StrCat(url_namer_->get_proxy_domain(),
                                     library_url_prefix_,
                                     assets_[kBlinkJs]->file_name,
                                     kJsExtension);
  assets_[kBlinkJs]->debug_url = blink_js_url;
  assets_[kBlinkJs]->opt_url = blink_js_url;
}

const char* StaticJavascriptManager::GetJsSnippet(
    const JsModule& module, const RewriteOptions* options) const {
  CHECK(module != kEndOfModules);
  return options->Enabled(RewriteOptions::kDebug) ?
      assets_[module]->js_debug :
      assets_[module]->js_optimized;
}

void StaticJavascriptManager::AddJsToElement(
    StringPiece js, HtmlElement* script, RewriteDriver* driver) const {
  DCHECK(script->keyword() == HtmlName::kScript);
  // CDATA tags are required for inlined JS in XHTML pages to prevent
  // interpretation of certain characters (like &). In apache, something
  // downstream of mod_pagespeed could modify the content type of the response.
  // So CDATA tags are added conservatively if we are not sure that it is safe
  // to exclude them.
  GoogleString js_str;

  if (!(driver->server_context()->response_headers_finalized() &&
        driver->MimeTypeXhtmlStatus() == RewriteDriver::kIsNotXhtml)) {
    StrAppend(&js_str, "//<![CDATA[\n", js, "\n//]]>");
    js = js_str;
  }

  if (!driver->doctype().IsVersion5()) {
    driver->AddAttribute(script, HtmlName::kType, "text/javascript");
  }
  HtmlCharactersNode* script_content = driver->NewCharactersNode(script, js);
  driver->AppendChild(script, script_content);
}

bool StaticJavascriptManager::GetJsSnippet(StringPiece file_name,
                                           StringPiece* content,
                                           StringPiece* cache_header) const {
  StringPieceVector names;
  SplitStringPieceToVector(file_name, ".", &names, true);
  // Expected file_name format is <name>[_debug].<HASH>.js
  // If file names doesn't contain hash in it, just return, because they may be
  // spurious request.
  if (names.size() != 3) {
    message_handler_->Message(kError, "Invalid url requested: %s.",
                              file_name.as_string().c_str());
    return false;
  }
  GoogleString plain_file_name;
  names[0].CopyToString(&plain_file_name);
  bool is_debug = false;

  if (StringPiece(plain_file_name).ends_with("_debug")) {
    is_debug = true;
    plain_file_name = plain_file_name.substr(0, plain_file_name.length() -
                                             strlen("_debug"));
  }

  FileNameToModuleMap::const_iterator p =
      file_name_to_module_map_.find(plain_file_name);
  if (p != file_name_to_module_map_.end()) {
    CHECK_GT(assets_.size(), p->second);
    Asset* asset = assets_[p->second];
    *content = is_debug ? asset->js_debug : asset->js_optimized;
    if (cache_header) {
      StringPiece hash = is_debug ? asset->js_debug_hash : asset->js_opt_hash;
      if (hash == names[1]) {  // compare hash
        *cache_header = cache_header_with_long_ttl_;
      } else {
        *cache_header = cache_header_with_private_ttl_;
      }
    }
    return true;
  }
  return false;
}

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

// Author: guptaa@google.com (Ashish Gupta)

#include "net/instaweb/rewriter/public/static_javascript_manager.h"

#include <utility>
#include "base/logging.h"
#include "net/instaweb/htmlparse/public/doctype.h"
#include "net/instaweb/htmlparse/public/html_element.h"
#include "net/instaweb/htmlparse/public/html_name.h"
#include "net/instaweb/htmlparse/public/html_node.h"
#include "net/instaweb/http/public/meta_data.h"
#include "net/instaweb/http/public/response_headers.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/url_namer.h"
#include "net/instaweb/util/public/hasher.h"
#include "net/instaweb/util/public/message_handler.h"
#include "net/instaweb/util/public/stl_util.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"

namespace net_instaweb {

extern const char* JS_add_instrumentation;
extern const char* JS_add_instrumentation_opt;
extern const char* JS_client_domain_rewriter;
extern const char* JS_client_domain_rewriter_opt;
extern const char* JS_critical_images_beacon;
extern const char* JS_critical_images_beacon_opt;
extern const char* JS_defer_iframe;
extern const char* JS_defer_iframe_opt;
extern const char* JS_delay_images;
extern const char* JS_delay_images_opt;
extern const char* JS_delay_images_inline;
extern const char* JS_delay_images_inline_opt;
extern const char* JS_js_defer;
extern const char* JS_js_defer_opt;
extern const char* JS_lazyload_images;
extern const char* JS_lazyload_images_opt;
extern const char* JS_deterministic;
extern const char* JS_deterministic_opt;
extern const char* JS_detect_reflow;
extern const char* JS_detect_reflow_opt;
extern const char* JS_local_storage_cache;
extern const char* JS_local_storage_cache_opt;

// The generated files(blink.js, js_defer.js) are named in "<hash>-<fileName>"
// format.
const char StaticJavascriptManager::kGStaticBase[] =
    "http://www.gstatic.com/psa/static/";

const char StaticJavascriptManager::kDefaultLibraryUrlPrefix[] = "/psajs/";
const char StaticJavascriptManager::kJsExtension[] = ".js";

struct StaticJavascriptManager::Asset {
  const char* file_name;
  const char* js_optimized;
  const char* js_debug;
  GoogleString js_opt_hash;
  GoogleString js_debug_hash;
  GoogleString opt_url;
  GoogleString debug_url;
};

StaticJavascriptManager::StaticJavascriptManager(
    UrlNamer* url_namer,
    Hasher* hasher,
    MessageHandler* message_handler)
    : url_namer_(url_namer),
      hasher_(hasher),
      message_handler_(message_handler),
      serve_js_from_gstatic_(false),
      library_url_prefix_(kDefaultLibraryUrlPrefix) {
  InitializeJsStrings();

  ResponseHeaders header;
  // TODO(ksimbili): Define a new constant kShortCacheTtlForMismatchedContentMs
  // in ServerContext for 5min.
  header.SetDateAndCaching(0, ResponseHeaders::kImplicitCacheTtlMs);
  cache_header_with_private_ttl_ = StrCat(
      header.Lookup1(HttpAttributes::kCacheControl),
      ",private");

  header.Clear();
  header.SetDateAndCaching(0, ServerContext::kGeneratedMaxAgeMs);
  cache_header_with_long_ttl_ = header.Lookup1(HttpAttributes::kCacheControl);
}

StaticJavascriptManager::~StaticJavascriptManager() {
  STLDeleteElements(&assets_);
}

const GoogleString& StaticJavascriptManager::GetJsUrl(
    const JsModule& module, const RewriteOptions* options) const {
  return options->Enabled(RewriteOptions::kDebug) ?
      assets_[module]->debug_url :
      assets_[module]->opt_url;
}

void StaticJavascriptManager::set_gstatic_hash(const JsModule& module,
                                               const GoogleString& hash) {
  if (serve_js_from_gstatic_) {
    CHECK(!hash.empty());
    assets_[module]->opt_url =
        StrCat(kGStaticBase, hash, "-", assets_[module]->file_name,
               kJsExtension);
  }
}

void StaticJavascriptManager::InitializeJsStrings() {
  assets_.resize(kEndOfModules);
  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    *it = new Asset;
  }
  // Initialize file names.
  assets_[kAddInstrumentationJs]->file_name = "add_instrumentation";
  assets_[kBlinkJs]->file_name = "blink";
  assets_[kClientDomainRewriter]->file_name = "client_domain_rewriter";
  assets_[kCriticalImagesBeaconJs]->file_name = "critical_images_beacon";
  assets_[kDeferIframe]->file_name = "defer_iframe";
  assets_[kDeferJs]->file_name = "js_defer";
  assets_[kDelayImagesJs]->file_name = "delay_images";
  assets_[kDelayImagesInlineJs]->file_name = "delay_images_inline";
  assets_[kLazyloadImagesJs]->file_name = "lazyload_images";
  assets_[kDetectReflowJs]->file_name = "detect_reflow";
  assets_[kDeterministicJs]->file_name = "deterministic";
  assets_[kLocalStorageCacheJs]->file_name = "local_storage_cache";

  // Initialize compiled javascript strings->
  assets_[kAddInstrumentationJs]->js_optimized = JS_add_instrumentation_opt;
  // Fetching the blink JS is not currently supported->
  assets_[kBlinkJs]->js_optimized = "// Unsupported";
  assets_[kClientDomainRewriter]->js_optimized =
      JS_client_domain_rewriter_opt;
  assets_[kCriticalImagesBeaconJs]->js_optimized =
      JS_critical_images_beacon_opt;
  assets_[kDeferIframe]->js_optimized = JS_defer_iframe_opt;
  assets_[kDeferJs]->js_optimized = JS_js_defer_opt;
  assets_[kDelayImagesJs]->js_optimized = JS_delay_images_opt;
  assets_[kDelayImagesInlineJs]->js_optimized = JS_delay_images_inline_opt;
  assets_[kLazyloadImagesJs]->js_optimized = JS_lazyload_images_opt;
  assets_[kDetectReflowJs]->js_optimized = JS_detect_reflow_opt;
  assets_[kDeterministicJs]->js_optimized = JS_deterministic_opt;
  assets_[kLocalStorageCacheJs]->js_optimized = JS_local_storage_cache_opt;

  // Initialize cleartext javascript strings->
  assets_[kAddInstrumentationJs]->js_debug = JS_add_instrumentation;
  // Fetching the blink JS is not currently supported-> Add a comment in as the
  // unit test expects debug code to include comments->
  assets_[kBlinkJs]->js_debug = "/* Unsupported */";
  assets_[kClientDomainRewriter]->js_debug = JS_client_domain_rewriter;
  assets_[kCriticalImagesBeaconJs]->js_debug = JS_critical_images_beacon;
  assets_[kDeferIframe]->js_debug = JS_defer_iframe;
  assets_[kDeferJs]->js_debug = JS_js_defer;
  assets_[kDelayImagesJs]->js_debug = JS_delay_images;
  assets_[kDelayImagesInlineJs]->js_debug = JS_delay_images_inline;
  assets_[kLazyloadImagesJs]->js_debug = JS_lazyload_images;
  assets_[kDetectReflowJs]->js_debug = JS_detect_reflow;
  assets_[kDeterministicJs]->js_debug = JS_deterministic;
  assets_[kLocalStorageCacheJs]->js_debug = JS_local_storage_cache;

  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    Asset* asset = *it;
    asset->js_opt_hash = hasher_->Hash(asset->js_optimized);
    asset->js_debug_hash = hasher_->Hash(asset->js_debug);

    // Setup a map of file name to the corresponding index in assets_ to
    // allow easier lookup in GetJsSnippet.
    file_name_to_module_map_[asset->file_name] =
        static_cast<JsModule>(it - assets_.begin());
  }
  InitializeJsUrls();
}

void StaticJavascriptManager::InitializeJsUrls() {
  for (std::vector<Asset*>::iterator it = assets_.begin();
       it != assets_.end(); ++it) {
    Asset* asset = *it;
    // Generated urls are in the format "<filename>.<md5>.js".
    asset->opt_url = StrCat(url_namer_->get_proxy_domain(),
                            library_url_prefix_,
                            asset->file_name,
                            ".", asset->js_opt_hash,
                            kJsExtension);

    // Generated debug urls are in the format "<fileName>_debug.<md5>.js".
    asset->debug_url = StrCat(url_namer_->get_proxy_domain(),
                              library_url_prefix_,
                              asset->file_name,
                              "_debug.", asset->js_debug_hash,
                              kJsExtension);
  }

  // Blink does not currently use the hash in the URL, so it is special cased
  // here.
  GoogleString blink_js_url = StrCat(url_namer_->get_proxy_domain(),
                                     library_url_prefix_,
                                     assets_[kBlinkJs]->file_name,
                                     kJsExtension);
  assets_[kBlinkJs]->debug_url = blink_js_url;
  assets_[kBlinkJs]->opt_url = blink_js_url;
}

const char* StaticJavascriptManager::GetJsSnippet(
    const JsModule& module, const RewriteOptions* options) const {
  CHECK(module != kEndOfModules);
  return options->Enabled(RewriteOptions::kDebug) ?
      assets_[module]->js_debug :
      assets_[module]->js_optimized;
}

void StaticJavascriptManager::AddJsToElement(
    StringPiece js, HtmlElement* script, RewriteDriver* driver) const {
  DCHECK(script->keyword() == HtmlName::kScript);
  // CDATA tags are required for inlined JS in XHTML pages to prevent
  // interpretation of certain characters (like &). In apache, something
  // downstream of mod_pagespeed could modify the content type of the response.
  // So CDATA tags are added conservatively if we are not sure that it is safe
  // to exclude them.
  GoogleString js_str;

  if (!(driver->server_context()->response_headers_finalized() &&
        driver->MimeTypeXhtmlStatus() == RewriteDriver::kIsNotXhtml)) {
    StrAppend(&js_str, "//<![CDATA[\n", js, "\n//]]>");
    js = js_str;
  }

  if (!driver->doctype().IsVersion5()) {
    driver->AddAttribute(script, HtmlName::kType, "text/javascript");
  }
  HtmlCharactersNode* script_content = driver->NewCharactersNode(script, js);
  driver->AppendChild(script, script_content);
}

bool StaticJavascriptManager::GetJsSnippet(StringPiece file_name,
                                           StringPiece* content,
                                           StringPiece* cache_header) const {
  StringPieceVector names;
  SplitStringPieceToVector(file_name, ".", &names, true);
  // Expected file_name format is <name>[_debug].<HASH>.js
  // If file names doesn't contain hash in it, just return, because they may be
  // spurious request.
  if (names.size() != 3) {
    message_handler_->Message(kError, "Invalid url requested: %s.",
                              file_name.as_string().c_str());
    return false;
  }
  GoogleString plain_file_name;
  names[0].CopyToString(&plain_file_name);
  bool is_debug = false;

  if (StringPiece(plain_file_name).ends_with("_debug")) {
    is_debug = true;
    plain_file_name = plain_file_name.substr(0, plain_file_name.length() -
                                             strlen("_debug"));
  }

  FileNameToModuleMap::const_iterator p =
      file_name_to_module_map_.find(plain_file_name);
  if (p != file_name_to_module_map_.end()) {
    CHECK_GT(assets_.size(), static_cast<size_t>(p->second));
    Asset* asset = assets_[p->second];
    *content = is_debug ? asset->js_debug : asset->js_optimized;
    if (cache_header) {
      StringPiece hash = is_debug ? asset->js_debug_hash : asset->js_opt_hash;
      if (hash == names[1]) {  // compare hash
        *cache_header = cache_header_with_long_ttl_;
      } else {
        *cache_header = cache_header_with_private_ttl_;
      }
    }
    return true;
  }
  return false;
}

}  // namespace net_instaweb
<|endoftext|>


<commit_before>/*
*  specguiorder.cpp
*  StatusSpec project
*
*  Copyright (c) 2014 thesupremecommander
*  BSD 2-Clause License
*  http://opensource.org/licenses/BSD-2-Clause
*
*/

#include "specguiorder.h"

SpecGUIOrder::SpecGUIOrder() {
	enabled = new ConVar("statusspec_specguiorder_enabled", "0", FCVAR_NONE, "enable ordering of spec GUI");
	reverse_blu = new ConVar("statusspec_specguiorder_reverse_blu", "0", FCVAR_NONE, "reverse order for BLU players");
	reverse_red = new ConVar("statusspec_specguiorder_reverse_red", "0", FCVAR_NONE, "reverse order for RED players");

	specguiSettings = new KeyValues("Resource/UI/SpectatorTournament.res");
	specguiSettings->LoadFromFile(Interfaces::pFileSystem, "resource/ui/spectatortournament.res", "mod");
}

bool SpecGUIOrder::IsEnabled() {
	return enabled->GetBool();
}

void SpecGUIOrder::InterceptMessage(vgui::VPANEL vguiPanel, KeyValues *params, vgui::VPANEL ifromPanel) {
	std::string originPanelName = g_pVGuiPanel->GetName(ifromPanel);

	if (originPanelName.substr(0, 11).compare("playerpanel") == 0 && strcmp(params->GetName(), "DialogVariables") == 0) {
		const char *playerName = params->GetString("playername", NULL);

		if (playerName) {
			for (int i = 0; i <= MAX_PLAYERS; i++) {
				Player player = i;

				if (!player) {
					continue;
				}

				if (strcmp(playerName, player.GetName()) == 0) {
					playerPanels[originPanelName] = player;

					break;
				}
			}
		}
	}
}

bool SpecGUIOrder::SetPosOverride(vgui::VPANEL vguiPanel, int &x, int &y) {
	std::string panelName = g_pVGuiPanel->GetName(vguiPanel);

	if (panelName.substr(0, 11).compare("playerpanel") == 0) {
		Player player = playerPanels[panelName];

		if (!player) {
			return false;
		}

		TFTeam team = player.GetTeam();

		if (team == TFTeam_Red) {
			int position;

			if (!reverse_red->GetBool()) {
				position = std::distance(redPlayers.begin(), std::find(redPlayers.begin(), redPlayers.end(), player));
			}
			else {
				position = std::distance(redPlayers.rbegin(), std::find(redPlayers.rbegin(), redPlayers.rend(), player));
			}

			int baseX = specguiSettings->FindKey("specgui")->GetInt("team2_player_base_offset_x");
			int baseY = specguiSettings->FindKey("specgui")->GetInt("team2_player_base_y");
			int deltaX = specguiSettings->FindKey("specgui")->GetInt("team2_player_delta_x");
			int deltaY = specguiSettings->FindKey("specgui")->GetInt("team2_player_delta_y");

			x = g_pVGuiSchemeManager->GetProportionalScaledValue(baseX + (position * deltaX));
			y = g_pVGuiSchemeManager->GetProportionalScaledValue(baseY + (position * deltaY));

			return true;
		}
		else if (team == TFTeam_Blue) {
			int position;

			if (!reverse_blu->GetBool()) {
				position = std::distance(bluPlayers.begin(), std::find(bluPlayers.begin(), bluPlayers.end(), player));
			}
			else {
				position = std::distance(bluPlayers.rbegin(), std::find(bluPlayers.rbegin(), bluPlayers.rend(), player));
			}

			int baseX = specguiSettings->FindKey("specgui")->GetInt("team1_player_base_offset_x");
			int baseY = specguiSettings->FindKey("specgui")->GetInt("team1_player_base_y");
			int deltaX = specguiSettings->FindKey("specgui")->GetInt("team1_player_delta_x");
			int deltaY = specguiSettings->FindKey("specgui")->GetInt("team1_player_delta_y");

			x = g_pVGuiSchemeManager->GetProportionalScaledValue(baseX + (position * deltaX));
			y = g_pVGuiSchemeManager->GetProportionalScaledValue(baseY + (position * deltaY));

			return true;
		}
	}

	return false;
}

void SpecGUIOrder::PreEntityUpdate() {
	bluPlayers.clear();
	redPlayers.clear();
}

void SpecGUIOrder::ProcessEntity(IClientEntity *entity) {
	Player player = entity;

	if (!player) {
		return;
	}

	TFTeam team = player.GetTeam();

	if (team == TFTeam_Red) {
		redPlayers.push_back(player);
	}
	else if (team == TFTeam_Blue) {
		bluPlayers.push_back(player);
	}
}

void SpecGUIOrder::PostEntityUpdate() {
	bluPlayers.sort();
	redPlayers.sort();
}<commit_msg>Fix an issue with small gaps in between players on the HUD.<commit_after>/*
*  specguiorder.cpp
*  StatusSpec project
*
*  Copyright (c) 2014 thesupremecommander
*  BSD 2-Clause License
*  http://opensource.org/licenses/BSD-2-Clause
*
*/

#include "specguiorder.h"

SpecGUIOrder::SpecGUIOrder() {
	enabled = new ConVar("statusspec_specguiorder_enabled", "0", FCVAR_NONE, "enable ordering of spec GUI");
	reverse_blu = new ConVar("statusspec_specguiorder_reverse_blu", "0", FCVAR_NONE, "reverse order for BLU players");
	reverse_red = new ConVar("statusspec_specguiorder_reverse_red", "0", FCVAR_NONE, "reverse order for RED players");

	specguiSettings = new KeyValues("Resource/UI/SpectatorTournament.res");
	specguiSettings->LoadFromFile(Interfaces::pFileSystem, "resource/ui/spectatortournament.res", "mod");
}

bool SpecGUIOrder::IsEnabled() {
	return enabled->GetBool();
}

void SpecGUIOrder::InterceptMessage(vgui::VPANEL vguiPanel, KeyValues *params, vgui::VPANEL ifromPanel) {
	std::string originPanelName = g_pVGuiPanel->GetName(ifromPanel);

	if (originPanelName.substr(0, 11).compare("playerpanel") == 0 && strcmp(params->GetName(), "DialogVariables") == 0) {
		const char *playerName = params->GetString("playername", NULL);

		if (playerName) {
			for (int i = 0; i <= MAX_PLAYERS; i++) {
				Player player = i;

				if (!player) {
					continue;
				}

				if (strcmp(playerName, player.GetName()) == 0) {
					playerPanels[originPanelName] = player;

					break;
				}
			}
		}
	}
}

bool SpecGUIOrder::SetPosOverride(vgui::VPANEL vguiPanel, int &x, int &y) {
	std::string panelName = g_pVGuiPanel->GetName(vguiPanel);

	if (panelName.substr(0, 11).compare("playerpanel") == 0) {
		Player player = playerPanels[panelName];

		if (!player) {
			return false;
		}

		TFTeam team = player.GetTeam();

		if (team == TFTeam_Red) {
			int position;

			if (!reverse_red->GetBool()) {
				position = std::distance(redPlayers.begin(), std::find(redPlayers.begin(), redPlayers.end(), player));
			}
			else {
				position = std::distance(redPlayers.rbegin(), std::find(redPlayers.rbegin(), redPlayers.rend(), player));
			}

			int baseX = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team2_player_base_offset_x"));
			int baseY = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team2_player_base_y"));
			int deltaX = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team2_player_delta_x"));
			int deltaY = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team2_player_delta_y"));

			x = baseX + (position * deltaX);
			y = baseY + (position * deltaY);

			return true;
		}
		else if (team == TFTeam_Blue) {
			int position;

			if (!reverse_blu->GetBool()) {
				position = std::distance(bluPlayers.begin(), std::find(bluPlayers.begin(), bluPlayers.end(), player));
			}
			else {
				position = std::distance(bluPlayers.rbegin(), std::find(bluPlayers.rbegin(), bluPlayers.rend(), player));
			}

			int baseX = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team1_player_base_offset_x"));
			int baseY = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team1_player_base_y"));
			int deltaX = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team1_player_delta_x"));
			int deltaY = g_pVGuiSchemeManager->GetProportionalScaledValue(specguiSettings->FindKey("specgui")->GetInt("team1_player_delta_y"));

			x = baseX + (position * deltaX);
			y = baseY + (position * deltaY);

			return true;
		}
	}

	return false;
}

void SpecGUIOrder::PreEntityUpdate() {
	bluPlayers.clear();
	redPlayers.clear();
}

void SpecGUIOrder::ProcessEntity(IClientEntity *entity) {
	Player player = entity;

	if (!player) {
		return;
	}

	TFTeam team = player.GetTeam();

	if (team == TFTeam_Red) {
		redPlayers.push_back(player);
	}
	else if (team == TFTeam_Blue) {
		bluPlayers.push_back(player);
	}
}

void SpecGUIOrder::PostEntityUpdate() {
	bluPlayers.sort();
	redPlayers.sort();
}<|endoftext|>


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

#pragma once

#include <cstdint>

#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/write_type.hpp>
#include <mongocxx/model/insert_one.hpp>
#include <mongocxx/model/delete_one.hpp>
#include <mongocxx/model/delete_many.hpp>
#include <mongocxx/model/update_one.hpp>
#include <mongocxx/model/update_many.hpp>
#include <mongocxx/model/replace_one.hpp>

#include <mongocxx/config/prelude.hpp>

namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace model {

///
/// @todo document this class
///
class MONGOCXX_API write {
   public:
    write(insert_one value);
    write(update_one value);
    write(update_many value);
    write(delete_one value);
    write(delete_many value);
    write(replace_one value);

    write(write&& rhs) noexcept;
    write& operator=(write&& rhs) noexcept;

    write(const write& rhs) = delete;
    write& operator=(const write& rhs) = delete;

    ~write();

    write_type type() const;

    const insert_one& get_insert_one() const;
    const update_one& get_update_one() const;
    const update_many& get_update_many() const;
    const delete_one& get_delete_one() const;
    const delete_many& get_delete_many() const;
    const replace_one& get_replace_one() const;

   private:
    MONGOCXX_PRIVATE void destroy_member() noexcept;

    write_type _type;

    union {
        insert_one _insert_one;
        update_one _update_one;
        update_many _update_many;
        delete_one _delete_one;
        delete_many _delete_many;
        replace_one _replace_one;
    };
};

}  // namespace model
MONGOCXX_INLINE_NAMESPACE_END
}  // namespace mongocxx

#include <mongocxx/config/postlude.hpp>
<commit_msg>CXX-847 Document the model/write class<commit_after>// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <cstdint>

#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/write_type.hpp>
#include <mongocxx/model/insert_one.hpp>
#include <mongocxx/model/delete_one.hpp>
#include <mongocxx/model/delete_many.hpp>
#include <mongocxx/model/update_one.hpp>
#include <mongocxx/model/update_many.hpp>
#include <mongocxx/model/replace_one.hpp>

#include <mongocxx/config/prelude.hpp>

namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace model {

///
/// Models a single write operation within a @bulk_write.
///
class MONGOCXX_API write {
   public:

    ///
    /// Constructs a write from an @insert_one.
    ///
    write(insert_one value);

    ///
    /// Constructs a write from an @update_one.
    ///
    write(update_one value);

    ///
    /// Constructs a write from an @update_many.
    ///
    write(update_many value);

    ///
    /// Constructs a write from a @delete_one.
    ///
    write(delete_one value);

    ///
    /// Constructs a write from a @delete_many.
    ///
    write(delete_many value);

    ///
    /// Constructs a write from a @replace_one.
    ///
    write(replace_one value);

    ///
    /// Move constructs a write.
    ///
    write(write&& rhs) noexcept;

    ///
    /// Move assigns a write.
    ///
    write& operator=(write&& rhs) noexcept;

    write(const write& rhs) = delete;
    write& operator=(const write& rhs) = delete;

    ///
    /// Destroys a write.
    ///
    ~write();

    ///
    /// Returns the current type of this write. You must call this
    /// method before calling any of the get methods below.
    ///
    write_type type() const;

    ///
    /// Accesses the write as an @insert_one. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const insert_one& get_insert_one() const;

    ///
    /// Accesses the write as an @update_one. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const update_one& get_update_one() const;

    ///
    /// Accesses the write as an @update_many. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const update_many& get_update_many() const;

    ///
    /// Accesses the write as a @delete_one. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const delete_one& get_delete_one() const;

    ///
    /// Accesses the write as a @delete_many. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const delete_many& get_delete_many() const;

    ///
    /// Accesses the write as a @replace_one. It is illegal to call
    /// this method if the return of @type (above) does not indicate
    /// that this object currently contains the applicable type.
    ///
    const replace_one& get_replace_one() const;

   private:
    MONGOCXX_PRIVATE void destroy_member() noexcept;

    write_type _type;

    union {
        insert_one _insert_one;
        update_one _update_one;
        update_many _update_many;
        delete_one _delete_one;
        delete_many _delete_many;
        replace_one _replace_one;
    };
};

}  // namespace model
MONGOCXX_INLINE_NAMESPACE_END
}  // namespace mongocxx

#include <mongocxx/config/postlude.hpp>
<|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file		g_network_client.cpp
* @version
* @brief
* @author	duye
* @date		2014-09-30
* @note
*
*  1. 2014-09-30 duye Created this file
*
*/
#include <g_network_client.h>

namespace gcom {

NetworkClient::NetworkClient() {}
NetworkClient::NetworkClient(const IPPortPair& server_addr)
  : m_serverAddr(server_addr)
  , m_connectState(CLIENT_INIT) {}

NetworkClient::~NetworkClient() {}

const IPPortPair& NetworkClient::getServerAddr() const
{
    return m_serverAddr;
}

const ClientConnectState& NetworkClient::getConnectState() const
{
    return m_connectState;
}

GResult NetworkClient::addObserver(NetworkClientInterface* observer)
{
    IS_YES_R(findObserver(observer));
    m_observerList.push_back(observer);
	return G_YES;
}

GResult NetworkClient::removeObserver(NetworkClientInterface* observer)
{
    m_observerList.remove(observer);
	return G_YES;
}

GResult NetworkClient::run()
{
    return this->msgLoop();
}

GResult NetworkClient::findObserver(NetworkClientInterface* observer)
{
    ObserverList::const_iterator iter = m_observerList.begin();
    for (; iter != m_observerList.end(); ++iter)
    {
        if (*iter == observer)
        {
            return G_YES;
        }
    }

    return G_NO;
}

}
<commit_msg>Update g_network_client.cpp<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file	    g_network_client.cpp
* @version
* @brief
* @author   duye
* @date	    2014-09-30
* @note
*
*  1. 2014-09-30 duye Created this file
*
*/
#include <g_network_client.h>

namespace gcom {

NetworkClient::NetworkClient() {}
NetworkClient::NetworkClient(const IPPortPair& server_addr)
  : m_serverAddr(server_addr)
  , m_connectState(CLIENT_INIT) {}

NetworkClient::~NetworkClient() {}

const IPPortPair& NetworkClient::getServerAddr() const
{
    return m_serverAddr;
}

const ClientConnectState& NetworkClient::getConnectState() const
{
    return m_connectState;
}

GResult NetworkClient::addObserver(NetworkClientObserver* observer)
{
    IS_YES_RX(findObserver(observer));
    m_observerList.push_back(observer);
    return G_YES;
}

GResult NetworkClient::removeObserver(NetworkClientObserver* observer)
{
    m_observerList.remove(observer);
    return G_YES;
}

void NetworkClient::setState(const ClientState& state)
{
    m_state = state;
}

const ClientState& NetworkClient::state() const
{
    return m_state;
}

GResult NetworkClient::run()
{
    return this->msgLoop();
}

GResult NetworkClient::findObserver(NetworkClientObserver* observer)
{
    ObserverList::const_iterator iter = m_observerList.begin();
    for (; iter != m_observerList.end(); ++iter)
    {
        if (*iter == observer)
        {
            return G_YES;
        }
    }

    return G_NO;
}

}
<|endoftext|>


<commit_before>//---------------------------------------------------------
// Copyright 2018 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_vcf2fasta - write a new genome sequence
// by introducing variants from a set of vcf files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <inttypes.h>
#include <assert.h>
#include <math.h>
#include <sys/time.h>
#include <algorithm>
#include <sstream>
#include <set>
#include <omp.h>
#include <getopt.h>
#include <fast5.hpp>
#include "htslib/faidx.h"
#include "nanopolish_common.h"
#include "nanopolish_variant.h"
#include "nanopolish_eventalign.h"
#include "nanopolish_haplotype.h"

//
// Getopt
//
#define SUBPROGRAM "vcf2fasta"

static const char *VCF2FASTA_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2018 Ontario Institute for Cancer Research\n";

static const char *VCF2FASTA_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " -g draft.fa segment1.vcf segment2.vcf ...\n"
"Write a new genome sequence by introducing variants from the input files\n"
"\n"
"  -v, --verbose                        display verbose output\n"
"      --version                        display version\n"
"      --help                           display this help and exit\n"
"  -g, --genome=FILE                    the input genome is in FILE\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose;
    static std::vector<std::string> input_vcf_files;
    static std::string genome_file;
}

static const char* shortopts = "g:v";

enum { OPT_HELP = 1, OPT_VERSION };

static const struct option longopts[] = {
    { "verbose",     no_argument,       NULL, 'v' },
    { "help",        no_argument,       NULL, OPT_HELP },
    { "version",     no_argument,       NULL, OPT_VERSION },
    { "genome",      required_argument, NULL, 'g' },
    { NULL, 0, NULL, 0 }
};

void parse_vcf2fasta_options(int argc, char** argv)
{
    bool die = false;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case '?': die = true; break;
            case 'v': opt::verbose++; break;
            case 'g': arg >> opt::genome_file; break;
            case OPT_HELP:
                std::cout << VCF2FASTA_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << VCF2FASTA_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
        }
    }

    if(opt::genome_file.empty()) {
        std::cerr << SUBPROGRAM ": -g/--genome file is required\n";
        die = true;
    }

    if (argc - optind < 1) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << VCF2FASTA_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    for(; optind < argc; ++optind) {
        opt::input_vcf_files.push_back(argv[optind]);
    }
}

int vcf2fasta_main(int argc, char** argv)
{
    parse_vcf2fasta_options(argc, argv);

    // Read genome file
    faidx_t *fai = fai_load(opt::genome_file.c_str());

    // Read VCF files and gather variants for each contig and the polishing window coordinates
    std::map<std::string, std::vector<Variant>> variants_by_contig;
    std::map<std::string, std::vector<std::pair<int, int>>> windows_by_contig;

    for(const auto& filename : opt::input_vcf_files) {

        std::string window_str;
        std::vector<Variant> out;
        std::ifstream infile(filename);
        std::string line;
        while(getline(infile, line)) {

            // parse header
            if(line[0] == '#') {

                // check for window coordinates
                if(line.find("nanopolish_window") != std::string::npos) {
                    std::vector<std::string> fields = split(line, '=');
                    assert(fields.size() == 2);
                    window_str = fields[1];
                }
            } else {
                Variant v(line);
                variants_by_contig[v.ref_name].push_back(v);
            }
        }

        if(window_str.empty()) {
            fprintf(stderr, "error: could not detect polishing window from input file %s\n", filename.c_str());
            exit(EXIT_FAILURE);
        }

        std::string window_contig;
        int window_start, window_end;
        parse_region_string(window_str, window_contig, window_start, window_end);
        windows_by_contig[window_contig].push_back(std::make_pair(window_start, window_end));
    }

    size_t n_contigs = faidx_nseq(fai);

    for(size_t contig_idx = 0; contig_idx < n_contigs; ++contig_idx) {
        std::string contig = faidx_iseq(fai, contig_idx);
        int contig_length = faidx_seq_len(fai, contig.c_str());

        // Confirm that all windows on this contig have been polished
        bool window_check_ok = true;
        auto& windows = windows_by_contig[contig];

        std::sort(windows.begin(), windows.end());
        if(windows[0].first != 0) {
            fprintf(stderr, "error: first %d bases are not covered by a polished window for contig %s.\n", windows[0].first, contig.c_str());
            window_check_ok = false;
        }

        for(size_t window_idx = 1; window_idx < windows.size(); ++window_idx) {
            int prev_start = windows[window_idx - 1].first;
            int prev_end = windows[window_idx - 1].second;
            int curr_start = windows[window_idx].first;
            int curr_end = windows[window_idx].second;
            if(curr_start > prev_end) {
                fprintf(stderr, "error: adjacent polishing windows do not overlap (%d-%d and %d-%d)\n", prev_start, prev_end, curr_start, curr_end);
                window_check_ok = false;
            }
        }

        int end_gap = contig_length - windows.back().second;
        if(end_gap > 500) {
            fprintf(stderr, "error: last %d bases are not covered by a polished window for contig %s.\n", end_gap, contig.c_str());
            window_check_ok = false;
        }

        if(!window_check_ok) {
            fprintf(stderr, "error: one or more polishing windows are missing. Please check that all nanopolish variants --consensus jobs ran to completion\n");
            exit(EXIT_FAILURE);
        }

        int length;
        char* seq = fai_fetch(fai, contig.c_str(), &length);
        if(length < 0) {
            fprintf(stderr, "error: could not fetch contig %s\n", contig.c_str());
            exit(EXIT_FAILURE);
        }

        auto& variants = variants_by_contig[contig];
        std::sort(variants.begin(), variants.end(), sortByPosition);

        // remove duplicate variants
        VariantKeyEqualityComp vkec;
        auto last = std::unique(variants.begin(), variants.end(), vkec);
        variants.erase(last, variants.end());

        assert(variants.size() < (1 << 30));
        uint32_t deleted_tag = 1 << 30;
        uint32_t variant_tag = 1 << 31;

        // make a vector holding either a literal character or an index to the variant that needs to be applied
        std::vector<uint32_t> consensus_record(length);
        for(size_t i = 0; i < length; ++i) {
            consensus_record[i] = seq[i];
        }

        size_t num_skipped = 0;
        size_t num_subs = 0;
        size_t num_insertions = 0;
        size_t num_deletions = 0;

        // update the consensus record according to the variants for this contig
        size_t applied_variants = 0;
        for(size_t variant_idx = 0; variant_idx < variants.size(); ++variant_idx) {
            const Variant& v = variants[variant_idx];

            // check if the variant record matches the reference sequence
            bool matches_ref = true;
            for(size_t i = 0; i < v.ref_seq.length(); ++i) {
                matches_ref = matches_ref && v.ref_seq[i] == consensus_record[v.ref_position + i];
            }

            if(!matches_ref) {
                num_skipped += 1;
                continue;
            }

            // mark the first base of the reference sequence as a variant and set the index
            consensus_record[v.ref_position] = variant_tag | variant_idx;

            // mark the subsequent bases of the reference as deleted
            for(size_t i = 1; i < v.ref_seq.length(); ++i) {
                consensus_record[v.ref_position + i] = deleted_tag;
            }

            num_subs += v.ref_seq.length() == v.alt_seq.length();
            num_insertions += v.ref_seq.length() < v.alt_seq.length();
            num_deletions += v.ref_seq.length() > v.alt_seq.length();
        }

        // write out the consensus record
        std::string out;
        out.reserve(length);
        for(size_t i = 0; i < length; ++i) {
            uint32_t r = consensus_record[i];
            if(r & variant_tag) {
                out.append(variants[r & ~variant_tag].alt_seq);
            } else if(r & ~deleted_tag) {
                out.append(1, r);
            } else {
                assert(r & deleted_tag);
            }
        }

        fprintf(stderr, "[vcf2fasta] rewrote contig %s with %zu subs, %zu ins, %zu dels (%zu skipped)\n", contig.c_str(), num_subs, num_insertions, num_deletions, num_skipped);
        fprintf(stdout, ">%s\n%s\n", contig.c_str(), out.c_str());

        free(seq);
        seq = NULL;
    }

    return 0;
}
<commit_msg>add option to skip the sanity checks<commit_after>//---------------------------------------------------------
// Copyright 2018 Ontario Institute for Cancer Research
// Written by Jared Simpson (jared.simpson@oicr.on.ca)
//---------------------------------------------------------
//
// nanopolish_vcf2fasta - write a new genome sequence
// by introducing variants from a set of vcf files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <inttypes.h>
#include <assert.h>
#include <math.h>
#include <sys/time.h>
#include <algorithm>
#include <sstream>
#include <set>
#include <omp.h>
#include <getopt.h>
#include <fast5.hpp>
#include "htslib/faidx.h"
#include "nanopolish_common.h"
#include "nanopolish_variant.h"
#include "nanopolish_eventalign.h"
#include "nanopolish_haplotype.h"

//
// Getopt
//
#define SUBPROGRAM "vcf2fasta"

static const char *VCF2FASTA_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2018 Ontario Institute for Cancer Research\n";

static const char *VCF2FASTA_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " -g draft.fa segment1.vcf segment2.vcf ...\n"
"Write a new genome sequence by introducing variants from the input files\n"
"\n"
"  -v, --verbose                        display verbose output\n"
"      --version                        display version\n"
"      --help                           display this help and exit\n"
"  -g, --genome=FILE                    the input genome is in FILE\n"
"      --skip-checks                    skip the sanity checks\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose;
    static std::vector<std::string> input_vcf_files;
    static std::string genome_file;
    static bool skip_checks = false;
}

static const char* shortopts = "g:v";

enum { OPT_HELP = 1, OPT_VERSION, OPT_SKIP_CHECKS };

static const struct option longopts[] = {
    { "verbose",       no_argument,       NULL, 'v' },
    { "help",          no_argument,       NULL, OPT_HELP },
    { "version",       no_argument,       NULL, OPT_VERSION },
    { "skip-checks",   no_argument,       NULL, OPT_SKIP_CHECKS },
    { "genome",      required_argument, NULL, 'g' },
    { NULL, 0, NULL, 0 }
};

void parse_vcf2fasta_options(int argc, char** argv)
{
    bool die = false;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case '?': die = true; break;
            case 'v': opt::verbose++; break;
            case 'g': arg >> opt::genome_file; break;
            case OPT_SKIP_CHECKS: opt::skip_checks = true; break;
            case OPT_HELP:
                std::cout << VCF2FASTA_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << VCF2FASTA_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
        }
    }

    if(opt::genome_file.empty()) {
        std::cerr << SUBPROGRAM ": -g/--genome file is required\n";
        die = true;
    }

    if (argc - optind < 1) {
        std::cerr << SUBPROGRAM ": not enough arguments\n";
        die = true;
    }

    if (die)
    {
        std::cout << "\n" << VCF2FASTA_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    for(; optind < argc; ++optind) {
        opt::input_vcf_files.push_back(argv[optind]);
    }
}

int vcf2fasta_main(int argc, char** argv)
{
    parse_vcf2fasta_options(argc, argv);

    // Read genome file
    faidx_t *fai = fai_load(opt::genome_file.c_str());

    // Read VCF files and gather variants for each contig and the polishing window coordinates
    std::map<std::string, std::vector<Variant>> variants_by_contig;
    std::map<std::string, std::vector<std::pair<int, int>>> windows_by_contig;

    for(const auto& filename : opt::input_vcf_files) {

        std::string window_str;
        std::vector<Variant> out;
        std::ifstream infile(filename);
        std::string line;
        while(getline(infile, line)) {

            // parse header
            if(line[0] == '#') {

                // check for window coordinates
                if(line.find("nanopolish_window") != std::string::npos) {
                    std::vector<std::string> fields = split(line, '=');
                    assert(fields.size() == 2);
                    window_str = fields[1];
                }
            } else {
                Variant v(line);
                variants_by_contig[v.ref_name].push_back(v);
            }
        }

        if(window_str.empty()) {
            fprintf(stderr, "error: could not detect polishing window from input file %s\n", filename.c_str());
            exit(EXIT_FAILURE);
        }

        std::string window_contig;
        int window_start, window_end;
        parse_region_string(window_str, window_contig, window_start, window_end);
        windows_by_contig[window_contig].push_back(std::make_pair(window_start, window_end));
    }

    size_t n_contigs = faidx_nseq(fai);

    for(size_t contig_idx = 0; contig_idx < n_contigs; ++contig_idx) {
        std::string contig = faidx_iseq(fai, contig_idx);
        int contig_length = faidx_seq_len(fai, contig.c_str());

        // Confirm that all windows on this contig have been polished
        bool window_check_ok = true;
        auto& windows = windows_by_contig[contig];

        std::sort(windows.begin(), windows.end());

        for(size_t window_idx = 1; window_idx < windows.size(); ++window_idx) {
            int prev_start = windows[window_idx - 1].first;
            int prev_end = windows[window_idx - 1].second;
            int curr_start = windows[window_idx].first;
            int curr_end = windows[window_idx].second;
            if(!opt::skip_checks && curr_start > prev_end) {
                fprintf(stderr, "error: adjacent polishing windows do not overlap (%d-%d and %d-%d)\n", prev_start, prev_end, curr_start, curr_end);
                window_check_ok = false;
            }
        }

        // check the first and last windows of the contig were polished
        if(!opt::skip_checks) {
            if(windows[0].first != 0) {
                fprintf(stderr, "error: first %d bases are not covered by a polished window for contig %s.\n", windows[0].first, contig.c_str());
                window_check_ok = false;
            }

            int end_gap = contig_length - windows.back().second;
            if(end_gap > 500) {
                fprintf(stderr, "error: last %d bases are not covered by a polished window for contig %s.\n", end_gap, contig.c_str());
                window_check_ok = false;
            }
        }

        if(!window_check_ok) {
            fprintf(stderr, "error: one or more polishing windows are missing. Please check that all nanopolish variants --consensus jobs ran to completion\n");
            exit(EXIT_FAILURE);
        }

        int length;
        char* seq = fai_fetch(fai, contig.c_str(), &length);
        if(length < 0) {
            fprintf(stderr, "error: could not fetch contig %s\n", contig.c_str());
            exit(EXIT_FAILURE);
        }

        auto& variants = variants_by_contig[contig];
        std::sort(variants.begin(), variants.end(), sortByPosition);

        // remove duplicate variants
        VariantKeyEqualityComp vkec;
        auto last = std::unique(variants.begin(), variants.end(), vkec);
        variants.erase(last, variants.end());

        assert(variants.size() < (1 << 30));
        uint32_t deleted_tag = 1 << 30;
        uint32_t variant_tag = 1 << 31;

        // make a vector holding either a literal character or an index to the variant that needs to be applied
        std::vector<uint32_t> consensus_record(length);
        for(size_t i = 0; i < length; ++i) {
            consensus_record[i] = seq[i];
        }

        size_t num_skipped = 0;
        size_t num_subs = 0;
        size_t num_insertions = 0;
        size_t num_deletions = 0;

        // update the consensus record according to the variants for this contig
        size_t applied_variants = 0;
        for(size_t variant_idx = 0; variant_idx < variants.size(); ++variant_idx) {
            const Variant& v = variants[variant_idx];

            // check if the variant record matches the reference sequence
            bool matches_ref = true;
            for(size_t i = 0; i < v.ref_seq.length(); ++i) {
                matches_ref = matches_ref && v.ref_seq[i] == consensus_record[v.ref_position + i];
            }

            if(!matches_ref) {
                num_skipped += 1;
                continue;
            }

            // mark the first base of the reference sequence as a variant and set the index
            consensus_record[v.ref_position] = variant_tag | variant_idx;

            // mark the subsequent bases of the reference as deleted
            for(size_t i = 1; i < v.ref_seq.length(); ++i) {
                consensus_record[v.ref_position + i] = deleted_tag;
            }

            num_subs += v.ref_seq.length() == v.alt_seq.length();
            num_insertions += v.ref_seq.length() < v.alt_seq.length();
            num_deletions += v.ref_seq.length() > v.alt_seq.length();
        }

        // write out the consensus record
        std::string out;
        out.reserve(length);
        for(size_t i = 0; i < length; ++i) {
            uint32_t r = consensus_record[i];
            if(r & variant_tag) {
                out.append(variants[r & ~variant_tag].alt_seq);
            } else if(r & ~deleted_tag) {
                out.append(1, r);
            } else {
                assert(r & deleted_tag);
            }
        }

        fprintf(stderr, "[vcf2fasta] rewrote contig %s with %zu subs, %zu ins, %zu dels (%zu skipped)\n", contig.c_str(), num_subs, num_insertions, num_deletions, num_skipped);
        fprintf(stdout, ">%s\n%s\n", contig.c_str(), out.c_str());

        free(seq);
        seq = NULL;
    }

    return 0;
}
<|endoftext|>


<commit_before>#ifndef __coldata2_hh__
#define __coldata2_hh__

#include <stdlib.h>
#include "coldata1.hh"

#ifndef NO_BINARY_OPERS

#define oprsw(opr, other, conv) \
  template<class Str> \
  inline other operator opr (mysql_ColData<Str> x, other y) \
    {return (conv)x opr y;} \
  template<class Str> \
  inline other operator opr (other x, mysql_ColData<Str> y) \
    {return x opr (conv)y;}

#define operator_binary(other, conv) \
  oprsw(+, other, conv) \
  oprsw(-, other, conv) \
  oprsw(*, other, conv) \
  oprsw(/, other, conv)

#define operator_binary_int(other, conv) \
  operator_binary(other, conv) \
  oprsw(%, other, conv) \
  oprsw(&, other, conv) \
  oprsw(^, other, conv) \
  oprsw(|, other, conv) \
  oprsw(<<, other, conv) \
  oprsw(>>, other, conv)

operator_binary(float, double)
operator_binary(double, double)

operator_binary_int(char,long int)
operator_binary_int(int, long int)
operator_binary_int(short int, long int)
operator_binary_int(long int, long int)

operator_binary_int(unsigned char, unsigned long int)
operator_binary_int(unsigned int, unsigned long int)
operator_binary_int(unsigned short int, unsigned long int)
operator_binary_int(unsigned long int, unsigned long int)

operator_binary_int(longlong, longlong)
operator_binary_int(ulonglong, ulonglong)

#endif // NO_BINARY_OPERS

#endif
<commit_msg>Wrapped some uses of long long GCC type in ifdef so platforms that don't support it can avoid using it.<commit_after>#ifndef __coldata2_hh__
#define __coldata2_hh__

#include <stdlib.h>
#include "coldata1.hh"

#ifndef NO_BINARY_OPERS

#define oprsw(opr, other, conv) \
  template<class Str> \
  inline other operator opr (mysql_ColData<Str> x, other y) \
    {return (conv)x opr y;} \
  template<class Str> \
  inline other operator opr (other x, mysql_ColData<Str> y) \
    {return x opr (conv)y;}

#define operator_binary(other, conv) \
  oprsw(+, other, conv) \
  oprsw(-, other, conv) \
  oprsw(*, other, conv) \
  oprsw(/, other, conv)

#define operator_binary_int(other, conv) \
  operator_binary(other, conv) \
  oprsw(%, other, conv) \
  oprsw(&, other, conv) \
  oprsw(^, other, conv) \
  oprsw(|, other, conv) \
  oprsw(<<, other, conv) \
  oprsw(>>, other, conv)

operator_binary(float, double)
operator_binary(double, double)

operator_binary_int(char,long int)
operator_binary_int(int, long int)
operator_binary_int(short int, long int)
operator_binary_int(long int, long int)

operator_binary_int(unsigned char, unsigned long int)
operator_binary_int(unsigned int, unsigned long int)
operator_binary_int(unsigned short int, unsigned long int)
operator_binary_int(unsigned long int, unsigned long int)

#if !defined(NO_LONG_LONGS)
operator_binary_int(longlong, longlong)
operator_binary_int(ulonglong, ulonglong)
#endif

#endif // NO_BINARY_OPERS

#endif
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016 Inviwo Foundation
 * 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 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 <modules/base/processors/randommeshgenerator.h>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo RandomMeshGenerator::processorInfo_{
    "org.inviwo.RandomMeshGenerator",  // Class identifier
    "Random Mesh Generator",           // Display name
    "Undefined",                       // Category
    CodeState::Experimental,           // Code state
    Tags::None,                        // Tags
};

const ProcessorInfo RandomMeshGenerator::getProcessorInfo() const { return processorInfo_; }

RandomMeshGenerator::RandomMeshGenerator()
    : Processor()
    , mesh_("mesh")
    , seed_("seed", "Seed", 0, 0, std::mt19937::max())
    , rand_()
    , reseed_("reseed_", "Seed")
    , numberOfBoxes_("numberOf_", "Number of Boxes", 1, 0, 100)
    , numberOfSpheres_("numberOfSpheres_", "Number of Spheres", 1, 0, 100)
    , numberOfCylinders_("numberOfCylinders_", "Number of cylinders", 1, 0, 100)
    , numberOfCones_("numberOfCones_", "Number of Cones", 1, 0, 100)
    , numberOfToruses_("numberOfToruses", "Number of Toruses", 1, 0, 100)

{

    addPort(mesh_);
    addProperty(numberOfBoxes_);
    addProperty(numberOfSpheres_);
    addProperty(numberOfCylinders_);
    addProperty(numberOfCones_);
    addProperty(numberOfToruses_);

    addProperty(seed_);
    addProperty(reseed_);

    reseed_.onChange([&]() {
        seed_.set(rand());
        rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));
    });
}

float RandomMeshGenerator::randD() { return dis_(rand_); }

float RandomMeshGenerator::randD(const float min, const float max) {
    return min + randD() * (max - min);
}

inviwo::vec4 RandomMeshGenerator::randColor() {
    float r = randD(0.5, 1.0);
    float g = randD(0.5, 1.0);
    float b = randD(0.5, 1.0);
    return vec4(r, g, b, 1);
}

vec3 RandomMeshGenerator::randVec3(const float min, const float max) {
    float x = randD(min, max);
    float y = randD(min, max);
    float z = randD(min, max);
    return vec3(x, y, z);
}

void RandomMeshGenerator::process() {
    auto mesh = std::make_shared<BasicMesh>();
    mesh_.setData(mesh);

    rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));

    for (int i = 0; i < numberOfBoxes_.get(); i++) {
        mat4 o = glm::rotate(mat4(1.0f), randD(0, 6.28f), vec3(1, 0, 0));
        o = glm::rotate(o, randD(0, 6.28f), vec3(0, 1, 0));
        o = glm::rotate(o, randD(0, 6.28f), vec3(0, 0, 1));
        o = glm::translate(o, randVec3());
        o = glm::scale(o, randVec3());
        auto mesh2 = BasicMesh::cube(o, randColor());
        mesh->append(mesh2.get());
    }
    for (int i = 0; i < numberOfSpheres_.get(); i++) {
        auto center = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        BasicMesh::sphere(center, radius, color, mesh);
    }
    for (int i = 0; i < numberOfCylinders_.get(); i++) {
        auto start = randVec3();
        auto end = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        auto mesh2 = BasicMesh::cylinder(start, end, color, radius);
        mesh->append(mesh2.get());
    }
    for (int i = 0; i < numberOfCones_.get(); i++) {
        auto start = randVec3();
        auto end = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        auto mesh2 = BasicMesh::cone(start, end, color, radius);
        mesh->append(mesh2.get());
    }

    for (int i = 0; i < numberOfToruses_.get(); i++) {
        auto center = randVec3();
        auto up = glm::normalize(randVec3());
        auto r2 = randD(0.1, 0.5f);
        auto r1 = randD(0.1 + r2, 1.0f + r2);
        auto color = randColor();
        auto mesh2 = BasicMesh::torus(center, up, r1, r2, ivec2(32, 8), color);
        mesh->append(mesh2.get());
    }
}

}  // namespace
<commit_msg>Base: RandomMeshGenerator: Include Fix<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016 Inviwo Foundation
 * 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 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 <modules/base/processors/randommeshgenerator.h>
#include <inviwo/core/datastructures/geometry/basicmesh.h>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo RandomMeshGenerator::processorInfo_{
    "org.inviwo.RandomMeshGenerator",  // Class identifier
    "Random Mesh Generator",           // Display name
    "Undefined",                       // Category
    CodeState::Experimental,           // Code state
    Tags::None,                        // Tags
};

const ProcessorInfo RandomMeshGenerator::getProcessorInfo() const { return processorInfo_; }

RandomMeshGenerator::RandomMeshGenerator()
    : Processor()
    , mesh_("mesh")
    , seed_("seed", "Seed", 0, 0, std::mt19937::max())
    , rand_()
    , reseed_("reseed_", "Seed")
    , numberOfBoxes_("numberOf_", "Number of Boxes", 1, 0, 100)
    , numberOfSpheres_("numberOfSpheres_", "Number of Spheres", 1, 0, 100)
    , numberOfCylinders_("numberOfCylinders_", "Number of cylinders", 1, 0, 100)
    , numberOfCones_("numberOfCones_", "Number of Cones", 1, 0, 100)
    , numberOfToruses_("numberOfToruses", "Number of Toruses", 1, 0, 100)

{

    addPort(mesh_);
    addProperty(numberOfBoxes_);
    addProperty(numberOfSpheres_);
    addProperty(numberOfCylinders_);
    addProperty(numberOfCones_);
    addProperty(numberOfToruses_);

    addProperty(seed_);
    addProperty(reseed_);

    reseed_.onChange([&]() {
        seed_.set(rand());
        rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));
    });
}

float RandomMeshGenerator::randD() { return dis_(rand_); }

float RandomMeshGenerator::randD(const float min, const float max) {
    return min + randD() * (max - min);
}

inviwo::vec4 RandomMeshGenerator::randColor() {
    float r = randD(0.5, 1.0);
    float g = randD(0.5, 1.0);
    float b = randD(0.5, 1.0);
    return vec4(r, g, b, 1);
}

vec3 RandomMeshGenerator::randVec3(const float min, const float max) {
    float x = randD(min, max);
    float y = randD(min, max);
    float z = randD(min, max);
    return vec3(x, y, z);
}

void RandomMeshGenerator::process() {
    auto mesh = std::make_shared<BasicMesh>();
    mesh_.setData(mesh);

    rand_.seed(static_cast<std::mt19937::result_type>(seed_.get()));

    for (int i = 0; i < numberOfBoxes_.get(); i++) {
        mat4 o = glm::rotate(mat4(1.0f), randD(0, 6.28f), vec3(1, 0, 0));
        o = glm::rotate(o, randD(0, 6.28f), vec3(0, 1, 0));
        o = glm::rotate(o, randD(0, 6.28f), vec3(0, 0, 1));
        o = glm::translate(o, randVec3());
        o = glm::scale(o, randVec3());
        auto mesh2 = BasicMesh::cube(o, randColor());
        mesh->append(mesh2.get());
    }
    for (int i = 0; i < numberOfSpheres_.get(); i++) {
        auto center = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        BasicMesh::sphere(center, radius, color, mesh);
    }
    for (int i = 0; i < numberOfCylinders_.get(); i++) {
        auto start = randVec3();
        auto end = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        auto mesh2 = BasicMesh::cylinder(start, end, color, radius);
        mesh->append(mesh2.get());
    }
    for (int i = 0; i < numberOfCones_.get(); i++) {
        auto start = randVec3();
        auto end = randVec3();
        auto color = randColor();
        auto radius = randD(0.1f, 1.0f);
        auto mesh2 = BasicMesh::cone(start, end, color, radius);
        mesh->append(mesh2.get());
    }

    for (int i = 0; i < numberOfToruses_.get(); i++) {
        auto center = randVec3();
        auto up = glm::normalize(randVec3());
        auto r2 = randD(0.1, 0.5f);
        auto r1 = randD(0.1 + r2, 1.0f + r2);
        auto color = randColor();
        auto mesh2 = BasicMesh::torus(center, up, r1, r2, ivec2(32, 8), color);
        mesh->append(mesh2.get());
    }
}

}  // namespace
<|endoftext|>