text:
#ifndef QOPENGLSHADERPROGRAM_H
#define QOPENGLSHADERPROGRAM_H

#include <QtCore/qglobal.h>

#ifndef QT_NO_OPENGL

#include <QtGui/qopengl.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
#include <QtGui/qmatrix4x4.h>

QT_BEGIN_NAMESPACE

class QOpenGLContext;
class QOpenGLShaderProgram;
class QOpenGLShaderPrivate;

class Q_GUI_EXPORT QOpenGLShader : public QObject
{
    Q_OBJECT
public:
    enum ShaderTypeBit
    {
        Vertex                 = 0x0001,
        Fragment               = 0x0002,
        Geometry               = 0x0004,
        TessellationControl    = 0x0008,
        TessellationEvaluation = 0x0010,
        Compute                = 0x0020
    };
    Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)

    explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = 0);
    virtual ~QOpenGLShader();

    QOpenGLShader::ShaderType shaderType() const;

    bool compileSourceCode(const char *source);
    bool compileSourceCode(const QByteArray& source);
    bool compileSourceCode(const QString& source);
    bool compileSourceFile(const QString& fileName);

    QByteArray sourceCode() const;

    bool isCompiled() const;
    QString log() const;

    GLuint shaderId() const;

    static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = 0);

private:
    friend class QOpenGLShaderProgram;

    Q_DISABLE_COPY(QOpenGLShader)
    Q_DECLARE_PRIVATE(QOpenGLShader)
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLShader::ShaderType)

class QOpenGLShaderProgramPrivate;

class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject
{
    Q_OBJECT
public:
    explicit QOpenGLShaderProgram(QObject *parent = 0);
    virtual ~QOpenGLShaderProgram();

    bool addShader(QOpenGLShader *shader);
    void removeShader(QOpenGLShader *shader);
    QList<QOpenGLShader *> shaders() const;

    bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source);
    bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray& source);
    bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString& source);
    bool addShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString& fileName);

    void removeAllShaders();

    virtual bool link();
    bool isLinked() const;
    QString log() const;

    bool bind();
    void release();

    bool create();

    GLuint programId() const;

    int maxGeometryOutputVertices() const;

    void setPatchVertexCount(int count);
    int patchVertexCount() const;

    void setDefaultOuterTessellationLevels(const QVector<float> &levels);
    QVector<float> defaultOuterTessellationLevels() const;

    void setDefaultInnerTessellationLevels(const QVector<float> &levels);
    QVector<float> defaultInnerTessellationLevels() const;

    void bindAttributeLocation(const char *name, int location);
    void bindAttributeLocation(const QByteArray& name, int location);
    void bindAttributeLocation(const QString& name, int location);

    int attributeLocation(const char *name) const;
    int attributeLocation(const QByteArray& name) const;
    int attributeLocation(const QString& name) const;

    void setAttributeValue(int location, GLfloat value);
    void setAttributeValue(int location, GLfloat x, GLfloat y);
    void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z);
    void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setAttributeValue(int location, const QVector2D& value);
    void setAttributeValue(int location, const QVector3D& value);
    void setAttributeValue(int location, const QVector4D& value);
    void setAttributeValue(int location, const QColor& value);
    void setAttributeValue(int location, const GLfloat *values, int columns, int rows);

    void setAttributeValue(const char *name, GLfloat value);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
    void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setAttributeValue(const char *name, const QVector2D& value);
    void setAttributeValue(const char *name, const QVector3D& value);
    void setAttributeValue(const char *name, const QVector4D& value);
    void setAttributeValue(const char *name, const QColor& value);
    void setAttributeValue(const char *name, const GLfloat *values, int columns, int rows);

    void setAttributeArray
        (int location, const GLfloat *values, int tupleSize, int stride = 0);
    void setAttributeArray
        (int location, const QVector2D *values, int stride = 0);
    void setAttributeArray
        (int location, const QVector3D *values, int stride = 0);
    void setAttributeArray
        (int location, const QVector4D *values, int stride = 0);
    void setAttributeArray
        (int location, GLenum type, const void *values, int tupleSize, int stride = 0);
    void setAttributeArray
        (const char *name, const GLfloat *values, int tupleSize, int stride = 0);
    void setAttributeArray
        (const char *name, const QVector2D *values, int stride = 0);
    void setAttributeArray
        (const char *name, const QVector3D *values, int stride = 0);
    void setAttributeArray
        (const char *name, const QVector4D *values, int stride = 0);
    void setAttributeArray
        (const char *name, GLenum type, const void *values, int tupleSize, int stride = 0);

    void setAttributeBuffer
        (int location, GLenum type, int offset, int tupleSize, int stride = 0);
    void setAttributeBuffer
        (const char *name, GLenum type, int offset, int tupleSize, int stride = 0);

    void enableAttributeArray(int location);
    void enableAttributeArray(const char *name);
    void disableAttributeArray(int location);
    void disableAttributeArray(const char *name);

    int uniformLocation(const char *name) const;
    int uniformLocation(const QByteArray& name) const;
    int uniformLocation(const QString& name) const;

    void setUniformValue(int location, GLfloat value);
    void setUniformValue(int location, GLint value);
    void setUniformValue(int location, GLuint value);
    void setUniformValue(int location, GLfloat x, GLfloat y);
    void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z);
    void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setUniformValue(int location, const QVector2D& value);
    void setUniformValue(int location, const QVector3D& value);
    void setUniformValue(int location, const QVector4D& value);
    void setUniformValue(int location, const QColor& color);
    void setUniformValue(int location, const QPoint& point);
    void setUniformValue(int location, const QPointF& point);
    void setUniformValue(int location, const QSize& size);
    void setUniformValue(int location, const QSizeF& size);
    void setUniformValue(int location, const QMatrix2x2& value);
    void setUniformValue(int location, const QMatrix2x3& value);
    void setUniformValue(int location, const QMatrix2x4& value);
    void setUniformValue(int location, const QMatrix3x2& value);
    void setUniformValue(int location, const QMatrix3x3& value);
    void setUniformValue(int location, const QMatrix3x4& value);
    void setUniformValue(int location, const QMatrix4x2& value);
    void setUniformValue(int location, const QMatrix4x3& value);
    void setUniformValue(int location, const QMatrix4x4& value);
    void setUniformValue(int location, const GLfloat value[2][2]);
    void setUniformValue(int location, const GLfloat value[3][3]);
    void setUniformValue(int location, const GLfloat value[4][4]);
    void setUniformValue(int location, const QTransform& value);

    void setUniformValue(const char *name, GLfloat value);
    void setUniformValue(const char *name, GLint value);
    void setUniformValue(const char *name, GLuint value);
    void setUniformValue(const char *name, GLfloat x, GLfloat y);
    void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
    void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setUniformValue(const char *name, const QVector2D& value);
    void setUniformValue(const char *name, const QVector3D& value);
    void setUniformValue(const char *name, const QVector4D& value);
    void setUniformValue(const char *name, const QColor& color);
    void setUniformValue(const char *name, const QPoint& point);
    void setUniformValue(const char *name, const QPointF& point);
    void setUniformValue(const char *name, const QSize& size);
    void setUniformValue(const char *name, const QSizeF& size);
    void setUniformValue(const char *name, const QMatrix2x2& value);
    void setUniformValue(const char *name, const QMatrix2x3& value);
    void setUniformValue(const char *name, const QMatrix2x4& value);
    void setUniformValue(const char *name, const QMatrix3x2& value);
    void setUniformValue(const char *name, const QMatrix3x3& value);
    void setUniformValue(const char *name, const QMatrix3x4& value);
    void setUniformValue(const char *name, const QMatrix4x2& value);
    void setUniformValue(const char *name, const QMatrix4x3& value);
    void setUniformValue(const char *name, const QMatrix4x4& value);
    void setUniformValue(const char *name, const GLfloat value[2][2]);
    void setUniformValue(const char *name, const GLfloat value[3][3]);
    void setUniformValue(const char *name, const GLfloat value[4][4]);
    void setUniformValue(const char *name, const QTransform& value);

    void setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize);
    void setUniformValueArray(int location, const GLint *values, int count);
    void setUniformValueArray(int location, const GLuint *values, int count);
    void setUniformValueArray(int location, const QVector2D *values, int count);
    void setUniformValueArray(int location, const QVector3D *values, int count);
    void setUniformValueArray(int location, const QVector4D *values, int count);
    void setUniformValueArray(int location, const QMatrix2x2 *values, int count);
    void setUniformValueArray(int location, const QMatrix2x3 *values, int count);
    void setUniformValueArray(int location, const QMatrix2x4 *values, int count);
    void setUniformValueArray(int location, const QMatrix3x2 *values, int count);
    void setUniformValueArray(int location, const QMatrix3x3 *values, int count);
    void setUniformValueArray(int location, const QMatrix3x4 *values, int count);
    void setUniformValueArray(int location, const QMatrix4x2 *values, int count);
    void setUniformValueArray(int location, const QMatrix4x3 *values, int count);
    void setUniformValueArray(int location, const QMatrix4x4 *values, int count);

    void setUniformValueArray(const char *name, const GLfloat *values, int count, int tupleSize);
    void setUniformValueArray(const char *name, const GLint *values, int count);
    void setUniformValueArray(const char *name, const GLuint *values, int count);
    void setUniformValueArray(const char *name, const QVector2D *values, int count);
    void setUniformValueArray(const char *name, const QVector3D *values, int count);
    void setUniformValueArray(const char *name, const QVector4D *values, int count);
    void setUniformValueArray(const char *name, const QMatrix2x2 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix2x3 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix2x4 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix3x2 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix3x3 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix3x4 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix4x2 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count);
    void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count);

    static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0);

private Q_SLOTS:
    void shaderDestroyed();

private:
    Q_DISABLE_COPY(QOpenGLShaderProgram)
    Q_DECLARE_PRIVATE(QOpenGLShaderProgram)

    bool init();
};

QT_END_NAMESPACE

#endif // QT_NO_OPENGL

#endif


text:
@echo off
@if not "%ECHO%" == ""  echo %ECHO%
@if "%OS%" == "Windows_NT" setlocal

if "%OS%" == "Windows_NT" (
  set "DIRNAME=%~dp0%"
) else (
  set DIRNAME=.\
)

pushd "%DIRNAME%.."
set "RESOLVED_JBOSS_HOME=%CD%"
popd

if "x%JBOSS_HOME%" == "x" (
  set "JBOSS_HOME=%RESOLVED_JBOSS_HOME%"
)

pushd "%JBOSS_HOME%"
set "SANITIZED_JBOSS_HOME=%CD%"
popd

if /i "%RESOLVED_JBOSS_HOME%" NEQ "%SANITIZED_JBOSS_HOME%" (
   echo.
   echo   WARNING: The JBOSS_HOME ^("%SANITIZED_JBOSS_HOME%"^) that this script uses points to a different installation than the one that this script resides in ^("%RESOLVED_JBOSS_HOME%"^). Unpredictable results may occur.
   echo.
   echo       JBOSS_HOME: "%JBOSS_HOME%"
   echo.
)

if "x%JAVA_HOME%" == "x" (
  set  JAVA=java
  echo JAVA_HOME is not set. Unexpected results may occur.
  echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
) else (
  set "JAVA=%JAVA_HOME%\bin\java"
)

if exist "%JBOSS_HOME%\jboss-modules.jar" (
    set "RUNJAR=%JBOSS_HOME%\jboss-modules.jar"
) else (
  echo Could not locate "%JBOSS_HOME%\jboss-modules.jar".
  echo Please check that you are in the bin directory when running this script.
  goto END
)

if "x%JBOSS_MODULEPATH%" == "x" (
  set "JBOSS_MODULEPATH=%JBOSS_HOME%\modules"
)

set "FUSEPATCH_OPTS=%TMP%\fusepatchopts.txt"
echo %JAVA_OPTS% > %FUSEPATCH_OPTS%
findstr /m "logging.configuration" %FUSEPATCH_OPTS%
if %errorlevel%==0 (
"%JAVA%" %JAVA_OPTS% ^
    -jar "%JBOSS_HOME%\jboss-modules.jar" ^
    -mp "%JBOSS_MODULEPATH%" ^
     org.wildfly.extras.patch ^
     %*
) else (
"%JAVA%" %JAVA_OPTS% ^
    -Dlogging.configuration="file:%JBOSS_HOME%\bin\fusepatch-logging.properties" ^
    -jar "%JBOSS_HOME%\jboss-modules.jar" ^
    -mp "%JBOSS_MODULEPATH%" ^
     org.wildfly.extras.patch ^
     %*
)

del /F %FUSEPATCH_OPTS%

redpajama_set_name: RedPajamaGithub


text:
(function () {
    'use strict';
    angular.module('common.services',['ngResource']);
}());


text:
module ActiveSupport
  module ForkTracker # :nodoc:
    module CoreExt
      def fork(*)
        if block_given?
          super do
            ForkTracker.check!
            yield
          end
        else
          unless pid = super
            ForkTracker.check!
          end
          pid
        end
      end
    end

    module CoreExtPrivate
      include CoreExt

      private
        def fork(*)
          super
        end
    end

    @pid = Process.pid
    @callbacks = []

    class << self
      def check!
        if @pid != Process.pid
          @callbacks.each(&:call)
          @pid = Process.pid
        end
      end

      def hook!
        if Process.respond_to?(:fork)
          ::Object.prepend(CoreExtPrivate)
          ::Kernel.prepend(CoreExtPrivate)
          ::Kernel.singleton_class.prepend(CoreExt)
          ::Process.singleton_class.prepend(CoreExt)
        end
      end

      def after_fork(&block)
        @callbacks << block
        block
      end

      def unregister(callback)
        @callbacks.delete(callback)
      end
    end
  end
end

ActiveSupport::ForkTracker.hook!


text:
import csv

from eva_cttv_pipeline.trait_mapping.trait import Trait

def output_trait_mapping(trait: Trait, mapping_writer: csv.writer):
    """
    Write any finished ontology mappings for a trait to a csv file writer.

    :param trait: A trait with finished ontology mappings in finished_mapping_set
    :param mapping_writer: A csv.writer to write the finished mappings
    """
    for ontology_entry in trait.finished_mapping_set:
        mapping_writer.writerow([trait.name, ontology_entry.uri, ontology_entry.label])

def get_mappings_for_curation(result_list) -> list:
    """Sorted in reverse so the highest ranked oxo mappings are shown first"""
    curation_mapping_list = []
    for result in result_list:
        for mapping in result.mapping_list:
            if (mapping.in_efo and mapping.is_current) or (not mapping.in_efo):
                curation_mapping_list.append(mapping)
    curation_mapping_list.sort(reverse=True)
    return curation_mapping_list

def output_for_curation(trait: Trait, curation_writer: csv.writer):
    """
    Write any non-finished Zooma or OxO mappings of a trait to a file for manual curation.
    Also outputs traits without any ontology mappings.

    :param trait: A Trait with no finished ontology mappings in finished_mapping_set
    :param curation_writer: A csv.writer to write non-finished ontology mappings for manual curation
    """

    # Traits which are associated with NT expansion variants should be prioritised and curated even if the number of
    # records they are associated with is low. This is added to the "Notes" column.
    output_row = [trait.name, trait.frequency, 'NT expansion' if trait.associated_with_nt_expansion else '']

    zooma_mapping_list = get_mappings_for_curation(trait.zooma_result_list)

    for zooma_mapping in zooma_mapping_list:
        cell = [zooma_mapping.uri, zooma_mapping.ontology_label, str(zooma_mapping.confidence),
                zooma_mapping.source, 'EFO_CURRENT' if zooma_mapping.in_efo else 'NOT_CONTAINED']
        output_row.append("|".join(cell))

    oxo_mapping_list = get_mappings_for_curation(trait.oxo_result_list)

    for oxo_mapping in oxo_mapping_list:
        cell = [str(oxo_mapping.uri), oxo_mapping.ontology_label, str(oxo_mapping.distance),
                oxo_mapping.query_id, 'EFO_CURRENT' if oxo_mapping.in_efo else 'NOT_CONTAINED']
        output_row.append("|".join(cell))

    curation_writer.writerow(output_row)

def output_trait(trait: Trait, mapping_writer: csv.writer, curation_writer: csv.writer):
    """
    Output finished ontology mappings of a trait, or non-finished mappings (if any) for curation.

    :param trait: A trait which has been used to query Zooma and possibly OxO.
    :param mapping_writer: A csv.writer to write the finished mappings
    :param curation_writer: A csv.writer to write non-finished ontology mappings for manual curation
    """
    if trait.is_finished:
        output_trait_mapping(trait, mapping_writer)
    else:
        output_for_curation(trait, curation_writer)


text:
package com.gemstone.gemfire.internal.cache;

import java.util.*;
import junit.framework.TestCase;
import com.gemstone.gemfire.cache.*;
import com.gemstone.gemfire.distributed.DistributedSystem;

/**
 * Confirm that bug 34583 is fixed. Cause of bug is recursion is
 * entries iterator that causes stack overflow.
 * @author darrel
 */
public class Bug34583JUnitTest extends TestCase {

  public Bug34583JUnitTest() {
  }

  public void setup() {
  }

  public void tearDown() {
  }

  public void testBunchOfInvalidEntries() throws Exception {
    Properties props = new Properties();
    DistributedSystem ds = DistributedSystem.connect(props);
    try {
      AttributesFactory factory = new AttributesFactory();
      Cache cache = null;
      cache = CacheFactory.create(ds);

      Region r = cache.createRegion("testRegion", factory.create());
      final int ENTRY_COUNT = 25000;
      {
        for (int i=1; i <= ENTRY_COUNT; i++) {
          r.put("key" + i, "value" + i);
        }
      }
      { // make sure iterator works while values are valid
        Collection c = r.values();
        assertEquals(ENTRY_COUNT, c.size());
        Iterator it = c.iterator();
        int count = 0;
        while (it.hasNext()) {
          it.next();
          count++;
        }
        assertEquals(ENTRY_COUNT, count);
      }
      r.localInvalidateRegion();
      // now we expect iterator to stackOverflow if bug 34583
      {
        Collection c = r.values();
        assertEquals(0, c.size());
        Iterator it = c.iterator();
        int count = 0;
        while (it.hasNext()) {
          it.next();
          count++;
        }
        assertEquals(0, count);
      }
    } finally {
      ds.disconnect();
    }
  }
}


text:
package overview.util;

public class WeightedPair<A, B> {
	public float weight;
	public A first;
	public B second;
	public WeightedPair (A a, B b) { weight = 1; first = a; second = b; }
}


text:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace BrowseDotNet.Web.Models
{
    public class LoginViewModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [Display(Name = "Remember me?")]
        public bool RememberMe { get; set; }
    }

    public class RegisterViewModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }
}


text:
require File.expand_path(File.join(File.dirname(__FILE__), "..", "helper.rb"))

module Theta
	class TestSet < Test::Unit::TestCase
		def setup
			@interpreter = Interpreter.new
		end

		should "set value of existing variable" do
			@interpreter.run("
				(define a 1)
				(set! a 2)
			")
			assert_equal(2, @interpreter.current_environment.find(:a))
		end

		should "raise an error if variable not defined" do
			assert_raise(TypeError) { @interpreter.run("(set! a 2)") }
		end
	end
end


text:
The `makefiles` directory contains various Makefiles that include common targets
 used in Kyma components.

### Directory structure

The directory has the following structure:

  ```
  ├── docs                  # Documentation for Makefiles
  ├── docker.mk             # Makefile for Docker
  └── generic-make-go.mk    # Makefile for Go components and Dockerfiles
  ```


text:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace NodeService
{
    [ServiceContract(Namespace = "http://sevensigma.com.au/NodeService")]
    public interface IMappingToolService
    {
        [OperationContract]
        SoapNode CreateNewDomain(string domainName);

        [OperationContract]
        Guid CreateNewMap(Guid domainId, string mapName);

        [OperationContract]
        void InsertNodes(Guid domainId, Guid mapId, string siteUrl, byte[] userToken, Guid webId, Guid listId, int itemId);

        [OperationContract]
        SoapNode AddNode(Guid domainId, SoapNodeType nodeType, string originalId);

        [OperationContract]
        bool RenameNodeMetadata(Guid domainId, Guid soapNodeId, Guid soapRelationshipId, SoapDescriptorType soapDescriptorType, string originalMetadataName, string newMetadataName);

        [OperationContract]
        SoapNode PasteNodeClone(Guid domainId, Guid copiedNodeId);

        [OperationContract]
        DeleteResult DeleteNode(Guid domainId, Guid nodeId);

        [OperationContract]
        DeleteResult DeleteNodePromoteTransclusion(Guid domainId, Guid mapIdToDeleteFrom, Guid nodeIdToDelete);

        [OperationContract]
        DeleteResult DeleteNodeTransclusion(Guid domainId, Guid mapIdToDeleteFrom, Guid nodeIdToDelete);

        [OperationContract]
        DeleteResult DeleteRelationship(Guid domainId, Guid relationshipId);

        [OperationContract]
        DeleteResult DeleteMetadata(MetadataContext key);

        [OperationContract]
        [FaultContract(typeof(ConnectNodesFailureFault))]
        ConnectedNodesResult ConnectNodes(Guid domainId, Dictionary<SoapDescriptorType, Guid> nodes, SoapRelationshipType relationshipType, string originalId);

        [OperationContract]
        SoapNode UpdateNodeMetadata(Guid domainId, Guid soapNodeId, Guid soapRelationshipId, SoapDescriptorType soapDescriptorType, string metadataName, string metadataValue, SoapMetadataType soapMetadataType);

        [OperationContract]
        Dictionary<string, Guid> GetDomainNodeIds();

        [OperationContract]
        Guid GetDomainNodeId(Guid domainId);

        [OperationContract]
        RelatedNodesSearchResult GetDomainMapNodes(Guid domainId);

        [OperationContract(Name="GetDomainMapNodesPaged")]
        RelatedNodesSearchResult GetDomainMapNodes(Guid domainId, int page, int pageSize);

        [OperationContract]
        List<SoapTypeElement> GetAllSoapTypes();

        [OperationContract]
        Dictionary<Guid, SoapNode> GetAllNodes(Guid domainId);

        [OperationContract]
        Dictionary<Guid, SoapNode> GetNodes(Dictionary<Guid, Guid> nodeIds);

        [OperationContract]
        RelatedNodesSearchResult GetRelatedNodes(Guid domainId, Guid nodeId, int depth);

        [OperationContract]
        RelatedNodesSearchResult GetMapsNodes(Guid domainId, Guid mapNodeId);

        [OperationContract]
        Guid GetContainerMapNodeId(Guid domainId, Guid nodeId);

        //[OperationContract]
        //RelatedNodesSearchResult GetNodesWithConditions(Guid domainId, Guid nodeId, int maxDepth, List<Condition> conditions);

        [OperationContract]
        RelatedNodesSearchResult GetNodesXmlQuery(string graphQueryXml);
    }

    [DataContract]
    public class RelatedNodesSearchResult
    {
        public RelatedNodesSearchResult()
        {
        }

        public RelatedNodesSearchResult(Guid nodeId, IEnumerable<Node> nodes)
        {
            Nodes = new Dictionary<Guid, SoapNode>();

            foreach (Node relatedNode in nodes)
            {
                SoapNode soapNode = relatedNode.ToSoapObject();

                if (soapNode.NodeType.Name != "DomainNode")
                {
                    Nodes.Add(soapNode.Id, soapNode);
                }
            }
        }

        [DataMember]
        public Guid SearchedNode
        {
            get;
            set;
        }

        [DataMember]
        public Dictionary<Guid, SoapNode> Nodes
        {
            get;
            set;
        }
    }

    [DataContract]
    public class ConnectedNodesResult
    {
        [DataMember]
        public SoapRelationship Relationship
        {
            get;
            set;
        }

        [DataMember]
        public Dictionary<Guid, SoapNode> Nodes
        {
            get;
            set;
        }
    }

    [DataContract]
    public class DeleteResult
    {
        [DataMember]
        public bool DeleteSuccessful
        {
            get;
            set;
        }

        [DataMember]
        public Guid DeletedId
        {
            get;
            set;
        }
    }

    [DataContract]
    public class ConnectNodesFailureFault { }

    [DataContract]
    public class MetadataContext
    {
        [DataMember]
        public string MetadataName
        {
            get;
            set;
        }

        [DataMember]
        public Guid? NodeUid
        {
            get;
            set;
        }

        [DataMember()]
        public Guid? RelationshipUid
        {
            get;
            set;
        }

        [DataMember]
        public Guid? DescriptorTypeUid
        {
            get;
            set;
        }
    }
}


text:
"""Base proxy module used to create compatible consoles
for OpenStack Nova."""

import os
import sys

from oslo_config import cfg
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr

from nova.console import websocketproxy
from nova import version

CONF = cfg.CONF
CONF.import_opt('record', 'nova.cmd.novnc')
CONF.import_opt('daemon', 'nova.cmd.novnc')
CONF.import_opt('ssl_only', 'nova.cmd.novnc')
CONF.import_opt('source_is_ipv6', 'nova.cmd.novnc')
CONF.import_opt('cert', 'nova.cmd.novnc')
CONF.import_opt('key', 'nova.cmd.novnc')
CONF.import_opt('web', 'nova.cmd.novnc')

def exit_with_error(msg, errno=-1):
    sys.stderr.write(msg + '\n')
    sys.exit(errno)

def proxy(host, port):

    if CONF.ssl_only and not os.path.exists(CONF.cert):
        exit_with_error("SSL only and %s not found" % CONF.cert)

    # Check to see if tty html/js/css files are present
    if CONF.web and not os.path.exists(CONF.web):
        exit_with_error("Can not find html/js files at %s." % CONF.web)

    logging.setup(CONF, "nova")

    gmr.TextGuruMeditation.setup_autorun(version)

    # Create and start the NovaWebSockets proxy
    websocketproxy.NovaWebSocketProxy(
        listen_host=host,
        listen_port=port,
        source_is_ipv6=CONF.source_is_ipv6,
        verbose=CONF.verbose,
        cert=CONF.cert,
        key=CONF.key,
        ssl_only=CONF.ssl_only,
        daemon=CONF.daemon,
        record=CONF.record,
        traffic=CONF.verbose and not CONF.daemon,
        web=CONF.web,
        file_only=True,
        RequestHandlerClass=websocketproxy.NovaProxyRequestHandler
    ).start_server()


text:
title: Allow end-users to add items to DropDownListEditor
page_title: Allow end-users to add items to DropDownListEditor - RadGridView
description: Allow end-users to add items to DropDownListEditor by directly typing the value at run-time.
slug: winforms/gridview/editors/how-to/allow-end-users-to-add-items-to-dropdownlisteditor
tags: allow,end-users,to,add,items,to,dropdownlisteditor
published: True
position: 0
previous_url: gridview-editors-howto-allow-end-users-to-add-items-to-dropdownlisteditor
---

# Allow end-users to add items to DropDownListEditor

The purpose of this article is to demonstrate how you can implement a scenario in which the end-users are able not only to choose from a predefined list of values represented by `RadDropDownListEditor`, but to add their own values to that list.

In order to achieve this goal, you need to add the value typed by the end-user to the datasource of the GridViewComboBoxColumn. This will allow the end-user to use the typed value in his/her further operations with the RadComboBoxEditor of the GridViewComboBoxColumn.

## Implementing a custom RadDropDownListEditor

For the purposes for the example, we will build our custom RadComboBoxEditor in the context of a sample scenario where RadGridView is bound to the Products table of the popular Northwind database and where we have a GridViewComboBoxColumn bound to the Categories table of the same database.

Let's assume that:

* The name of the form on which the RadGridView instance lies is AllowEndUsersAddItemsComboBoxEditor.

* The appropriate instances of the `DataSet`, `BindingSources` and `TableAdapters` are created.

* RadGridView is bound to the binding source of the `Products` table.

* The __AutoIncrementStep__ of the __CategoryID__ field in the Category table is set to 1.

1\. First, we need to create a __GridViewComboBoxColumn__ that will later display our custom editor. This column should be bound to the binding source of the __Categories__ table. For additional information about __GridViewComboBoxColumn__ and its specifics, you can read [this article]({%slug winforms/gridview/columns/column-types/gridviewcomboboxcolumn%}). The following snippet shows how you can add the column:

{{source=..\SamplesCS\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.cs region=comboColumn}}
{{source=..\SamplesVB\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.vb region=comboColumn}}

````C#
GridViewComboBoxColumn categoriesColumn = new GridViewComboBoxColumn();
categoriesColumn.DisplayMember = "CategoryName";
categoriesColumn.ValueMember = "CategoryID";
categoriesColumn.FieldName = "CategoryID";
categoriesColumn.HeaderText = "Category";
categoriesColumn.DataSource = this.categoriesBindingSource;
categoriesColumn.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown;
categoriesColumn.Width = 150;
this.radGridView1.Columns.Insert(4, categoriesColumn);

````
````VB.NET
Dim categoriesColumn As New GridViewComboBoxColumn()
categoriesColumn.DisplayMember = "CategoryName"
categoriesColumn.ValueMember = "CategoryID"
categoriesColumn.FieldName = "CategoryID"
categoriesColumn.HeaderText = "Category"
categoriesColumn.DataSource = Me.CategoriesBindingSource
categoriesColumn.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown
categoriesColumn.Width = 150
Me.RadGridView1.Columns.Insert(4, categoriesColumn)

````

{{endregion}}

2\. Since we will need to get the instances of the DataSet and the TableAdapters of the Category table outside the context of the main form, let's expose two properties in the body of the form:

{{source=..\SamplesCS\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.cs region=properties}}
{{source=..\SamplesVB\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.vb region=properties}}

````C#
public NwindDataSet DataSet
{
    get
    {
        return this.nwindDataSet;
    }
}
public CategoriesTableAdapter CategoriesTA
{
    get
    {
        return this.categoriesTableAdapter;
    }
}

````
````VB.NET
Public ReadOnly Property DataSet() As NwindDataSet
    Get
        Return Me.NwindDataSet
    End Get
End Property
Public ReadOnly Property CategoriesTA() As CategoriesTableAdapter
    Get
        Return Me.CategoriesTableAdapter
    End Get
End Property

````

{{endregion}}

3\. Now it is time to create our custom editor. For the purposes of our goal, we need to create a class that derives from __RadDropDownListEditor__ and override the __EndEdit__ method.

4\. In the __EndEdit__ method, we first need to check whether the value typed by the user exists or not in the datasource of the GridViewComboBoxColumn. If it exists, we should terminate the execution of the EndEdit method:

{{source=..\SamplesCS\GridView\Editors\How-To\CustomDropDownEditor.cs region=checkValue}}
{{source=..\SamplesVB\GridView\Editors\How-To\CustomDropDownEditor.vb region=checkValue}}

````C#
GridComboBoxCellElement cellElement = this.OwnerElement as GridComboBoxCellElement;
RadGridView grid = cellElement.GridControl;
AllowEnd_usersAddItemsComboBoxEditor f = (AllowEnd_usersAddItemsComboBoxEditor)grid.FindForm();
// Checking if the typed value exists in the datasource of the column.
NwindDataSet.CategoriesDataTable dt = f.DataSet.Categories;
for (int i = 0; i < dt.Rows.Count; i++)
{
    if (dt.Rows[i]["CategoryName"].ToString() == ((RadDropDownListEditorElement)this.EditorElement).Text)
    {
        return base.EndEdit();
    }
}

````
````VB.NET
Dim cellElement As GridComboBoxCellElement = TryCast(Me.OwnerElement, GridComboBoxCellElement)
Dim grid As RadGridView = cellElement.GridControl
Dim f As AllowEnd_usersAddItemsComboBoxEditor = CType(grid.FindForm(), AllowEnd_usersAddItemsComboBoxEditor)
' Checking if the typed value exists in the datasource of the column.
Dim dt As NwindDataSet.CategoriesDataTable = f.DataSet.Categories
For i As Integer = 0 To dt.Rows.Count - 1
    If dt.Rows(i)("CategoryName").ToString() = (CType(Me.EditorElement, RadDropDownListEditorElement)).Text Then
        Return MyBase.EndEdit()
    End If
Next i

````

{{endregion}}

5\. If the typed value is not found in the datasource, we continue with the execution of our code in the EndEdit method. Since the typed value does not exist, we should add it to the data source. Here you can add it to the database as well:

{{source=..\SamplesCS\GridView\Editors\How-To\CustomDropDownEditor.cs region=addValue}}
{{source=..\SamplesVB\GridView\Editors\How-To\CustomDropDownEditor.vb region=addValue}}

````C#
// An example of what we can do when we enter the custom text.
// In this case we are adding a new data row in the underlying datasource of
// the combobox column and then in the CellEndEdit we are setting
// the ID value of the newly created row to RadGridView.
NwindDataSet.CategoriesRow newCategoriesRow = dt.NewCategoriesRow();
newCategoriesRow.CategoryName = ((RadDropDownListEditorElement)this.EditorElement).Text;
f.DataSet.Categories.Rows.Add(newCategoriesRow);
// Updating the database. You can do it here at another place
// you find suitable for this purpose, for example, on FormClosing.
f.CategoriesTA.Update(f.DataSet.Categories);
cellElement.Tag = newCategoriesRow.CategoryID;
return base.EndEdit();

````
````VB.NET
' An example of what we can do when we enter the custom text.
' In this case we are adding a new data row in the underlying datasource of
' the combobox column and then in the CellEndEdit we are setting
' the ID value of the newly created row to RadGridView.
Dim newCategoriesRow As NwindDataSet.CategoriesRow = dt.NewCategoriesRow()
newCategoriesRow.CategoryName = (CType(Me.EditorElement, RadDropDownListEditorElement)).Text
f.DataSet.Categories.Rows.Add(newCategoriesRow)
' Updating the database. You can do it here at another place
' you find suitable for this purpose, for example, on FormClosing.
f.CategoriesTA.Update(f.DataSet.Categories)
cellElement.Tag = newCategoriesRow.CategoryID
Return MyBase.EndEdit()

````

{{endregion}}

6\. The Tag value saved in the previous code snippet is used in the CellEndEdit event handler of RadGridView. It helps us to set the ID of the newly created record to the cell that the end-user has just edited. As a consequence, the correct string value is displayed in the cell of RadGridView.

{{source=..\SamplesCS\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.cs region=cellEndEdit}}
{{source=..\SamplesVB\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.vb region=cellEndEdit}}

````C#
void radGridView1_CellEndEdit(object sender, GridViewCellEventArgs e)
{
    if (this.radGridView1.CurrentCell.Tag != null)
    {
        this.radGridView1.CurrentCell.Value = this.radGridView1.CurrentCell.Tag;
        this.radGridView1.CurrentCell.Tag = null;
    }
}

````
````VB.NET
Private Sub radGridView1_CellEndEdit(ByVal sender As Object, ByVal e As GridViewCellEventArgs)
    If Me.RadGridView1.CurrentCell.Tag IsNot Nothing Then
        Me.RadGridView1.CurrentCell.Value = Me.RadGridView1.CurrentCell.Tag
        Me.RadGridView1.CurrentCell.Tag = Nothing
    End If
End Sub

````

{{endregion}}

7\. Finally, we need to attach the custom editor to RadGridView. This is done in the EditorRequired event handler. Let's assume that the class of our custom editor is called CustomDropDownEditor:

{{source=..\SamplesCS\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.cs region=editorRequired}}
{{source=..\SamplesVB\GridView\Editors\How-To\AllowEnd-usersAddItemsComboBoxEditor.vb region=editorRequired}}

````C#
void radGridView1_EditorRequired(object sender, EditorRequiredEventArgs e)
{
    if (e.EditorType == typeof(RadDropDownListEditor))
    {
        e.Editor = new CustomDropDownEditor();
    }
}

````
````VB.NET
Private Sub radGridView1_EditorRequired(ByVal sender As Object, ByVal e As EditorRequiredEventArgs)
    If e.EditorType Is GetType(RadDropDownListEditor) Then
        e.Editor = New CustomDropDownEditor()
    End If
End Sub

````

{{endregion}}

## End-user experience

So, how should this implementation work? Let's say that we have a list of categories available at each product in RadGridView. However, we decide that this list does not cover the range of products, so we have to add the category 'SpaceFood'. We should just start editing the appropriate cell in the GridViewComboBoxColumn and type 'SpaceFood'. Then we can press Enter or we have press Tab to go to the next cell and the 'SpaceFood' value will be added. As you can see in the screenshot below, the record 'SpaceFood' receives a new CategoryID 9, which is saved in the appropriate RadGridView cell under the CategoryID column:

![gridview-editors-howto-allow-end-users-to-add-items-to-dropdownlisteditor 001](images/gridview-editors-howto-allow-end-users-to-add-items-to-dropdownlisteditor001.png)

A complete solution which demonstrate the approach in this article is available in our [SDK repository](https://docs.telerik.com/devtools/winforms/controls/gridview/rows/how-to/autosize-entire-row).

# See Also
* [Change the Active Editor Depending on the Cell Value Type.]({%slug winforms/gridview/editors/how-to/change-the-active-editor-depending-on-the-cell-value-type.%})

* [User-Defined Values in RadMultiColumnComboBox]({%slug user-defined-values-in-multicolumncombobox%})


text:
{{ "" | safeHTML }}

{{ with .Site.Params.about.title }}{{.}}{{ end }}

Education

Bachelor of Science University of California San Diego

            Bioinformatics with spec in Computer Science

Publications

1. Nadejda Beliakova-Bethell, Jin X Zhang, Akul Singhania, Vivian Lee, Valeri H Terry, Douglas D Richman, Celsa A Spina, and Christopher H Woelk. Suberoylanilide hydroxamic acid induces limited changes in the transcriptome of primary CD4+ T cells. AIDS 27, 29-37. 2013.

2. Jin X Zhang, Christopher H Woelk, Lorraine Walls, Suganya Viriyakosol, Akul Singhania, Theo N Kirkland, and Joshua Fierer. Factors regulated by interferon gamma and hypoxia-inducible factor 1A contribute to responses that protect mice from Coccidioides immitis infection. BMC Microbiology 12:218. 2012.

3. Josué Pérez-Santiago, Rebeca Diez-Alarcia, Luis F Callado, Jin X Zhang, Gursharan Chana, Cory H White, Stephen J Glatt, Ming T Tsuang, Ian P Everall, J Javier Meana, and Christopher H Woelk. A combined analysis of microarray gene expression studies of the human prefrontal cortex identifies genes implicated in schizophrenia. Journal of Psychiatric Research 46, 1464-74. 2012.

4. Brett N Bowman, Paul R McAdam, Sandro Vivona, Jin X Zhang, Tiffany Luong, Richard K Belew, Harpal Sahota, Donald Guiney, Faramarz Valafar, Joshua Fierer, and Christopher H Woelk. Improving reverse vaccinology with a machine learning approach. Vaccine 29, 8156-64. 2011.

                     {{ with .Site.Params.about.button.text }}{{ . }}{{ end }}


text:
#ifndef GrDawnProgramBuilder_DEFINED
#define GrDawnProgramBuilder_DEFINED

#include "src/gpu/ganesh/GrSPIRVUniformHandler.h"
#include "src/gpu/ganesh/GrSPIRVVaryingHandler.h"
#include "src/gpu/ganesh/dawn/GrDawnProgramDataManager.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "webgpu/webgpu_cpp.h"
#include "src/gpu/ganesh/glsl/GrGLSLProgramBuilder.h"

#include <vector>

class GrPipeline;

namespace SkSL { class Compiler; }

struct GrDawnProgram : public SkRefCnt {
    struct RenderTargetState {
        SkISize         fRenderTargetSize;
        GrSurfaceOrigin fRenderTargetOrigin;

        RenderTargetState() { this->invalidate(); }
        void invalidate() {
            fRenderTargetSize.fWidth = -1;
            fRenderTargetSize.fHeight = -1;
            fRenderTargetOrigin = (GrSurfaceOrigin) -1;
        }
    };
    typedef GrGLSLBuiltinUniformHandles BuiltinUniformHandles;
    GrDawnProgram(const GrSPIRVUniformHandler::UniformInfoArray& uniforms,
                  uint32_t uniformBufferSize)
      : fDataManager(uniforms, uniformBufferSize) {
    }
    std::unique_ptr<GrGeometryProcessor::ProgramImpl> fGPImpl;
    std::unique_ptr<GrXferProcessor::ProgramImpl> fXPImpl;
    std::vector<std::unique_ptr<GrFragmentProcessor::ProgramImpl>> fFPImpls;
    std::vector<wgpu::BindGroupLayout> fBindGroupLayouts;
    wgpu::RenderPipeline fRenderPipeline;
    GrDawnProgramDataManager fDataManager;
    RenderTargetState fRenderTargetState;
    BuiltinUniformHandles fBuiltinUniformHandles;

    void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
    wgpu::BindGroup setUniformData(GrDawnGpu*, const GrRenderTarget*, const GrProgramInfo&);
    wgpu::BindGroup setTextures(GrDawnGpu*,
                                const GrGeometryProcessor&,
                                const GrPipeline&,
                                const GrSurfaceProxy* const geomProcTextures[]);
};

class GrDawnProgramBuilder : public GrGLSLProgramBuilder {
public:
    static sk_sp<GrDawnProgram> Build(GrDawnGpu*,
                                      GrRenderTarget*,
                                      const GrProgramInfo&,
                                      wgpu::TextureFormat colorFormat,
                                      bool hasDepthStencil,
                                      wgpu::TextureFormat depthStencilFormat,
                                      GrProgramDesc*);
    const GrCaps* caps() const override;
    GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; }
    const GrGLSLUniformHandler* uniformHandler() const override { return &fUniformHandler; }
    GrGLSLVaryingHandler* varyingHandler() override { return &fVaryingHandler; }

    GrDawnGpu* gpu() const { return fGpu; }

    SkSL::Compiler* shaderCompiler() const override;

private:
    GrDawnProgramBuilder(GrDawnGpu*,
                         const GrProgramInfo&,
                         GrProgramDesc*);
    wgpu::ShaderModule createShaderModule(const GrGLSLShaderBuilder&, SkSL::ProgramKind,
                                          bool flipY, SkSL::Program::Inputs* inputs);
    GrDawnGpu*             fGpu;
    GrSPIRVVaryingHandler   fVaryingHandler;
    GrSPIRVUniformHandler   fUniformHandler;

    using INHERITED = GrGLSLProgramBuilder;
};
#endif


text:
var path = require('path');
var sassTrue = require('sass-true');

var sassFile = path.join(__dirname, '/tests.scss');
sassTrue.runSass({
  file: sassFile,
  includePaths: ['node_modules'],
}, describe, it);


text:
<?php
return [
    'providers' => [
        'Phpna\Themes\Providers\ThemeServiceProvider'
    ],
    'facades' => ['Theme' => 'themes']
];


text:
package com.consol.citrus.integration;

import com.consol.citrus.annotations.CitrusXmlTest;
import com.consol.citrus.testng.spring.TestNGCitrusSpringSupport;
import org.testng.annotations.Test;

/**
 * @author Christoph Deppisch
 */
public class ScriptMessageValidationIT extends TestNGCitrusSpringSupport {
    @Test
    @CitrusXmlTest
    public void ScriptMessageValidationIT() {}
}


text: R CMD REMOVE --library=$PREFIX/lib/R/library/ imcdatasets


text:
using System.Reflection;
using UnityEngine;

namespace UnityEditor.ShaderGraph
{
    [Title("Artistic", "Mask", "Color Mask")]
    class ColorMaskNode : CodeFunctionNode
    {
        public ColorMaskNode()
        {
            name = "Color Mask";
        }

        protected override MethodInfo GetFunctionToConvert()
        {
            return GetType().GetMethod("Unity_ColorMask", BindingFlags.Static | BindingFlags.NonPublic);
        }

        static string Unity_ColorMask(
            [Slot(0, Binding.None)] Vector3 In,
            [Slot(1, Binding.None)] ColorRGB MaskColor,
            [Slot(2, Binding.None)] Vector1 Range,
            [Slot(4, Binding.None)] Vector1 Fuzziness,
            [Slot(3, Binding.None)] out Vector1 Out)
        {
            return
                @"
{
    {precision} Distance = distance(MaskColor, In);
    Out = saturate(1 - (Distance - Range) / max(Fuzziness, 1e-5));
}";
        }
    }
}


text:
class Player < Spaceship
  attr_reader :score

  def collide
    Sound.instance.play(:beep)
    @score += 1
  end
end


text:
<?php
declare(strict_types=1);

namespace WyriHaximus\Travis\Resource\Async;

use WyriHaximus\Travis\Resource\RepositoryKey as BaseRepositoryKey;

class RepositoryKey extends BaseRepositoryKey
{
    public function refresh() : RepositoryKey
    {
        return $this->wait($this->callAsync('refresh'));
    }
}


text:
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor
from twisted.protocols.basic import LineReceiver
from twisted.conch.telnet import TelnetProtocol
from twisted.internet import stdio

class StdinProtocol(LineReceiver):
  from os import linesep as delimiter

  def __init__(self, network):
    self.network = network

  def write(self, text):
    self.transport.write('\007' + text)

  def print_prompt(self):
    self.write('#> ')

  def connectionMade(self):
    self.print_prompt()

  def lineReceived(self, line):
    self.network.transport.write(line)
    self.network.transport.write('\r\n')

    self.print_prompt()

class VikiProtocol(LineReceiver, TelnetProtocol):
  def connectionMade(self):
    self.stdin = StdinProtocol(self)
    stdio.StandardIO(self.stdin)

  def lineReceived(self, line):
    self.stdin.write('\033[2;K' + line + '\r\n\r\n')
    self.stdin.print_prompt()

class VikiFactory(ClientFactory):
  def buildProtocol(self, addr):
    p = VikiProtocol()
    p.factory = self
    return p

def main():
  reactor.connectTCP("localhost", 8123, VikiFactory())
  reactor.run()

if __name__ == '__main__':
  main()


text:
module Metasm
class DynLdr
	# basic C defs for ruby internals - 1.8 and 1.9 compat - x86/x64
	RUBY_H = <<EOS
#line #{__LINE__}
typedef uintptr_t VALUE;

#define INT2VAL(v) rb_uint2inum(v)
#define VAL2INT(v) rb_num2ulong(v)

struct rb_string_t {
	VALUE flags;
	VALUE klass;
	VALUE len;
	char *ptr;
	union {
		long capa;
		VALUE shared;
	} aux;
};
#define RString(x) ((struct rb_string_t *)(x))

struct rb_array_t {
	VALUE flags;
	VALUE klass;
	VALUE len;
	union {
		long capa;
		VALUE shared;
	} aux;
	VALUE *ptr;
};
#define RArray(x) ((struct rb_array_t *)(x))

// TODO improve autoimport to handle data imports correctly
extern VALUE *rb_cObject __attribute__((import));
extern VALUE *rb_eRuntimeError __attribute__((import));
extern VALUE *rb_eArgError __attribute__((import));

#define Qfalse ((VALUE)0)
#define Qtrue  ((VALUE)2)
#define Qnil   ((VALUE)4)

// allows generating a ruby1.9 dynldr.so from ruby1.8
#ifndef DYNLDR_RUBY_19
#define DYNLDR_RUBY_19 #{RUBY_VERSION >= '1.9' ? 1 : 0}
#endif

#if DYNLDR_RUBY_19
 #define T_STRING 0x05
 #define T_ARRAY  0x07
 #define T_FIXNUM 0x15
 #define T_MASK   0x1f
 #define RSTRING_NOEMBED (1<<13)
 #define STR_PTR(o) ((RString(o)->flags & RSTRING_NOEMBED) ? RString(o)->ptr : (char*)&RString(o)->len)
 #define STR_LEN(o) ((RString(o)->flags & RSTRING_NOEMBED) ? RString(o)->len : (RString(o)->flags >> 14) & 0x1f)
 #define RARRAY_EMBED (1<<13)
 #define ARY_PTR(o) ((RArray(o)->flags & RARRAY_EMBED) ? (VALUE*)&RArray(o)->len : RArray(o)->ptr)
 #define ARY_LEN(o) ((RArray(o)->flags & RARRAY_EMBED) ? ((RArray(o)->flags >> 15) & 3) : RArray(o)->len)
#else
 #define T_STRING 0x07
 #define T_ARRAY  0x09
 #define T_FIXNUM 0x0a
 #define T_MASK   0x3f
 #define STR_PTR(o) (RString(o)->ptr)
 #define STR_LEN(o) (RString(o)->len)
 #define ARY_PTR(o) (RArray(o)->ptr)
 #define ARY_LEN(o) (RArray(o)->len)
#endif

#define TYPE(x) (((VALUE)(x) & 1) ? T_FIXNUM : (((VALUE)(x) & 3) || ((VALUE)(x) < 7)) ? 0x40 : RString(x)->flags & T_MASK)

VALUE rb_uint2inum(VALUE);
VALUE rb_ull2inum(unsigned long long);
VALUE rb_num2ulong(VALUE);
VALUE rb_str_new(const char* ptr, long len);	// alloc + memcpy + 0term
VALUE rb_ary_new2(int len);
VALUE rb_float_new(double);

VALUE rb_intern(char *);
VALUE rb_funcall(VALUE recv, VALUE id, int nargs, ...);
VALUE rb_const_get(VALUE, VALUE);
VALUE rb_raise(VALUE, char*, ...);
void rb_define_const(VALUE, char *, VALUE);
void rb_define_method(VALUE, char *, VALUE (*)(), int);
void rb_define_singleton_method(VALUE, char *, VALUE (*)(), int);

EOS

	# generic C source for the native component, ruby glue
	DYNLDR_C = <<EOS
#{RUBY_H}
#line #{__LINE__}

#ifdef __PE__
 __stdcall uintptr_t LoadLibraryA(char *);
 __stdcall uintptr_t GetProcAddress(uintptr_t, char *);

 #define os_load_lib(l) LoadLibraryA(l)
 #define os_load_sym(l, s) GetProcAddress(l, s)
 #define os_load_sym_ord(l, s) GetProcAddress(l, (char*)s)
#endif

#ifdef __ELF__
 asm(".pt_gnu_stack rw");

 #define RTLD_LAZY 1
 uintptr_t dlopen(char*, int);
 uintptr_t dlsym(uintptr_t, char*);

 #define os_load_lib(l) dlopen(l, RTLD_LAZY)
 #define os_load_sym(l, s) dlsym(l, s)
 #define os_load_sym_ord(l, s) 0U
#endif

extern int *cb_ret_table;
extern void *callback_handler;
extern void *callback_id_0;
extern void *callback_id_1;

static VALUE dynldr;

static VALUE memory_read(VALUE self, VALUE addr, VALUE len)
{
	return rb_str_new((char*)VAL2INT(addr), (long)VAL2INT(len));
}

static VALUE memory_read_int(VALUE self, VALUE addr)
{
	return INT2VAL(*(uintptr_t*)VAL2INT(addr));
}

static VALUE memory_write(VALUE self, VALUE addr, VALUE val)
{
	if (TYPE(val) != T_STRING)
		rb_raise(*rb_eArgError, "mem_write needs a String");

	char *src = STR_PTR(val);
	char *dst = (char*)VAL2INT(addr);
	unsigned len = (unsigned)STR_LEN(val);
	while (len--)
		*dst++ = *src++;
	return val;
}

static VALUE memory_write_int(VALUE self, VALUE addr, VALUE val)
{
	*(uintptr_t *)VAL2INT(addr) = VAL2INT(val);
	return Qtrue;
}

static VALUE str_ptr(VALUE self, VALUE str)
{
	if (TYPE(str) != T_STRING)
		rb_raise(*rb_eArgError, "Invalid ptr");
	return INT2VAL((uintptr_t)STR_PTR(str));
}

// return the VALUE of an object (different of .object_id for Symbols, maybe others)
static VALUE rb_obj_to_value(VALUE self, VALUE obj)
{
	return INT2VAL((uintptr_t)obj);
}

// return the ruby object at VALUE
// USE WITH CAUTION, passing invalid values will segfault the interpreter/GC
static VALUE rb_value_to_obj(VALUE self, VALUE val)
{
	return VAL2INT(val);
}

// load a symbol from a lib byname, byordinal if integral
static VALUE sym_addr(VALUE self, VALUE lib, VALUE func)
{
	uintptr_t h, p;

	if (TYPE(lib) == T_STRING)
		h = os_load_lib(STR_PTR(lib));
	else if (TYPE(lib) == T_FIXNUM)
		h = VAL2INT(lib);
	else
		rb_raise(*rb_eArgError, "Invalid lib");

	if (TYPE(func) != T_STRING && TYPE(func) != T_FIXNUM)
		rb_raise(*rb_eArgError, "Invalid func");

	if (TYPE(func) == T_FIXNUM)
		p = os_load_sym_ord(h, VAL2INT(func));
	else
		p = os_load_sym(h, STR_PTR(func));

	return INT2VAL(p);
}

#ifdef __i386__

__int64 do_invoke_stdcall(unsigned, unsigned, unsigned*);
__int64 do_invoke_fastcall(unsigned, unsigned, unsigned*);
__int64 do_invoke(unsigned, unsigned, unsigned*);
double fake_float(void);

// invoke a symbol
// args is an array of Integers
// flags: 1 stdcall  2 fastcall  4 ret_64bits  8 ret_float
// TODO float args
static VALUE invoke(VALUE self, VALUE ptr, VALUE args, VALUE flags)
{
	if (TYPE(args) != T_ARRAY || ARY_LEN(args) > 64)
		rb_raise(*rb_eArgError, "bad args");

	uintptr_t flags_v = VAL2INT(flags);
	uintptr_t ptr_v = VAL2INT(ptr);
	unsigned i, argsz;
	uintptr_t args_c[64];
	__int64 ret;

	argsz = ARY_LEN(args);
	for (i=0U ; i<argsz ; ++i)
		args_c[i] = VAL2INT(ARY_PTR(args)[i]);

	if (flags_v & 2)
		ret = do_invoke_fastcall(ptr_v, argsz, args_c);	// supercedes stdcall
	else if (flags_v & 1)
		ret = do_invoke_stdcall(ptr_v, argsz, args_c);
	else
		ret = do_invoke(ptr_v, argsz, args_c);

	if (flags_v & 4)
		return rb_ull2inum((unsigned __int64)ret);
	else if (flags_v & 8)
		// fake_float does nothing, to allow the compiler to use ST(0)
		// which was in fact set by ptr_v()
		return rb_float_new(fake_float());

	return INT2VAL((unsigned)ret);
}

// this is the function that is called on behalf of all callbacks
// we're called through callback_handler (asm), itself called from the unique
// callback generated by callback_alloc
// heavy stack magick at work here !
// TODO float args / float retval / ret __int64
uintptr_t do_callback_handler(uintptr_t ori_retaddr, uintptr_t caller_id, uintptr_t arg0)
{
	uintptr_t *addr = &arg0;
	unsigned i, ret;
	VALUE args = rb_ary_new2(8);

	// copy our args to a ruby-accessible buffer
	for (i=0U ; i<8U ; ++i)
		ARY_PTR(args)[i] = INT2VAL(*addr++);
	RArray(args)->len = 8U;	// len == 8, no need to ARY_LEN/EMBED stuff

	ret = rb_funcall(dynldr, rb_intern("callback_run"), 2, INT2VAL(caller_id), args);

	// dynldr.callback will give us the arity (in bytes) of the callback in args[0]
	// we just put the stack lifting offset in caller_id for the asm stub to use
	caller_id = VAL2INT(ARY_PTR(args)[0]);

	return VAL2INT(ret);
}

#elif defined __amd64__

uintptr_t do_invoke(uintptr_t, uintptr_t, uintptr_t*);
double fake_float(void);

// invoke a symbol
// args is an array of Integers
// flags: 1 stdcall  2 fastcall  4 ret_64bits  8 ret_float
// TODO float args
static VALUE invoke(VALUE self, VALUE ptr, VALUE args, VALUE flags)
{
	if (TYPE(args) != T_ARRAY || ARY_LEN(args) > 16)
		rb_raise(*rb_eArgError, "bad args");

	uintptr_t flags_v = VAL2INT(flags);
	uintptr_t ptr_v = VAL2INT(ptr);
	int i, argsz;
	uintptr_t args_c[16];
	uintptr_t ret;
	uintptr_t (*ptr_f)(uintptr_t, ...) = (void*)ptr_v;

	argsz = (int)ARY_LEN(args);
	for (i=0 ; i<argsz ; ++i)
		args_c[i] = VAL2INT(ARY_PTR(args)[i]);

	for (i=argsz ; i<16 ; ++i)
		args_c[i] = 0;

	if (argsz <= 4)
		ret = ptr_f(args_c[0], args_c[1], args_c[2], args_c[3]);
	else
		ret = ptr_f(args_c[0],  args_c[1],  args_c[2],  args_c[3],
			    args_c[4],  args_c[5],  args_c[6],  args_c[7],
			    args_c[8],  args_c[9],  args_c[10], args_c[11],
			    args_c[12], args_c[13], args_c[14], args_c[15]);

	if (flags_v & 8)
		return rb_float_new(fake_float());

	return INT2VAL(ret);
}

extern uintptr_t *callback_id_tmp;
uintptr_t do_callback_handler(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, uintptr_t arg7)
{
	uintptr_t ret;
	VALUE args = rb_ary_new2(8);

	RArray(args)->len = 8;
	ARY_PTR(args)[0] = INT2VAL(arg0);
	ARY_PTR(args)[1] = INT2VAL(arg1);
	ARY_PTR(args)[2] = INT2VAL(arg2);
	ARY_PTR(args)[3] = INT2VAL(arg3);
	ARY_PTR(args)[4] = INT2VAL(arg4);
	ARY_PTR(args)[5] = INT2VAL(arg5);
	ARY_PTR(args)[6] = INT2VAL(arg6);
	ARY_PTR(args)[7] = INT2VAL(arg7);

	ret = rb_funcall(dynldr, rb_intern("callback_run"), 2, *callback_id_tmp, args);

	return VAL2INT(ret);
}
#endif

int Init_dynldr(void) __attribute__((export_as(Init_<insertfilenamehere>)))	// to patch before parsing to match the .so name
{
	dynldr = rb_const_get(rb_const_get(*rb_cObject, rb_intern("Metasm")), rb_intern("DynLdr"));
	rb_define_singleton_method(dynldr, "memory_read",  memory_read, 2);
	rb_define_singleton_method(dynldr, "memory_read_int",  memory_read_int, 1);
	rb_define_singleton_method(dynldr, "memory_write", memory_write, 2);
	rb_define_singleton_method(dynldr, "memory_write_int", memory_write_int, 2);
	rb_define_singleton_method(dynldr, "str_ptr", str_ptr, 1);
	rb_define_singleton_method(dynldr, "rb_obj_to_value", rb_obj_to_value, 1);
	rb_define_singleton_method(dynldr, "rb_value_to_obj", rb_value_to_obj, 1);
	rb_define_singleton_method(dynldr, "sym_addr", sym_addr, 2);
	rb_define_singleton_method(dynldr, "raw_invoke", invoke, 3);
	rb_define_const(dynldr, "CALLBACK_TARGET", INT2VAL((VALUE)&callback_handler));
	rb_define_const(dynldr, "CALLBACK_ID_0", INT2VAL((VALUE)&callback_id_0));
	rb_define_const(dynldr, "CALLBACK_ID_1", INT2VAL((VALUE)&callback_id_1));
	return 0;
}
EOS

	# see the note in compile_bin_module
	# this is a dynamic resolver for the ruby symbols we use
	DYNLDR_C_PE_HACK = <<EOS
#line #{__LINE__}

void* get_peb(void);

// check if the wstr s1 contains 'ruby' (case-insensitive)
static void *wstrcaseruby(short *s1, int len)
{
	int i = 0;
	int match = 0;

	static char *want = "ruby";	// cant contain the same letter twice

	while (i < len) {
		if (want[match] == (s1[i] | 0x20)) {	// downcase cmp
			if (match == 3)
				return s1+i-match;
		} else
			match = 0;
		if (want[match] == (s1[i] | 0x20))
			++match;
		++i;
	}

	return 0;
}

asm(".text");	// TODO fix compiler
#ifdef __x86_64__
asm("get_peb: mov rax, gs:[60h] ret");
#endif
#ifdef __i386__
asm("get_peb: mov eax, fs:[30h] ret");
#endif

struct _lmodule {
	struct _lmodule *next;	// list_head
	void *; void *; void*; void*; void*;
	uintptr_t base, entry, size;
	short; short; short*;
	short len, maxlen;
	short *basename;
};

struct _peb {
	void*; void*; void*;
	struct {
		int; int; void*;
		struct _lmodule *inloadorder; // list_head
	} *ldr;
};

// find the ruby library in the loaded modules list of the interpreter through the PEB
static uintptr_t find_ruby_module(void)
{
	struct _lmodule *ptr;
	void *base;
	struct _peb *peb = get_peb();

	base = &peb->ldr->inloadorder;
	ptr = ((struct _lmodule *)base)->next;
	ptr = ptr->next;	// skip the first entry = ruby.exe
	while (ptr != base) {
		if (wstrcaseruby(ptr->basename, ptr->len/2))
			return ptr->base;
		ptr = ptr->next;
	}

	return 0;
}

// a table of string offsets, base = the table itself
// each entry is a ruby function, whose address is to be put inplace in the table
// last entry == 0
extern void *ruby_import_table;

__stdcall uintptr_t GetProcAddress(uintptr_t, char *);
// resolve the ruby imports found by offset in ruby_import_table
static int load_ruby_imports(void)
{
	uintptr_t ruby_module;
	uintptr_t *ptr;
	char *table;

	static int loaded_ruby_imports = 0;
	if (loaded_ruby_imports)
		return 0;
	loaded_ruby_imports = 1;

 	ruby_module = find_ruby_module();
	if (!ruby_module)
		return 0;

	ptr = &ruby_import_table;
	table = (char*)ptr;

	while (*ptr) {
		if (!(*ptr = GetProcAddress(ruby_module, table+*ptr)))
			// TODO warning or something
			return 0;
		ptr++;
	}

	return 1;
}

#define DLL_PROCESS_ATTACH 1
__stdcall int DllMain(void *handle, int reason, void *res)
{
	if (reason == DLL_PROCESS_ATTACH)
		return load_ruby_imports();
	return 1;
}
EOS

	# ia32 asm source for the native component: handles ABI stuff
	DYNLDR_ASM_IA32 = <<EOS
.text
do_invoke_fastcall:
	push ebp
	mov ebp, esp

	// load ecx/edx, fix arg/argcount
	mov eax, [ebp+16]
	mov ecx, [eax]
	mov edx, [eax+4]
	add eax, 8
	mov [ebp+16], eax

	mov eax, [ebp+12]
	sub eax, 2
	jb _do_invoke_call
	jmp _do_invoke_copy

do_invoke:
do_invoke_stdcall:
	push ebp
	mov ebp, esp
	mov eax, [ebp+12]
_do_invoke_copy:
	// make room for args
	shl eax, 2
	jz _do_invoke_call
	sub esp, eax
	// copy args
	push esi
	push edi
	push ecx
	mov ecx, [ebp+12]
	mov esi, [ebp+16]
	mov edi, esp
	add edi, 12
	rep movsd
	pop ecx
	pop edi
	pop esi
	// go
_do_invoke_call:
	call dword ptr [ebp+8]
	leave
fake_float:
	ret

// entrypoint for callbacks: to the native api, give the addr of some code
//  that will push a unique cb_identifier and jmp here
callback_handler:
	// stack here: cb_id_retaddr, cb_native_retaddr, cb_native_arg0, ...
	// swap caller retaddr & cb_identifier, fix cb_identifier from the stub
	pop eax		// stuff pushed by the stub
	sub eax, callback_id_1 - callback_id_0	// fixup cb_id_retaddr to get a cb id
	xchg eax, [esp]	// put on stack, retrieve original retaddr
	push eax	// push intended cb retaddr
	call do_callback_handler
	// do_cb_handler puts the nr of bytes we have to pop from the stack in its 1st arg (eg [esp+4] here)
	// stack here: cb_native_retaddr, ruby_popcount, cb_native_arg0, ...
	pop ecx		// get retaddr w/o interfering with retval (incl 64bits eax+edx)
	add esp, [esp]	// pop cb args if stdcall
	add esp, 4	// pop cb_id/popcount
	jmp ecx		// return

// those are valid callback id
// most of the time only 2 cb is used (source: meearse)
// so this prevents dynamic allocation of a whole page for the most common case
callback_id_0: call callback_handler
callback_id_1: call callback_handler
EOS

	# ia32 asm source for the native component: handles ABI stuff
	DYNLDR_ASM_X86_64 = <<EOS
.text
fake_float:
	ret

// entrypoint for callbacks: to the native api, give the addr of some code
//  that will push a unique cb_identifier and jmp here
callback_handler:
	// stack here: cb_id_retaddr, cb_native_retaddr, cb_native_arg0, ...
	// swap caller retaddr & cb_identifier, fix cb_identifier from the stub
	pop rax		// stuff pushed by the stub
	sub rax, callback_id_1 - callback_id_0	// fixup cb_id_retaddr to get a cb id
	mov [rip+callback_id_tmp-1f], rax	// XXX racey if not greenthreaded..
1:
	jmp do_callback_handler

callback_id_0: call callback_handler
callback_id_1: call callback_handler

.data
callback_id_tmp dq ?
EOS

	# initialization
	# load (build if needed) the binary module
	def self.start
		# callbacks are really just a list of asm 'call', so we share them among subclasses of DynLdr
		@@callback_addrs = []	# list of all allocated callback addrs (in use or not)
		@@callback_table = {}	# addr -> cb structure (inuse only)

		binmodule = find_bin_path

		if not File.exists?(binmodule) or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
			compile_binary_module(host_exe, host_cpu, binmodule)
		end

		require binmodule

		@@callback_addrs << CALLBACK_ID_0 << CALLBACK_ID_1
	end

	# compile the dynldr binary ruby module for a specific arch/cpu/modulename
	def self.compile_binary_module(exe, cpu, modulename)
		bin = exe.new(cpu)
		# compile the C code, but patch the Init_ export name, which must match the string used in 'require'
		module_c_src = DYNLDR_C.gsub('<insertfilenamehere>', File.basename(modulename, '.so'))
		bin.compile_c module_c_src
		# compile the Asm stuff according to the target architecture
		bin.assemble  case cpu.shortname
		              when 'ia32'; DYNLDR_ASM_IA32
		              when 'x64'; DYNLDR_ASM_X86_64
			      end

		# tweak the resulting binary linkage procedures if needed
		compile_binary_module_hack(bin)

		# save the shared library
		bin.encode_file(modulename, :lib)
	end

	def self.compile_binary_module_hack(bin)
		# this is a hack
		# we need the module to use ruby symbols
		# but we don't know the actual ruby lib filename (depends on ruby version, # platform, ...)
		case bin.class.name.gsub(/.*::/, '')
		when 'ELF'
			# we know the lib is already loaded by the main ruby executable, no DT_NEEDED needed
			class << bin
				def automagic_symbols(*a)
					# do the plt generation
					super(*a)
					# but remove the specific lib names
					@tag.delete 'NEEDED'
				end
			end
			return
		when 'PE'
			# the hard part, see below
		else
			# unhandled arch, dont tweak
			return
		end

		# we remove the PE IAT section related to ruby symbols, and make
		# a manual symbol resolution on module loading.

		# populate the ruby import table ourselves on module loading
		bin.imports.delete_if { |id| id.libname =~ /ruby/ }

		# the C glue: getprocaddress etc
		bin.compile_c DYNLDR_C_PE_HACK

		# we generate something like:
		#  .data
		#  ruby_import_table:
		#  rb_cObject dd str_rb_cObject - ruby_import_table
		#  riat_rb_intern dd str_rb_intern - ruby_import_table
		#  dd 0
		#
		#  .rodata
		#  str_rb_cObject db "rb_cObject", 0
		#  str_rb_intern db "rb_intern", 0
		#
		#  .text
		#  rb_intern: jmp [riat_rb_intern]
		#
		# the PE_HACK code will parse ruby_import_table and make the symbol resolution on startup

		# setup the string table and the thunks
		text = bin.sections.find { |s| s.name == '.text' }.encoded
		rb_syms = text.reloc_externals.grep(/^rb_/)

		dd = (bin.cpu.size == 64 ? 'dq' : 'dd')
		# the IAT, initialized with relative offsets to symbol names
		asm_table = ['.data', '.align 8', 'ruby_import_table:']
		# strings will be in .rodata
		bin.parse('.rodata')
		rb_syms.each { |sym|
			# raw symbol name
			str_label = bin.parse_new_label('str', "db #{sym.inspect}, 0")

			if sym !~ /^rb_[ce][A-Z]/
				# if we dont reference a data import (rb_cClass / rb_eException),
				# then create a function thunk
				i = PE::ImportDirectory::Import.new
				i.thunk = sym
				sym = i.target = 'riat_' + str_label
				bin.arch_encode_thunk(text, i)	# encode a jmp [importtable]
			end

			# update the IAT
			asm_table << "#{sym} #{dd} #{str_label} - ruby_import_table"
		}
		# IAT null-terminated
		asm_table << "#{dd} 0"

		# now parse & assemble the IAT in .data
		bin.assemble asm_table.join("\n")
	end

	# find the path of the binary module
	# if none exists, create a path writeable by the current user
	def self.find_bin_path
		fname = ['dynldr', host_arch, host_cpu.shortname,
			 ('19' if RUBY_VERSION >= '1.9')].compact.join('-') + '.so'
		dir = File.dirname(__FILE__)
		binmodule = File.join(dir, fname)
		if not File.exists? binmodule or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
			if not dir = find_write_dir
				raise LoadError, "no writable dir to put the DynLdr ruby module, try to run as root"
			end
			binmodule = File.join(dir, fname)
		end
		binmodule
	end

	# find a writeable directory
	# searches this script directory, $HOME / %APPDATA% / %USERPROFILE%, or $TMP
	def self.find_write_dir
		writable = lambda { |d|
			begin
				foo = '/_test_write_' + rand(1<<32).to_s
				true if File.writable?(d) and
				File.open(d+foo, 'w') { true } and
				File.unlink(d+foo)
			rescue
			end
		}
		dir = File.dirname(__FILE__)
		return dir if writable[dir]
		dir = ENV['HOME'] || ENV['APPDATA'] || ENV['USERPROFILE']
		if writable[dir]
			dir = File.join(dir, '.metasm')
			Dir.mkdir dir if not File.directory? dir
			return dir
		end
		ENV['TMP'] || ENV['TEMP'] || '.'
	end

	# CPU suitable for compiling code for the current running host
	def self.host_cpu
		@cpu ||=
		case RUBY_PLATFORM
		when /i[3-6]86/; Ia32.new
		when /x86_64|x64/i; X86_64.new
		else raise LoadError, "Unsupported host platform #{RUBY_PLATFORM}"
		end
	end

	# returns whether we run on linux or windows
	def self.host_arch
		case RUBY_PLATFORM
		when /linux/i; :linux
		when /mswin|mingw|cygwin/i; :windows
		else raise LoadError, "Unsupported host platform #{RUBY_PLATFORM}"
		end
	end

	# ExeFormat suitable as current running host native module
	def self.host_exe
		case host_arch
		when :linux; ELF
		when :windows; PE
		end
	end

	# parse a C string into the @cp parser, create it if needed
	def self.parse_c(src)
		cp.parse(src)
	end

	# compile a C fragment into a Shellcode, honors the host ABI
	def self.compile_c(src)
		# XXX could we reuse self.cp ? (for its macros etc)
		cp = C::Parser.new(host_exe.new(host_cpu))
		cp.parse(src)
		sc = Shellcode.new(host_cpu)
		asm = host_cpu.new_ccompiler(cp, sc).compile
		sc.assemble(asm)
	end

	# retrieve the library where a symbol is to be found (uses AutoImport)
	def self.lib_from_sym(symname)
		case host_arch
		when :linux; GNUExports::EXPORT
		when :windows; WindowsExports::EXPORT
		end[symname]
	end

	# reads a bunch of C code, creates binding for those according to the prototypes
	# handles enum/defines to define constants
	# For each toplevel method prototype, it generates a ruby method in this module, the name is lowercased
	# For each numeric macro/enum, it also generates an uppercase named constant
	# When such a function is called with a lambda as argument, a callback is created for the duration of the call
	# and destroyed afterwards ; use callback_alloc_c to get a callback id with longer life span
	def self.new_api_c(proto, fromlib=nil)
		proto += "\n;"	# allow 'int foo()' and '#include <bar>'
		parse_c(proto)

		cp.toplevel.symbol.dup.each_value { |v|
			next if not v.kind_of? C::Variable	# enums
			cp.toplevel.symbol.delete v.name
			lib = fromlib || lib_from_sym(v.name)
			addr = sym_addr(lib, v.name)
		       	if addr == 0 or addr == -1 or addr == 0xffff_ffff or addr == 0xffffffff_ffffffff
				api_not_found(lib, v.name)
				next
			end

			rbname = c_func_name_to_rb(v.name)
			if not v.type.kind_of? C::Function
				# not a function, simply return the symbol address
				# TODO struct/table access through hash/array ?
				class << self ; self ; end.send(:define_method, rbname) { addr }
				next
			end
			next if v.initializer	# inline & stuff
			puts "new_api_c: load method #{rbname} from #{lib}" if $DEBUG

			new_caller_for(v, rbname, addr)
		}

		# predeclare constants from enums
		# macros are handled in const_missing (too slow to (re)do here everytime)
		# TODO #define FOO(v) (v<<1)|1   =>  create ruby counterpart
		cexist = constants.inject({}) { |h, c| h.update c.to_s => true }
		cp.toplevel.symbol.each { |k, v|
			if v.kind_of? ::Integer
				n = c_const_name_to_rb(k)
				const_set(n, v) if v.kind_of? Integer and not cexist[n]
			end
		}

		# avoid WTF rb warning: toplevel const TRUE referenced by WinAPI::TRUE
		cp.lexer.definition.each_key { |k|
			n = c_const_name_to_rb(k)
			if not cexist[n] and Object.const_defined?(n) and v = @cp.macro_numeric(n)
				const_set(n, v)
			end
		}
	end

	# const_missing handler: will try to find a matching #define
	def self.const_missing(c)
		# infinite loop on autorequire C..
		return super(c) if not defined? @cp or not @cp

		cs = c.to_s
		if @cp.lexer.definition[cs]
			m = cs
		else
			m = @cp.lexer.definition.keys.find { |k| c_const_name_to_rb(k) == cs }
		end

		if m and v = @cp.macro_numeric(m)
			const_set(c, v)
			v
		else
			super(c)
		end
	end

	# when defining ruby wrapper for C methods, the ruby method name is the string returned by this function from the C name
	def self.c_func_name_to_rb(name)
		n = name.to_s.gsub(/[^a-z0-9_]/i) { |c| c.unpack('H*')[0] }.downcase
		n = "m#{n}" if n !~ /^[a-z]/
		n
	end

	# when defining ruby wrapper for C constants (numeric define/enum), the ruby const name is
	# the string returned by this function from the C name. It should follow ruby standards (1st letter upcase)
	def self.c_const_name_to_rb(name)
		n = name.to_s.gsub(/[^a-z0-9_]/i) { |c| c.unpack('H*')[0] }.upcase
		n = "C#{n}" if n !~ /^[A-Z]/
		n
	end

	def self.api_not_found(lib, func)
		raise "could not find symbol #{func.inspect} in #{lib.inspect}"
	end

	# define a new method 'name' in the current module to invoke the raw method at addr addr
	# translates ruby args to raw args using the specified prototype
	def self.new_caller_for(proto, name, addr)
		flags = 0
		flags |= 1 if proto.has_attribute('stdcall')
		flags |= 2 if proto.has_attribute('fastcall')
		flags |= 4 if proto.type.type.integral? and cp.sizeof(nil, proto.type.type) == 8
		flags |= 8 if proto.type.type.float?
		class << self ; self ; end.send(:define_method, name) { |*a|
			raise ArgumentError, "bad arg count for #{name}: #{a.length} for #{proto.type.args.length}" if a.length != proto.type.args.length and not proto.type.varargs

			# convert the arglist suitably for raw_invoke
			auto_cb = []	# list of automatic C callbacks generated from lambdas
			a = a.zip(proto.type.args).map { |ra, fa|
				aa = convert_rb2c(fa, ra, :cb_list => auto_cb)
				if fa and fa.type.integral? and cp.sizeof(fa) == 8 and host_cpu.size == 32
					aa = [aa & 0xffff_ffff, (aa >> 32) & 0xffff_ffff]
					aa.reverse! if host_cpu.endianness != :little
				end
				aa
			}.flatten

			# do it
			ret = raw_invoke(addr, a, flags)

			# cleanup autogenerated callbacks
			auto_cb.each { |cb| callback_free(cb) }

			# interpret return value
			ret = convert_ret_c2rb(proto, ret)
		}
	end

	# ruby object -> integer suitable as arg for raw_invoke
	def self.convert_rb2c(formal, val, opts=nil)
		case val
		when String; str_ptr(val)
		when Proc; cb = callback_alloc_cobj(formal, val) ; (opts[:cb_list] << cb if opts and opts[:cb_list]) ; cb
		when C::AllocCStruct; str_ptr(val.str) + val.stroff
		when Hash
			if not formal.type.pointed.kind_of?(C::Struct)
				raise "invalid argument #{val.inspect} for #{formal}, need a struct*"
			end
			buf = cp.alloc_c_struct(formal, val)
			val.instance_variable_set('@rb2c', buf)	# GC trick: lifetime(buf) >= lifetime(hash) (XXX or until next call to convert_rb2c)
			str_ptr(buf.str)
		#when Float; val	# TODO handle that in raw_invoke C code
		else val.to_i rescue 0	# NaN, Infinity, etc
		end
	end

	# this method is called from the C part to run the ruby code corresponding to
	# a given C callback allocated by callback_alloc_c
	def self.callback_run(id, args)
		cb = @@callback_table[id]
		raise "invalid callback #{'%x' % id} not in #{@@callback_table.keys.map { |c| c.to_s(16) }}" if not cb

		rawargs = args.dup
		ra = cb[:proto] ? cb[:proto].args.map { |fa| convert_cbargs_c2rb(fa, rawargs) } : []

		# run it
		ret = cb[:proc].call(*ra)

		# the C code expects to find in args[0] the amount of stack fixing needed for __stdcall callbacks
		args[0] = cb[:abi_stackfix] || 0
		ret
	end

	# C raw cb arg -> ruby object
	# will combine 2 32bit values for 1 64bit arg
	def self.convert_cbargs_c2rb(formal, rawargs)
		val = rawargs.shift
		if formal.type.integral? and cp.sizeof(formal) == 8 and host_cpu.size == 32
			if host.cpu.endianness == :little
				val |= rawargs.shift << 32
			else
				val = (val << 32) | rawargs.shift
			end
		end

		convert_c2rb(formal, val)
	end

	# interpret a raw decoded C value to a ruby value according to the C prototype
	# handles signedness etc
	# XXX val is an integer, how to decode Floats etc ? raw binary ptr ?
	def self.convert_c2rb(formal, val)
		formal = formal.type if formal.kind_of? C::Variable
		val = Expression.make_signed(val, 8*cp.sizeof(formal)) if formal.integral? and formal.signed?
		val = nil if formal.pointer? and val == 0
		val
	end

	# C raw ret -> ruby obj
	# can be overridden for system-specific calling convention (eg return 0/-1 => raise an error)
	def self.convert_ret_c2rb(fproto, ret)
		fproto = fproto.type if fproto.kind_of? C::Variable
		convert_c2rb(fproto.untypedef.type, ret)
	end

	def self.cp ; @cp ||= C::Parser.new(host_exe.new(host_cpu)) ; end
	def self.cp=(c); @cp = c ; end

	# allocate a callback for a given C prototype (string)
	# accepts full C functions (with body) (only 1 at a time) or toplevel 'asm' statement
	def self.callback_alloc_c(proto, &b)
		proto += ';'	# allow 'int foo()'
		parse_c(proto)
		v = cp.toplevel.symbol.values.find_all { |v_| v_.kind_of? C::Variable and v_.type.kind_of? C::Function }.first
		if (v and v.initializer) or cp.toplevel.statements.find { |st| st.kind_of? C::Asm }
			cp.toplevel.statements.delete_if { |st| st.kind_of? C::Asm }
			cp.toplevel.symbol.delete v.name if v
			sc = compile_c(proto)
			ptr = memory_alloc(sc.encoded.length)
			sc.base_addr = ptr
			# TODO fixup external calls
			memory_write ptr, sc.encode_string
			memory_perm ptr, sc.encoded.length, 'rwx'
			ptr
		elsif not v
			raise 'empty prototype'
		else
			cp.toplevel.symbol.delete v.name
			callback_alloc_cobj(v, b)
		end
	end

	# allocates a callback for a given C prototype (C variable, pointer to func accepted)
	def self.callback_alloc_cobj(proto, b)
		ori = proto
		proto = proto.type if proto and proto.kind_of? C::Variable
		proto = proto.pointed while proto and proto.pointer?
		id = callback_find_id
		cb = {}
		cb[:id] = id
		cb[:proc] = b
		cb[:proto] = proto
		cb[:abi_stackfix] = proto.args.inject(0) { |s, a| s + [cp.sizeof(a), cp.typesize[:ptr]].max } if ori and ori.has_attribute('stdcall')
		cb[:abi_stackfix] = proto.args[2..-1].to_a.inject(0) { |s, a| s + [cp.sizeof(a), cp.typesize[:ptr]].max } if ori and ori.has_attribute('fastcall')	# supercedes stdcall
		@@callback_table[id] = cb
		id
	end

	# releases a callback id, so that it may be reused by a later callback_alloc
	def self.callback_free(id)
		@@callback_table.delete id
	end

	# finds a free callback id, allocates a new page if needed
	def self.callback_find_id
		if not id = @@callback_addrs.find { |a| not @@callback_table[a] }
			cb_page = memory_alloc(4096)
			sc = Shellcode.new(host_cpu, cb_page)
			case sc.cpu.shortname
			when 'ia32', 'x64'
				addr = cb_page
				nrcb = 128	# TODO should be 4096/5, but the parser/compiler is really too slow
				nrcb.times {
					@@callback_addrs << addr
					sc.parse "call #{CALLBACK_TARGET}"
					addr += 5
				}
			end
			sc.assemble
			memory_write cb_page, sc.encode_string
			memory_perm cb_page, 4096, 'rx'
			raise 'callback_alloc bouh' if not id = @@callback_addrs.find { |a| not @@callback_table[a] }
		end
		id
	end

	# compile a bunch of C functions, defines methods in this module to call them
	# returns the raw pointer to the code page
	# if given a block, run the block and then undefine all the C functions & free memory
	def self.new_func_c(src)
		sc = compile_c(src)
		ptr = memory_alloc(sc.encoded.length)
		sc.base_addr = ptr
		bd = sc.encoded.binding(ptr)
		sc.encoded.reloc_externals.uniq.each { |ext| bd[ext] = sym_addr(lib_from_sym(ext), ext) or raise "unknown symbol #{ext}" }
		sc.encoded.fixup(bd)
		memory_write ptr, sc.encode_string
		memory_perm ptr, sc.encoded.length, 'rwx'
		parse_c(src)	# XXX the Shellcode parser may have defined stuff / interpreted C another way...
		defs = []
		cp.toplevel.symbol.dup.each_value { |v|
			next if not v.kind_of? C::Variable
			cp.toplevel.symbol.delete v.name
			next if not v.type.kind_of? C::Function or not v.initializer
			next if not off = sc.encoded.export[v.name]
			new_caller_for(v, v.name, ptr+off)
			defs << v.name
		}
		if block_given?
			begin
				yield
			ensure
				defs.each { |d| class << self ; self ; end.send(:remove_method, d) }
				memory_free ptr
			end
		else
			ptr
		end
	end

	# compile an asm sequence, callable with the ABI of the C prototype given
	# function name comes from the prototype
	def self.new_func_asm(proto, asm)
		proto += "\n;"
		old = cp.toplevel.symbol.keys
		parse_c(proto)
		news = cp.toplevel.symbol.keys - old
		raise "invalid proto #{proto}" if news.length != 1
		f = cp.toplevel.symbol[news.first]
		raise "invalid func proto #{proto}" if not f.name or not f.type.kind_of? C::Function or f.initializer
		cp.toplevel.symbol.delete f.name

		sc = Shellcode.assemble(host_cpu, asm)
		ptr = memory_alloc(sc.encoded.length)
		bd = sc.encoded.binding(ptr)
		sc.encoded.reloc_externals.uniq.each { |ext| bd[ext] = sym_addr(lib_from_sym(ext), ext) or raise "unknown symbol #{ext}" }
		sc.encoded.fixup(bd)
		memory_write ptr, sc.encode_string
		memory_perm ptr, sc.encoded.length, 'rwx'
		new_caller_for(f, f.name, ptr)
		if block_given?
			begin
				yield
			ensure
				class << self ; self ; end.send(:remove_method, f.name)
				memory_free ptr
			end
		else
			ptr
		end
	end

	# allocate a C::AllocStruct to hold a specific struct defined in a previous new_api_c
	def self.alloc_c_struct(structname, values={})
		cp.alloc_c_struct(structname, values)
	end

	def self.create_c_struct(structname, data, offset=0 )
		cp.create_c_struct(structname, data, offset )
	end

	def self.sizeof_c_struct(structname)
		cp.sizeof_c_struct(structname)
	end

	# return the binary version of a ruby value encoded as a C variable
	# only integral types handled for now
	def self.encode_c_value(var, val)
		cp.encode_c_value(var, val)
	end

	# decode a C variable
	# only integral types handled for now
	def self.decode_c_value(str, var, off=0)
		cp.decode_c_value(str, var, off)
	end

	# read a 0-terminated string from memory
	def self.memory_read_strz(ptr, szmax=4096)
		# read up to the end of the ptr memory page
		pglim = (ptr + 0x1000) & ~0xfff
		sz = [pglim-ptr, szmax].min
		data = memory_read(ptr, sz)
		return data[0, data.index(?\0)] if data.index(?\0)
		if sz < szmax
			data = memory_read(ptr, szmax)
			data = data[0, data.index(?\0)] if data.index(?\0)
		end
		data
	end

	# read a 0-terminated wide string from memory
	def self.memory_read_wstrz(ptr, szmax=4096)
		# read up to the end of the ptr memory page
		pglim = (ptr + 0x1000) & ~0xfff
		sz = [pglim-ptr, szmax].min
		data = memory_read(ptr, sz)
		if i = data.unpack('v*').index(0)
			return data[0, 2*i]
		end
		if sz < szmax
			data = memory_read(ptr, szmax)
			data = data[0, 2*i] if i = data.unpack('v*').index(0)
		end
		data
	end

	# automatically build/load the bin module
	start

	case host_arch
	when :windows

		new_api_c <<EOS, 'kernel32'
#define PAGE_NOACCESS          0x01
#define PAGE_READONLY          0x02
#define PAGE_READWRITE         0x04
#define PAGE_WRITECOPY         0x08
#define PAGE_EXECUTE           0x10
#define PAGE_EXECUTE_READ      0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD            0x100
#define PAGE_NOCACHE          0x200
#define PAGE_WRITECOMBINE     0x400

#define MEM_COMMIT           0x1000
#define MEM_RESERVE          0x2000
#define MEM_DECOMMIT         0x4000
#define MEM_RELEASE          0x8000
#define MEM_FREE            0x10000
#define MEM_PRIVATE         0x20000
#define MEM_MAPPED          0x40000
#define MEM_RESET           0x80000
#define MEM_TOP_DOWN       0x100000
#define MEM_WRITE_WATCH    0x200000
#define MEM_PHYSICAL       0x400000
#define MEM_LARGE_PAGES  0x20000000
#define MEM_4MB_PAGES    0x80000000

__stdcall uintptr_t VirtualAlloc(uintptr_t addr, uintptr_t size, int type, int prot);
__stdcall uintptr_t VirtualFree(uintptr_t addr, uintptr_t size, int freetype);
__stdcall uintptr_t VirtualProtect(uintptr_t addr, uintptr_t size, int prot, int *oldprot);
EOS

		# allocate some memory suitable for code allocation (ie VirtualAlloc)
		def self.memory_alloc(sz)
			virtualalloc(nil, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)
		end

		# free memory allocated through memory_alloc
		def self.memory_free(addr)
			virtualfree(addr, 0, MEM_RELEASE)
		end

		# change memory permissions - perm in [r rw rx rwx]
		def self.memory_perm(addr, len, perm)
			perm = { 'r' => PAGE_READONLY, 'rw' => PAGE_READWRITE, 'rx' => PAGE_EXECUTE_READ,
				'rwx' => PAGE_EXECUTE_READWRITE }[perm.to_s.downcase]
			virtualprotect(addr, len, perm, str_ptr([0].pack('C')*8))
		end

	when :linux

		new_api_c <<EOS
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define PROT_EXEC 0x4

#define MAP_PRIVATE 0x2
#define MAP_ANONYMOUS 0x20

uintptr_t mmap(uintptr_t addr, uintptr_t length, int prot, int flags, uintptr_t fd, uintptr_t offset);
uintptr_t munmap(uintptr_t addr, uintptr_t length);
uintptr_t mprotect(uintptr_t addr, uintptr_t len, int prot);
EOS

		# allocate some memory suitable for code allocation (ie mmap)
		def self.memory_alloc(sz)
			@mmaps ||= {}	# save size for mem_free
			a = mmap(nil, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
			@mmaps[a] = sz
			a
		end

		# free memory allocated through memory_alloc
		def self.memory_free(addr)
			munmap(addr, @mmaps[addr])
		end

		# change memory permissions - perm 'rwx'
		# on PaX-enabled systems, this may need a non-mprotect-restricted ruby interpreter
		def self.memory_perm(addr, len, perm)
			perm = perm.to_s.downcase
			len += (addr & 0xfff) + 0xfff
			len &= ~0xfff
			addr &= ~0xfff
			p = 0
			p |= PROT_READ if perm.include? 'r'
			p |= PROT_WRITE if perm.include? 'w'
			p |= PROT_EXEC if perm.include? 'x'
			mprotect(addr, len, p)
		end

	end
end
end