text:
require 'ffi'

module ThemisCommon
  def string_to_pointer_size(string)
    string_buf = FFI::MemoryPointer.from_string(string)
    [string_buf, string.bytesize]
  end

  def empty?(value)
    return value.nil? || value.empty?
  end

  module_function :string_to_pointer_size
  module_function :empty?
end

module ThemisImport
  extend FFI::Library

  def self.canonical_themis_paths
    host_os = RbConfig::CONFIG['host_os']
    paths = []
    if host_os.start_with? 'linux'
      # Default library installation path for "make install"
      paths.append '/usr/local/lib/libthemis.so.0'
      # Don't bother figuring out the "right" absolute path, since
      # that depends on the distro and non-distro-provided Rubies
      # don't know about the right paths at all. The ones installed
      # via RVM certainly don't. Use soname and let ld figure it out.
      paths.append 'libthemis.so.0'
    end
    if host_os.start_with? 'darwin'
      # Default library installation path for "make install"
      paths.append '/usr/local/lib/libthemis.0.dylib'
      # These are install names of libraries installed via Homebrew
      # Add both M1 and Intel paths so that x86 Ruby works on M1
      paths.append '/opt/homebrew/opt/libthemis/lib/libthemis.0.dylib'
      paths.append '/usr/local/opt/libthemis/lib/libthemis.0.dylib'
      # Last try, look for ABI-qualified name
      paths.append 'libthemis.0.dylib'
    end
    return paths
  end

  def self.load_themis
    for path in canonical_themis_paths
      begin
        return ffi_lib path
      rescue LoadError
        next
      end
    end
    warn <<~EOF
      WARN: failed to load the canonical Themis Core library

      Proceeding to find 'themis' library in standard paths.
      This might cause ABI mismatch and crash the process.
    EOF
    return ffi_lib 'themis'
  end

  load_themis

  callback :get_pub_key_by_id_type,
           [:pointer, :int, :pointer, :int, :pointer], :int
  callback :send_callback_type, [:pointer, :int, :uint], :int
  callback :receive_callback_type, [:pointer, :int, :uint], :int

  class CallbacksStruct < FFI::Struct
    layout :send_data, :send_callback_type,
           :receive_data, :receive_callback_type,
           :state_changed, :pointer,
           :get_pub_key_for_id, :get_pub_key_by_id_type,
           :user_data, :pointer
  end

  attach_function :secure_session_create,
                  [:pointer, :uint, :pointer, :uint, :pointer], :pointer
  attach_function :secure_session_destroy, [:pointer], :int
  attach_function :secure_session_generate_connect_request,
                  [:pointer, :pointer, :pointer], :int

  attach_function :secure_session_wrap,
                  [:pointer, :pointer, :int, :pointer, :pointer], :int
  attach_function :secure_session_unwrap,
                  [:pointer, :pointer, :int, :pointer, :pointer], :int
  attach_function :secure_session_is_established, [:pointer], :bool

  attach_function :themis_secure_message_encrypt,
                  [:pointer, :int, :pointer, :int, :pointer,
                   :int, :pointer, :pointer], :int
  attach_function :themis_secure_message_decrypt,
                  [:pointer, :int, :pointer, :int, :pointer,
                   :int, :pointer, :pointer], :int
  attach_function :themis_secure_message_sign,
                  [:pointer, :int, :pointer, :int, :pointer,
                   :pointer], :int
  attach_function :themis_secure_message_verify,
                  [:pointer, :int, :pointer, :int, :pointer,
                   :pointer], :int

  attach_function :themis_gen_rsa_key_pair,
                  [:pointer, :pointer, :pointer, :pointer], :int
  attach_function :themis_gen_ec_key_pair,
                  [:pointer, :pointer, :pointer, :pointer], :int
  attach_function :themis_gen_sym_key,
                  [:pointer, :pointer], :int

  THEMIS_KEY_INVALID = 0
  THEMIS_KEY_RSA_PRIVATE = 1
  THEMIS_KEY_RSA_PUBLIC = 2
  THEMIS_KEY_EC_PRIVATE = 3
  THEMIS_KEY_EC_PUBLIC = 4

  attach_function :themis_is_valid_asym_key, [:pointer, :int], :int
  attach_function :themis_get_asym_key_kind, [:pointer, :int], :int

  attach_function :themis_secure_cell_encrypt_seal,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :pointer], :int
  attach_function :themis_secure_cell_decrypt_seal,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :pointer], :int

  attach_function :themis_secure_cell_encrypt_seal_with_passphrase,
                   [:pointer, :int, :pointer, :int, :pointer, :int,
                    :pointer, :pointer], :int
  attach_function :themis_secure_cell_decrypt_seal_with_passphrase,
                   [:pointer, :int, :pointer, :int, :pointer, :int,
                    :pointer, :pointer], :int

  attach_function :themis_secure_cell_encrypt_token_protect,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :pointer, :pointer, :pointer], :int
  attach_function :themis_secure_cell_decrypt_token_protect,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :int, :pointer, :pointer], :int

  attach_function :themis_secure_cell_encrypt_context_imprint,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :pointer], :int
  attach_function :themis_secure_cell_decrypt_context_imprint,
                  [:pointer, :int, :pointer, :int, :pointer, :int,
                   :pointer, :pointer], :int

  begin
    attach_function :secure_comparator_create, [], :pointer
    attach_function :secure_comparator_destroy, [:pointer], :int
    attach_function :secure_comparator_append_secret,
                    [:pointer, :pointer, :int], :int
    attach_function :secure_comparator_begin_compare,
                    [:pointer, :pointer, :pointer], :int
    attach_function :secure_comparator_proceed_compare,
                    [:pointer, :pointer, :int, :pointer, :pointer], :int
    attach_function :secure_comparator_get_result, [:pointer], :int
  rescue FFI::NotFoundError
  end
end

module Themis
  extend ThemisCommon
  extend ThemisImport

  extend Gem::Deprecate

  BUFFER_TOO_SMALL = 14
  SUCCESS = 0
  FAIL = 11
  INVALID_ARGUMENT = 12
  SEND_AS_IS = 1

  # Common class of errors caused by Themis functions.
  # You can access the numerical value via "error_code" attribute.
  # Human-readable message is accessible via "message" attribute.
  class ThemisError < StandardError
    attr_reader :error_code

    def initialize(error_code = INVALID_ARGUMENT)
      super
      @error_code = error_code
    end
  end

  class Callbacks
    def get_pub_key_by_id(id)
      raise ThemisError, 'Callback is not implemented: get_pub_key_by_id'
    end

    def send(message)
      raise ThemisError, 'Callback is not implemented: send'
    end

    def receive
      raise ThemisError, 'Callback is not implemented: receive'
    end
  end

  class SKeyPairGen
    include ThemisCommon
    include ThemisImport

    def ec
      private_key_length = FFI::MemoryPointer.new(:uint)
      public_key_length = FFI::MemoryPointer.new(:uint)

      res = themis_gen_ec_key_pair(
        nil, private_key_length, nil, public_key_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError, "Themis failed generating EC KeyPair: #{res}"
      end

      private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
      public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)

      res = themis_gen_ec_key_pair(
        private_key, private_key_length, public_key, public_key_length)
      if res != SUCCESS
        raise ThemisError, "Themis failed generating EC KeyPair: #{res}"
      end

      [private_key.get_bytes(0, private_key_length.read_uint),
       public_key.get_bytes(0, public_key_length.read_uint)]
    end

    def rsa
      private_key_length = FFI::MemoryPointer.new(:uint)
      public_key_length = FFI::MemoryPointer.new(:uint)

      res = themis_gen_rsa_key_pair(
        nil, private_key_length, nil, public_key_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError, "Themis failed generating RSA KeyPair: #{res}"
      end

      private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
      public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)

      res = themis_gen_rsa_key_pair(
        private_key, private_key_length, public_key, public_key_length)
      if res != SUCCESS
        raise ThemisError, "Themis failed generating RSA KeyPair: #{res}"
      end

      [private_key.get_bytes(0, private_key_length.read_uint),
       public_key.get_bytes(0, public_key_length.read_uint)]
    end
  end

  def Themis.valid_key(key)
    if key.nil? || key.empty?
      return false
    end
    key_, len_ = string_to_pointer_size(key)
    return themis_is_valid_asym_key(key_, len_) == SUCCESS
  end

  def Themis.private_key(key)
    key_, len_ = string_to_pointer_size(key)
    kind = themis_get_asym_key_kind(key_, len_)
    return kind == ThemisImport::THEMIS_KEY_RSA_PRIVATE \
        || kind == ThemisImport::THEMIS_KEY_EC_PRIVATE
  end

  def Themis.public_key(key)
    key_, len_ = string_to_pointer_size(key)
    kind = themis_get_asym_key_kind(key_, len_)
    return kind == ThemisImport::THEMIS_KEY_RSA_PUBLIC \
        || kind == ThemisImport::THEMIS_KEY_EC_PUBLIC
  end

  class Ssession
    include ThemisCommon
    include ThemisImport

    extend Gem::Deprecate

    MAPPING = {}

    GetPubKeyByIDCallback =
      FFI::Function.new(:int, [:pointer, :int, :pointer, :int, :pointer]) do |id_buf, id_length, pubkey_buf, pubkey_length, obj|
        pub_key = MAPPING[obj.read_uint64].get_pub_key_by_id(
          id_buf.get_bytes(0, id_length))
        return -1 unless pub_key
        pubkey_buf.put_bytes(0, pub_key)
        0
      end

    def initialize(id, private_key, transport)
      id_buf, id_length = string_to_pointer_size(id)
      private_key_buf, private_key_length = string_to_pointer_size(private_key)

      @callbacks = CallbacksStruct.new
      @callbacks[:get_pub_key_for_id] = GetPubKeyByIDCallback

      MAPPING[transport.object_id] = transport
      @transport_obj_id = transport.object_id

      @callbacks[:user_data] = FFI::MemoryPointer.new(:uint64)
      @callbacks[:user_data].write_uint64(@transport_obj_id)

      @session = secure_session_create(
        id_buf, id_length, private_key_buf, private_key_length, @callbacks)

      raise ThemisError, 'Secure Session failed creating' if @session.null?
    end

    def is_established
      established?
    end
    deprecate(:is_established, :established?, 2018, 6)

    def established?
      secure_session_is_established @session
    end

    def connect_request
      connect_request_length = FFI::MemoryPointer.new(:uint)
      res = secure_session_generate_connect_request(
        @session, nil, connect_request_length)
      if res != BUFFER_TOO_SMALL
        raise(ThemisError,
              "Secure Session failed making connection request: #{res}")
      end
      connect_request = FFI::MemoryPointer.new(
        :char, connect_request_length.read_uint)
      res = secure_session_generate_connect_request(
        @session, connect_request, connect_request_length)
      if res != SUCCESS
        raise(ThemisError,
              "Secure Session failed making connection request: #{res}")
      end
      connect_request.get_bytes(0, connect_request_length.read_uint)
    end

    def unwrap(message)
      message_, message_length_ = string_to_pointer_size message
      unwrapped_message_length = FFI::MemoryPointer.new(:uint)

      res = secure_session_unwrap(
        @session, message_, message_length_, nil, unwrapped_message_length)
      return SUCCESS, '' if res == SUCCESS
      if res != BUFFER_TOO_SMALL
        raise ThemisError, "Secure Session failed decrypting: #{res}"
      end

      unwrapped_message = FFI::MemoryPointer.new(
        :char, unwrapped_message_length.read_uint)
      res = secure_session_unwrap(@session, message_, message_length_,
                                  unwrapped_message, unwrapped_message_length)
      if res != SUCCESS && res != SEND_AS_IS
        raise ThemisError, "Secure Session failed decrypting: #{res}"
      end

      [res, unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)]
    end

    def wrap(message)
      message_, message_length_ = string_to_pointer_size(message)

      wrapped_message_length = FFI::MemoryPointer.new(:uint)
      res = secure_session_wrap(
        @session, message_, message_length_, nil, wrapped_message_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError, "Secure Session failed encrypting: #{res}"
      end

      wrapped_message = FFI::MemoryPointer.new(
        :char, wrapped_message_length.read_uint)
      res = secure_session_wrap(@session, message_, message_length_,
                                wrapped_message, wrapped_message_length)
      if res != SUCCESS && res != SEND_AS_IS
        raise ThemisError, "Secure Session failed encrypting: #{res}"
      end

      wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
    end

    def finalize
      res = secure_session_destroy(@session)
      raise ThemisError, 'Secure Session failed destroying' if res != SUCCESS
    end
  end

  class Smessage
    include ThemisCommon
    include ThemisImport

    def initialize(private_key, peer_public_key)
      if not Themis.valid_key(private_key)
        raise ThemisError, "Secure Message: invalid private key"
      end
      if not Themis.valid_key(peer_public_key)
        raise ThemisError, "Secure Message: invalid public key"
      end
      if not Themis.private_key(private_key)
        raise ThemisError, "Secure Message: public key used instead of private"
      end
      if not Themis.public_key(peer_public_key)
        raise ThemisError, "Secure Message: private key used instead of public"
      end

      @private_key, @private_key_length = string_to_pointer_size(private_key)
      @peer_public_key, @peer_public_key_length =
        string_to_pointer_size(peer_public_key)
    end

    def wrap(message)
        message_, message_length_ = string_to_pointer_size(message)

        wrapped_message_length = FFI::MemoryPointer.new(:uint)
        res = themis_secure_message_encrypt(
          @private_key, @private_key_length, @peer_public_key,
          @peer_public_key_length, message_, message_length_,
          nil, wrapped_message_length)
        if res != BUFFER_TOO_SMALL
          raise ThemisError, "Secure Message failed to encrypt: #{res}"
        end

        wrapped_message = FFI::MemoryPointer.new(
          :char, wrapped_message_length.read_uint)
        res = themis_secure_message_encrypt(
          @private_key, @private_key_length, @peer_public_key,
          @peer_public_key_length, message_, message_length_,
          wrapped_message, wrapped_message_length)
        if res != SUCCESS
          raise ThemisError, "Secure Message failed to encrypt: #{res}"
        end

        wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
    end

    def unwrap(message)
      message_, message_length_ = string_to_pointer_size(message)
      unwrapped_message_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_message_decrypt(
        @private_key, @private_key_length, @peer_public_key,
        @peer_public_key_length, message_, message_length_,
        nil, unwrapped_message_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError, "Secure Message failed to decrypt: #{res}"
      end

      unwrapped_message = FFI::MemoryPointer.new(
        :char, unwrapped_message_length.read_uint)
      res = themis_secure_message_decrypt(
        @private_key, @private_key_length, @peer_public_key,
        @peer_public_key_length, message_, message_length_,
        unwrapped_message, unwrapped_message_length)
      if res != SUCCESS
        raise ThemisError, "Secure Message failed to decrypt: #{res}"
      end

      unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
    end
  end

  def Ssign(*args)
    s_sign(*args)
  end
  deprecate :Ssign, :s_sign, 2018, 6

  def s_sign(private_key, message)
    if not valid_key(private_key)
      raise ThemisError, "Secure Message: invalid private key"
    end
    if not private_key(private_key)
      raise ThemisError, "Secure Message: public key used instead of private"
    end

    private_key_, private_key_length_ = string_to_pointer_size(private_key)
    message_, message_length_ = string_to_pointer_size(message)

    wrapped_message_length = FFI::MemoryPointer.new(:uint)
    res = themis_secure_message_sign(
      private_key_, private_key_length_, message_,
      message_length_, nil, wrapped_message_length)
    if res != BUFFER_TOO_SMALL
      raise ThemisError, "Secure Message failed to sign: #{res}"
    end

    wrapped_message = FFI::MemoryPointer.new(
      :char, wrapped_message_length.read_uint)
    res = themis_secure_message_sign(
      private_key_, private_key_length_, message_,
      message_length_, wrapped_message, wrapped_message_length)
    if res != SUCCESS
      raise ThemisError, "Secure Message failed to sign: #{res}"
    end

    wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
  end

  def Sverify(*args)
    s_verify(*args)
  end
  deprecate :Sverify, :s_verify, 2018, 6

  def s_verify(peer_public_key, message)
    if not valid_key(peer_public_key)
      raise ThemisError, "Secure Message: invalid public key"
    end
    if not public_key(peer_public_key)
      raise ThemisError, "Secure Message: private key used instead of public"
    end

    public_key_, public_key_length_ = string_to_pointer_size(peer_public_key)
    message_, message_length_ = string_to_pointer_size(message)

    unwrapped_message_length = FFI::MemoryPointer.new(:uint)
    res = themis_secure_message_verify(
      public_key_, public_key_length_, message_,
      message_length_, nil, unwrapped_message_length)
    if res != BUFFER_TOO_SMALL
      raise ThemisError, "Secure Message failed to verify: #{res}"
    end

    unwrapped_message = FFI::MemoryPointer.new(
      :char, unwrapped_message_length.read_uint)
    res = themis_secure_message_verify(
      public_key_, public_key_length_, message_,
      message_length_, unwrapped_message, unwrapped_message_length)
    if res != SUCCESS
      raise ThemisError, "Secure Message failed to verify: #{res}"
    end

    unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
  end

  def gen_sym_key
    key_length = FFI::MemoryPointer.new(:uint)

    res = themis_gen_sym_key(nil, key_length)
    if res != BUFFER_TOO_SMALL
      raise ThemisError, "failed to get symmetric key size: #{res}"
    end

    key = FFI::MemoryPointer.new(:char, key_length.read_uint)

    res = themis_gen_sym_key(key, key_length)
    if res != SUCCESS
      raise ThemisError, "failed to generate symmetric key: #{res}"
    end

    return key.get_bytes(0, key_length.read_uint)
  end

  # Scell base class is retained for compatibility.
  # New code should use ScellSeal, ScellTokenProtect, or ScellContextImprint.
  class Scell
    include ThemisCommon
    include ThemisImport

    SEAL_MODE = 0
    TOKEN_PROTECT_MODE = 1
    CONTEXT_IMPRINT_MODE = 2

    def initialize(key, mode)
      # We could have replaced this with "self.new" but it's not possible
      # to override new *and* keep Scell as superclass of ScellSeal et al.
      # So we keep an instance of appropriate class here and never call
      # superclass initialize in subclasses.
      case mode
      when SEAL_MODE
        @cell = ScellSeal.new(key)
      when TOKEN_PROTECT_MODE
        @cell = ScellTokenProtect.new(key)
      when CONTEXT_IMPRINT_MODE
        @cell = ScellContextImprint.new(key)
      else
        raise ThemisError, "unknown Secure Cell mode: #{mode}"
      end
      warn "NOTE: #{self.class.name} is deprecated; use #{@cell.class.name} instead."
    end

    def encrypt(message, context = nil)
      @cell.encrypt(message, context)
    end

    def decrypt(message, context = nil)
      @cell.decrypt(message, context)
    end
  end

  # Secure Cell in Seal mode.
  class ScellSeal < Scell
    include ThemisCommon
    include ThemisImport

    # Make a new Secure Cell with given key.
    # The key must not be empty and is treated as binary data.
    # You can use Themis::gen_sym_key to generate new keys.
    def initialize(key)
      if empty? key
        raise ThemisError, "key cannot be empty"
      end
      @key, @key_length = string_to_pointer_size(key)
    end

    # Encrypts message with given optional context.
    # The context is cryptographically combined with message but is not included
    # into encrypted data, you will need to provide the same context for decryption.
    # Resulting encrypted message includes authentication token.
    # Message must not be empty, but context may be omitted.
    # Both message and context are treated as binary data.
    def encrypt(message, context = nil)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      encrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_encrypt_seal(
        @key, @key_length, context_, context_length_,
        message_, message_length_, nil, encrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message = FFI::MemoryPointer.new(:char, encrypted_length.read_uint)
      res = themis_secure_cell_encrypt_seal(
        @key, @key_length, context_, context_length_,
        message_, message_length_, encrypted_message, encrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message.get_bytes(0, encrypted_length.read_uint)
    end

    # Decrypts message with given context.
    # The context must be the same as the one used during encryption,
    # or be omitted or set to nil if no context were used.
    # Decrypted message is returned as binary data.
    def decrypt(message, context = nil)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      decrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_decrypt_seal(
        @key, @key_length, context_, context_length_,
        message_, message_length_, nil, decrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message = FFI::MemoryPointer.new(:char, decrypted_length.read_uint)
      res = themis_secure_cell_decrypt_seal(
        @key, @key_length, context_, context_length_,
        message_, message_length_, decrypted_message, decrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message.get_bytes(0, decrypted_length.read_uint)
    end
  end

  # Secure Cell in Seal mode.
  class ScellSealPassphrase < ScellSeal
    include ThemisCommon
    include ThemisImport

    # Make a new Secure Cell with given passphrase.
    # The passphrase must not be empty.
    # If the passphrase is not binary it will be encoded in UTF-8 by default,
    # you can use optional "encoding:" argument to use a different encoding.
    def initialize(passphrase, encoding: Encoding::UTF_8)
      if empty? passphrase
        raise ThemisError, "passphrase cannot be empty"
      end
      if passphrase.encoding != Encoding::BINARY
        passphrase = passphrase.encode(encoding)
      end
      @passphrase, @passphrase_length = string_to_pointer_size(passphrase)
    end

    # Encrypts message with given optional context.
    # The context is cryptographically combined with message but is not included
    # into encrypted data, you will need to provide the same context for decryption.
    # Resulting encrypted message includes authentication token.
    # Message must not be empty, but context may be omitted.
    # Both message and context are treated as binary data.
    def encrypt(message, context = nil)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      encrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_encrypt_seal_with_passphrase(
        @passphrase, @passphrase_length, context_, context_length_,
        message_, message_length_, nil, encrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message = FFI::MemoryPointer.new(:char, encrypted_length.read_uint)
      res = themis_secure_cell_encrypt_seal_with_passphrase(
        @passphrase, @passphrase_length, context_, context_length_,
        message_, message_length_, encrypted_message, encrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message.get_bytes(0, encrypted_length.read_uint)
    end

    # Decrypts message with given context.
    # The context must be the same as the one used during encryption,
    # or be omitted or set to nil if no context were used.
    # Decrypted message is returned as binary data.
    def decrypt(message, context = nil)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      decrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_decrypt_seal_with_passphrase(
        @passphrase, @passphrase_length, context_, context_length_,
        message_, message_length_, nil, decrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message = FFI::MemoryPointer.new(:char, decrypted_length.read_uint)
      res = themis_secure_cell_decrypt_seal_with_passphrase(
        @passphrase, @passphrase_length, context_, context_length_,
        message_, message_length_, decrypted_message, decrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message.get_bytes(0, decrypted_length.read_uint)
    end
  end

  # Secure Cell in Token Protect mode.
  class ScellTokenProtect < Scell
    include ThemisCommon
    include ThemisImport

    # Make a new Secure Cell with given key.
    # The key must not be empty and is treated as binary data.
    # You can use Themis::gen_sym_key to generate new keys.
    def initialize(key)
      if empty? key
        raise ThemisError, "key cannot be empty"
      end
      @key, @key_length = string_to_pointer_size(key)
    end

    # Encrypts message with given optional context.
    # The context is cryptographically combined with message but is not included
    # into encrypted data, you will need to provide the same context for decryption.
    # Resulting encrypted message (the same length as input) and authentication token
    # are returned separately; you will need to provide them both for decryption.
    # Message must not be empty, but context may be omitted.
    # Both message and context are treated as binary data.
    def encrypt(message, context = nil)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      auth_token_length = FFI::MemoryPointer.new(:uint)
      encrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_encrypt_token_protect(
        @key, @key_length, context_, context_length_, message_, message_length_,
        nil, auth_token_length, nil, encrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "encrypt failed"
      end

      auth_token = FFI::MemoryPointer.new(:char, auth_token_length.read_uint)
      encrypted_message = FFI::MemoryPointer.new(:char, encrypted_length.read_uint)
      res = themis_secure_cell_encrypt_token_protect(
        @key, @key_length, context_, context_length_, message_, message_length_,
        auth_token, auth_token_length, encrypted_message, encrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "encrypt failed"
      end

      [encrypted_message.get_bytes(0, encrypted_length.read_uint),
       auth_token.get_bytes(0, auth_token_length.read_uint),]
    end

    # Decrypts message with given authentication token and context.
    # The context must be the same as the one used during encryption,
    # or be omitted or set to nil if no context were used.
    # The token also must be the one returned during encryption.
    # Decrypted message is returned as binary data.
    def decrypt(message, token = nil, context = nil)
      # For compatibility with older API we allow the message and token to be
      # provided as a list in the first argument. In this case the second one
      # contains (an optional) context. Then there is no third argument.
      if message.kind_of? Array
        context = token
        message, token = message
      end

      if empty? message
        raise ThemisError, "message cannot be empty"
      end
      if empty? token
        raise ThemisError, "token cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      token_, token_length_ = string_to_pointer_size(token)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      decrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_decrypt_token_protect(
        @key, @key_length, context_, context_length_,
        message_, message_length_, token_, token_length_,
        nil, decrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message = FFI::MemoryPointer.new(:char, decrypted_length.read_uint)
      res = themis_secure_cell_decrypt_token_protect(
        @key, @key_length, context_, context_length_,
        message_, message_length_, token_, token_length_,
        decrypted_message, decrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message.get_bytes(0, decrypted_length.read_uint)
    end
  end

  # Secure Cell in Context Imprint mode.
  class ScellContextImprint < Scell
    include ThemisCommon
    include ThemisImport

    # Make a new Secure Cell with given key.
    # The key must not be empty and is treated as binary data.
    # You can use Themis::gen_sym_key to generate new keys.
    def initialize(key)
      if empty? key
        raise ThemisError, "key cannot be empty"
      end
      @key, @key_length = string_to_pointer_size(key)
    end

    # Encrypts message with given context.
    # The context is cryptographically combined with message but is not included
    # into encrypted data, you will need to provide the same context for decryption.
    # Resulting encrypted message has the same length as input and does not include
    # authentication data, so its integrity cannot be verified.
    # Message and context must not be empty, both are treated as binary data.
    def encrypt(message, context)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end
      if empty? context
        raise ThemisError, "context cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      encrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_encrypt_context_imprint(
        @key, @key_length, message_, message_length_,
        context_, context_length_, nil, encrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message = FFI::MemoryPointer.new(:char, encrypted_length.read_uint)
      res = themis_secure_cell_encrypt_context_imprint(
        @key, @key_length, message_, message_length_,
        context_, context_length_, encrypted_message, encrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "encrypt failed"
      end

      encrypted_message.get_bytes(0, encrypted_length.read_uint)
    end

    # Decrypts message with given context.
    # The context must be the same as the one used during encryption.
    # Since Context Imprint mode does not include authentication data,
    # integrity of the resulting message is not guaranteed.
    # You need to verify it via some other means.
    # Decrypted message is returned as binary data.
    def decrypt(message, context)
      if empty? message
        raise ThemisError, "message cannot be empty"
      end
      if empty? context
        raise ThemisError, "message cannot be empty"
      end

      message_, message_length_ = string_to_pointer_size(message)
      context_, context_length_ =
        context.nil? ? [nil, 0] : string_to_pointer_size(context)

      decrypted_length = FFI::MemoryPointer.new(:uint)
      res = themis_secure_cell_decrypt_context_imprint(
        @key, @key_length, message_, message_length_,
        context_, context_length_, nil, decrypted_length)
      if res != BUFFER_TOO_SMALL
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message = FFI::MemoryPointer.new(:char, decrypted_length.read_uint)
      res = themis_secure_cell_decrypt_context_imprint(
        @key, @key_length, message_, message_length_,
        context_, context_length_, decrypted_message, decrypted_length)
      if res != SUCCESS
        raise ThemisError.new(res), "decrypt failed"
      end

      decrypted_message.get_bytes(0, decrypted_length.read_uint)
    end
  end

  class Scomparator
    include ThemisCommon
    include ThemisImport

    MATCH = 21
    NOT_MATCH = 22
    NOT_READY = 0

    def initialize(shared_secret)
      shared_secret_buf, shared_secret_length =
        string_to_pointer_size(shared_secret)
      @comparator = secure_comparator_create
      raise ThemisError, 'Secure Comparator failed creating' if @comparator.null?
      res = secure_comparator_append_secret(
        @comparator, shared_secret_buf, shared_secret_length)
      if res != SUCCESS
        raise ThemisError, 'Secure Comparator failed appending secret'
      end
    end

    def finalize
      res = secure_comparator_destroy(@comparator)
      if res != SUCCESS
        raise ThemisError, 'Secure Comparator failed destroying'
      end
    end

    def begin_compare
      res_length = FFI::MemoryPointer.new(:uint)
      res = secure_comparator_begin_compare(@comparator, nil, res_length)
      if res != BUFFER_TOO_SMALL
        raise(ThemisError,
              'Secure Comparator failed making initialisation message')
      end

      res_buffer = FFI::MemoryPointer.new(:char, res_length.read_uint)
      res = secure_comparator_begin_compare(@comparator, res_buffer, res_length)
      if res != SUCCESS && res != SEND_AS_IS
        raise(ThemisError,
              'Secure Comparator failed making initialisation message')
      end

      res_buffer.get_bytes(0, res_length.read_uint)
    end

    def proceed_compare(control_message)
      message, message_length = string_to_pointer_size(control_message)
      res_length = FFI::MemoryPointer.new(:uint)

      res = secure_comparator_proceed_compare(
        @comparator, message, message_length, nil, res_length)
      return '' if res == SUCCESS
      if res != BUFFER_TOO_SMALL
        raise ThemisError, 'Secure Comparator failed proceeding message'
      end

      res_buffer = FFI::MemoryPointer.new(:char, res_length.read_uint)
      res = secure_comparator_proceed_compare(
        @comparator, message, message_length, res_buffer, res_length)
      if res != SUCCESS && res != SEND_AS_IS
        raise ThemisError, 'Secure Comparator failed proceeding message'
      end

      res_buffer.get_bytes(0, res_length.read_uint)
    end

    def result
      secure_comparator_get_result(@comparator)
    end
  end

  module_function :Ssign
  module_function :Sverify
  module_function :s_sign
  module_function :s_verify
  module_function :gen_sym_key
end


text:
package com.google.gwt.core.ext;

import com.google.gwt.core.ext.linker.Artifact;
import com.google.gwt.core.ext.linker.GeneratedResource;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.resource.ResourceOracle;

import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * An abstract generator context class which delegates all methods to a provided
 * baseContext. Implementing classes can selectively override individual
 * methods.
 */
public abstract class DelegatingGeneratorContext implements GeneratorContext {

  private final GeneratorContext baseContext;

  /**
   * Get a new instance wrapped from a base {@link GeneratorContext}
   * implementation.
   */
  public DelegatingGeneratorContext(GeneratorContext baseContext) {
    this.baseContext = baseContext;
  }

  @Override
  public boolean checkRebindRuleAvailable(String sourceTypeName) {
    return baseContext.checkRebindRuleAvailable(sourceTypeName);
  }

  @Override
  public void commit(TreeLogger logger, PrintWriter pw) {
    baseContext.commit(logger, pw);
  }

  @Override
  public void commitArtifact(TreeLogger logger, Artifact<?> artifact)
      throws UnableToCompleteException {
    baseContext.commitArtifact(logger, artifact);
  }

  @Override
  public GeneratedResource commitResource(TreeLogger logger, OutputStream os)
      throws UnableToCompleteException {
    return baseContext.commitResource(logger, os);
  }

  @Override
  public CachedGeneratorResult getCachedGeneratorResult() {
    return baseContext.getCachedGeneratorResult();
  }

  @Override
  public PropertyOracle getPropertyOracle() {
    return baseContext.getPropertyOracle();
  }

  @Override
  public ResourceOracle getResourcesOracle() {
    return baseContext.getResourcesOracle();
  }

  @Override
  public TypeOracle getTypeOracle() {
    return baseContext.getTypeOracle();
  }

  @Override
  public boolean isGeneratorResultCachingEnabled() {
    return baseContext.isGeneratorResultCachingEnabled();
  }

  @Override
  public boolean isProdMode() {
    return baseContext.isProdMode();
  }
  @Override
  public PrintWriter tryCreate(TreeLogger logger, String packageName, String simpleName) {
    return baseContext.tryCreate(logger, packageName, simpleName);
  }

  @Override
  public OutputStream tryCreateResource(TreeLogger logger, String partialPath)
      throws UnableToCompleteException {
    return baseContext.tryCreateResource(logger, partialPath);
  }

  @Override
  public boolean tryReuseTypeFromCache(String typeName) {
    return baseContext.tryReuseTypeFromCache(typeName);
  }
}

redpajama_set_name: RedPajamaGithub


text:
import {
  BufferLoader,
  defer,
  Resource,
  ResourceCache,
} from "../../Source/Cesium.js";

describe("Scene/BufferLoader", function () {
  const typedArray = new Uint8Array([1, 3, 7, 15, 31, 63, 127, 255]);
  const arrayBuffer = typedArray.buffer;
  const resource = new Resource({ url: "https://example.com/external.bin" });

  afterEach(function () {
    ResourceCache.clearForSpecs();
  });

  it("throws if neither options.typedArray nor options.resource are defined", function () {
    expect(function () {
      return new BufferLoader({
        typedArray: undefined,
        resource: undefined,
      });
    }).toThrowDeveloperError();
  });

  it("throws if both options.typedArray and options.resource are defined", function () {
    expect(function () {
      return new BufferLoader({
        typedArray: typedArray,
        resource: resource,
      });
    }).toThrowDeveloperError();
  });

  it("rejects promise if buffer cannot be fetched", function () {
    const error = new Error("404 Not Found");
    spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () {
      return Promise.reject(error);
    });

    const bufferLoader = new BufferLoader({
      resource: resource,
    });

    bufferLoader.load();

    return bufferLoader.promise
      .then(function (bufferLoader) {
        fail();
      })
      .catch(function (runtimeError) {
        expect(runtimeError.message).toBe(
          "Failed to load external buffer: https://example.com/external.bin\n404 Not Found"
        );
      });
  });

  it("loads buffer from typed array", function () {
    const bufferLoader = new BufferLoader({
      typedArray: typedArray,
    });
    bufferLoader.load();

    return bufferLoader.promise.then(function (bufferLoader) {
      expect(bufferLoader.typedArray).toBe(typedArray);
    });
  });

  it("loads external buffer", function () {
    const fetchBuffer = spyOn(
      Resource.prototype,
      "fetchArrayBuffer"
    ).and.returnValue(Promise.resolve(arrayBuffer));

    const bufferLoader = new BufferLoader({
      resource: resource,
    });

    bufferLoader.load();

    return bufferLoader.promise.then(function (bufferLoader) {
      expect(fetchBuffer).toHaveBeenCalled();
      expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer);
    });
  });

  it("destroys buffer", function () {
    spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(
      Promise.resolve(arrayBuffer)
    );

    const bufferLoader = new BufferLoader({
      resource: resource,
    });

    expect(bufferLoader.typedArray).not.toBeDefined();

    bufferLoader.load();

    return bufferLoader.promise.then(function (bufferLoader) {
      expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer);
      expect(bufferLoader.isDestroyed()).toBe(false);

      bufferLoader.destroy();
      expect(bufferLoader.typedArray).not.toBeDefined();
      expect(bufferLoader.isDestroyed()).toBe(true);
    });
  });

  function resolveAfterDestroy(reject) {
    const deferredPromise = defer();
    spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(
      deferredPromise.promise
    );

    const bufferLoader = new BufferLoader({
      resource: resource,
    });

    expect(bufferLoader.typedArray).not.toBeDefined();

    bufferLoader.load();
    bufferLoader.destroy();

    if (reject) {
      deferredPromise.reject(new Error());
    } else {
      deferredPromise.resolve(arrayBuffer);
    }

    expect(bufferLoader.typedArray).not.toBeDefined();
    expect(bufferLoader.isDestroyed()).toBe(true);
  }

  it("handles resolving uri after destroy", function () {
    resolveAfterDestroy(false);
  });

  it("handles rejecting uri after destroy", function () {
    resolveAfterDestroy(true);
  });
});


text:
package sword.ios.app.test;

import com.taobao.sword.ios.object.By;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import sword.ios.app.utils.SleepUtils;

/**
 * Created by admin on 16/4/20.
 */
public class iOSWXAnimationTest  extends iOSWeexTest{
    @Before
    public void startDriver() throws Exception {
        super.startDriver();
        findAnimationAndTap();
    }
    @After
    public  void stopDriver() throws Exception{
        super.stopDriver();
    }

    enum Animation {
        TC_Animation_Rotate,TC_Animation_Scale,TC_Animation_Shadow,
        TC_Animation_Transform,TC_Animation_Translate;
    }

    @Test
    public void testScreen_TC_Animation_Rotate_Test() throws Exception {
        app.tableCell(By.index(Animation.TC_Animation_Rotate.ordinal())).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Rotate_01_init");

        app.staticText(By.name("Click Me To Rotate")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Rotate_02_Turn90");

        app.staticText(By.name("Click Me To Rotate")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Rotate_03_Turn180");

        app.staticText(By.name("Click Me To Rotate")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Rotate_04_Turn270");

        app.staticText(By.name("Click Me To Rotate")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Rotate_05_Turn360");
    }

    @Test
    public void testScreen_TC_Animation_Scale_Test() throws Exception {
        app.tableCell(By.index(Animation.TC_Animation_Scale.ordinal())).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Scale_01_init");

        app.staticText(By.name("Click Me To Scale")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Scale_02_large");

        app.staticText(By.name("Click Me To Scale")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Scale_03_smaller");
    }

    @Test
    public void testScreen_TC_Animation_Shadow_Test() throws Exception {
        app.tableCell(By.index(Animation.TC_Animation_Shadow.ordinal())).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Shadow_01_init");

        app.staticText(By.name("Click Me To Opacity")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Shadow_02_opacityLow");

        app.staticText(By.name("Click Me To Opacity")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Shadow_03_opacityHigh");
    }

    @Test
    public void testScreen_TC_Animation_Transform_Test() throws Exception {
        app.tableCell(By.index(Animation.TC_Animation_Transform.ordinal())).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Transform_01_init");

        app.staticText(By.name("Click Me To Transform")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Transform_02_show");

        app.staticText(By.name("Click Me To Transform")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Transform_03_origin");
    }

    @Test
    public void testScreen_TC_Animation_Translate_Test() throws Exception {
        app.tableCell(By.index(Animation.TC_Animation_Translate.ordinal())).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Translate_01_init");

        app.staticText(By.name("Click Me To Translate")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Translate_02_Translate");

        app.staticText(By.name("Click Me To TranslateX")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Translate_03_TranslateX");

        app.staticText(By.name("Click Me To TranslateY")).tap();
        waitAfterTap();
        screenshot("TC", "Animation", "Translate_04_TranslateY");
    }
}


text:
- Requirements: Python 2.6+, Git, SVN
- Clone the git repo (you have probably already done that):
    git clone git://github.com/digitalfruit/limejs.git
- bin/lime.py --help
- bin/lime.py init
- bin/lime.py create helloworld

-----

- open ./helloworld/helloworld.html in the browser
- study/tweak the source

-----

- demos are available at lime/demos/
- documentation is at lime/docs/
- programming guide is at lime/guide/
- unit tests are at lime/tests/

###Windows users:

If you consider yourself advanced user and know how to use Git/Python you are probably better off reading through Mac/Linux guide and choosing your best alternative tools/methods yourself. If not then follow this step-by-step route.

1.  Download and install Git client from http://code.google.com/p/msysgit/downloads/list (if not already installed). While installing select "Run Git from the Windows Command Prompt".
2.  Clone lime git repo or download zip package from https://github.com/digitalfruit/limejs/zipball/master
3.  Extract the contents to suitable place on your hard drive. Next examples will use c:\ as the base path.
4.  If you don't have python download and install it from http://www.python.org/download/
5.  Launch Command Prompt (or PowerShell)
6.  Check if you have python installed on your global path by running:
     python --version

    If this returned error you have to add it to your global path or use full path to binaries in next steps.

    To add python to your global path:

    1. Open Control Panel -> System and Security -> System -> Advanced system settings
    2. Under Advanced tab select Environment Variables...
    3. Under system variables find variable named Path.
    4. Select it and click Edit.
    5. Append semicolon and path to the folder you installed python to the value.
        For example ";C:\Python27\"
    6. Press OK and OK
    7. Restart Command Prompt
    8. Try if it works now

7.  Move to lime base folder
    cd c:\lime

8.  python bin/lime.py --help
9.  In similar pattern continue from Mac/Linux tutorial from step 3

##Browser support:

- *Current:* Chrome, Safari 5, Firefox 3.6+(4beta for best performance), Mobile Safari
- *Working:* (but not quite supported): Opera, IE9
- *Soon:* Android
- *Maybe:* Blackberry Playbook, WebOS

##Links:

Closure Library: <http://closure-library.googlecode.com/svn/docs/index.html>

Closure Compiler: <http://code.google.com/closure/compiler/docs/overview.html>

Closure Templates: <http://code.google.com/closure/templates/docs/helloworld_js.html>

Box2D: <http://www.box2dflash.org/docs/2.0.2/reference/>

Canvas 2D API spec: <http://dev.w3.org/html5/2dcontext/>

WebGL spec: <https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/WebGL-spec.html>

Closure book: <http://books.google.com/books?id=p7uyWPcVGZsC&lpg=PP1&ots=x6aPMrK-uP&dq=closure%20the%20definitive%20guide&pg=PP1#v=onepage&q&f=false>

Closure video from Google I/O 2010:
<http://www.youtube.com/watch?v=yp_9q3tgDnQ>

### Known issues:

- Weird mixup on events on scaled elements(at least on polygons)
- Opera & IE9 rotate wrong in potgame
- Transition based animations don't fire stop events on Spawn&Sequence
- ...add your issues to the github page

### Missing/broken:

- Custom Canvas context
- Custom WebGL context
- Frame fill
- Sprite fill
- Web-app installing tutorial
- Unit tests
- Some basic fallback for non supported browsers

### Future:

- Strokes
- More shapes
- Box2D basic integration
- Different shape masks
- More transitions
- Better audio support
- Local cache support
- Other mobile platforms support(Android,WebOS,Playbook)
- Data support(endtable?)
- Gradients
- Resources loading
- Preloader
- WebGL Renderer
- Dev console
- Tiles
- Scrollers
- Menus
- UI controls
- Video support
- Markup with templates
- Integration with MoRe

###Random notes on design (to be later formed into Programming Guide):

It's built upon Google Closure JS library and uses its style but does not use goog.graphics and goog.fx
Cocos2d is where we have taken the base design about what a game is and how it should be developed. Check their docs if you are confused about what director,scene,node and schedulemanager stand for. Animations are also using similar logic.

You will have no problems with display object if you have build games with Flash in ActionScript. It's uses similar movieclip logic. There are layers,sprites and some custom shapes like circles and polygons.  You can change properties like dimensions, position,scale,opacity,anchorpoint,etc and stack them in drawing tree. Anchorpoints and autoresize masks make it easy to have flexible layouts. Masking is also similar to flash where you set one displayobject as mask for another. Fills are object that add displayobjects some visible form.

Events are done in a way you only need game specific parts to make the game work for both mouse or touch screen. In any scenario. You can also swallow() an event so that it remains tied to this object until event ends(touchend,mouseup etc.).

Don't use setTimeout(),setInterval(). There is no need. This is all done by the scheduleManager. You get your ON_ENTER_FRAME style event from that static object. It also draws all object in dirty-objects queue. If you for example change position of a node, the position is set as DIV elements transform property in next frame because object was now marked dirty. As a bonus for sticking with scheduleManager you get pausing support for director.

There are currently two separate renderers. DOM and Canvas. This means that you can make your display list in JS and in any moment call setRenderer(lime.Renderer.DOM) or setRenderer(lime.Renderer.CANVAS) on any node. It will not change anything visually but internally it changes if tree is drawn as separate DIVs or one Canvas. This comes to play if you have different performing devices. For instance canvas is very quick on some PC browsers and dead slow on iOS4.2(where CSS is fast). You can use same code and render it with completely different lower-end technology. Also static content usually performes better on Canvas and dynamic better on CSS. WebGL renderer is also planned for the future.


text:
import { isNumeric, isString, offsetTop, query } from '../util/index';

export default function (UIkit) {

    UIkit.component('height-viewport', {

        props: {
            expand: Boolean,
            offsetTop: Boolean,
            offsetBottom: Boolean
        },

        defaults: {
            expand: false,
            offsetTop: false,
            offsetBottom: false
        },

        update: {

            write() {

                this.$el.css('boxSizing', 'border-box');

                var viewport = window.innerHeight, height, offset = 0;

                if (this.expand) {

                    this.$el.css({height: '', minHeight: ''});

                    var diff = viewport - document.documentElement.offsetHeight;

                    if (diff > 0) {
                        this.$el.css('min-height', height = this.$el.outerHeight() + diff)
                    }

                } else {

                    var top = offsetTop(this.$el);

                    if (top < viewport / 2 && this.offsetTop) {
                        offset += top;
                    }

                    if (this.offsetBottom === true) {

                        offset += this.$el.next().outerHeight() || 0;

                    } else if (isNumeric(this.offsetBottom)) {

                        offset += (viewport / 100) * this.offsetBottom;

                    } else if (this.offsetBottom && this.offsetBottom.substr(-2) === 'px') {

                        offset += parseFloat(this.offsetBottom);

                    } else if (isString(this.offsetBottom)) {

                        var el = query(this.offsetBottom, this.$el);
                        offset += el && el.outerHeight() || 0;

                    }

                    this.$el.css('min-height', height = offset ? `calc(100vh - ${offset}px)` : '100vh');

                }

                // IE 10-11 fix (min-height on a flex container won't apply to its flex items)
                this.$el.height('');
                if (height && viewport - offset >= this.$el.outerHeight()) {
                    this.$el.css('height', height);
                }

            },

            events: ['load', 'resize']

        }

    });

}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Geometry (aka GGL, Generic Geometry Library)</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">

Main Page

Related Pages

Modules

Namespaces

Classes

Files

Examples

File List

File Members

home

travis

build

boostorg

boost

boost

geometry

algorithms

detail

is_simple

Namespaces |
Functions

debug_print_boundary_points.hpp File Reference

Namespaces

 	boost

 	boost::geometry

 	boost::geometry::detail

 	boost::geometry::detail::is_simple

Functions

template<typename Linear >

void 	boost::geometry::detail::is_simple::debug_print_boundary_points (Linear const &)

April 2, 2011

Copyright © 2007-2011 Barend Gehrels, Amsterdam, the Netherlands

Copyright © 2008-2011 Bruno Lalande, Paris, France

Copyright © 2009-2010 Mateusz Loskot, London, UK

<address style="text-align: right;">
Documentation is generated by Doxygen
</address>


text:
import { Event } from '@klasa/core';

export default class extends Event {

	public run(error: Error): void {
		this.client.console.error(error);
	}

	public init(): void {
		if (!this.client.options.consoleEvents.error) this.disable();
	}

}


text:
fail () {
  echo "$@" >&2
  exit 1
}

main () {
  update_package_list
  install_tools
  clean_up_packages
  install_bash_profile
  # install_nodejs
  # install_npm
  # symlink_node_to_nodejs
  install_node
  install_apache2
  configure_apache2
  restart_services
  install_foundation_cli
  install_gulp
  install_bower
  install_browserify
}

print_section () {
  local msg="$1"
  echo "************************************************************"
  echo "$msg"
  echo "************************************************************"
}

update_package_list () {
  print_section "Updating package list"
  sudo apt-get update
}

install_tools () {
  print_section "Installing good-to-have packages"
  sudo apt-get install -y \
    build-essential \
    git-core \
    vim \
    curl \
    ack-grep \
    wget \
    tree \
    || fail "Unable to install tools."
}

clean_up_packages () {
  print_section "Cleaning up packages"
  (sudo apt-get autoremove -y && sudo apt-get autoclean -y) \
  || fail "Unable to clean up packages"
}

install_bash_profile () {
  print_section "Installing .bash_profile"
  cp /vagrant/configs/.bash_profile /home/vagrant/.bash_profile
  chown vagrant:vagrant /home/vagrant/.bash_profile
}

## not used
install_nodejs () {
  print_section "Installing nodejs."
  sudo apt-get install nodejs -y || fail "Unable to install nodejs."
}

## not used
install_npm () {
  print_section "Installing node package manager [npm]."
  sudo apt-get install npm -y || fail "Unable to install npm."
}

## not used
symlink_node_to_nodejs () {
  print_section "Symlinking node command to nodejs package"
  sudo ln -s "$(which nodejs)" /usr/bin/node \
  || fail "Could not symlink to node"
}

## here, there be dragons
install_node () {
  print_section "Installing Node.js"
  ## this is the reccomended way: https://nodejs.org/en/download/package-manager/
  curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - || fail \
    "Unable to run scary nodejs installation script"
  sudo apt-get install nodejs -y || fail "Unable to install Node.js."
}

install_apache2() {
  print_section "Installing Apache2"
  sudo apt-get install -y apache2  || fail "Unable to install Apache2"
}

configure_apache2 () {
  print_section "Configure Apache2"
  sudo cp /vagrant/configs/002-front-end.conf /etc/apache2/sites-enabled/  \
    || fail "Unable to copy Apache config file."

  sudo a2dissite 000-default || fail "Unable to disable the default site."

  sudo ln -s /vagrant /var/www/html/front-end || fail "Unable to link /vagrant to /var/www/html/front-end"
}

restart_services () {
  print_section "Restart services"
  sudo service apache2 reload || fail "Could not reload apache2."
}

install_foundation_cli () {
  print_section "Installing foundation_cli"
  sudo npm install -g foundation-cli || fail "Unable to install foundation-cli"
}

install_gulp () {
  print_section "Installing Gulp"
  sudo npm install -g gulp || fail "Unable to install gulp"
}

install_bower () {
  print_section "Installing Bower"
  sudo npm install -g bower || fail "Unable to install bower"
}

install_browserify () {
  print_section "Installing Browserify for React"
  sudo npm install -g browserify || fail "Could not install browserify"
}

main "$@"


text:
package com.systematic.trading.backtest.output.elastic.model.index.matcher;

import java.util.Optional;

import javax.ws.rs.client.Entity;

import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Description;
import org.mockito.ArgumentMatcher;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Matcher for a sub-string within an JSON Entity.
 *
 * @author CJ Hare
 */
public class JsonEntityMatcher extends ArgumentMatcher<Entity<?>> {

	private final ObjectMapper mapper = new ObjectMapper();
	private final String expectedJson;

	public JsonEntityMatcher( final String expectedJson ) {

		this.expectedJson = expectedJson;
	}

	public boolean matches( Object argument ) {

		if (argument instanceof Entity<?>) {

			final Entity<?> entity = (Entity<?>) argument;
			final Optional<String> jsonEntity = parseEntity(entity);
			return jsonEntity.isPresent() && StringUtils.contains(jsonEntity.get(), expectedJson);
		}

		return false;
	}

	@Override
	public void describeTo( Description description ) {

		description.appendText(expectedJson);
	}

	private Optional<String> parseEntity( final Entity<?> entity ) {

		try {
			return Optional.of(mapper.writeValueAsString(entity.getEntity()));
		} catch (JsonProcessingException e) {
			return Optional.empty();
		}
	}
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
		<title>Alternet Tools - Generator 1.0 Reference</title>
		<link rel="stylesheet" type="text/css" href="stylesheet.css" title="style" />

			All Classes

Packages

				ml.alternet.util.gen

				ml.alternet.util.gen.sample


text:
"""Package that supports decoding and detokenizing strings."""

from pw_tokenizer.detokenize import AutoUpdatingDetokenizer, Detokenizer


text:
<?php

namespace Prezent\Tests\Doctrine\Translatable\Mapping;

use Prezent\Tests\Tool\ORMTestCase;

class TranslatableListenerTest extends ORMTestCase
{
    public function getFixtureClasses()
    {
        $fixtures = array(
            'Prezent\\Tests\\Fixture\\Basic',
            'Prezent\\Tests\\Fixture\\BasicTranslation',
            'Prezent\\Tests\\Fixture\\Mapped',
            'Prezent\\Tests\\Fixture\\MappedTranslation',
            'Prezent\\Tests\\Fixture\\Inherited',
            'Prezent\\Tests\\Fixture\\InheritedTranslation',
        );

        if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
            $fixtures[] = 'Prezent\\Tests\\Fixture\\Mixin';
            $fixtures[] = 'Prezent\\Tests\\Fixture\\MixinTranslation';
        }

        return $fixtures;
    }

    public function getEntities()
    {
        return array(
            array('5.3.0', 'Prezent\\Tests\\Fixture\\Basic',     'Prezent\\Tests\\Fixture\\BasicTranslation'),
            array('5.3.0', 'Prezent\\Tests\\Fixture\\Mapped',    'Prezent\\Tests\\Fixture\\MappedTranslation'),
            array('5.3.0', 'Prezent\\Tests\\Fixture\\Inherited', 'Prezent\\Tests\\Fixture\\InheritedTranslation'),
            array('5.4.0', 'Prezent\\Tests\\Fixture\\Mixin',     'Prezent\\Tests\\Fixture\\MixinTranslation'),
        );
    }

    /**
     * @dataProvider getEntities
     */
    public function testPostLoad($version, $translatableClass, $translationClass)
    {
        if (version_compare(PHP_VERSION, $version) < 0) {
            $this->markTestSkipped('Traits require PHP 5.4');
        }

        // setup
        $em = $this->getEntityManager();
        $listener = $this->getTranslatableListener();
        $listener->setCurrentLocale('de')
                 ->setFallbackLocale('en');

        $en = new $translationClass();
        $en->setLocale('en')
           ->setName('foo');

        $de = new $translationClass();
        $de->setLocale('de')
           ->setName('bar');

        $entity = new $translatableClass();
        $entity->addTranslation($en)
               ->addTranslation($de);

        $em->persist($entity);
        $em->flush();
        $em->clear();
        // end setup

        $entity = $em->find($translatableClass, 1);

        $this->assertNotNull($entity);
        $this->assertEquals('de', $entity->currentLocale);
        $this->assertEquals('de', $entity->getTranslations()->get($entity->currentLocale)->getLocale());
        $this->assertEquals('en', $entity->fallbackLocale);
        $this->assertEquals('en', $entity->getTranslations()->get($entity->fallbackLocale)->getLocale());
    }
}


text:
This lib target to help you create some dynamic syntax
where you could create method name based logic for factory like use cases.

## Installation

Add this line to your application's Gemfile:

    gem 'syntax_sugar'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install syntax_sugar

## Usage

```ruby

    require 'syntax_sugar'

    hash = Hash.new
    sugar = SyntaxSugar::NullObject.new(hash, /^(.*)=$/ => :[]=, /^get_(.*)$/ => :[], /^fetch$/ => :[])

    sugar.asd = 'cat'
    p sugar.get_asd #> "cat"
    p hash #> {"asd"=>"cat"}
    p sugar.fetch 'asd' #> "cat"

```

## Contributing

1. Fork it ( https://github.com/[my-github-username]/syntax_sugar/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request


text:
"""
Memcache store module
"""
import memcache
import re

from threading import Lock
from ovs.log.logHandler import LogHandler

logger = LogHandler('extensions', 'memcache store')

def locked():
    """
    Locking decorator.
    """
    def wrap(f):
        """
        Returns a wrapped function
        """
        def new_function(self, *args, **kwargs):
            """
            Executes the decorated function in a locked context
            """
            lock = kwargs.get('lock', True)
            if 'lock' in kwargs:
                del kwargs['lock']
            if lock:
                with self._lock:
                    return f(self, *args, **kwargs)
            else:
                return f(self, *args, **kwargs)
        return new_function
    return wrap

class MemcacheStore(object):
    """
    Memcache client wrapper:
    * stringifies the keys
    """

    def __init__(self, nodes):
        """
        Initializes the client
        """
        self._nodes = nodes
        self._client = memcache.Client(self._nodes, cache_cas=True)
        self._lock = Lock()
        self._validate = True

    def _get(self, action, key, default=None):
        """
        Retrieves a certain value for a given key (get or gets)
        """
        key = MemcacheStore._clean_key(key)
        if action == 'get':
            data = self._client.get(key)
        else:
            data = self._client.gets(key)
        if data is None:
            # Cache miss
            return default
        if self._validate:
            if data['key'] == key:
                return data['value']
            error = 'Invalid data received'
            logger.exception('Invalid data received: Got key {0} instead of {1}'.format(data['key'], key))
            raise RuntimeError(error)
        else:
            return data

    @locked()
    def get(self, key, default=None):
        """
        Retrieves a certain value for a given key (get)
        """
        return self._get('get', key, default=default)

    @locked()
    def gets(self, key, default=None):
        """
        Retrieves a certain value for a given key (gets)
        """
        return self._get('gets', key, default=default)

    def _set(self, action, key, value, time=0):
        """
        Sets the value for a key to a given value
        """
        key = MemcacheStore._clean_key(key)
        if self._validate:
            data = {'value': value,
                    'key': key}
        else:
            data = value
        if action == 'set':
            return self._client.set(key, data, time)
        return self._client.cas(key, data, time)

    @locked()
    def set(self, key, value, time=0):
        """
        Sets the value for a key to a given value (set)
        """
        return self._set('set', key, value, time=time)

    @locked()
    def cas(self, key, value, time=0):
        """
        Sets the value for a key to a given value (cas)
        """
        return self._set('cas', key, value, time=time)

    @locked()
    def add(self, key, value, time=0):
        """
        Adds a given key to the store, expecting the key does not exists yet
        """
        key = MemcacheStore._clean_key(key)
        if self._validate:
            data = {'value': value,
                    'key': key}
        else:
            data = value
        return self._client.add(key, data, time)

    @locked()
    def incr(self, key, delta=1):
        """
        Increments the value of the key, expecting it exists
        """
        if self._validate:
            value = self.get(key, lock=False)
            if value is not None:
                value += delta
            else:
                value = 1
            self.set(key, value, 60, lock=False)
            return True
        else:
            return self._client.incr(MemcacheStore._clean_key(key), delta)

    @locked()
    def delete(self, key):
        """
        Deletes a given key from the store
        """
        return self._client.delete(MemcacheStore._clean_key(key))

    @staticmethod
    def _clean_key(key):
        return re.sub('[^\x21-\x7e\x80-\xff]', '', str(key))


text:
<?php

use Zelenin\yii\SemanticUI\Elements;

$this->title = 'Button';

Elements::header($this->title);
?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::button('Follow'),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::button('Follow');
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::button('Save', ['class' => 'primary']) . Elements::button('Discard'),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::button('Save', ['class' => 'primary']);
echo Elements::button('Discard');
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::button(Elements::icon('pause') . 'Pause', ['class' => 'labeled icon']) . Elements::button(Elements::icon('right arrow') . 'Next', ['class' => 'right labeled icon']),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::button(Elements::icon('pause') . 'Pause', ['class' => 'labeled icon']);
echo Elements::button(Elements::icon('right arrow') . 'Next', ['class' => 'right labeled icon']);
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::buttonsGroup(Elements::button('One') . Elements::button('Two') . Elements::button('Three')),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::buttonsGroup(
    Elements::button('One') .
    Elements::button('Two') .
    Elements::button('Three')
);
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::buttonsGroup(Elements::button('Cancel') . '

' . Elements::button('Save', ['class' => 'positive'])),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::buttonsGroup(
    Elements::button('Cancel') .
    '

' .
    Elements::button('Save', ['class' => 'positive'])
);
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::button('Save', ['class' => 'loading']),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::button('Save', ['class' => 'loading']);
PHP
]) ?>

<?= \app\modules\demo\widgets\Example::widget([
    'demo' => Elements::button('Save', ['class' => 'small']),
    'code' => <<<PHP
use Zelenin\yii\SemanticUI\Elements;
echo Elements::button('Save', ['class' => 'small']);
PHP
]) ?>


text:
8" SDR11 HDPE
New Fire Line

Landels School
 HDPE Fire Line

Project: New Fire Line

Type of Pipe: 8" SDR11 HDPE

length of Pipe: 1,560 Feet

Location: Mountain View, CA.

					Contractor: Rodan Builders & R&B Fusion

		include "lightbox-landels.html"

Santa Clara County passed Measure G in 2012. Measure G will generate up to $198 million for the Mountain View Whisman School District. The funds will help schools upgrade, repair or expand the campuses to provide students and staff with safe, efficient and modern facilities.

One recipient of these funds is Landels Elementary School, which is adding a new sports building to its campus. Construction of the new building started over the summer break and it needed a new fire line installed before school begins in August. To be able to have the new line installed on time, it was decided that Horizontal Directional Drilling (HDD) would be fastest and least intrusive. The new line totals at 1,560' of 8" SDR11 HDPE split into six runs. Each run had a pull-head fused to one end so it could be pulled between the insertion and connection pits.

By installing the new line in this manner no trenches had to be dug resulting in less damage to the campus. A total of six pits had to be dug for pulling in each run. The runs were fused together using a Tega Electrofusion Coupling to complete the fire line. Using Horizontal Directional Drilling rather than the traditional open trench method resulted in both time and money savings.

		Download the PDF here.

Locations

	include "branches.html"


text:
if (typeof window.console == "undefined") {
  window.console = { messages: [] }
  window.console.log = function (msg) {
    this.messages.push(msg);
  }
  window.console.warn = window.console.log;
}

// A simple version of console.dir that works on iOS.
//
window.console.compatDir = function (obj) {
  var stringify = function (o) {
    var parts = [];
    for (var x in o) {
      parts.push(x + ": " + o[x]);
    }
    return parts.join(";\n");
  }

  var out = stringify(obj);
  window.console.log(out);
  return out;
}

// This is called by Monocle methods and practices that are no longer
// recommended and will soon be removed.
//
window.console.deprecation = function (msg) {
  console.warn("[DEPRECATION]: "+msg);
  if (typeof console.trace == "function") {
    console.trace();
  }
}

// A convenient alias for setTimeout that assumes 0 if no timeout is specified.
//
Monocle.defer = function (fn, time) {
  if (typeof fn == "function") {
    return setTimeout(fn, time || 0);
  }
}


text:
package flags

import (
	"testing"
)

func TestPointerBool(t *testing.T) {
	var opts = struct {
		Value *bool `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v")

	assertStringArray(t, ret, []string{})

	if !*opts.Value {
		t.Errorf("Expected Value to be true")
	}
}

func TestPointerString(t *testing.T) {
	var opts = struct {
		Value *string `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v", "value")

	assertStringArray(t, ret, []string{})
	assertString(t, *opts.Value, "value")
}

func TestPointerSlice(t *testing.T) {
	var opts = struct {
		Value *[]string `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v", "value1", "-v", "value2")

	assertStringArray(t, ret, []string{})
	assertStringArray(t, *opts.Value, []string{"value1", "value2"})
}

func TestPointerMap(t *testing.T) {
	var opts = struct {
		Value *map[string]int `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v", "k1:2", "-v", "k2:-5")

	assertStringArray(t, ret, []string{})

	if v, ok := (*opts.Value)["k1"]; !ok {
		t.Errorf("Expected key \"k1\" to exist")
	} else if v != 2 {
		t.Errorf("Expected \"k1\" to be 2, but got %#v", v)
	}

	if v, ok := (*opts.Value)["k2"]; !ok {
		t.Errorf("Expected key \"k2\" to exist")
	} else if v != -5 {
		t.Errorf("Expected \"k2\" to be -5, but got %#v", v)
	}
}

type marshalledString string

func (m *marshalledString) UnmarshalFlag(value string) error {
	*m = marshalledString(value)
	return nil
}

func (m marshalledString) MarshalFlag() (string, error) {
	return string(m), nil
}

func TestPointerStringMarshalled(t *testing.T) {
	var opts = struct {
		Value *marshalledString `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v", "value")

	assertStringArray(t, ret, []string{})

	if opts.Value == nil {
		t.Error("Expected value not to be nil")
		return
	}

	assertString(t, string(*opts.Value), "value")
}

type marshalledStruct struct {
	Value string
}

func (m *marshalledStruct) UnmarshalFlag(value string) error {
	m.Value = value
	return nil
}

func (m marshalledStruct) MarshalFlag() (string, error) {
	return m.Value, nil
}

func TestPointerStructMarshalled(t *testing.T) {
	var opts = struct {
		Value *marshalledStruct `short:"v"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v", "value")

	assertStringArray(t, ret, []string{})

	if opts.Value == nil {
		t.Error("Expected value not to be nil")
		return
	}

	assertString(t, opts.Value.Value, "value")
}

type PointerGroup struct {
	Value bool `short:"v"`
}

func TestPointerGroup(t *testing.T) {
	var opts = struct {
		Group *PointerGroup `group:"Group Options"`
	}{}

	ret := assertParseSuccess(t, &opts, "-v")

	assertStringArray(t, ret, []string{})

	if !opts.Group.Value {
		t.Errorf("Expected Group.Value to be true")
	}
}

func TestDoNotChangeNonTaggedFields(t *testing.T) {
	var opts struct {
		A struct {
			Pointer *int
		}
		B *struct {
			Pointer *int
		}
	}

	ret := assertParseSuccess(t, &opts)

	assertStringArray(t, ret, []string{})

	if opts.A.Pointer != nil {
		t.Error("Expected A.Pointer to be nil")
	}
	if opts.B != nil {
		t.Error("Expected B to be nil")
	}
	if opts.B != nil && opts.B.Pointer != nil {
		t.Error("Expected B.Pointer to be nil")
	}
}


text:
<?php
include 'settings.php';

$root = __DIR__."/../";

$file = $_FILES["file"];
$fileName = $_GET['fileName'];

$fileName == "background.png" ? $folder = Settings::$img_folder : $folder= Settings::$icons_folder;

if(isset($_GET['api'])){
	$api= explode('/',$_GET['api']);
}

header('Content-type: application/json');

$out = new stdClass();
$err = checkFoErrors($file);
if($err)$out = $err;
else{
	$filename = uploadImage($root,$folder,$file,$fileName);
	if($filename){
		$out->success='success';
		$out->result= $filename;

	}else $out->error='error move file';
}

echo json_encode($out);
function uploadImage($root,$folder,$file,$fileName){
		if (!file_exists($root.$folder)) mkdir($root.$folder, 0755, true);
		$filename = $folder.'/'.$fileName;
		if(move_uploaded_file($file["tmp_name"],$root.$filename))return $filename;
		return 0;
	}

	function checkFoErrors($file){
		$out=new stdClass();
		if ($file["error"] > 0){
			$out->error= $file["error"];
				switch ($file["error"]) {
					case UPLOAD_ERR_OK:
						$out->result = 'UPLOAD_ERR_OK';
					break;
					case UPLOAD_ERR_NO_FILE:
						$out->result = 'UPLOAD_ERR_NO_FILE';
					case UPLOAD_ERR_INI_SIZE:
					case UPLOAD_ERR_FORM_SIZE:
						$out->result = 'UPLOAD_ERR_INI_SIZE';
					default:
						$out->result = 'UNKNOWN_ERROR';
				}

			return $out;
		}
		return 0;
	}

?>


text:
package database

import (
	"testing"

	"github.com/drone/drone/pkg/database"
)

// TODO unit test to verify unique constraint on Member.UserID and Member.TeamID

// TestGetRepo tests the ability to retrieve a Repo
// from the database by Unique ID.
func TestGetRepo(t *testing.T) {
	Setup()
	defer Teardown()

	repo, err := database.GetRepo(1)
	if err != nil {
		t.Error(err)
	}

	if repo.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.ID)
	}

	if repo.Slug != "github.com/drone/drone" {
		t.Errorf("Exepected Slug %s, got %s", "github.com/drone/drone", repo.Slug)
	}

	if repo.Host != "github.com" {
		t.Errorf("Exepected Host %s, got %s", "github.com", repo.Host)
	}

	if repo.Owner != "drone" {
		t.Errorf("Exepected Owner %s, got %s", "drone", repo.Owner)
	}

	if repo.Name != "drone" {
		t.Errorf("Exepected Name %s, got %s", "drone", repo.Name)
	}

	if repo.Private != true {
		t.Errorf("Exepected Private %v, got %v", true, repo.Private)
	}

	if repo.Disabled != false {
		t.Errorf("Exepected Private %v, got %v", false, repo.Disabled)
	}

	if repo.SCM != "git" {
		t.Errorf("Exepected Type %s, got %s", "git", repo.SCM)
	}

	if repo.URL != "git@github.com:drone/drone.git" {
		t.Errorf("Exepected URL %s, got %s", "git@github.com:drone/drone.git", repo.URL)
	}

	if repo.Username != "no username" {
		t.Errorf("Exepected Username %s, got %s", "no username", repo.Username)
	}

	if repo.Password != "no password" {
		t.Errorf("Exepected Password %s, got %s", "no password", repo.Password)
	}

	if repo.PublicKey != "public key" {
		t.Errorf("Exepected PublicKey %s, got %s", "public key", repo.PublicKey)
	}

	if repo.PrivateKey != "private key" {
		t.Errorf("Exepected PrivateKey %s, got %s", "private key", repo.PrivateKey)
	}

	if repo.UserID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.UserID)
	}

	if repo.TeamID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.TeamID)
	}
}

// TestGetRepoSlug tests the ability to retrieve a Repo
// from the database by it's Canonical Name.
func TestGetRepoSlug(t *testing.T) {
	Setup()
	defer Teardown()

	repo, err := database.GetRepoSlug("github.com/drone/drone")
	if err != nil {
		t.Error(err)
	}

	if repo.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.ID)
	}

	if repo.Slug != "github.com/drone/drone" {
		t.Errorf("Exepected Slug %s, got %s", "github.com/drone/drone", repo.Slug)
	}

	if repo.Host != "github.com" {
		t.Errorf("Exepected Host %s, got %s", "github.com", repo.Host)
	}

	if repo.Owner != "drone" {
		t.Errorf("Exepected Owner %s, got %s", "drone", repo.Owner)
	}

	if repo.Name != "drone" {
		t.Errorf("Exepected Name %s, got %s", "drone", repo.Name)
	}

	if repo.Private != true {
		t.Errorf("Exepected Private %v, got %v", true, repo.Private)
	}

	if repo.Disabled != false {
		t.Errorf("Exepected Private %v, got %v", false, repo.Disabled)
	}

	if repo.SCM != "git" {
		t.Errorf("Exepected Type %s, got %s", "git", repo.SCM)
	}

	if repo.URL != "git@github.com:drone/drone.git" {
		t.Errorf("Exepected URL %s, got %s", "git@github.com:drone/drone.git", repo.URL)
	}

	if repo.Username != "no username" {
		t.Errorf("Exepected Username %s, got %s", "no username", repo.Username)
	}

	if repo.Password != "no password" {
		t.Errorf("Exepected Password %s, got %s", "no password", repo.Password)
	}

	if repo.PublicKey != "public key" {
		t.Errorf("Exepected PublicKey %s, got %s", "public key", repo.PublicKey)
	}

	if repo.PrivateKey != "private key" {
		t.Errorf("Exepected PrivateKey %s, got %s", "private key", repo.PrivateKey)
	}

	if repo.UserID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.UserID)
	}

	if repo.TeamID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.TeamID)
	}
}

func TestSaveRepo(t *testing.T) {
	Setup()
	defer Teardown()

	// get the repo we plan to update
	repo, err := database.GetRepo(1)
	if err != nil {
		t.Error(err)
	}

	// update fields
	repo.Slug = "bitbucket.org/drone/drone"
	repo.Host = "bitbucket.org"
	repo.Private = false
	repo.Disabled = true
	repo.SCM = "hg"
	repo.URL = "https://bitbucket.org/drone/drone"
	repo.Username = "brad"
	repo.Password = "password"
	repo.TeamID = 0

	// update the database
	if err := database.SaveRepo(repo); err != nil {
		t.Error(err)
	}

	// get the updated repo
	updatedRepo, err := database.GetRepo(1)
	if err != nil {
		t.Error(err)
	}

	if updatedRepo.Slug != repo.Slug {
		t.Errorf("Exepected Slug %s, got %s", updatedRepo.Slug, repo.Slug)
	}

	if updatedRepo.Host != repo.Host {
		t.Errorf("Exepected Host %s, got %s", updatedRepo.Host, repo.Host)
	}

	if updatedRepo.Private != repo.Private {
		t.Errorf("Exepected Private %v, got %v", updatedRepo.Private, repo.Private)
	}

	if updatedRepo.Disabled != repo.Disabled {
		t.Errorf("Exepected Private %v, got %v", updatedRepo.Disabled, repo.Disabled)
	}

	if updatedRepo.SCM != repo.SCM {
		t.Errorf("Exepected Type %s, got %s", true, repo.SCM)
	}

	if updatedRepo.URL != repo.URL {
		t.Errorf("Exepected URL %s, got %s", updatedRepo.URL, repo.URL)
	}

	if updatedRepo.Username != repo.Username {
		t.Errorf("Exepected Username %s, got %s", updatedRepo.Username, repo.Username)
	}

	if updatedRepo.Password != repo.Password {
		t.Errorf("Exepected Password %s, got %s", updatedRepo.Password, repo.Password)
	}

	if updatedRepo.TeamID != repo.TeamID {
		t.Errorf("Exepected TeamID %d, got %d", updatedRepo.TeamID, repo.TeamID)
	}
}

func TestDeleteRepo(t *testing.T) {
	Setup()
	defer Teardown()

	if err := database.DeleteRepo(1); err != nil {
		t.Error(err)
	}

	// try to get the deleted row
	_, err := database.GetRepo(1)
	if err == nil {
		t.Fail()
	}
}

/*
func TestListRepos(t *testing.T) {
	Setup()
	defer Teardown()

	// repos for user_id = 1
	repos, err := database.ListRepos(1)
	if err != nil {
		t.Error(err)
	}

	// verify user count
	if len(repos) != 2 {
		t.Errorf("Exepected %d repos in database, got %d", 2, len(repos))
		return
	}

	// get the second repo in the list and verify
	// fields are being populated correctly
	// NOTE: we get the 2nd repo due to sorting
	repo := repos[1]

	if repo.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.ID)
	}

	if repo.Name != "github.com/drone/drone" {
		t.Errorf("Exepected Name %s, got %s", "github.com/drone/drone", repo.Name)
	}

	if repo.Host != "github.com" {
		t.Errorf("Exepected Host %s, got %s", "github.com", repo.Host)
	}

	if repo.Owner != "drone" {
		t.Errorf("Exepected Owner %s, got %s", "drone", repo.Owner)
	}

	if repo.Slug != "drone" {
		t.Errorf("Exepected Slug %s, got %s", "drone", repo.Slug)
	}

	if repo.Private != true {
		t.Errorf("Exepected Private %v, got %v", true, repo.Private)
	}

	if repo.Disabled != false {
		t.Errorf("Exepected Private %v, got %v", false, repo.Disabled)
	}

	if repo.SCM != "git" {
		t.Errorf("Exepected Type %s, got %s", "git", repo.SCM)
	}

	if repo.URL != "git@github.com:drone/drone.git" {
		t.Errorf("Exepected URL %s, got %s", "git@github.com:drone/drone.git", repo.URL)
	}

	if repo.Username != "no username" {
		t.Errorf("Exepected Username %s, got %s", "no username", repo.Username)
	}

	if repo.Password != "no password" {
		t.Errorf("Exepected Password %s, got %s", "no password", repo.Password)
	}

	if repo.PublicKey != "public key" {
		t.Errorf("Exepected PublicKey %s, got %s", "public key", repo.PublicKey)
	}

	if repo.PrivateKey != "private key" {
		t.Errorf("Exepected PrivateKey %s, got %s", "private key", repo.PrivateKey)
	}

	if repo.UserID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.UserID)
	}

	if repo.TeamID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.TeamID)
	}
}
*/

func TestListReposTeam(t *testing.T) {
	Setup()
	defer Teardown()

	// repos for team_id = 1
	repos, err := database.ListReposTeam(1)
	if err != nil {
		t.Error(err)
	}

	// verify user count
	if len(repos) != 2 {
		t.Errorf("Exepected %d repos in database, got %d", 2, len(repos))
		return
	}

	// get the second repo in the list and verify
	// fields are being populated correctly
	// NOTE: we get the 2nd repo due to sorting
	repo := repos[1]

	if repo.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.ID)
	}

	if repo.Slug != "github.com/drone/drone" {
		t.Errorf("Exepected Slug %s, got %s", "github.com/drone/drone", repo.Slug)
	}

	if repo.Host != "github.com" {
		t.Errorf("Exepected Host %s, got %s", "github.com", repo.Host)
	}

	if repo.Owner != "drone" {
		t.Errorf("Exepected Owner %s, got %s", "drone", repo.Owner)
	}

	if repo.Name != "drone" {
		t.Errorf("Exepected Name %s, got %s", "drone", repo.Name)
	}

	if repo.Private != true {
		t.Errorf("Exepected Private %v, got %v", true, repo.Private)
	}

	if repo.Disabled != false {
		t.Errorf("Exepected Private %v, got %v", false, repo.Disabled)
	}

	if repo.SCM != "git" {
		t.Errorf("Exepected Type %s, got %s", "git", repo.SCM)
	}

	if repo.URL != "git@github.com:drone/drone.git" {
		t.Errorf("Exepected URL %s, got %s", "git@github.com:drone/drone.git", repo.URL)
	}

	if repo.Username != "no username" {
		t.Errorf("Exepected Username %s, got %s", "no username", repo.Username)
	}

	if repo.Password != "no password" {
		t.Errorf("Exepected Password %s, got %s", "no password", repo.Password)
	}

	if repo.PublicKey != "public key" {
		t.Errorf("Exepected PublicKey %s, got %s", "public key", repo.PublicKey)
	}

	if repo.PrivateKey != "private key" {
		t.Errorf("Exepected PrivateKey %s, got %s", "private key", repo.PrivateKey)
	}

	if repo.UserID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.UserID)
	}

	if repo.TeamID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, repo.TeamID)
	}
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Uses of Class org.apache.cassandra.db.Memtable (apache-cassandra API)</title>
<meta name="date" content="2015-05-13">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Uses of Class
org.apache.cassandra.db.Memtable

Packages that use Memtable

Package
Description

org.apache.cassandra.db

org.apache.cassandra.db.compaction

org.apache.cassandra.db.filter

org.apache.cassandra.notifications

Uses of Memtable in org.apache.cassandra.db

Fields in org.apache.cassandra.db with type parameters of type Memtable

Modifier and Type
Field and Description

java.lang.Iterable<Memtable>
ColumnFamilyStore.ViewFragment.memtables

Methods in org.apache.cassandra.db that return Memtable

Modifier and Type
Method and Description

Memtable
DataTracker.getMemtable()

Memtable
DataTracker.switchMemtable()

Switch the current memtable.

Methods in org.apache.cassandra.db that return types with arguments of type Memtable

Modifier and Type
Method and Description

java.lang.Iterable<Memtable>
DataTracker.getAllMemtables()

java.util.Set<Memtable>
ColumnFamilyStore.getMemtablesPendingFlush()

java.util.Set<Memtable>
DataTracker.getMemtablesPendingFlush()

Methods in org.apache.cassandra.db with parameters of type Memtable

Modifier and Type
Method and Description

void
DataTracker.notifyRenewed(Memtable renewed)

void
DataTracker.replaceFlushed(Memtable memtable,
              SSTableReader sstable)

Method parameters in org.apache.cassandra.db with type arguments of type Memtable

Modifier and Type
Method and Description

static CloseableIterator<Row>
RowIteratorFactory.getIterator(java.lang.Iterable<Memtable> memtables,
           java.util.Collection<SSTableReader> sstables,
           DataRange range,
           ColumnFamilyStore cfs,
           long now)

Get a row iterator over the provided memtables and sstables, between the provided keys
 and filtered by the queryfilter.

Constructor parameters in org.apache.cassandra.db with type arguments of type Memtable

Constructor and Description

ColumnFamilyStore.ViewFragment(java.util.List<SSTableReader> sstables,
                              java.lang.Iterable<Memtable> memtables)

Uses of Memtable in org.apache.cassandra.db.compaction

Methods in org.apache.cassandra.db.compaction with parameters of type Memtable

Modifier and Type
Method and Description

void
AbstractCompactionStrategy.replaceFlushed(Memtable memtable,
              SSTableReader sstable)

Handle a flushed memtable.

Uses of Memtable in org.apache.cassandra.db.filter

Methods in org.apache.cassandra.db.filter with parameters of type Memtable

Modifier and Type
Method and Description

OnDiskAtomIterator
QueryFilter.getMemtableColumnIterator(Memtable memtable)

Uses of Memtable in org.apache.cassandra.notifications

Fields in org.apache.cassandra.notifications declared as Memtable

Modifier and Type
Field and Description

Memtable
MemtableRenewedNotification.renewed

Constructors in org.apache.cassandra.notifications with parameters of type Memtable

Constructor and Description

MemtableRenewedNotification(Memtable renewed)

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Copyright © 2015 The Apache Software Foundation


text:
package org.starapp.rbac.rest;

import java.net.URI;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.util.UriComponentsBuilder;
import org.starapp.core.beanvalidator.BeanValidators;
import org.starapp.rbac.entity.Objects;
import org.starapp.rbac.service.ObjectsService;

/**
 * Objects的Restful API的Controller.
 *
 * @author wangqiang@cisoft.com.cn
 *
 */

@Controller
@RequestMapping(value = "/admin/api/v1/objects")
public class ObjectsRestController {

	@Autowired
	private ObjectsService objectsService;

	@Autowired
	private Validator validator;

	@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public List<Objects> list() {
		return objectsService.getAllObjects();
	}

	@RequestMapping(value = "/{objectId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResponseEntity<?> get(@PathVariable("objectId") String objectId) {
		Objects entity = objectsService.getObjects(objectId);
		if (entity == null) {
			return new ResponseEntity(HttpStatus.NOT_FOUND);
		}
		return new ResponseEntity(entity, HttpStatus.OK);
	}

	@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResponseEntity<?> create(@RequestBody Objects entity, UriComponentsBuilder uriBuilder) {
		//调用JSR303 Bean Validator进行校验,如果出错返回含400错误码及json格式的错误信息.
		Set<ConstraintViolation<Objects>> failures = validator.validate(entity);
		if (!failures.isEmpty()) {
			return new ResponseEntity(BeanValidators.extractPropertyAndMessage(failures), HttpStatus.BAD_REQUEST);
		}

		//保存任务
		objectsService.saveObjects(entity);

		//按照Restful风格约定,创建指向新任务的url, 也可以直接返回id或对象.
		String objectId = entity.getObjectId();

		URI uri = uriBuilder.path("/api/v1/admin/objects/" + objectId).build().toUri();

		HttpHeaders headers = new HttpHeaders();
		headers.setLocation(uri);

		return new ResponseEntity(headers, HttpStatus.CREATED);
	}

	@RequestMapping(value = "update", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> update(@RequestBody Objects entity) {
		//调用JSR303 Bean Validator进行校验,如果出错返回含400错误码及json格式的错误信息.
		Set<ConstraintViolation<Objects>> failures = validator.validate(entity);
		if (!failures.isEmpty()) {
			return new ResponseEntity(BeanValidators.extractPropertyAndMessage(failures), HttpStatus.BAD_REQUEST);
		}

		//保存
		objectsService.saveObjects(entity);

		//按Restful约定,返回204状态码, 无内容. 也可以返回200状态码.
		return new ResponseEntity(HttpStatus.OK);
	}

	@RequestMapping(value = "delete/{objectId}")
	@ResponseStatus(HttpStatus.NO_CONTENT)
	public void delete(@PathVariable("objectId") String objectId) {
		objectsService.deleteObjects(objectId);
	}
}