text:
using NTF.Data.Common;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace NTF.Data.MySqlClient
{
    /// <summary>
    /// Formats a query expression into TSQL language syntax
    /// </summary>
    public class MySqlFormatter : CmdFormatter
    {
        protected MySqlFormatter(QueryLanguage language)
            : base(language)
        {
        }

        public static new string Format(Expression expression)
        {
            return Format(expression, new MySqlLanguage());
        }

        public static string Format(Expression expression, QueryLanguage language)
        {
            MySqlFormatter formatter = new MySqlFormatter(language);
            formatter.Visit(expression);
            return formatter.ToString();
        }

        protected override Expression VisitSelect(SelectExpression select)
        {
            this.AddAliases(select.From);
            this.Write("SELECT ");
            if (select.IsDistinct)
            {
                this.Write("DISTINCT ");
            }
            this.WriteColumns(select.Columns);
            if (select.From != null)
            {
                this.WriteLine(Indentation.Same);
                this.Write("FROM ");
                this.VisitSource(select.From);
            }
            if (select.Where != null)
            {
                this.WriteLine(Indentation.Same);
                this.Write("WHERE ");
                this.VisitPredicate(select.Where);
            }
            if (select.GroupBy != null && select.GroupBy.Count > 0)
            {
                this.WriteLine(Indentation.Same);
                this.Write("GROUP BY ");
                for (int i = 0, n = select.GroupBy.Count; i < n; i++)
                {
                    if (i > 0)
                    {
                        this.Write(", ");
                    }
                    this.VisitValue(select.GroupBy[i]);
                }
            }
            if (select.OrderBy != null && select.OrderBy.Count > 0)
            {
                this.WriteLine(Indentation.Same);
                this.Write("ORDER BY ");
                for (int i = 0, n = select.OrderBy.Count; i < n; i++)
                {
                    OrderExpression exp = select.OrderBy[i];
                    if (i > 0)
                    {
                        this.Write(", ");
                    }
                    this.VisitValue(exp.Expression);
                    if (exp.OrderType != OrderType.Ascending)
                    {
                        this.Write(" DESC");
                    }
                }
            }
            if (select.Take != null)
            {
                this.WriteLine(Indentation.Same);
                this.Write("LIMIT ");
                if (select.Skip == null)
                {
                    this.Write("0");
                }
                else
                {
                    this.Write(select.Skip);
                }
                this.Write(", ");
                this.Visit(select.Take);
            }
            return select;
        }

        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            if (m.Member.DeclaringType == typeof(string))
            {
                switch (m.Member.Name)
                {
                    case "Length":
                        this.Write("CHAR_LENGTH(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                }
            }
            else if (m.Member.DeclaringType == typeof(DateTime) || m.Member.DeclaringType == typeof(DateTimeOffset))
            {
                switch (m.Member.Name)
                {
                    case "Day":
                        this.Write("DAY(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Month":
                        this.Write("MONTH(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Year":
                        this.Write("YEAR(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Hour":
                        this.Write("HOUR(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Minute":
                        this.Write("MINUTE(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Second":
                        this.Write("SECOND(");
                        this.Visit(m.Expression);
                        this.Write(")");
                        return m;
                    case "Millisecond":
                        this.Write("(MICROSECOND(");
                        this.Visit(m.Expression);
                        this.Write(")/1000)");
                        return m;
                    case "DayOfWeek":
                        this.Write("(DAYOFWEEK(");
                        this.Visit(m.Expression);
                        this.Write(") - 1)");
                        return m;
                    case "DayOfYear":
                        this.Write("(DAYOFYEAR(");
                        this.Visit(m.Expression);
                        this.Write(") - 1)");
                        return m;
                }
            }
            return base.VisitMemberAccess(m);
        }

        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m.Method.DeclaringType == typeof(string))
            {
                switch (m.Method.Name)
                {
                    case "StartsWith":
                        this.Write("(");
                        this.Visit(m.Object);
                        this.Write(" LIKE CONCAT(");
                        this.Visit(m.Arguments[0]);
                        this.Write(",'%'))");
                        return m;
                    case "EndsWith":
                        this.Write("(");
                        this.Visit(m.Object);
                        this.Write(" LIKE CONCAT('%',");
                        this.Visit(m.Arguments[0]);
                        this.Write("))");
                        return m;
                    case "Contains":
                        this.Write("(");
                        this.Visit(m.Object);
                        this.Write(" LIKE CONCAT('%',");
                        this.Visit(m.Arguments[0]);
                        this.Write(",'%'))");
                        return m;
                    case "Concat":
                        IList<Expression> args = m.Arguments;
                        if (args.Count == 1 && args[0].NodeType == ExpressionType.NewArrayInit)
                        {
                            args = ((NewArrayExpression)args[0]).Expressions;
                        }
                        this.Write("CONCAT(");
                        for (int i = 0, n = args.Count; i < n; i++)
                        {
                            if (i > 0) this.Write(", ");
                            this.Visit(args[i]);
                        }
                        this.Write(")");
                        return m;
                    case "IsNullOrEmpty":
                        this.Write("(");
                        this.Visit(m.Arguments[0]);
                        this.Write(" IS NULL OR ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" = '')");
                        return m;
                    case "ToUpper":
                        this.Write("UPPER(");
                        this.Visit(m.Object);
                        this.Write(")");
                        return m;
                    case "ToLower":
                        this.Write("LOWER(");
                        this.Visit(m.Object);
                        this.Write(")");
                        return m;
                    case "Replace":
                        this.Write("REPLACE(");
                        this.Visit(m.Object);
                        this.Write(", ");
                        this.Visit(m.Arguments[0]);
                        this.Write(", ");
                        this.Visit(m.Arguments[1]);
                        this.Write(")");
                        return m;
                    case "Substring":
                        this.Write("SUBSTRING(");
                        this.Visit(m.Object);
                        this.Write(", ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" + 1");
                        if (m.Arguments.Count == 2)
                        {
                            this.Write(", ");
                            this.Visit(m.Arguments[1]);
                        }
                        this.Write(")");
                        return m;
                    case "Remove":
                        if (m.Arguments.Count == 1)
                        {
                            this.Write("LEFT(");
                            this.Visit(m.Object);
                            this.Write(", ");
                            this.Visit(m.Arguments[0]);
                            this.Write(")");
                        }
                        else
                        {
                            this.Write("CONCAT(");
                            this.Write("LEFT(");
                            this.Visit(m.Object);
                            this.Write(", ");
                            this.Visit(m.Arguments[0]);
                            this.Write("), SUBSTRING(");
                            this.Visit(m.Object);
                            this.Write(", ");
                            this.Visit(m.Arguments[0]);
                            this.Write(" + ");
                            this.Visit(m.Arguments[1]);
                            this.Write("))");
                        }
                        return m;
                    case "IndexOf":
                        this.Write("(LOCATE(");
                        this.Visit(m.Arguments[0]);
                        this.Write(", ");
                        this.Visit(m.Object);
                        if (m.Arguments.Count == 2 && m.Arguments[1].Type == typeof(int))
                        {
                            this.Write(", ");
                            this.Visit(m.Arguments[1]);
                            this.Write(" + 1");
                        }
                        this.Write(") - 1)");
                        return m;
                    case "Trim":
                        this.Write("TRIM(");
                        this.Visit(m.Object);
                        this.Write(")");
                        return m;
                }
            }
            else if (m.Method.DeclaringType == typeof(DateTime))
            {
                switch (m.Method.Name)
                {
                    case "op_Subtract":
                        if (m.Arguments[1].Type == typeof(DateTime))
                        {
                            this.Write("DATEDIFF(");
                            this.Visit(m.Arguments[0]);
                            this.Write(", ");
                            this.Visit(m.Arguments[1]);
                            this.Write(")");
                            return m;
                        }
                        break;
                    case "AddYears":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" YEAR)");
                        return m;
                    case "AddMonths":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" MONTH)");
                        return m;
                    case "AddDays":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" DAY)");
                        return m;
                    case "AddHours":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" HOUR)");
                        return m;
                    case "AddMinutes":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" MINUTE)");
                        return m;
                    case "AddSeconds":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL ");
                        this.Visit(m.Arguments[0]);
                        this.Write(" SECOND)");
                        return m;
                    case "AddMilliseconds":
                        this.Write("DATE_ADD(");
                        this.Visit(m.Object);
                        this.Write(", INTERVAL (");
                        this.Visit(m.Arguments[0]);
                        this.Write("* 1000) MICROSECOND)");
                        return m;
                }
            }
            else if (m.Method.DeclaringType == typeof(Decimal))
            {
                switch (m.Method.Name)
                {
                    case "Add":
                    case "Subtract":
                    case "Multiply":
                    case "Divide":
                    case "Remainder":
                        this.Write("(");
                        this.VisitValue(m.Arguments[0]);
                        this.Write(" ");
                        this.Write(GetOperator(m.Method.Name));
                        this.Write(" ");
                        this.VisitValue(m.Arguments[1]);
                        this.Write(")");
                        return m;
                    case "Negate":
                        this.Write("-");
                        this.Visit(m.Arguments[0]);
                        this.Write("");
                        return m;
                    case "Ceiling":
                    case "Floor":
                        this.Write(m.Method.Name.ToUpper());
                        this.Write("(");
                        this.Visit(m.Arguments[0]);
                        this.Write(")");
                        return m;
                    case "Round":
                        if (m.Arguments.Count == 1)
                        {
                            this.Write("ROUND(");
                            this.Visit(m.Arguments[0]);
                            this.Write(")");
                            return m;
                        }
                        else if (m.Arguments.Count == 2 && m.Arguments[1].Type == typeof(int))
                        {
                            this.Write("ROUND(");
                            this.Visit(m.Arguments[0]);
                            this.Write(", ");
                            this.Visit(m.Arguments[1]);
                            this.Write(")");
                            return m;
                        }
                        break;
                    case "Truncate":
                        this.Write("TRUNCATE(");
                        this.Visit(m.Arguments[0]);
                        this.Write(",0)");
                        return m;
                }
            }
            else if (m.Method.DeclaringType == typeof(Math))
            {
                switch (m.Method.Name)
                {
                    case "Abs":
                    case "Acos":
                    case "Asin":
                    case "Atan":
                    case "Atan2":
                    case "Cos":
                    case "Exp":
                    case "Log10":
                    case "Sin":
                    case "Tan":
                    case "Sqrt":
                    case "Sign":
                    case "Ceiling":
                    case "Floor":
                        this.Write(m.Method.Name.ToUpper());
                        this.Write("(");
                        this.Visit(m.Arguments[0]);
                        this.Write(")");
                        return m;
                    case "Log":
                        if (m.Arguments.Count == 1)
                        {
                            goto case "Log10";
                        }
                        break;
                    case "Pow":
                        this.Write("POWER(");
                        this.Visit(m.Arguments[0]);
                        this.Write(", ");
                        this.Visit(m.Arguments[1]);
                        this.Write(")");
                        return m;
                    case "Round":
                        if (m.Arguments.Count == 1)
                        {
                            this.Write("ROUND(");
                            this.Visit(m.Arguments[0]);
                            this.Write(")");
                            return m;
                        }
                        else if (m.Arguments.Count == 2 && m.Arguments[1].Type == typeof(int))
                        {
                            this.Write("ROUND(");
                            this.Visit(m.Arguments[0]);
                            this.Write(", ");
                            this.Visit(m.Arguments[1]);
                            this.Write(")");
                            return m;
                        }
                        break;
                    case "Truncate":
                        this.Write("TRUNCATE(");
                        this.Visit(m.Arguments[0]);
                        this.Write(",0)");
                        return m;
                }
            }
            if (m.Method.Name == "ToString")
            {
                if (m.Object.Type != typeof(string))
                {
                    this.Write("CAST(");
                    this.Visit(m.Object);
                    this.Write(" AS CHAR)");
                }
                else
                {
                    this.Visit(m.Object);
                }
                return m;
            }
            else if (!m.Method.IsStatic && m.Method.Name == "CompareTo" && m.Method.ReturnType == typeof(int) && m.Arguments.Count == 1)
            {
                this.Write("(CASE WHEN ");
                this.Visit(m.Object);
                this.Write(" = ");
                this.Visit(m.Arguments[0]);
                this.Write(" THEN 0 WHEN ");
                this.Visit(m.Object);
                this.Write(" < ");
                this.Visit(m.Arguments[0]);
                this.Write(" THEN -1 ELSE 1 END)");
                return m;
            }
            else if (m.Method.IsStatic && m.Method.Name == "Compare" && m.Method.ReturnType == typeof(int) && m.Arguments.Count == 2)
            {
                this.Write("(CASE WHEN ");
                this.Visit(m.Arguments[0]);
                this.Write(" = ");
                this.Visit(m.Arguments[1]);
                this.Write(" THEN 0 WHEN ");
                this.Visit(m.Arguments[0]);
                this.Write(" < ");
                this.Visit(m.Arguments[1]);
                this.Write(" THEN -1 ELSE 1 END)");
                return m;
            }
            return base.VisitMethodCall(m);
        }

        protected override NewExpression VisitNew(NewExpression nex)
        {
            if (nex.Constructor.DeclaringType == typeof(DateTime))
            {
                if (nex.Arguments.Count == 3)
                {
                    this.Write("CAST(CONCAT(");
                    this.Visit(nex.Arguments[0]);
                    this.Write(",'-',");
                    this.Visit(nex.Arguments[1]);
                    this.Write(",'-',");
                    this.Visit(nex.Arguments[2]);
                    this.Write(") AS DATETIME)");
                    return nex;
                }
                else if (nex.Arguments.Count == 6)
                {
                    this.Write("CAST(CONCAT(");
                    this.Visit(nex.Arguments[0]);
                    this.Write(",'-',");
                    this.Visit(nex.Arguments[1]);
                    this.Write(",'-',");
                    this.Visit(nex.Arguments[2]);
                    this.Write(",' ',");
                    this.Visit(nex.Arguments[3]);
                    this.Write(",':',");
                    this.Visit(nex.Arguments[4]);
                    this.Write(",':',");
                    this.Visit(nex.Arguments[5]);
                    this.Write(") AS DATETIME)");
                    return nex;
                }
            }
            return base.VisitNew(nex);
        }

        protected override Expression VisitBinary(BinaryExpression b)
        {
            if (b.NodeType == ExpressionType.Power)
            {
                this.Write("POWER(");
                this.VisitValue(b.Left);
                this.Write(", ");
                this.VisitValue(b.Right);
                this.Write(")");
                return b;
            }
            else if (b.NodeType == ExpressionType.Coalesce)
            {
                this.Write("COALESCE(");
                this.VisitValue(b.Left);
                this.Write(", ");
                Expression right = b.Right;
                while (right.NodeType == ExpressionType.Coalesce)
                {
                    BinaryExpression rb = (BinaryExpression)right;
                    this.VisitValue(rb.Left);
                    this.Write(", ");
                    right = rb.Right;
                }
                this.VisitValue(right);
                this.Write(")");
                return b;
            }
            else if (b.NodeType == ExpressionType.LeftShift)
            {
                this.Write("(");
                this.VisitValue(b.Left);
                this.Write(" << ");
                this.VisitValue(b.Right);
                this.Write(")");
                return b;
            }
            else if (b.NodeType == ExpressionType.RightShift)
            {
                this.Write("(");
                this.VisitValue(b.Left);
                this.Write(" >> ");
                this.VisitValue(b.Right);
                this.Write(")");
                return b;
            }
            else if (b.NodeType == ExpressionType.Add && b.Type == typeof(string))
            {
                this.Write("CONCAT(");
                int n = 0;
                this.VisitConcatArg(b.Left, ref n);
                this.VisitConcatArg(b.Right, ref n);
                this.Write(")");
                return b;
            }
            else if (b.NodeType == ExpressionType.Divide && this.IsInteger(b.Type))
            {
                this.Write("TRUNCATE(");
                base.VisitBinary(b);
                this.Write(",0)");
                return b;
            }
            return base.VisitBinary(b);
        }

        private void VisitConcatArg(Expression e, ref int n)
        {
            if (e.NodeType == ExpressionType.Add && e.Type == typeof(string))
            {
                BinaryExpression b = (BinaryExpression)e;
                VisitConcatArg(b.Left, ref n);
                VisitConcatArg(b.Right, ref n);
            }
            else
            {
                if (n > 0)
                    this.Write(", ");
                this.Visit(e);
                n++;
            }
        }

        protected override Expression VisitValue(Expression expr)
        {
            if (IsPredicate(expr))
            {
                this.Write("CASE WHEN (");
                this.Visit(expr);
                this.Write(") THEN 1 ELSE 0 END");
                return expr;
            }
            return base.VisitValue(expr);
        }

        protected override Expression VisitConditional(ConditionalExpression c)
        {
            if (this.IsPredicate(c.Test))
            {
                this.Write("(CASE WHEN ");
                this.VisitPredicate(c.Test);
                this.Write(" THEN ");
                this.VisitValue(c.IfTrue);
                Expression ifFalse = c.IfFalse;
                while (ifFalse != null && ifFalse.NodeType == ExpressionType.Conditional)
                {
                    ConditionalExpression fc = (ConditionalExpression)ifFalse;
                    this.Write(" WHEN ");
                    this.VisitPredicate(fc.Test);
                    this.Write(" THEN ");
                    this.VisitValue(fc.IfTrue);
                    ifFalse = fc.IfFalse;
                }
                if (ifFalse != null)
                {
                    this.Write(" ELSE ");
                    this.VisitValue(ifFalse);
                }
                this.Write(" END)");
            }
            else
            {
                this.Write("(CASE ");
                this.VisitValue(c.Test);
                this.Write(" WHEN 0 THEN ");
                this.VisitValue(c.IfFalse);
                this.Write(" ELSE ");
                this.VisitValue(c.IfTrue);
                this.Write(" END)");
            }
            return c;
        }
    }
}


text:
///
///@file  MeshTypes.h
///@brief Forward declarations of Mesh get_type_description.
///
///@author
///       Michael Callahan
///       Department of Computer Science
///       University of Utah
///@date  January 2005
///
///@details
///  The GCC 3.4 compiler will not compile the GenericField template
///  without these being declared ahead of time.  It will compile one
///  field include because the mesh is included before GenericField.
///  However if you include two field files it will fail because the
///  second one is not declared before the GenericField.h insertion
///  point.  It fails in order_type_description.
///

#ifndef Datatypes_MeshTypes_h
#define Datatypes_MeshTypes_h

namespace SCIRun {

class CurveMeshNode;
class CurveMeshEdge;
const TypeDescription *get_type_description(CurveMeshNode *);
const TypeDescription *get_type_description(CurveMeshEdge *);

class HexVolMeshNode;
class HexVolMeshCell;
const TypeDescription *get_type_description(HexVolMeshNode *);
const TypeDescription *get_type_description(HexVolMeshCell *);

class ImageMeshNode;
class ImageMeshFace;
const TypeDescription *get_type_description(ImageMeshNode *);
const TypeDescription *get_type_description(ImageMeshFace *);

class LatVolMeshNode;
class LatVolMeshCell;
const TypeDescription *get_type_description(LatVolMeshNode *);
const TypeDescription *get_type_description(LatVolMeshCell *);

class MaskedLatVolMeshNode;
class MaskedLatVolMeshCell;
const TypeDescription *get_type_description(MaskedLatVolMeshNode *);
const TypeDescription *get_type_description(MaskedLatVolMeshCell *);

class PointCloudMeshNode;
const TypeDescription *get_type_description(PointCloudMeshNode *);

class PrismVolMeshNode;
class PrismVolMeshCell;
const TypeDescription *get_type_description(PrismVolMeshNode *);
const TypeDescription *get_type_description(PrismVolMeshCell *);

class QuadraticLatVolMeshNode;
const TypeDescription *get_type_description(QuadraticLatVolMeshNode *);

class QuadSurfMeshNode;
class QuadSurfMeshFace;
const TypeDescription *get_type_description(QuadSurfMeshNode *);
const TypeDescription *get_type_description(QuadSurfMeshFace *);

class ScanlineMeshNode;
class ScanlineMeshEdge;
const TypeDescription *get_type_description(ScanlineMeshNode *);
const TypeDescription *get_type_description(ScanlineMeshEdge *);

class TetVolMeshNode;
class TetVolMeshCell;
const TypeDescription *get_type_description(TetVolMeshNode *);
const TypeDescription *get_type_description(TetVolMeshCell *);

class TriSurfMeshNode;
class TriSurfMeshFace;
const TypeDescription *get_type_description(TriSurfMeshNode *);
const TypeDescription *get_type_description(TriSurfMeshFace *);

} // end namespace SCIRun

#endif // Datatypes_MeshTypes_h

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace SilverWare\Navigation\Components;

use SilverWare\Navigation\Model\LinkHolder;

/**
 * An extension of the link holder class for block navigation.
 *
 * @package SilverWare\Navigation\Components
 * @author Colin Tucker <colin@praxis.net.au>
 * @copyright 2017 Praxis Interactive
 * @license https://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @link https://github.com/praxisnetau/silverware-navigation
 */
class BlockNavigation extends LinkHolder
{
    /**
     * Human-readable singular name.
     *
     * @var string
     * @config
     */
    private static $singular_name = 'Block Navigation';

    /**
     * Human-readable plural name.
     *
     * @var string
     * @config
     */
    private static $plural_name = 'Block Navigation';

    /**
     * Description of this object.
     *
     * @var string
     * @config
     */
    private static $description = 'A component which shows a series of links in a block';

    /**
     * Icon file for this object.
     *
     * @var string
     * @config
     */
    private static $icon = 'silverware/navigation: admin/client/dist/images/icons/BlockNavigation.png';

    /**
     * Defines the table name to use for this object.
     *
     * @var string
     * @config
     */
    private static $table_name = 'SilverWare_BlockNavigation';

    /**
     * Defines an ancestor class to hide from the admin interface.
     *
     * @var string
     * @config
     */
    private static $hide_ancestor = LinkHolder::class;

    /**
     * Answers an array of wrapper class names for the HTML template.
     *
     * @return array
     */
    public function getWrapperClassNames()
    {
        $classes = parent::getWrapperClassNames();

        $classes[] = 'block';

        return $classes;
    }
}


text:
/*************************************************************************/
/*  audio_server_sw.cpp                                                  */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "audio_server_sw.h"
#include "globals.h"
#include "os/os.h"

struct _AudioDriverLock {

	_AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->lock(); }
	~_AudioDriverLock() { if (AudioDriverSW::get_singleton()) AudioDriverSW::get_singleton()->unlock(); }

};

#define AUDIO_LOCK _AudioDriverLock _adlock;

AudioMixer *AudioServerSW::get_mixer() {

	return mixer;
}

/* CALLBACKS */

void AudioServerSW::audio_mixer_chunk_callback(int p_frames) {
/*
	for(List<Stream*>::Element *E=event_streams.front();E;E=E->next()) {

		if (E->get()->active)
			E->get()->audio_stream->mix(NULL,p_frames);
	}
*/
}

void AudioServerSW::_mixer_callback(void *p_udata) {

	AudioServerSW *self = (AudioServerSW*)p_udata;
	for(List<Stream*>::Element *E=self->active_audio_streams.front();E;E=E->next()) {

		if (!E->get()->active)
			continue;

		EventStream *es=E->get()->event_stream;
		if (!es)
			continue;

		es->update(self->mixer_step_usecs);
	}

}

void AudioServerSW::driver_process_chunk(int p_frames,int32_t *p_buffer) {

	int samples=p_frames*internal_buffer_channels;

	for(int i=0;i<samples;i++) {
		internal_buffer[i]=0;
	}

	while(voice_rb.commands_left()) {

		VoiceRBSW::Command cmd = voice_rb.pop_command();

		if (cmd.type==VoiceRBSW::Command::CMD_CHANGE_ALL_FX_VOLUMES) {

			SelfList<Voice>*al =  active_list.first();
			while(al) {

				Voice *v=al->self();
				if (v->channel!=AudioMixer::INVALID_CHANNEL) {
					mixer->channel_set_volume(v->channel,v->volume*fx_volume_scale);
				}
				al=al->next();
			}

			continue;
		}
		if (!voice_owner.owns(cmd.voice))
			continue;

		Voice *v = voice_owner.get(cmd.voice);

		switch(cmd.type) {
			case VoiceRBSW::Command::CMD_NONE: {

			} break;
			case VoiceRBSW::Command::CMD_PLAY: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_free(v->channel);

				RID sample = cmd.play.sample;
				if (!sample_manager->is_sample(sample))
					continue;

				v->channel=mixer->channel_alloc(sample);
				v->volume=1.0;
				mixer->channel_set_volume(v->channel,fx_volume_scale);
				if (v->channel==AudioMixer::INVALID_CHANNEL) {
#ifdef AUDIO_DEBUG
					WARN_PRINT("AUDIO: all channels used, failed to allocate voice");
#endif
					v->active=false;
					break; // no voices left?
				}

				v->active=true; // this kind of ensures it works
				if (!v->active_item.in_list())
					active_list.add(&v->active_item);

			} break;
			case VoiceRBSW::Command::CMD_STOP: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL) {
					mixer->channel_free(v->channel);
					if (v->active_item.in_list()) {
						active_list.remove(&v->active_item);
					}
				}
				v->active=false;
			} break;
			case VoiceRBSW::Command::CMD_SET_VOLUME: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL) {
					v->volume=cmd.volume.volume;
					mixer->channel_set_volume(v->channel,cmd.volume.volume*fx_volume_scale);
				}

			} break;
			case VoiceRBSW::Command::CMD_SET_PAN: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_pan(v->channel,cmd.pan.pan,cmd.pan.depth,cmd.pan.height);

			} break;
			case VoiceRBSW::Command::CMD_SET_FILTER: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_filter(v->channel,(AudioMixer::FilterType)cmd.filter.type,cmd.filter.cutoff,cmd.filter.resonance,cmd.filter.gain);
			} break;
			case VoiceRBSW::Command::CMD_SET_CHORUS: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_chorus(v->channel,cmd.chorus.send);

			} break;
			case VoiceRBSW::Command::CMD_SET_REVERB: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_reverb(v->channel,(AudioMixer::ReverbRoomType)cmd.reverb.room,cmd.reverb.send);

			} break;
			case VoiceRBSW::Command::CMD_SET_MIX_RATE: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_mix_rate(v->channel,cmd.mix_rate.mix_rate);

			} break;
			case VoiceRBSW::Command::CMD_SET_POSITIONAL: {

				if (v->channel!=AudioMixer::INVALID_CHANNEL)
					mixer->channel_set_positional(v->channel,cmd.positional.positional);

			} break;
			default: {}

		}
	}

	mixer->mix(internal_buffer,p_frames);
	//uint64_t stepsize=mixer->get_step_usecs();

	for(List<Stream*>::Element *E=active_audio_streams.front();E;E=E->next()) {

		ERR_CONTINUE(!E->get()->active); // bug?

		AudioStream *as=E->get()->audio_stream;
		if (!as)
			continue;

		int channels=as->get_channel_count();
		if (channels==0)
			continue; // does not want mix
		if (!as->mix(stream_buffer,p_frames))
			continue; //nothing was mixed!!

		int32_t stream_vol_scale=(stream_volume*stream_volume_scale*E->get()->volume_scale)*(1<<STREAM_SCALE_BITS);

#define STRSCALE(m_val)	(((m_val>>STREAM_SCALE_BITS)*stream_vol_scale)>>8)
		switch(internal_buffer_channels) {

			case 2: {

				switch(channels) {
					case 1: {

						for(int i=0;i<p_frames;i++) {

							internal_buffer[(i<<1)+0]+=STRSCALE(stream_buffer[i]);
							internal_buffer[(i<<1)+1]+=STRSCALE(stream_buffer[i]);
						}
					} break;
					case 2: {

						for(int i=0;i<p_frames*2;i++) {

							internal_buffer[i]+=STRSCALE(stream_buffer[i]);
						}
					} break;
					case 4: {

						for(int i=0;i<p_frames;i++) {

							internal_buffer[(i<<2)+0]+=STRSCALE((stream_buffer[(i<<2)+0]+stream_buffer[(i<<2)+2])>>1);
							internal_buffer[(i<<2)+1]+=STRSCALE((stream_buffer[(i<<2)+1]+stream_buffer[(i<<2)+3])>>1);
						}
					} break;

				} break;

			} break;
			case 4: {

				switch(channels) {
					case 1: {

						for(int i=0;i<p_frames;i++) {

							internal_buffer[(i<<2)+0]+=STRSCALE(stream_buffer[i]);
							internal_buffer[(i<<2)+1]+=STRSCALE(stream_buffer[i]);
							internal_buffer[(i<<2)+2]+=STRSCALE(stream_buffer[i]);
							internal_buffer[(i<<2)+3]+=STRSCALE(stream_buffer[i]);
						}
					} break;
					case 2: {

						for(int i=0;i<p_frames*2;i++) {

							internal_buffer[(i<<2)+0]+=STRSCALE(stream_buffer[(i<<1)+0]);
							internal_buffer[(i<<2)+1]+=STRSCALE(stream_buffer[(i<<1)+1]);
							internal_buffer[(i<<2)+2]+=STRSCALE(stream_buffer[(i<<1)+0]);
							internal_buffer[(i<<2)+3]+=STRSCALE(stream_buffer[(i<<1)+1]);
						}
					} break;
					case 4: {

						for(int i=0;i<p_frames*4;i++) {
							internal_buffer[i]+=STRSCALE(stream_buffer[i]);
						}
					} break;

				} break;

			} break;
			case 6: {

			} break;
		}

#undef STRSCALE
	}

	SelfList<Voice> *activeE=active_list.first();
	while(activeE) {

		SelfList<Voice> *activeN=activeE->next();
		if (activeE->self()->channel==AudioMixer::INVALID_CHANNEL || !mixer->channel_is_valid(activeE->self()->channel)) {

			active_list.remove(activeE);
			activeE->self()->active=false;

		}
		activeE=activeN;
	}

	uint32_t peak=0;
	for(int i=0;i<samples;i++) {
		//clamp to (1<<24) using branchless code
		int32_t in = internal_buffer[i];
#ifdef DEBUG_ENABLED
		{
		  int mask = (in >> (32 - 1));
		  uint32_t p = (in + mask) ^ mask;
		  if (p>peak)
			peak=p;
		}
#endif
		int32_t lo = -0x800000, hi=0x7FFFFF;
		lo-=in;
		hi-=in;
		in += (lo & ((lo < 0) - 1)) + (hi & ((hi > 0) - 1));
		p_buffer[i]=in<<8;
	}

	if (peak>max_peak)
		max_peak=peak;
}

void AudioServerSW::driver_process(int p_frames,int32_t *p_buffer) {

	_output_delay=p_frames/double(AudioDriverSW::get_singleton()->get_mix_rate());
	//process in chunks to make sure to never process more than INTERNAL_BUFFER_SIZE
	int todo=p_frames;
	while(todo) {

		int tomix=MIN(todo,INTERNAL_BUFFER_SIZE);
		driver_process_chunk(tomix,p_buffer);
		p_buffer+=tomix;
		todo-=tomix;
	}

}

/* SAMPLE API */

RID AudioServerSW::sample_create(SampleFormat p_format, bool p_stereo, int p_length) {

	AUDIO_LOCK

	return sample_manager->sample_create(p_format,p_stereo,p_length);
}

void AudioServerSW::sample_set_description(RID p_sample, const String& p_description) {

	AUDIO_LOCK
	sample_manager->sample_set_description(p_sample,p_description);
}
String AudioServerSW::sample_get_description(RID p_sample, const String& p_description) const {

	AUDIO_LOCK
	return sample_manager->sample_get_description(p_sample);
}

AS::SampleFormat AudioServerSW::sample_get_format(RID p_sample) const {
	//AUDIO_LOCK
	return sample_manager->sample_get_format(p_sample);
}
bool AudioServerSW::sample_is_stereo(RID p_sample) const {
	//AUDIO_LOCK
	return sample_manager->sample_is_stereo(p_sample);
}
int AudioServerSW::sample_get_length(RID p_sample) const  {
	///AUDIO_LOCK
	return sample_manager->sample_get_length(p_sample);
}

const void* AudioServerSW::sample_get_data_ptr(RID p_sample) const  {
	///AUDIO_LOCK
	return sample_manager->sample_get_data_ptr(p_sample);
}

void AudioServerSW::sample_set_data(RID p_sample, const DVector<uint8_t>& p_buffer) {
	AUDIO_LOCK
	sample_manager->sample_set_data(p_sample,p_buffer);
}
const DVector<uint8_t> AudioServerSW::sample_get_data(RID p_sample) const {
	AUDIO_LOCK
	return sample_manager->sample_get_data(p_sample);
}

void AudioServerSW::sample_set_mix_rate(RID p_sample,int p_rate) {
	AUDIO_LOCK
	sample_manager->sample_set_mix_rate(p_sample,p_rate);
}
int AudioServerSW::sample_get_mix_rate(RID p_sample) const {
	AUDIO_LOCK
	return sample_manager->sample_get_mix_rate(p_sample);
}

void AudioServerSW::sample_set_loop_format(RID p_sample,SampleLoopFormat p_format) {
	AUDIO_LOCK
	sample_manager->sample_set_loop_format(p_sample,p_format);
}
AS::SampleLoopFormat AudioServerSW::sample_get_loop_format(RID p_sample) const {
	AUDIO_LOCK
	return sample_manager->sample_get_loop_format(p_sample);
}

void AudioServerSW::sample_set_loop_begin(RID p_sample,int p_pos) {
	AUDIO_LOCK
	sample_manager->sample_set_loop_begin(p_sample,p_pos);
}
int AudioServerSW::sample_get_loop_begin(RID p_sample) const {
	AUDIO_LOCK
	return sample_manager->sample_get_loop_begin(p_sample);
}

void AudioServerSW::sample_set_loop_end(RID p_sample,int p_pos) {
	AUDIO_LOCK
	sample_manager->sample_set_loop_end(p_sample,p_pos);
}
int AudioServerSW::sample_get_loop_end(RID p_sample) const {
	AUDIO_LOCK
	return sample_manager->sample_get_loop_end(p_sample);
}

/* VOICE API */

RID AudioServerSW::voice_create() {

	Voice * v = memnew( Voice );
	v->channel=AudioMixer::INVALID_CHANNEL;

	AUDIO_LOCK
	return voice_owner.make_rid(v);

}
void AudioServerSW::voice_play(RID p_voice, RID p_sample) {

	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND(!v);
	v->active=true; // force actvive (will be disabled later i gues..)

	//stop old, start new
	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_PLAY;
	cmd.voice=p_voice;
	cmd.play.sample=p_sample;
	voice_rb.push_command(cmd);

}

void AudioServerSW::voice_set_volume(RID p_voice, float p_db) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_VOLUME;
	cmd.voice=p_voice;
	cmd.volume.volume=p_db;
	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_pan(RID p_voice, float p_pan, float p_depth,float p_height) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_PAN;
	cmd.voice=p_voice;
	cmd.pan.pan=p_pan;
	cmd.pan.depth=p_depth;
	cmd.pan.height=p_height;
	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_filter(RID p_voice, FilterType p_type, float p_cutoff, float p_resonance,float p_gain) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_FILTER;
	cmd.voice=p_voice;
	cmd.filter.type=p_type;
	cmd.filter.cutoff=p_cutoff;
	cmd.filter.resonance=p_resonance;
	cmd.filter.gain=p_gain;
	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_chorus(RID p_voice, float p_chorus ) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_CHORUS;
	cmd.voice=p_voice;
	cmd.chorus.send=p_chorus;
	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_reverb(RID p_voice, ReverbRoomType p_room_type, float p_reverb) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_REVERB;
	cmd.voice=p_voice;
	cmd.reverb.room=p_room_type;
	cmd.reverb.send=p_reverb;

	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_mix_rate(RID p_voice, int p_mix_rate) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_MIX_RATE;
	cmd.voice=p_voice;
	cmd.mix_rate.mix_rate=p_mix_rate;
	voice_rb.push_command(cmd);

}
void AudioServerSW::voice_set_positional(RID p_voice, bool p_positional) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_SET_POSITIONAL;
	cmd.voice=p_voice;
	cmd.positional.positional=p_positional;
	voice_rb.push_command(cmd);

}

float AudioServerSW::voice_get_volume(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_volume( v->channel );

}
float AudioServerSW::voice_get_pan(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_pan( v->channel );

}
float AudioServerSW::voice_get_pan_depth(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_pan_depth( v->channel );

}
float AudioServerSW::voice_get_pan_height(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_pan_height( v->channel );

}
AS::FilterType AudioServerSW::voice_get_filter_type(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, AS::FILTER_NONE);

	return (AS::FilterType)mixer->channel_get_filter_type(v->channel);

}
float AudioServerSW::voice_get_filter_cutoff(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_filter_cutoff( v->channel );

}
float AudioServerSW::voice_get_filter_resonance(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_filter_resonance( v->channel );

}
float AudioServerSW::voice_get_chorus(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_chorus( v->channel );

}
AS::ReverbRoomType AudioServerSW::voice_get_reverb_type(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, REVERB_SMALL);

	return (AS::ReverbRoomType)mixer->channel_get_reverb_type( v->channel );

}
float AudioServerSW::voice_get_reverb(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_reverb( v->channel );

}

int AudioServerSW::voice_get_mix_rate(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_get_mix_rate( v->channel );

}
bool AudioServerSW::voice_is_positional(RID p_voice) const {

	AUDIO_LOCK
	Voice *v = voice_owner.get( p_voice );
	ERR_FAIL_COND_V(!v, 0);

	return mixer->channel_is_positional( v->channel );

}

void AudioServerSW::voice_stop(RID p_voice) {

	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_STOP;
	cmd.voice=p_voice;
	voice_rb.push_command(cmd);

	//return mixer->channel_free( v->channel );

}

bool AudioServerSW::voice_is_active(RID p_voice) const {

	Voice *v = voice_owner.get(p_voice);
	ERR_FAIL_COND_V(!v,false);
	return v->active;

}

/* STREAM API */

RID AudioServerSW::audio_stream_create(AudioStream *p_stream) {

	AUDIO_LOCK
	Stream *s = memnew(Stream);
	s->audio_stream=p_stream;
	s->event_stream=NULL;
	s->active=false;
	s->E=NULL;
	s->volume_scale=1.0;
	p_stream->set_mix_rate(AudioDriverSW::get_singleton()->get_mix_rate());

	return stream_owner.make_rid(s);
}

RID AudioServerSW::event_stream_create(EventStream *p_stream) {

	AUDIO_LOCK
	Stream *s = memnew(Stream);
	s->audio_stream=NULL;
	s->event_stream=p_stream;
	s->active=false;
	s->E=NULL;
	s->volume_scale=1.0;
	//p_stream->set_mix_rate(AudioDriverSW::get_singleton()->get_mix_rate());

	return stream_owner.make_rid(s);

}

void AudioServerSW::stream_set_active(RID p_stream, bool p_active) {

	Stream *s = stream_owner.get(p_stream);
	ERR_FAIL_COND(!s);

	if (s->active==p_active)
		return;
	AUDIO_LOCK;
	_THREAD_SAFE_METHOD_
	s->active=p_active;
	if (p_active)
		s->E=active_audio_streams.push_back(s);
	else {
		active_audio_streams.erase(s->E);
		s->E=NULL;
	}
}

bool AudioServerSW::stream_is_active(RID p_stream) const {

	Stream *s = stream_owner.get(p_stream);
	ERR_FAIL_COND_V(!s,false);
	return s->active;
}

void AudioServerSW::stream_set_volume_scale(RID p_stream, float p_scale) {

	Stream *s = stream_owner.get(p_stream);
	ERR_FAIL_COND(!s);
	s->volume_scale=p_scale;

}

float AudioServerSW::stream_set_volume_scale(RID p_stream) const {

	Stream *s = stream_owner.get(p_stream);
	ERR_FAIL_COND_V(!s,0);
	return s->volume_scale;

}

void AudioServerSW::free(RID p_id) {

	if(voice_owner.owns(p_id)) {

		Voice *v = voice_owner.get(p_id);
		AUDIO_LOCK
		mixer->channel_free( v->channel );
		voice_owner.free(p_id);
		memdelete(v);

	} else if (stream_owner.owns(p_id)) {

		Stream *s=stream_owner.get(p_id);

		if (s->active) {
			stream_set_active(p_id,false);
		}

		memdelete(s);
		stream_owner.free(p_id);

	} else if (sample_manager->is_sample(p_id)) {

		AUDIO_LOCK
		sample_manager->free(p_id);
	}

}

void AudioServerSW::_thread_func(void *self) {

	AudioServerSW *as=(AudioServerSW *)self;

	while (!as->exit_update_thread) {
		as->_update_streams(true);
		OS::get_singleton()->delay_usec(5000);
	}

}

void AudioServerSW::init() {

	int latency = GLOBAL_DEF("audio/mixer_latency",10);
	internal_buffer_channels=2; // read from driver
	internal_buffer = memnew_arr(int32_t,INTERNAL_BUFFER_SIZE*internal_buffer_channels);
	stream_buffer = memnew_arr(int32_t,INTERNAL_BUFFER_SIZE*4); //max 4 channels
	AudioMixerSW::MixChannels mix_chans = AudioMixerSW::MIX_STEREO;

	switch(AudioDriverSW::get_singleton()->get_output_format()) {

		case AudioDriverSW::OUTPUT_MONO:
		case AudioDriverSW::OUTPUT_STEREO:
			mix_chans=AudioMixerSW::MIX_STEREO;
			break;
		case AudioDriverSW::OUTPUT_QUAD:
		case AudioDriverSW::OUTPUT_5_1:
			mix_chans=AudioMixerSW::MIX_QUAD;
			break;
	}

	mixer = memnew( AudioMixerSW( sample_manager, latency, AudioDriverSW::get_singleton()->get_mix_rate(),mix_chans,mixer_use_fx,mixer_interp,_mixer_callback,this ) );
	mixer_step_usecs=mixer->get_step_usecs();

	_output_delay=0;

	stream_volume=0.3;
	// start the audio driver
	if (AudioDriverSW::get_singleton())
		AudioDriverSW::get_singleton()->start();

#ifndef NO_THREADS
	exit_update_thread=false;
	thread = Thread::create(_thread_func,this);
#endif

}

void AudioServerSW::finish() {

#ifndef NO_THREADS
	exit_update_thread=true;
	Thread::wait_to_finish(thread);
	memdelete(thread);
#endif

	if (AudioDriverSW::get_singleton())
		AudioDriverSW::get_singleton()->finish();

	memdelete_arr(internal_buffer);
	memdelete_arr(stream_buffer);
	memdelete(mixer);

}

void AudioServerSW::_update_streams(bool p_thread) {

	_THREAD_SAFE_METHOD_
	for(List<Stream*>::Element *E=active_audio_streams.front();E;) { //stream might be removed durnig this callback

		List<Stream*>::Element *N=E->next();

		if (E->get()->audio_stream && p_thread == E->get()->audio_stream->can_update_mt())
			E->get()->audio_stream->update();

		E=N;
	}

}

void AudioServerSW::update() {

	_update_streams(false);
#ifdef NO_THREADS

	_update_streams(true);
#endif
}

void AudioServerSW::lock() {

	AudioDriverSW::get_singleton()->lock();
}

void AudioServerSW::unlock() {
	AudioDriverSW::get_singleton()->unlock();

}

int AudioServerSW::get_default_mix_rate() const {

	return AudioDriverSW::get_singleton()->get_mix_rate();
}
int AudioServerSW::get_default_channel_count() const {
	return internal_buffer_channels;
}

void AudioServerSW::set_mixer_params(AudioMixerSW::InterpolationType p_interp, bool p_use_fx) {

	mixer_interp=p_interp;
	mixer_use_fx=p_use_fx;
}

void AudioServerSW::set_stream_global_volume_scale(float p_volume) {

	stream_volume_scale=p_volume;
}

float AudioServerSW::get_stream_global_volume_scale() const {

	return stream_volume_scale;

}

void AudioServerSW::set_fx_global_volume_scale(float p_volume) {

	fx_volume_scale=p_volume;
	//mixer->set_mixer_volume(fx_volume_scale);
	VoiceRBSW::Command cmd;
	cmd.type=VoiceRBSW::Command::CMD_CHANGE_ALL_FX_VOLUMES;
	cmd.voice=RID();
	cmd.volume.volume=p_volume;
	voice_rb.push_command(cmd);

}

float AudioServerSW::get_fx_global_volume_scale() const {

	return fx_volume_scale;
}

void AudioServerSW::set_event_voice_global_volume_scale(float p_volume) {

	event_voice_volume_scale=p_volume;
	//mixer->set_mixer_volume(event_voice_volume_scale);
}

float AudioServerSW::get_event_voice_global_volume_scale() const {

	return event_voice_volume_scale;
}

double AudioServerSW::get_output_delay() const {

	return _output_delay;
}

double AudioServerSW::get_mix_time() const {

	return AudioDriverSW::get_singleton()->get_mix_time();
}

uint32_t AudioServerSW::read_output_peak() const {

	uint32_t val = max_peak;
	uint32_t *p = (uint32_t*)&max_peak;
	*p=0;
	return val;
}

AudioServerSW::AudioServerSW(SampleManagerSW *p_sample_manager) {

	sample_manager=p_sample_manager;
	String interp = GLOBAL_DEF("audio/mixer_interp","linear");
	Globals::get_singleton()->set_custom_property_info("audio/mixer_interp",PropertyInfo(Variant::STRING,"audio/mixer_interp",PROPERTY_HINT_ENUM,"raw,linear,cubic"));
	if (interp=="raw")
		mixer_interp=AudioMixerSW::INTERPOLATION_RAW;
	else if (interp=="cubic")
		mixer_interp=AudioMixerSW::INTERPOLATION_CUBIC;
	else
		mixer_interp=AudioMixerSW::INTERPOLATION_LINEAR;
	mixer_use_fx = GLOBAL_DEF("audio/use_chorus_reverb",true);
	stream_volume_scale=GLOBAL_DEF("audio/stream_volume_scale",1.0);
	fx_volume_scale=GLOBAL_DEF("audio/fx_volume_scale",1.0);
	event_voice_volume_scale=GLOBAL_DEF("audio/event_voice_volume_scale",0.5);
	max_peak=0;

}

AudioServerSW::~AudioServerSW() {

}

AudioDriverSW *AudioDriverSW::singleton=NULL;
AudioDriverSW *AudioDriverSW::get_singleton() {

	return singleton;
}

void AudioDriverSW::set_singleton() {

	singleton=this;
}

void AudioDriverSW::audio_server_process(int p_frames,int32_t *p_buffer,bool p_update_mix_time) {

	AudioServerSW * audio_server = static_cast<AudioServerSW*>(AudioServer::get_singleton());
	if (p_update_mix_time)
		update_mix_time(p_frames);
	audio_server->driver_process(p_frames,p_buffer);
}

void AudioDriverSW::update_mix_time(int p_frames) {

	_mix_amount+=p_frames;
	_last_mix_time=OS::get_singleton()->get_ticks_usec();
}

double AudioDriverSW::get_mix_time() const {

	double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
	total+=_mix_amount/(double)get_mix_rate();
	return total;

}

AudioDriverSW::AudioDriverSW() {

	_last_mix_time=0;
	_mix_amount=0;
}

AudioDriverSW *AudioDriverManagerSW::drivers[MAX_DRIVERS];
int AudioDriverManagerSW::driver_count=0;

void AudioDriverManagerSW::add_driver(AudioDriverSW *p_driver) {

	ERR_FAIL_COND(driver_count>=MAX_DRIVERS);
	drivers[driver_count++]=p_driver;
}

int AudioDriverManagerSW::get_driver_count() {

	return driver_count;
}
AudioDriverSW *AudioDriverManagerSW::get_driver(int p_driver) {

	ERR_FAIL_INDEX_V(p_driver,driver_count,NULL);
	return drivers[p_driver];
}


text:
.class Lcom/tencent/open/x;
.super Lcom/tencent/open/C;

# instance fields
.field final synthetic a:Lcom/tencent/open/TaskGuide;

# direct methods
.method private constructor <init>(Lcom/tencent/open/TaskGuide;)V
    .locals 1

    iput-object p1, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    const/4 v0, 0x0

    invoke-direct {p0, p1, v0}, Lcom/tencent/open/C;-><init>(Lcom/tencent/open/TaskGuide;Lcom/tencent/open/t;)V

    return-void
.end method

.method synthetic constructor <init>(Lcom/tencent/open/TaskGuide;Lcom/tencent/open/t;)V
    .locals 0

    invoke-direct {p0, p1}, Lcom/tencent/open/x;-><init>(Lcom/tencent/open/TaskGuide;)V

    return-void
.end method

# virtual methods
.method protected a(Ljava/lang/Exception;)V
    .locals 5

    if-eqz p1, :cond_0

    invoke-virtual {p1}, Ljava/lang/Exception;->printStackTrace()V

    :cond_0
    if-nez p1, :cond_1

    new-instance v1, Lorg/json/JSONObject;

    invoke-direct {v1}, Lorg/json/JSONObject;-><init>()V

    :try_start_0
    const-string v0, "result"

    const-string v2, "\u6682\u65e0\u4efb\u52a1"

    invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    :try_end_0
    .catch Lorg/json/JSONException; {:try_start_0 .. :try_end_0} :catch_0

    :goto_0
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    iget-object v0, v0, Lcom/tencent/open/TaskGuide;->c:Lcom/tencent/tauth/IUiListener;

    invoke-interface {v0, v1}, Lcom/tencent/tauth/IUiListener;->onComplete(Ljava/lang/Object;)V

    :goto_1
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    invoke-static {v0}, Lcom/tencent/open/TaskGuide;->x(Lcom/tencent/open/TaskGuide;)Landroid/os/Handler;

    move-result-object v0

    new-instance v1, Lcom/tencent/open/y;

    invoke-direct {v1, p0}, Lcom/tencent/open/y;-><init>(Lcom/tencent/open/x;)V

    invoke-virtual {v0, v1}, Landroid/os/Handler;->post(Ljava/lang/Runnable;)Z

    return-void

    :catch_0
    move-exception v0

    invoke-virtual {v0}, Lorg/json/JSONException;->printStackTrace()V

    goto :goto_0

    :cond_1
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    iget-object v0, v0, Lcom/tencent/open/TaskGuide;->c:Lcom/tencent/tauth/IUiListener;

    new-instance v1, Lcom/tencent/tauth/UiError;

    const/16 v2, 0x64

    const-string v3, "error "

    const-string v4, "\u83b7\u53d6\u4efb\u52a1\u5931\u8d25"

    invoke-direct {v1, v2, v3, v4}, Lcom/tencent/tauth/UiError;-><init>(ILjava/lang/String;Ljava/lang/String;)V

    invoke-interface {v0, v1}, Lcom/tencent/tauth/IUiListener;->onError(Lcom/tencent/tauth/UiError;)V

    goto :goto_1
.end method

.method public onComplete(Lorg/json/JSONObject;)V
    .locals 3

    :try_start_0
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    invoke-static {p1}, Lcom/tencent/open/E;->a(Lorg/json/JSONObject;)Lcom/tencent/open/E;

    move-result-object v1

    invoke-static {v0, v1}, Lcom/tencent/open/TaskGuide;->a(Lcom/tencent/open/TaskGuide;Lcom/tencent/open/E;)Lcom/tencent/open/E;
    :try_end_0
    .catch Lorg/json/JSONException; {:try_start_0 .. :try_end_0} :catch_0

    :goto_0
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    invoke-static {v0}, Lcom/tencent/open/TaskGuide;->y(Lcom/tencent/open/TaskGuide;)Lcom/tencent/open/E;

    move-result-object v0

    if-eqz v0, :cond_0

    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    invoke-static {v0}, Lcom/tencent/open/TaskGuide;->y(Lcom/tencent/open/TaskGuide;)Lcom/tencent/open/E;

    move-result-object v0

    invoke-virtual {v0}, Lcom/tencent/open/E;->a()Z

    move-result v0

    if-eqz v0, :cond_0

    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    invoke-virtual {v0}, Lcom/tencent/open/TaskGuide;->showWindow()V

    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    const/4 v1, 0x2

    sget-object v2, Lcom/tencent/open/z;->d:Lcom/tencent/open/z;

    invoke-static {v0, v1, v2}, Lcom/tencent/open/TaskGuide;->a(Lcom/tencent/open/TaskGuide;ILcom/tencent/open/z;)V

    new-instance v1, Lorg/json/JSONObject;

    invoke-direct {v1}, Lorg/json/JSONObject;-><init>()V

    :try_start_1
    const-string v0, "result"

    const-string v2, "\u83b7\u53d6\u6210\u529f"

    invoke-virtual {v1, v0, v2}, Lorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    :try_end_1
    .catch Lorg/json/JSONException; {:try_start_1 .. :try_end_1} :catch_1

    :goto_1
    iget-object v0, p0, Lcom/tencent/open/x;->a:Lcom/tencent/open/TaskGuide;

    iget-object v0, v0, Lcom/tencent/open/TaskGuide;->c:Lcom/tencent/tauth/IUiListener;

    invoke-interface {v0, v1}, Lcom/tencent/tauth/IUiListener;->onComplete(Ljava/lang/Object;)V

    :goto_2
    return-void

    :catch_0
    move-exception v0

    invoke-virtual {v0}, Lorg/json/JSONException;->printStackTrace()V

    goto :goto_0

    :catch_1
    move-exception v0

    invoke-virtual {v0}, Lorg/json/JSONException;->printStackTrace()V

    goto :goto_1

    :cond_0
    const/4 v0, 0x0

    invoke-virtual {p0, v0}, Lcom/tencent/open/x;->a(Ljava/lang/Exception;)V

    goto :goto_2
.end method


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="gray" type="color">#FF888888</color>
    <color name="ltgray" type="color">#FFCCCCCC</color>
</resources>


text:
import json
import multiprocessing
import os
import math
import six

import tensorflow as tf
from tensorflow.python.lib.io import file_io

from tensorflow.contrib.learn.python.learn.utils import input_fn_utils
from tensorflow.contrib.learn.python.learn import export_strategy
from tensorflow.contrib.learn.python.learn.utils import (
    saved_model_export_utils)

from tensorflow.python.ops import resources
from tensorflow.python.ops import variables
from tensorflow.contrib.framework.python.ops import variables as contrib_variables
from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib
from tensorflow.python.training import saver
from tensorflow.python.framework import ops
from tensorflow.python.client import session as tf_session
from tensorflow.python.saved_model import builder as saved_model_builder
from tensorflow.python.saved_model import tag_constants
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.util import compat
from tensorflow.python.platform import gfile
from tensorflow.python.saved_model import signature_def_utils

SCHEMA_FILE = 'schema.json'
NUMERICAL_ANALYSIS = 'stats.json'
CATEGORICAL_ANALYSIS = 'vocab_%s.csv'

# Constants for the Prediction Graph fetch tensors.
PG_TARGET = 'target'  # from input

PG_REGRESSION_PREDICTED_TARGET = 'predicted'

PG_CLASSIFICATION_FIRST_LABEL = 'predicted'
PG_CLASSIFICATION_FIRST_SCORE = 'score'
PG_CLASSIFICATION_LABEL_TEMPLATE = 'predicted_%s'
PG_CLASSIFICATION_SCORE_TEMPLATE = 'score_%s'

class NotFittedError(ValueError):
    pass

# ==============================================================================
# Functions for saving the exported graphs.
# ==============================================================================

def _recursive_copy(src_dir, dest_dir):
  """Copy the contents of src_dir into the folder dest_dir.
  Args:
    src_dir: gsc or local path.
    dest_dir: gcs or local path.
  When called, dest_dir should exist.
  """
  src_dir = python_portable_string(src_dir)
  dest_dir = python_portable_string(dest_dir)

  file_io.recursive_create_dir(dest_dir)
  for file_name in file_io.list_directory(src_dir):
    old_path = os.path.join(src_dir, file_name)
    new_path = os.path.join(dest_dir, file_name)

    if file_io.is_directory(old_path):
      _recursive_copy(old_path, new_path)
    else:
      file_io.copy(old_path, new_path, overwrite=True)

def serving_from_csv_input(train_config, args, keep_target):
  """Read the input features from a placeholder csv string tensor."""
  examples = tf.placeholder(
      dtype=tf.string,
      shape=(None,),
      name='csv_input_string')

  features = parse_example_tensor(examples=examples,
                                  train_config=train_config,
                                  keep_target=keep_target)

  if keep_target:
    target = features.pop(train_config['target_column'])
  else:
    target = None
  features, target = preprocess_input(
      features=features,
      target=target,
      train_config=train_config,
      preprocess_output_dir=args.preprocess_output_dir,
      model_type=args.model_type)

  return input_fn_utils.InputFnOps(features,
                                   target,
                                   {'csv_line': examples}
                                   )

def make_output_tensors(train_config, args, input_ops, model_fn_ops, keep_target=True):
    target_name = train_config['target_column']
    key_name = train_config['key_column']

    outputs = {}
    outputs[key_name] = tf.squeeze(input_ops.features[key_name])

    if is_classification_model(args.model_type):

      # build maps from ints to the origional categorical strings.
      string_value = get_vocabulary(args.preprocess_output_dir, target_name)
      table = tf.contrib.lookup.index_to_string_table_from_tensor(
          mapping=string_value,
          default_value='UNKNOWN')

      # Get the label of the input target.
      if keep_target:
        input_target_label = table.lookup(input_ops.labels)
        outputs[PG_TARGET] = tf.squeeze(input_target_label)

      # TODO(brandondutra): get the score of the target label too.
      probabilities = model_fn_ops.predictions['probabilities']

      # get top k labels and their scores.
      (top_k_values, top_k_indices) = tf.nn.top_k(probabilities, k=args.top_n)
      top_k_labels = table.lookup(tf.to_int64(top_k_indices))

      # Write the top_k values using 2*top_k columns.
      num_digits = int(math.ceil(math.log(args.top_n, 10)))
      if num_digits == 0:
        num_digits = 1
      for i in range(0, args.top_n):
        # Pad i based on the size of k. So if k = 100, i = 23 -> i = '023'. This
        # makes sorting the columns easy.
        padded_i = str(i + 1).zfill(num_digits)

        if i == 0:
          label_alias = PG_CLASSIFICATION_FIRST_LABEL
        else:
          label_alias = PG_CLASSIFICATION_LABEL_TEMPLATE % padded_i

        label_tensor_name = (tf.squeeze(
            tf.slice(top_k_labels, [0, i], [tf.shape(top_k_labels)[0], 1])))

        if i == 0:
          score_alias = PG_CLASSIFICATION_FIRST_SCORE
        else:
          score_alias = PG_CLASSIFICATION_SCORE_TEMPLATE % padded_i

        score_tensor_name = (tf.squeeze(
            tf.slice(top_k_values,
                     [0, i],
                     [tf.shape(top_k_values)[0], 1])))

        outputs.update({label_alias: label_tensor_name,
                        score_alias: score_tensor_name})

    else:
      if keep_target:
        outputs[PG_TARGET] = tf.squeeze(input_ops.labels)

      scores = model_fn_ops.predictions['scores']
      outputs[PG_REGRESSION_PREDICTED_TARGET] = tf.squeeze(scores)

    return outputs

def make_export_strategy(train_config, args, keep_target, assets_extra=None):
  def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None):
    with ops.Graph().as_default() as g:
      contrib_variables.create_global_step(g)

      input_ops = serving_from_csv_input(train_config, args, keep_target)
      model_fn_ops = estimator._call_model_fn(input_ops.features,
                                              None,
                                              model_fn_lib.ModeKeys.INFER)
      output_fetch_tensors = make_output_tensors(
          train_config=train_config,
          args=args,
          input_ops=input_ops,
          model_fn_ops=model_fn_ops,
          keep_target=keep_target)

      signature_def_map = {
        'serving_default': signature_def_utils.predict_signature_def(input_ops.default_inputs,
                                                                     output_fetch_tensors)
      }

      if not checkpoint_path:
        # Locate the latest checkpoint
        checkpoint_path = saver.latest_checkpoint(estimator._model_dir)
      if not checkpoint_path:
        raise NotFittedError("Couldn't find trained model at %s."
                             % estimator._model_dir)

      export_dir = saved_model_export_utils.get_timestamped_export_dir(
          export_dir_base)

      if (model_fn_ops.scaffold is not None and
         model_fn_ops.scaffold.saver is not None):
        saver_for_restore = model_fn_ops.scaffold.saver
      else:
        saver_for_restore = saver.Saver(sharded=True)

      with tf_session.Session('') as session:
        saver_for_restore.restore(session, checkpoint_path)
        init_op = control_flow_ops.group(
            variables.local_variables_initializer(),
            resources.initialize_resources(resources.shared_resources()),
            tf.tables_initializer())

        # Perform the export
        builder = saved_model_builder.SavedModelBuilder(export_dir)
        builder.add_meta_graph_and_variables(
            session, [tag_constants.SERVING],
            signature_def_map=signature_def_map,
            assets_collection=ops.get_collection(
                ops.GraphKeys.ASSET_FILEPATHS),
            legacy_init_op=init_op)
        builder.save(False)

      # Add the extra assets
      if assets_extra:
        assets_extra_path = os.path.join(compat.as_bytes(export_dir),
                                         compat.as_bytes('assets.extra'))
        for dest_relative, source in assets_extra.items():
          dest_absolute = os.path.join(compat.as_bytes(assets_extra_path),
                                       compat.as_bytes(dest_relative))
          dest_path = os.path.dirname(dest_absolute)
          gfile.MakeDirs(dest_path)
          gfile.Copy(source, dest_absolute)

    # only keep the last 3 models
    saved_model_export_utils.garbage_collect_exports(
        python_portable_string(export_dir_base),
        exports_to_keep=3)

    # save the last model to the model folder.
    # export_dir_base = A/B/intermediate_models/
    if keep_target:
      final_dir = os.path.join(args.job_dir, 'evaluation_model')
    else:
      final_dir = os.path.join(args.job_dir, 'model')
    if file_io.is_directory(final_dir):
      file_io.delete_recursively(final_dir)
    file_io.recursive_create_dir(final_dir)
    _recursive_copy(export_dir, final_dir)

    return export_dir

  if keep_target:
    intermediate_dir = 'intermediate_evaluation_models'
  else:
    intermediate_dir = 'intermediate_prediction_models'

  return export_strategy.ExportStrategy(intermediate_dir, export_fn)

# ==============================================================================
# Reading the input csv files and parsing its output into tensors.
# ==============================================================================

def parse_example_tensor(examples, train_config, keep_target):
  """Read the csv files.

  Args:
    examples: string tensor
    train_config: training config
    keep_target: if true, the target column is expected to exist and it is
        returned in the features dict.

  Returns:
    Dict of feature_name to tensor. Target feature is in the dict.
  """

  csv_header = []
  if keep_target:
    csv_header = train_config['csv_header']
  else:
    csv_header = [name for name in train_config['csv_header']
                  if name != train_config['target_column']]

  # record_defaults are used by tf.decode_csv to insert defaults, and to infer
  # the datatype.
  record_defaults = [[train_config['csv_defaults'][name]]
                     for name in csv_header]
  tensors = tf.decode_csv(examples, record_defaults, name='csv_to_tensors')

  # I'm not really sure why expand_dims needs to be called. If using regression
  # models, it errors without it.
  tensors = [tf.expand_dims(x, axis=1) for x in tensors]

  tensor_dict = dict(zip(csv_header, tensors))
  return tensor_dict

def read_examples(input_files, batch_size, shuffle, num_epochs=None):
  """Creates readers and queues for reading example protos."""
  files = []
  for e in input_files:
    for path in e.split(','):
      files.extend(file_io.get_matching_files(path))
  thread_count = multiprocessing.cpu_count()

  # The minimum number of instances in a queue from which examples are drawn
  # randomly. The larger this number, the more randomness at the expense of
  # higher memory requirements.
  min_after_dequeue = 1000

  # When batching data, the queue's capacity will be larger than the batch_size
  # by some factor. The recommended formula is (num_threads + a small safety
  # margin). For now, we use a single thread for reading, so this can be small.
  queue_size_multiplier = thread_count + 3

  # Convert num_epochs == 0 -> num_epochs is None, if necessary
  num_epochs = num_epochs or None

  # Build a queue of the filenames to be read.
  filename_queue = tf.train.string_input_producer(files, num_epochs, shuffle)

  example_id, encoded_example = tf.TextLineReader().read_up_to(
      filename_queue, batch_size)

  if shuffle:
    capacity = min_after_dequeue + queue_size_multiplier * batch_size
    return tf.train.shuffle_batch(
        [example_id, encoded_example],
        batch_size,
        capacity,
        min_after_dequeue,
        enqueue_many=True,
        num_threads=thread_count)

  else:
    capacity = queue_size_multiplier * batch_size
    return tf.train.batch(
        [example_id, encoded_example],
        batch_size,
        capacity=capacity,
        enqueue_many=True,
        num_threads=thread_count)

# ==============================================================================
# Building the TF learn estimators
# ==============================================================================

def get_estimator(output_dir, train_config, args):
  """Returns a tf learn estimator.

  We only support {DNN, Linear}Regressor and {DNN, Linear}Classifier. This is
  controlled by the values of model_type in the args.

  Args:
    output_dir: Modes are saved into outputdir/train
    train_config: our training config
    args: command line parameters

  Returns:
    TF lean estimator

  Raises:
    ValueError: if config is wrong.
  """

  # Check the requested mode fits the preprocessed data.
  target_name = train_config['target_column']
  if is_classification_model(args.model_type) and target_name not in \
          train_config['categorical_columns']:
    raise ValueError('When using a classification model, the target must be a '
                     'categorical variable.')
  if is_regression_model(args.model_type) and target_name not in \
          train_config['numerical_columns']:
    raise ValueError('When using a regression model, the target must be a '
                     'numerical variable.')

  # Check layers used for dnn models.
  if is_dnn_model(args.model_type) and not args.layer_sizes:
    raise ValueError('--layer-size* must be used with DNN models')
  if is_linear_model(args.model_type) and args.layer_sizes:
    raise ValueError('--layer-size* cannot be used with linear models')

  # Build tf.learn features
  feature_columns = _tflearn_features(train_config, args)

  # Set how often to run checkpointing in terms of time.
  config = tf.contrib.learn.RunConfig(
      save_checkpoints_secs=args.save_checkpoints_secs)

  train_dir = os.path.join(output_dir, 'train')
  if args.model_type == 'dnn_regression':
    estimator = tf.contrib.learn.DNNRegressor(
        feature_columns=feature_columns,
        hidden_units=args.layer_sizes,
        config=config,
        model_dir=train_dir,
        optimizer=tf.train.AdamOptimizer(
            args.learning_rate, epsilon=args.epsilon))
  elif args.model_type == 'linear_regression':
    estimator = tf.contrib.learn.LinearRegressor(
        feature_columns=feature_columns,
        config=config,
        model_dir=train_dir,
        optimizer=tf.train.AdamOptimizer(
            args.learning_rate, epsilon=args.epsilon))
  elif args.model_type == 'dnn_classification':
    estimator = tf.contrib.learn.DNNClassifier(
        feature_columns=feature_columns,
        hidden_units=args.layer_sizes,
        n_classes=train_config['vocab_stats'][target_name]['n_classes'],
        config=config,
        model_dir=train_dir,
        optimizer=tf.train.AdamOptimizer(
            args.learning_rate, epsilon=args.epsilon))
  elif args.model_type == 'linear_classification':
    estimator = tf.contrib.learn.LinearClassifier(
        feature_columns=feature_columns,
        n_classes=train_config['vocab_stats'][target_name]['n_classes'],
        config=config,
        model_dir=train_dir,
        optimizer=tf.train.AdamOptimizer(
            args.learning_rate, epsilon=args.epsilon))
  else:
    raise ValueError('bad --model-type value')

  return estimator

def preprocess_input(features, target, train_config, preprocess_output_dir,
                     model_type):
  """Perform some transformations after reading in the input tensors.

  Args:
    features: dict of feature_name to tensor
    target: tensor
    train_config: our training config object
    preprocess_output_dir: folder should contain the vocab files.
    model_type: the tf model type.

  Raises:
    ValueError: if wrong transforms are used

  Returns:
    New features dict and new target tensor.
  """

  target_name = train_config['target_column']
  key_name = train_config['key_column']

  # Do the numerical transforms.
  # Numerical transforms supported for regression/classification
  # 1) num -> do nothing (identity, default)
  # 2) num -> scale to -1, 1 (scale)
  # 3) num -> scale to -a, a (scale with value parameter)
  with tf.name_scope('numerical_feature_preprocess'):
    if train_config['numerical_columns']:
      numerical_analysis_file = os.path.join(preprocess_output_dir,
                                             NUMERICAL_ANALYSIS)
      if not file_io.file_exists(numerical_analysis_file):
        raise ValueError('File %s not found in %s' %
                         (NUMERICAL_ANALYSIS, preprocess_output_dir))

      numerical_anlysis = json.loads(
          python_portable_string(
              file_io.read_file_to_string(numerical_analysis_file)))

      for name in train_config['numerical_columns']:
        if name == target_name or name == key_name:
          continue

        transform_config = train_config['transforms'].get(name, {})
        transform_name = transform_config.get('transform', None)
        if transform_name == 'scale':
          value = float(transform_config.get('value', 1.0))
          features[name] = _scale_tensor(
              features[name],
              range_min=numerical_anlysis[name]['min'],
              range_max=numerical_anlysis[name]['max'],
              scale_min=-value,
              scale_max=value)
        elif transform_name == 'identity' or transform_name is None:
          pass
        else:
          raise ValueError(('For numerical variables, only scale '
                            'and identity are supported: '
                            'Error for %s') % name)

  # Do target transform if it exists.
  if target is not None:
    with tf.name_scope('target_feature_preprocess'):
      if target_name in train_config['categorical_columns']:
        labels = train_config['vocab_stats'][target_name]['labels']
        table = tf.contrib.lookup.string_to_index_table_from_tensor(labels)
        target = table.lookup(target)
        # target = tf.contrib.lookup.string_to_index(target, labels)

  # Do categorical transforms. Only apply vocab mapping. The real
  # transforms are done with tf learn column features.
  with tf.name_scope('categorical_feature_preprocess'):
    for name in train_config['categorical_columns']:
      if name == key_name or name == target_name:
        continue
      transform_config = train_config['transforms'].get(name, {})
      transform_name = transform_config.get('transform', None)

      if is_dnn_model(model_type):
        if transform_name == 'embedding' or transform_name == 'one_hot' or transform_name is None:
          map_vocab = True
        else:
          raise ValueError('Unknown transform %s' % transform_name)
      elif is_linear_model(model_type):
        if (transform_name == 'one_hot' or transform_name is None):
          map_vocab = True
        elif transform_name == 'embedding':
          map_vocab = False
        else:
          raise ValueError('Unknown transform %s' % transform_name)
      if map_vocab:
        labels = train_config['vocab_stats'][name]['labels']
        table = tf.contrib.lookup.string_to_index_table_from_tensor(labels)
        features[name] = table.lookup(features[name])

  return features, target

def _scale_tensor(tensor, range_min, range_max, scale_min, scale_max):
  """Scale a tensor to scale_min to scale_max.

  Args:
    tensor: input tensor. Should be a numerical tensor.
    range_min: min expected value for this feature/tensor.
    range_max: max expected Value.
    scale_min: new expected min value.
    scale_max: new expected max value.

  Returns:
    scaled tensor.
  """
  if range_min == range_max:
    return tensor

  float_tensor = tf.to_float(tensor)
  scaled_tensor = tf.divide((tf.subtract(float_tensor, range_min) *
                             tf.constant(float(scale_max - scale_min))),
                            tf.constant(float(range_max - range_min)))
  shifted_tensor = scaled_tensor + tf.constant(float(scale_min))

  return shifted_tensor

def _tflearn_features(train_config, args):
  """Builds the tf.learn feature list.

  All numerical features are just given real_valued_column because all the
  preprocessing transformations are done in preprocess_input. Categoriacl
  features are processed here depending if the vocab map (from string to int)
  was applied in preprocess_input.

  Args:
    train_config: our train config object
    args: command line args.

  Returns:
    List of TF lean feature columns.

  Raises:
    ValueError: if wrong transforms are used for the model type.
  """
  feature_columns = []
  target_name = train_config['target_column']
  key_name = train_config['key_column']

  for name in train_config['numerical_columns']:
    if name != target_name and name != key_name:
      feature_columns.append(tf.contrib.layers.real_valued_column(
          name,
          dimension=1))

      # Supported transforms:
      # for DNN
      # 1) string -> make int -> embedding (embedding)
      # 2) string -> make int -> one_hot (one_hot, default)
      # for linear
      # 1) string -> sparse_column_with_hash_bucket (embedding)
      # 2) string -> make int -> sparse_column_with_integerized_feature (one_hot, default)
      # It is unfortunate that tf.layers has different feature transforms if the
      # model is linear or DNN. This pacakge should not expose to the user that
      # we are using tf.layers. It is crazy that DNN models support more feature
      # types (like string -> hash sparse column -> embedding)
  for name in train_config['categorical_columns']:
    if name != target_name and name != key_name:
      transform_config = train_config['transforms'].get(name, {})
      transform_name = transform_config.get('transform', None)

      if is_dnn_model(args.model_type):
        if transform_name == 'embedding':
          sparse = tf.contrib.layers.sparse_column_with_integerized_feature(
              name,
              bucket_size=train_config['vocab_stats'][name]['n_classes'])
          learn_feature = tf.contrib.layers.embedding_column(
              sparse,
              dimension=transform_config['embedding_dim'])
        elif transform_name == 'one_hot' or transform_name is None:
          sparse = tf.contrib.layers.sparse_column_with_integerized_feature(
              name,
              bucket_size=train_config['vocab_stats'][name]['n_classes'])
          learn_feature = tf.contrib.layers.one_hot_column(sparse)
        else:
          raise ValueError(('Unknown transform name. Only \'embedding\' '
                            'and \'one_hot\' transforms are supported. Got %s')
                           % transform_name)
      elif is_linear_model(args.model_type):
        if transform_name == 'one_hot' or transform_name is None:
          learn_feature = tf.contrib.layers.sparse_column_with_integerized_feature(
              name,
              bucket_size=train_config['vocab_stats'][name]['n_classes'])
        elif transform_name == 'embedding':
          learn_feature = tf.contrib.layers.sparse_column_with_hash_bucket(
              name,
              hash_bucket_size=transform_config['embedding_dim'])
        else:
          raise ValueError(('Unknown transform name. Only \'embedding\' '
                            'and \'one_hot\' transforms are supported. Got %s')
                           % transform_name)

      # Save the feature
      feature_columns.append(learn_feature)
  return feature_columns

# ==============================================================================
# Functions for dealing with the parameter files.
# ==============================================================================

def get_vocabulary(preprocess_output_dir, name):
  """Loads the vocabulary file as a list of strings.

  Args:
    preprocess_output_dir: Should contain the file CATEGORICAL_ANALYSIS % name.
    name: name of the csv column.

  Returns:
    List of strings.

  Raises:
    ValueError: if file is missing.
  """
  vocab_file = os.path.join(preprocess_output_dir, CATEGORICAL_ANALYSIS % name)
  if not file_io.file_exists(vocab_file):
    raise ValueError('File %s not found in %s' %
                     (CATEGORICAL_ANALYSIS % name, preprocess_output_dir))

  labels = python_portable_string(
      file_io.read_file_to_string(vocab_file)).split('\n')
  label_values = [x for x in labels if x]  # remove empty lines

  return label_values

def merge_metadata(preprocess_output_dir, transforms_file):
  """Merge schema, analysis, and transforms files into one python object.

  Args:
    preprocess_output_dir: the output folder of preprocessing. Should contain
        the schema, and the numerical and categorical
        analysis files.
    transforms_file: the training transforms file.

  Returns:
    A dict in the form
    {
      csv_header: [name1, name2, ...],
      csv_defaults: {name1: value, name2: value},
      key_column: name,
      target_column: name,
      categorical_columns: []
      numerical_columns: []
      transforms: { name1: {transform: scale, value: 2},
                    name2: {transform: embedding, dim: 50}, ...
                  }
      vocab_stats: { name3: {n_classes: 23, labels: ['1', '2', ..., '23']},
                     name4: {n_classes: 102, labels: ['red', 'blue', ...]}}
    }

  Raises:
    ValueError: if one of the input metadata files is wrong.
  """
  numerical_anlysis_file = os.path.join(preprocess_output_dir,
                                        NUMERICAL_ANALYSIS)
  schema_file = os.path.join(preprocess_output_dir, SCHEMA_FILE)

  numerical_anlysis = json.loads(
      python_portable_string(
          file_io.read_file_to_string(numerical_anlysis_file)))
  schema = json.loads(
      python_portable_string(file_io.read_file_to_string(schema_file)))
  transforms = json.loads(
      python_portable_string(file_io.read_file_to_string(transforms_file)))

  result_dict = {}
  result_dict['csv_header'] = [col_schema['name'] for col_schema in schema]
  result_dict['key_column'] = None
  result_dict['target_column'] = None
  result_dict['categorical_columns'] = []
  result_dict['numerical_columns'] = []
  result_dict['transforms'] = {}
  result_dict['csv_defaults'] = {}
  result_dict['vocab_stats'] = {}

  # get key column.
  for name, trans_config in six.iteritems(transforms):
    if trans_config.get('transform', None) == 'key':
      result_dict['key_column'] = name
      break
  if result_dict['key_column'] is None:
    raise ValueError('Key transform missing form transfroms file.')

  # get target column.
  result_dict['target_column'] = schema[0]['name']
  for name, trans_config in six.iteritems(transforms):
    if trans_config.get('transform', None) == 'target':
      result_dict['target_column'] = name
      break
  if result_dict['target_column'] is None:
    raise ValueError('Target transform missing from transforms file.')

  # Get the numerical/categorical columns.
  for col_schema in schema:
    col_name = col_schema['name']
    col_type = col_schema['type'].lower()
    if col_name == result_dict['key_column']:
      continue

    if col_type == 'string':
      result_dict['categorical_columns'].append(col_name)
    elif col_type == 'integer' or col_type == 'float':
      result_dict['numerical_columns'].append(col_name)
    else:
      raise ValueError('Unsupported schema type %s' % col_type)

  # Get the transforms.
  for name, trans_config in six.iteritems(transforms):
    if name != result_dict['target_column'] and name != result_dict['key_column']:
      result_dict['transforms'][name] = trans_config

  # Get the vocab_stats
  for name in result_dict['categorical_columns']:
    if name == result_dict['key_column']:
      continue

    label_values = get_vocabulary(preprocess_output_dir, name)
    if name != result_dict['target_column'] and '' not in label_values:
      label_values.append('')  # append a 'missing' label.
    n_classes = len(label_values)
    result_dict['vocab_stats'][name] = {'n_classes': n_classes,
                                        'labels': label_values}

  # Get the csv_defaults
  for col_schema in schema:
    name = col_schema['name']
    col_type = col_schema['type'].lower()
    default = transforms.get(name, {}).get('default', None)

    if name == result_dict['target_column']:
      if name in result_dict['numerical_columns']:
        default = float(default or 0.0)
      else:
        default = default or ''
    elif name == result_dict['key_column']:
      if col_type == 'string':
        default = str(default or '')
      elif col_type == 'float':
        default = float(default or 0.0)
      else:
        default = int(default or 0)
    else:
      if col_type == 'string':
        default = str(default or '')
        if default not in result_dict['vocab_stats'][name]['labels']:
          raise ValueError('Default %s is not in the vocab for %s' %
                           (default, name))
      else:
        default = float(default or numerical_anlysis[name]['mean'])

    result_dict['csv_defaults'][name] = default

  validate_metadata(result_dict)
  return result_dict

def validate_metadata(train_config):
  """Perform some checks that the trainig config is correct.

  Args:
    train_config: train config as produced by merge_metadata()

  Raises:
    ValueError: if columns look wrong.
  """

  # Make sure we have a default for every column
  if len(train_config['csv_header']) != len(train_config['csv_defaults']):
    raise ValueError('Unequal number of columns in input features file and '
                     'schema file.')

  # Check there are no missing columns. sorted_colums has two copies of the
  # target column because the target column is also listed in
  # categorical_columns or numerical_columns.
  sorted_columns = sorted(train_config['csv_header'] +
                          [train_config['target_column']])

  sorted_columns2 = sorted(train_config['categorical_columns'] +
                           train_config['numerical_columns'] +
                           [train_config['key_column']] +
                           [train_config['target_column']])
  if sorted_columns2 != sorted_columns:
    raise ValueError('Each csv header must be a numerical/categorical type, a '
                     ' key, or a target.')

def is_linear_model(model_type):
  return model_type.startswith('linear_')

def is_dnn_model(model_type):
  return model_type.startswith('dnn_')

def is_regression_model(model_type):
  return model_type.endswith('_regression')

def is_classification_model(model_type):
  return model_type.endswith('_classification')

# Note that this function exists in google.datalab.utils, but that is not
# installed on the training workers.
def python_portable_string(string, encoding='utf-8'):
  """Converts bytes into a string type.

  Valid string types are retuned without modification. So in Python 2, type str
  and unicode are not converted.

  In Python 3, type bytes is converted to type str (unicode)
  """
  if isinstance(string, six.string_types):
    return string

  if six.PY3:
    return string.decode(encoding)

  raise ValueError('Unsupported type %s' % str(type(string)))


text:
package main

import "github.com/mackerelio/go-check-plugins/check-memcached/lib"

func main() {
	checkmemcached.Do()
}


text:
package org.apache.sis.internal.referencing.provider;

import javax.measure.quantity.Angle;
import javax.measure.quantity.Length;
import javax.xml.bind.annotation.XmlTransient;
import org.opengis.util.FactoryException;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterValueGroup;
import org.apache.sis.internal.util.Constants;
import org.apache.sis.referencing.operation.transform.InterpolatedMolodenskyTransform;

/**
 * An approximation of geocentric interpolations which uses {@link InterpolatedMolodenskyTransform}
 * instead than {@link org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform}.
 *
 *
This operation method is not standard, and as of SIS 0.7 not yet registered in the operation methods
 * provided by {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory}.
 * This class extends {@code FranceGeocentricInterpolation} for now because the later is currently
 * the only operation performing interpolation in the geocentric domain.
 * However this class hierarchy may be revisited in any future SIS version.

 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.7
 * @since   0.7
 * @module
 */
@XmlTransient
public final class MolodenskyInterpolation extends FranceGeocentricInterpolation {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = 4265894749866901286L;

    /**
     * Constructs a provider.
     */
    public MolodenskyInterpolation() {
        super(2, 2, builder().setCodeSpace(null, Constants.SIS).addName("Molodensky interpolation")
                        .createGroupWithSameParameters(PARAMETERS), new MolodenskyInterpolation[4]);
        final ParameterDescriptorGroup parameters = super.getParameters();
        redimensioned[0] = this;
        redimensioned[1] = new MolodenskyInterpolation(2, 3, parameters, redimensioned);
        redimensioned[2] = new MolodenskyInterpolation(3, 2, parameters, redimensioned);
        redimensioned[3] = new MolodenskyInterpolation(3, 3, parameters, redimensioned);
    }

    /**
     * Constructs a provider for the given number of dimensions.
     *
     * @param sourceDimensions  number of dimensions in the source CRS of this operation method.
     * @param targetDimensions  number of dimensions in the target CRS of this operation method.
     * @param parameters        description of parameters expected by this operation.
     * @param redimensioned     providers for all combinations between 2D and 3D cases, or {@code null}.
     */
    private MolodenskyInterpolation(final int sourceDimensions,
                                    final int targetDimensions,
                                    final ParameterDescriptorGroup parameters,
                                    final GeodeticOperation[] redimensioned)
    {
        super(sourceDimensions, targetDimensions, parameters, redimensioned);
    }

    /**
     * Invoked by {@link #createMathTransform(MathTransformFactory, ParameterValueGroup)}
     * after all parameters have been processed.
     */
    @Override
    MathTransform createGeodeticTransformation(final MathTransformFactory factory,
            final Ellipsoid source, final Ellipsoid target, final boolean withHeights,
            final DatumShiftGridFile<Angle,Length> grid) throws FactoryException
    {
        return InterpolatedMolodenskyTransform.createGeodeticTransformation(
                factory, source, withHeights, target, withHeights, grid);
    }
}


text:
- card.io Android SDK Version:
- Android Version and Device (Motorola Droid Razr Maxx with Android 4.4.2, Samsung S7 with Android 6.0, etc...):

### Issue Description
> Please include as many details (logs, steps to reproduce, screenshots) as you can to help us reproduce this issue faster.


text:
Nifty type-safe implementations of various lambda calculi (currently just untyped and simply typed).

Finite totally ordered sets are used for De Bruijn indexing:

```haskell
data Fin n where
    Zero :: Fin (S n)
    Succ :: Fin n -> Fin (S n)
```

This project is currently on hold, but may someday be used in the implementation of a crappy toy dependantly typed language. Who knows.


text:
using System;
namespace com.esendex.sdk.inbox
{
    /// <summary>
    /// Contains the values of an inbox message status.
    /// </summary>
    [Serializable]
    public enum InboxMessageStatus
    {
        /// <summary>
        /// Message marked as read.
        /// </summary>
        Read,

        /// <summary>
        /// Message marked as unread.
        /// </summary>
        Unread
    }
}