<commit_before>// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <llvm/ADT/Optional.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/ScopedPrinter.h>
#include <mlir/IR/BuiltinOps.h>
#include <llvm/Support/raw_os_ostream.hv
#include <llvm/Support/raw_ostream.h>
#include <mlir/Dialect/StandardOps/IR/Ops.h>
#include <mlir/IR/AsmState.h>
#include <mlir/IR/Block.h>
#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/Operation.h>
#include <mlir/IR/Region.h>
#include <mlir/IR/Verifier.h>
#include <mlir/Parser.h>
#include <mlir/Pass/PassManager.h>
#include <mlir/Support/LogicalResult.h>
#include <mlir/Transforms/Passes.h>
#include <iostream>

#include "paddle/infrt/common/global.h"
#include "paddle/infrt/dialect/init_infrt_dialects.h"

namespace cl = llvm::cl;

static cl::opt<std::string> inputFilename(cl::Positional,
                                          cl::desc("<input toy file>"),
                                          cl::init("-"),
                                          cl::value_desc("filename"));

llvm::raw_ostream &printIndent(int indent = 0) {
  for (int i = 0; i < indent; ++i) llvm::outs() << "    ";
  return llvm::outs();
}

void printOperation(mlir::Operation *op, int indent);
void printRegion(mlir::Region &region, int indent);  // NOLINT
void printBlock(mlir::Block &block, int indent);     // NOLINT

void printOperation(mlir::Operation *op, int indent) {
  llvm::Optional<mlir::ModuleOp> module_op = llvm::None;
  if (llvm::isa<mlir::ModuleOp>(op))
    module_op = llvm::dyn_cast<mlir::ModuleOp>(op);
  llvm::Optional<mlir::FuncOp> func_op = llvm::None;
  if (llvm::isa<mlir::FuncOp>(op)) func_op = llvm::dyn_cast<mlir::FuncOp>(op);

  printIndent(indent) << "op: '" << op->getName();
  // This getName is inherited from Operation::getName
  if (module_op) {
    printIndent() << "@" << module_op->getName();
  }
  // This getName is inherited from SymbolOpInterfaceTrait::getName,
  // which return value of "sym_name" in ModuleOp or FuncOp attributes.
  if (func_op) {
    printIndent() << "@" << func_op->getName();
  }
  printIndent() << "' with " << op->getNumOperands() << " operands"
                << ", " << op->getNumResults() << " results"
                << ", " << op->getAttrs().size() << " attributes"
                << ", " << op->getNumRegions() << " regions"
                << ", " << op->getNumSuccessors() << " successors\n";
  if (!op->getAttrs().empty()) {
    printIndent(indent) << op->getAttrs().size() << " attributes:\n";
    for (mlir::NamedAttribute attr : op->getAttrs()) {
      printIndent(indent + 1) << "- {" << attr.first << " : " << attr.second
                              << "}\n";
    }
  }

  if (op->getNumRegions() > 0) {
    printIndent(indent) << op->getNumRegions() << " nested regions:\n";
    for (mlir::Region &region : op->getRegions()) {
      printRegion(region, indent + 1);
    }
  }
}

void printRegion(mlir::Region &region, int indent) {  // NOLINT
  printIndent(indent) << "Region with " << region.getBlocks().size()
                      << " blocks:\n";
  for (mlir::Block &block : region.getBlocks()) {
    printBlock(block, indent + 1);
  }
}

void printBlock(mlir::Block &block, int indent) {  // NOLINT
  printIndent(indent) << "Block with " << block.getNumArguments()
                      << " arguments"
                      << ", " << block.getNumSuccessors() << " successors"
                      << ", " << block.getOperations().size()
                      << " operations\n";

  for (mlir::Operation &operation : block.getOperations()) {
    printOperation(&operation, indent + 1);
  }
}

int main(int argc, char **argv) {
  mlir::registerAsmPrinterCLOptions();
  mlir::registerMLIRContextCLOptions();
  mlir::registerPassManagerCLOptions();
  cl::ParseCommandLineOptions(argc, argv, "mlir demo");

  mlir::DialectRegistry registry;
  infrt::registerCinnDialects(registry);
  mlir::MLIRContext context(registry);
  // mlir will verify module automatically after parsing.
  // https://github.com/llvm/llvm-project/blob/38d18d93534d290d045bbbfa86337e70f1139dc2/mlir/lib/Parser/Parser.cpp#L2051
  // mlir::OwningModuleRef module_ref = mlir::parseSourceString(mlir_source,
  // context);
  mlir::OwningModuleRef module_ref =
      mlir::parseSourceFile(inputFilename, &context);
  std::cout << "----------print IR Structure begin----------" << std::endl;
  printOperation(module_ref->getOperation(), 0);
  std::cout << "----------print IR Structure end----------" << std::endl;

  module_ref->dump();
  return 0;
}
<commit_msg>fix build bug (#38997)<commit_after>// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <llvm/ADT/Optional.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/ScopedPrinter.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Support/raw_ostream.h>
#include <mlir/Dialect/StandardOps/IR/Ops.h>
#include <mlir/IR/AsmState.h>
#include <mlir/IR/Block.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/Operation.h>
#include <mlir/IR/Region.h>
#include <mlir/IR/Verifier.h>
#include <mlir/Parser.h>
#include <mlir/Pass/PassManager.h>
#include <mlir/Support/LogicalResult.h>
#include <mlir/Transforms/Passes.h>
#include <iostream>

#include "paddle/infrt/common/global.h"
#include "paddle/infrt/dialect/init_infrt_dialects.h"

namespace cl = llvm::cl;

static cl::opt<std::string> inputFilename(cl::Positional,
                                          cl::desc("<input toy file>"),
                                          cl::init("-"),
                                          cl::value_desc("filename"));

llvm::raw_ostream &printIndent(int indent = 0) {
  for (int i = 0; i < indent; ++i) llvm::outs() << "    ";
  return llvm::outs();
}

void printOperation(mlir::Operation *op, int indent);
void printRegion(mlir::Region &region, int indent);  // NOLINT
void printBlock(mlir::Block &block, int indent);     // NOLINT

void printOperation(mlir::Operation *op, int indent) {
  llvm::Optional<mlir::ModuleOp> module_op = llvm::None;
  if (llvm::isa<mlir::ModuleOp>(op))
    module_op = llvm::dyn_cast<mlir::ModuleOp>(op);
  llvm::Optional<mlir::FuncOp> func_op = llvm::None;
  if (llvm::isa<mlir::FuncOp>(op)) func_op = llvm::dyn_cast<mlir::FuncOp>(op);

  printIndent(indent) << "op: '" << op->getName();
  // This getName is inherited from Operation::getName
  if (module_op) {
    printIndent() << "@" << module_op->getName();
  }
  // This getName is inherited from SymbolOpInterfaceTrait::getName,
  // which return value of "sym_name" in ModuleOp or FuncOp attributes.
  if (func_op) {
    printIndent() << "@" << func_op->getName();
  }
  printIndent() << "' with " << op->getNumOperands() << " operands"
                << ", " << op->getNumResults() << " results"
                << ", " << op->getAttrs().size() << " attributes"
                << ", " << op->getNumRegions() << " regions"
                << ", " << op->getNumSuccessors() << " successors\n";
  if (!op->getAttrs().empty()) {
    printIndent(indent) << op->getAttrs().size() << " attributes:\n";
    for (mlir::NamedAttribute attr : op->getAttrs()) {
      printIndent(indent + 1) << "- {" << attr.getName() << " : "
                              << attr.getValue() << "}\n";
    }
  }

  if (op->getNumRegions() > 0) {
    printIndent(indent) << op->getNumRegions() << " nested regions:\n";
    for (mlir::Region &region : op->getRegions()) {
      printRegion(region, indent + 1);
    }
  }
}

void printRegion(mlir::Region &region, int indent) {  // NOLINT
  printIndent(indent) << "Region with " << region.getBlocks().size()
                      << " blocks:\n";
  for (mlir::Block &block : region.getBlocks()) {
    printBlock(block, indent + 1);
  }
}

void printBlock(mlir::Block &block, int indent) {  // NOLINT
  printIndent(indent) << "Block with " << block.getNumArguments()
                      << " arguments"
                      << ", " << block.getNumSuccessors() << " successors"
                      << ", " << block.getOperations().size()
                      << " operations\n";

  for (mlir::Operation &operation : block.getOperations()) {
    printOperation(&operation, indent + 1);
  }
}

int main(int argc, char **argv) {
  mlir::registerAsmPrinterCLOptions();
  mlir::registerMLIRContextCLOptions();
  mlir::registerPassManagerCLOptions();
  cl::ParseCommandLineOptions(argc, argv, "mlir demo");

  mlir::DialectRegistry registry;
  infrt::registerCinnDialects(registry);
  mlir::MLIRContext context(registry);
  // mlir will verify module automatically after parsing.
  // https://github.com/llvm/llvm-project/blob/38d18d93534d290d045bbbfa86337e70f1139dc2/mlir/lib/Parser/Parser.cpp#L2051
  // mlir::OwningModuleRef module_ref = mlir::parseSourceString(mlir_source,
  // context);
  mlir::OwningModuleRef module_ref =
      mlir::parseSourceFile(inputFilename, &context);
  std::cout << "----------print IR Structure begin----------" << std::endl;
  printOperation(module_ref->getOperation(), 0);
  std::cout << "----------print IR Structure end----------" << std::endl;

  module_ref->dump();
  return 0;
}
<|endoftext|>


<commit_before>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QtTest/QtTest>

#include "json_driver.h"
#include "serializer.h"

#include <QtCore/QVariant>

using namespace QJSon;

class TestJSonDriver: public QObject
{
  Q_OBJECT
  private slots:
    void parseNonAsciiString();
    void parseSimpleObject();
    void parseEmptyObject();
    void parseUrl();
    void parseMultipleObject();

    void parseSimpleArray();
    void parseInvalidObject();
    void parseMultipleArray();

    void testTrueFalseNullValues();
    void testEscapeChars();
    void testNumbers();

    void testReadWriteEmptyDocument();
    void testSerialize();
    void testSerialize_data();
    void testReadWrite();
    void testReadWrite_data();
};

Q_DECLARE_METATYPE(QVariant)

void TestJSonDriver::parseSimpleObject() {
  QString json = "{\"foo\":\"bar\"}";
  QVariantMap map;
  map.insert ("foo", "bar");
  QVariant expected(map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseEmptyObject() {
  QString json = "{}";
  QVariantMap map;
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseInvalidObject() {
  QString json = "{\"foo\":\"bar\"";

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (!ok);
}

void TestJSonDriver::parseNonAsciiString() {
  QString json = "{\"artist\":\"Queensr\\u00ffche\"}";
  QVariantMap map;

  QChar unicode_char (0x00ff);
  QString unicode_string;
  unicode_string.setUnicode(&unicode_char, 1);
  unicode_string = "Queensr" + unicode_string + "che";

  map.insert ("artist", unicode_string);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleObject() {
  //put also some extra spaces inside the json string
  QString json = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
  QVariantMap map;
  map.insert ("foo", "bar");
  map.insert ("number", 51.3);
  QVariantList list;
  list.append (QString("item1"));
  list.append (QString("123"));
  map.insert ("array", list);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QVERIFY (result.toMap()["number"].canConvert<float>());
  QVERIFY (result.toMap()["array"].canConvert<QVariantList>());
}

void TestJSonDriver::parseUrl(){
  //"http:\/\/www.last.fm\/venue\/8926427"
  QString json = "[\"http:\\/\\/www.last.fm\\/venue\\/8926427\"]";
  QVariantList list;
  list.append (QVariant(QString("http://www.last.fm/venue/8926427")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

 void TestJSonDriver::parseSimpleArray() {
  QString json = "[\"foo\",\"bar\"]";
  QVariantList list;
  list.append (QVariant(QString("foo")));
  list.append (QVariant(QString("bar")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleArray() {
  //put also some extra spaces inside the json string
  QString json = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
  QVariantMap map;
  map.insert ("foo", "bar");

  QVariantList array;
  array.append (QString("item1"));
  array.append (123);

  QVariantList list;
  list.append (map);
  list.append (QString("number"));
  list.append (QString("51.3"));
  list.append ((QVariant) array);

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testTrueFalseNullValues() {
  QString json = "[true,false, null, {\"foo\" : true}]";
  QVariantList list;
  list.append (QVariant(true));
  list.append (QVariant(false));
  list.append (QVariant());
  QVariantMap map;
  map.insert ("foo", true);
  list.append (map);
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QCOMPARE (result.toList().at(0).toBool(), true);
  QCOMPARE (result.toList().at(1).toBool(), false);
  QVERIFY (result.toList().at(2).isNull());
}

void TestJSonDriver::testEscapeChars() {
  QString json = "[\"\\b \\f \\n \\r \\t \", \" \\\\ \\/ \\\" \", \"http://foo.com\"]";

  QVariantList list;
  list.append (QVariant("\b \f \n \r \t "));
  list.append (QVariant(" \\\\ / \\\" "));
  list.append (QVariant("http://foo.com"));

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testNumbers() {
  QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
  QVariantList list;
  list.append (QVariant(1));
  list.append (QVariant(2.4));
  list.append (QVariant(-100));
  list.append (QVariant(-3.4));
  list.append (QVariant("-5e+"));
  list.append (QVariant("2e"));
  list.append (QVariant("3e+"));
  list.append (QVariant("4.3E"));
  list.append (QVariant("5.4E-"));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);

  QVariantList numbers = result.toList();
  QCOMPARE( numbers[0].type(),QVariant::Int );
  QCOMPARE( numbers[1].type(), QVariant::Double );
  QCOMPARE( numbers[2].type(), QVariant::Int );
  QCOMPARE( numbers[3].type(), QVariant::Double );
}

void TestJSonDriver::testReadWriteEmptyDocument()
{
  QString json = QString("");
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
  QVERIFY( !serialized.isNull() );
  QVERIFY( serialized.isEmpty() );
}

void TestJSonDriver::testSerialize()
{
  QFETCH( QVariant, qvariant );
  QFETCH( QString, expected );
  Serializer serializer;
  bool ok;
  QString result = serializer.serialize( qvariant);
  result = result.replace(" ", "");
  expected = expected.replace(" ", "");
  QCOMPARE(result, expected);
}

void TestJSonDriver::testSerialize_data()
{
    QTest::addColumn<QVariant>( "qvariant" );
    QTest::addColumn<QString>( "expected" );

    // array tests
    QVariantList array;
    array.clear();
    QTest::newRow( "empty array") << (QVariant) array << "[]";

    array << QVariant("foo") << QVariant("bar");
    QTest::newRow( "basic array") << (QVariant)  array << "[\"foo\",\"bar\"]";

    array.clear();
    array << QVariant(6);
    QTest::newRow( "int array") << (QVariant)  array << "[6]";

    // document tests
    QVariantMap map;
    map.clear();
    QTest::newRow( "empty object") << (QVariant)  map << "{}";

    map["foo"] = QVariant("bar");
    QTest::newRow( "basic document") << (QVariant) map << "{ \"foo\":\"bar\" }";

    map["foo"] = QVariant(6);
    QTest::newRow( "object with ints" ) << (QVariant) map << "{ \"foo\":6 }";
}

void TestJSonDriver::testReadWrite()
{
  QFETCH( QString, json );
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
//  qWarning() << serialized;
  QVariant writtenThenRead = driver.parse( serialized, &ok );
  QCOMPARE( result, writtenThenRead );
}

void TestJSonDriver::testReadWrite_data()
{
    QTest::addColumn<QString>( "json" );

    // array tests
    QTest::newRow( "empty array" ) << "[]";
    QTest::newRow( "basic array" ) << "[\"foo\",\"bar\"]";
    QTest::newRow( "single int array" ) << "[6]";
    QTest::newRow( "int array" ) << "[6,5,6,7]";
    const QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
    QTest::newRow( "array of various numbers" ) << json;

    // document tests
    QTest::newRow( "empty object" ) << "{}";
    QTest::newRow( "basic document" ) << "{\"foo\":\"bar\"}";
    QTest::newRow( "object with ints" ) << "{\"foo\":6}";
    QString json2 = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
    QTest::newRow( "complicated document" ) << json2;

    // more complex cases
    const QString json3 = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
    QTest::newRow( "complicated array" ) << json3;
}

QTEST_MAIN(TestJSonDriver)
#include "moc_testjsondriver.cxx"
<commit_msg>remove useless test case<commit_after>/* This file is part of QJson
 *
 * Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <QtTest/QtTest>

#include "json_driver.h"
#include "serializer.h"

#include <QtCore/QVariant>

using namespace QJSon;

class TestJSonDriver: public QObject
{
  Q_OBJECT
  private slots:
    void parseNonAsciiString();
    void parseSimpleObject();
    void parseEmptyObject();
    void parseUrl();
    void parseMultipleObject();

    void parseSimpleArray();
    void parseInvalidObject();
    void parseMultipleArray();

    void testTrueFalseNullValues();
    void testEscapeChars();
    void testNumbers();

    void testReadWriteEmptyDocument();
    void testReadWrite();
    void testReadWrite_data();
};

Q_DECLARE_METATYPE(QVariant)

void TestJSonDriver::parseSimpleObject() {
  QString json = "{\"foo\":\"bar\"}";
  QVariantMap map;
  map.insert ("foo", "bar");
  QVariant expected(map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseEmptyObject() {
  QString json = "{}";
  QVariantMap map;
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseInvalidObject() {
  QString json = "{\"foo\":\"bar\"";

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (!ok);
}

void TestJSonDriver::parseNonAsciiString() {
  QString json = "{\"artist\":\"Queensr\\u00ffche\"}";
  QVariantMap map;

  QChar unicode_char (0x00ff);
  QString unicode_string;
  unicode_string.setUnicode(&unicode_char, 1);
  unicode_string = "Queensr" + unicode_string + "che";

  map.insert ("artist", unicode_string);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleObject() {
  //put also some extra spaces inside the json string
  QString json = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
  QVariantMap map;
  map.insert ("foo", "bar");
  map.insert ("number", 51.3);
  QVariantList list;
  list.append (QString("item1"));
  list.append (QString("123"));
  map.insert ("array", list);
  QVariant expected (map);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QVERIFY (result.toMap()["number"].canConvert<float>());
  QVERIFY (result.toMap()["array"].canConvert<QVariantList>());
}

void TestJSonDriver::parseUrl(){
  //"http:\/\/www.last.fm\/venue\/8926427"
  QString json = "[\"http:\\/\\/www.last.fm\\/venue\\/8926427\"]";
  QVariantList list;
  list.append (QVariant(QString("http://www.last.fm/venue/8926427")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

 void TestJSonDriver::parseSimpleArray() {
  QString json = "[\"foo\",\"bar\"]";
  QVariantList list;
  list.append (QVariant(QString("foo")));
  list.append (QVariant(QString("bar")));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::parseMultipleArray() {
  //put also some extra spaces inside the json string
  QString json = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
  QVariantMap map;
  map.insert ("foo", "bar");

  QVariantList array;
  array.append (QString("item1"));
  array.append (123);

  QVariantList list;
  list.append (map);
  list.append (QString("number"));
  list.append (QString("51.3"));
  list.append ((QVariant) array);

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testTrueFalseNullValues() {
  QString json = "[true,false, null, {\"foo\" : true}]";
  QVariantList list;
  list.append (QVariant(true));
  list.append (QVariant(false));
  list.append (QVariant());
  QVariantMap map;
  map.insert ("foo", true);
  list.append (map);
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
  QCOMPARE (result.toList().at(0).toBool(), true);
  QCOMPARE (result.toList().at(1).toBool(), false);
  QVERIFY (result.toList().at(2).isNull());
}

void TestJSonDriver::testEscapeChars() {
  QString json = "[\"\\b \\f \\n \\r \\t \", \" \\\\ \\/ \\\" \", \"http://foo.com\"]";

  QVariantList list;
  list.append (QVariant("\b \f \n \r \t "));
  list.append (QVariant(" \\\\ / \\\" "));
  list.append (QVariant("http://foo.com"));

  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);
}

void TestJSonDriver::testNumbers() {
  QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
  QVariantList list;
  list.append (QVariant(1));
  list.append (QVariant(2.4));
  list.append (QVariant(-100));
  list.append (QVariant(-3.4));
  list.append (QVariant("-5e+"));
  list.append (QVariant("2e"));
  list.append (QVariant("3e+"));
  list.append (QVariant("4.3E"));
  list.append (QVariant("5.4E-"));
  QVariant expected (list);

  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse (json, &ok);
  QVERIFY (ok);
  QCOMPARE(result, expected);

  QVariantList numbers = result.toList();
  QCOMPARE( numbers[0].type(),QVariant::Int );
  QCOMPARE( numbers[1].type(), QVariant::Double );
  QCOMPARE( numbers[2].type(), QVariant::Int );
  QCOMPARE( numbers[3].type(), QVariant::Double );
}

void TestJSonDriver::testReadWriteEmptyDocument()
{
  QString json = QString("");
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
  QVERIFY( !serialized.isNull() );
  QVERIFY( serialized.isEmpty() );
}

void TestJSonDriver::testReadWrite()
{
  QFETCH( QString, json );
  JSonDriver driver;
  bool ok;
  QVariant result = driver.parse( json, &ok );
  QVERIFY(ok);
  Serializer serializer;
  const QString serialized = serializer.serialize( result );
//  qWarning() << serialized;
  QVariant writtenThenRead = driver.parse( serialized, &ok );
  QCOMPARE( result, writtenThenRead );
}

void TestJSonDriver::testReadWrite_data()
{
    QTest::addColumn<QString>( "json" );

    // array tests
    QTest::newRow( "empty array" ) << "[]";
    QTest::newRow( "basic array" ) << "[\"foo\",\"bar\"]";
    QTest::newRow( "single int array" ) << "[6]";
    QTest::newRow( "int array" ) << "[6,5,6,7]";
    const QString json = "[1,2.4, -100, -3.4, -5e+, 2e,3e+,4.3E,5.4E-]";
    QTest::newRow( "array of various numbers" ) << json;

    // document tests
    QTest::newRow( "empty object" ) << "{}";
    QTest::newRow( "basic document" ) << "{\"foo\":\"bar\"}";
    QTest::newRow( "object with ints" ) << "{\"foo\":6}";
    QString json2 = "{ \"foo\":\"bar\",\n\"number\" : 51.3 , \"array\":[\"item1\", 123]}";
    QTest::newRow( "complicated document" ) << json2;

    // more complex cases
    const QString json3 = "[ {\"foo\":\"bar\"},\n\"number\",51.3 , [\"item1\", 123]]";
    QTest::newRow( "complicated array" ) << json3;
}

QTEST_MAIN(TestJSonDriver)
#include "moc_testjsondriver.cxx"
<|endoftext|>


<commit_before>#pragma once

#include "integrators/implicit_runge_kutta_nyström_integrator.hpp"

#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>

#include "glog/logging.h"
#include "quantities/quantities.hpp"

#ifdef ADVANCE_ΔQSTAGE
#error ADVANCE_ΔQSTAGE already defined
#else
#define ADVANCE_ΔQSTAGE(step)                                              \
  do {                                                                     \
    Time const step_evaluated = (step);                                    \
    for (int k = 0; k < dimension; ++k) {                                  \
      Displacement const Δq = (*Δqstage_previous)[k] +                     \
                              step_evaluated * v_stage[k];                 \
      q_stage[k] = q_last[k].value + Δq;                                   \
      (*Δqstage_current)[k] = Δq;                                          \
    }                                                                      \
  } while (false)
#endif

#ifdef ADVANCE_ΔVSTAGE
#error ADVANCE_ΔVSTAGE already defined
#else
#define ADVANCE_ΔVSTAGE(step, q_clock)                                     \
  do {                                                                     \
    Time const step_evaluated = (step);                                    \
    compute_acceleration((q_clock), q_stage, &a);                          \
    for (int k = 0; k < dimension; ++k) {                                  \
      Velocity const Δv = (*Δvstage_previous)[k] + step_evaluated * a[k];  \
      v_stage[k] = v_last[k].value + Δv;                                   \
      (*Δvstage_current)[k] = Δv;                                          \
    }                                                                      \
  } while (false)
#endif

namespace principia {

using quantities::Difference;
using quantities::Quotient;

namespace integrators {

template<typename Position>
void IRKNIntegrator::SolveTrivialKineticEnergyIncrement(
    IRKNRightHandSideComputation<Position> compute_acceleration,
    Parameters<Position, Variation<Position>> const& parameters,
    not_null<Solution<Position, Variation<Position>>*> const solution) const {
  using Velocity = Variation<Position>;
  using Displacement = Difference<Position>;
  int const dimension = parameters.initial.positions.size();

  std::vector<std::vector<Displacement>> Δqstages(stages_);
  for (auto& Δqstage : Δqstages) {
    Δqstage.resize(dimension);
  }

  // Dimension the result.
  int const capacity = parameters.sampling_period == 0 ?
    1 :
    static_cast<int>(
        ceil((((parameters.tmax - parameters.initial.time.value) /
                    parameters.Δt) + 1) /
                parameters.sampling_period)) + 1;
  solution->clear();
  solution->reserve(capacity);

  std::vector<DoublePrecision<Position>> q_last(parameters.initial.positions);
  std::vector<DoublePrecision<Velocity>> v_last(parameters.initial.momenta);
  int sampling_phase = 0;

  std::vector<Position> q_stage(dimension);
  std::vector<Velocity> v_stage(dimension);
  std::vector<Quotient<Velocity, Time>> a(dimension);  // Current accelerations.

  // The following quantity is generally equal to |Δt|, but during the last
  // iteration, if |tmax_is_exact|, it may differ significantly from |Δt|.
  Time h = parameters.Δt;  // Constant for now.

  // During one iteration of the outer loop below we process the time interval
  // [|tn|, |tn| + |h|[.  |tn| is computed using compensated summation to make
  // sure that we don't have drifts.
  DoublePrecision<Time> tn = parameters.initial.time;

  bool at_end = !parameters.tmax_is_exact && parameters.tmax < tn.value + h;
  while (!at_end) {
    // Check if this is the last interval and if so process it appropriately.
    if (parameters.tmax_is_exact) {
      // If |tn| is getting close to |tmax|, use |tmax| as the upper bound of
      // the interval and update |h| accordingly.  The bound chosen here for
      // |tmax| ensures that we don't end up with a ridiculously small last
      // interval: we'd rather make the last interval a bit bigger.  More
      // precisely, the last interval generally has a length between 0.5 Δt and
      // 1.5 Δt, unless it is also the first interval.
      // NOTE(phl): This may lead to convergence as bad as (1.5 Δt)^5 rather
      // than Δt^5.
      if (parameters.tmax <= tn.value + 3 * h / 2) {
        at_end = true;
        h = (parameters.tmax - tn.value) - tn.error;
      }
    } else if (parameters.tmax < tn.value + 2 * h) {
      // If the next interval would overshoot, make this the last interval but
      // stick to the same step.
      at_end = true;
    }
    // Here |h| is the length of the current time interval and |tn| is its
    // start.

    for (int k = 0; k < dimension; ++k) {
      (*Δqstage_current)[k] = Displacement();
      (*Δvstage_current)[k] = Velocity();
      q_stage[k] = q_last[k].value;
    }

    // Fixed-point iteration.
    for (int i = 0; i < stages_; ++i) {
      std::swap(Δqstage_current, Δqstage_previous);
      std::swap(Δvstage_current, Δvstage_previous);

    // Compensated summation from "'SymplecticPartitionedRungeKutta' Method
    // for NDSolve", algorithm 2.
    for (int k = 0; k < dimension; ++k) {
      q_last[k].Increment((*Δqstage_current)[k]);
      v_last[k].Increment((*Δvstage_current)[k]);
      q_stage[k] = q_last[k].value;
      v_stage[k] = v_last[k].value;
    }
    tn.Increment(h);

    if (parameters.sampling_period != 0) {
      if (sampling_phase % parameters.sampling_period == 0) {
        solution->emplace_back();
        SystemState<Position, Velocity>* state = &solution->back();
        state->time = tn;
        state->positions.reserve(dimension);
        state->momenta.reserve(dimension);
        for (int k = 0; k < dimension; ++k) {
          state->positions.emplace_back(q_last[k]);
          state->momenta.emplace_back(v_last[k]);
        }
      }
      ++sampling_phase;
    }
  }

  if (parameters.sampling_period == 0) {
    solution->emplace_back();
    SystemState<Position, Velocity>* state = &solution->back();
    state->time = tn;
    state->positions.reserve(dimension);
    state->momenta.reserve(dimension);
    for (int k = 0; k < dimension; ++k) {
      state->positions.emplace_back(q_last[k]);
      state->momenta.emplace_back(v_last[k]);
    }
  }
}

}  // namespace integrators
}  // namespace principia

#undef ADVANCE_ΔQSTAGE
#undef ADVANCE_ΔVSTAGE
<commit_msg>this is too messy<commit_after>#pragma once

#include "integrators/implicit_runge_kutta_nyström_integrator.hpp"

#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>

#include "glog/logging.h"
#include "quantities/quantities.hpp"

#ifdef ADVANCE_ΔQSTAGE
#error ADVANCE_ΔQSTAGE already defined
#else
#define ADVANCE_ΔQSTAGE(step)                                              \
  do {                                                                     \
    Time const step_evaluated = (step);                                    \
    for (int k = 0; k < dimension; ++k) {                                  \
      Displacement const Δq = (*Δqstage_previous)[k] +                     \
                              step_evaluated * v_stage[k];                 \
      q_stage[k] = q_last[k].value + Δq;                                   \
      (*Δqstage_current)[k] = Δq;                                          \
    }                                                                      \
  } while (false)
#endif

#ifdef ADVANCE_ΔVSTAGE
#error ADVANCE_ΔVSTAGE already defined
#else
#define ADVANCE_ΔVSTAGE(step, q_clock)                                     \
  do {                                                                     \
    Time const step_evaluated = (step);                                    \
    compute_acceleration((q_clock), q_stage, &a);                          \
    for (int k = 0; k < dimension; ++k) {                                  \
      Velocity const Δv = (*Δvstage_previous)[k] + step_evaluated * a[k];  \
      v_stage[k] = v_last[k].value + Δv;                                   \
      (*Δvstage_current)[k] = Δv;                                          \
    }                                                                      \
  } while (false)
#endif

namespace principia {

using quantities::Difference;
using quantities::Quotient;

namespace integrators {

template<typename Position>
void IRKNIntegrator::SolveTrivialKineticEnergyIncrement(
    IRKNRightHandSideComputation<Position> compute_acceleration,
    Parameters<Position, Variation<Position>> const& parameters,
    not_null<Solution<Position, Variation<Position>>*> const solution) const {
  using Velocity = Variation<Position>;
  using Displacement = Difference<Position>;
  int const dimension = parameters.initial.positions.size();

  std::vector<std::vector<Displacement>>* Δqstages_current(stages_);
  std::vector<std::vector<Displacement>>* Δqstages_previous(stages_);
  for (int i = 0; i < stages_; ++i) {
    Δqstages_current[i].resize(dimension);
    Δqstages_previous[i].resize(dimension);
  }

  // Dimension the result.
  int const capacity = parameters.sampling_period == 0 ?
    1 :
    static_cast<int>(
        ceil((((parameters.tmax - parameters.initial.time.value) /
                    parameters.Δt) + 1) /
                parameters.sampling_period)) + 1;
  solution->clear();
  solution->reserve(capacity);

  std::vector<DoublePrecision<Position>> q_last(parameters.initial.positions);
  std::vector<DoublePrecision<Velocity>> v_last(parameters.initial.momenta);
  int sampling_phase = 0;

  std::vector<Position> q_stage(dimension);
  std::vector<Velocity> v_stage(dimension);
  std::vector<Quotient<Velocity, Time>> a(dimension);  // Current accelerations.

  // The following quantity is generally equal to |Δt|, but during the last
  // iteration, if |tmax_is_exact|, it may differ significantly from |Δt|.
  Time h = parameters.Δt;  // Constant for now.

  // During one iteration of the outer loop below we process the time interval
  // [|tn|, |tn| + |h|[.  |tn| is computed using compensated summation to make
  // sure that we don't have drifts.
  DoublePrecision<Time> tn = parameters.initial.time;

  bool at_end = !parameters.tmax_is_exact && parameters.tmax < tn.value + h;
  while (!at_end) {
    // Check if this is the last interval and if so process it appropriately.
    if (parameters.tmax_is_exact) {
      // If |tn| is getting close to |tmax|, use |tmax| as the upper bound of
      // the interval and update |h| accordingly.  The bound chosen here for
      // |tmax| ensures that we don't end up with a ridiculously small last
      // interval: we'd rather make the last interval a bit bigger.  More
      // precisely, the last interval generally has a length between 0.5 Δt and
      // 1.5 Δt, unless it is also the first interval.
      // NOTE(phl): This may lead to convergence as bad as (1.5 Δt)^5 rather
      // than Δt^5.
      if (parameters.tmax <= tn.value + 3 * h / 2) {
        at_end = true;
        h = (parameters.tmax - tn.value) - tn.error;
      }
    } else if (parameters.tmax < tn.value + 2 * h) {
      // If the next interval would overshoot, make this the last interval but
      // stick to the same step.
      at_end = true;
    }
    // Here |h| is the length of the current time interval and |tn| is its
    // start.

    for (int k = 0; k < dimension; ++k) {
      (*Δqstage_current)[k] = Displacement();
      (*Δvstage_current)[k] = Velocity();
      q_stage[k] = q_last[k].value;
    }

    // Fixed-point iteration.
    // NOTE(egg): this does not work for stiff systems, newton iteration is then
    // required.
    for (int i = 0; i < stages_; ++i) {
      Δqstages[i]
    }

    // Compensated summation from "'SymplecticPartitionedRungeKutta' Method
    // for NDSolve", algorithm 2.
    for (int k = 0; k < dimension; ++k) {
      q_last[k].Increment((*Δqstage_current)[k]);
      v_last[k].Increment((*Δvstage_current)[k]);
      q_stage[k] = q_last[k].value;
      v_stage[k] = v_last[k].value;
    }
    tn.Increment(h);

    if (parameters.sampling_period != 0) {
      if (sampling_phase % parameters.sampling_period == 0) {
        solution->emplace_back();
        SystemState<Position, Velocity>* state = &solution->back();
        state->time = tn;
        state->positions.reserve(dimension);
        state->momenta.reserve(dimension);
        for (int k = 0; k < dimension; ++k) {
          state->positions.emplace_back(q_last[k]);
          state->momenta.emplace_back(v_last[k]);
        }
      }
      ++sampling_phase;
    }
  }

  if (parameters.sampling_period == 0) {
    solution->emplace_back();
    SystemState<Position, Velocity>* state = &solution->back();
    state->time = tn;
    state->positions.reserve(dimension);
    state->momenta.reserve(dimension);
    for (int k = 0; k < dimension; ++k) {
      state->positions.emplace_back(q_last[k]);
      state->momenta.emplace_back(v_last[k]);
    }
  }
}

}  // namespace integrators
}  // namespace principia

#undef ADVANCE_ΔQSTAGE
#undef ADVANCE_ΔVSTAGE
<|endoftext|>


<commit_before>#pragma once

#include <vector>

#include "base/not_null.hpp"
#include "integrators/symplectic_integrator.hpp"

namespace principia {

using base::not_null;

namespace integrators {

enum VanishingCoefficients {
  None,
  FirstBVanishes,
  LastAVanishes,
};

template<typename Position, typename Momentum>
class SPRKIntegrator : public SymplecticIntegrator<Position, Momentum> {
 public:
  using Coefficients = typename SymplecticIntegrator<Position,
                                                     Momentum>::Coefficients;
  using Parameters = typename SymplecticIntegrator<Position,
                                                   Momentum>::Parameters;
  using SystemState = typename SymplecticIntegrator<Position,
                                                    Momentum>::SystemState;

  SPRKIntegrator();
  ~SPRKIntegrator() override = default;

  // Coefficients from Robert I. McLachlan and Pau Atela (1992),
  // The accuracy of symplectic integrators, table 2.
  // http://eaton.math.rpi.edu/CSUMS/Papers/Symplectic/McLachlan_Atela_92.pdf
  Coefficients const& Leapfrog() const;
  Coefficients const& Order4FirstSameAsLast() const;
  Coefficients const& Order5Optimal() const;
  // http://sixtrack.web.cern.ch/SixTrack/doc/yoshida00.pdf

  void Initialize(Coefficients const& coefficients) override;

  template<typename AutonomousRightHandSideComputation,
           typename RightHandSideComputation>
  void Solve(RightHandSideComputation compute_force,
             AutonomousRightHandSideComputation compute_velocity,
             Parameters const& parameters,
             not_null<std::vector<SystemState>*> const solution) const;

 private:

  struct FirstSameAsLast {
    double first;
    double last;
  };

  // TODO(egg): either get rid of the non-autonomous RHS, or have neither of
  // them be autonomous, this is messy.
  template<VanishingCoefficients vanishing_coefficients_,
           typename AutonomousRightHandSideComputation,
           typename RightHandSideComputation>
  void SolveOptimized(RightHandSideComputation compute_force,
                      AutonomousRightHandSideComputation compute_velocity,
                      Parameters const& parameters,
                      not_null<std::vector<SystemState>*> const solution) const;

  VanishingCoefficients vanishing_coefficients_;
  // Null if, and only if, |vanishing_coefficients_| is |None|.
  // If |vanishing_coefficients_| is |FirstBVanishes|, this contains the first
  // and last a coefficients.
  // If |vanishing_coefficients_| is |FirstAVanishes|, this contains the first
  // and last b coefficients.
  // These are used to desynchronize and synchronize first-same-as-last
  // integrators.
  std::unique_ptr<FirstSameAsLast> first_same_as_last_;

  // The number of stages, or the number of stages minus one for a
  // first-same-as-last integrator.
  int stages_;

  // The position and momentum nodes.
  // If |vanishing_coefficients_| is |FirstBVanishes|, we do not store the first
  // b coefficient, and the last entry of |a_| is the sum of the first and last
  // a coefficients.
  // If |vanishing_coefficients_| is |LastAVanishes|, we do not store the last
  // a coefficient, and the first entry of |b_| is the sum of the first and last
  // b coefficients.
  std::vector<double> a_;
  std::vector<double> b_;

  // TODO(egg): remove when we find a way to use only autonomous
  // right-hand-sides.
  // The weights.
  std::vector<double> c_;
};

}  // namespace integrators
}  // namespace principia

#include "integrators/symplectic_partitioned_runge_kutta_integrator_body.hpp"
<commit_msg>crashy IDE<commit_after>#pragma once

#include <vector>

#include "base/not_null.hpp"
#include "integrators/symplectic_integrator.hpp"

namespace principia {

using base::not_null;

namespace integrators {

enum VanishingCoefficients {
  None,
  FirstBVanishes,
  LastAVanishes,
};

template<typename Position, typename Momentum>
class SPRKIntegrator : public SymplecticIntegrator<Position, Momentum> {
 public:
  using Coefficients = typename SymplecticIntegrator<Position,
                                                     Momentum>::Coefficients;
  using Parameters = typename SymplecticIntegrator<Position,
                                                   Momentum>::Parameters;
  using SystemState = typename SymplecticIntegrator<Position,
                                                    Momentum>::SystemState;

  SPRKIntegrator();
  ~SPRKIntegrator() override = default;

  // Coefficients from Robert I. McLachlan and Pau Atela (1992),
  // The accuracy of symplectic integrators, table 2.
  // http://eaton.math.rpi.edu/CSUMS/Papers/Symplectic/McLachlan_Atela_92.pdf
  Coefficients const& Leapfrog() const;
  Coefficients const& PseudoLeapfrog() const;
  Coefficients const& Order4FirstSameAsLast() const;
  Coefficients const& Order5Optimal() const;
  // http://sixtrack.web.cern.ch/SixTrack/doc/yoshida00.pdf

  void Initialize(Coefficients const& coefficients) override;

  template<typename AutonomousRightHandSideComputation,
           typename RightHandSideComputation>
  void Solve(RightHandSideComputation compute_force,
             AutonomousRightHandSideComputation compute_velocity,
             Parameters const& parameters,
             not_null<std::vector<SystemState>*> const solution) const;

 private:

  struct FirstSameAsLast {
    double first;
    double last;
  };

  // TODO(egg): either get rid of the non-autonomous RHS, or have neither of
  // them be autonomous, this is messy.
  template<VanishingCoefficients vanishing_coefficients_,
           typename AutonomousRightHandSideComputation,
           typename RightHandSideComputation>
  void SolveOptimized(RightHandSideComputation compute_force,
                      AutonomousRightHandSideComputation compute_velocity,
                      Parameters const& parameters,
                      not_null<std::vector<SystemState>*> const solution) const;

  VanishingCoefficients vanishing_coefficients_;
  // Null if, and only if, |vanishing_coefficients_| is |None|.
  // If |vanishing_coefficients_| is |FirstBVanishes|, this contains the first
  // and last a coefficients.
  // If |vanishing_coefficients_| is |FirstAVanishes|, this contains the first
  // and last b coefficients.
  // These are used to desynchronize and synchronize first-same-as-last
  // integrators.
  std::unique_ptr<FirstSameAsLast> first_same_as_last_;

  // The number of stages, or the number of stages minus one for a
  // first-same-as-last integrator.
  int stages_;

  // The position and momentum nodes.
  // If |vanishing_coefficients_| is |FirstBVanishes|, we do not store the first
  // b coefficient, and the last entry of |a_| is the sum of the first and last
  // a coefficients.
  // If |vanishing_coefficients_| is |LastAVanishes|, we do not store the last
  // a coefficient, and the first entry of |b_| is the sum of the first and last
  // b coefficients.
  std::vector<double> a_;
  std::vector<double> b_;

  // TODO(egg): remove when we find a way to use only autonomous
  // right-hand-sides.
  // The weights.
  std::vector<double> c_;
};

}  // namespace integrators
}  // namespace principia

#include "integrators/symplectic_partitioned_runge_kutta_integrator_body.hpp"
<|endoftext|>


<commit_before>#include "sliding_window.hpp"
#include <iostream>
#include <vector>
using iter::sliding_window;
int main() {
    std::vector<int> v = {1,2,3,4,5,6,7,8,9};
    for (auto sec : sliding_window(v,4)) {
        for (auto i : sec) {
            std::cout << i << " ";
            i.get() = 90;
        }
        std::cout << std::endl;
    }
    return 0;
}
<commit_msg>adds test with temporary<commit_after>#include "sliding_window.hpp"
#include <iostream>
#include <vector>
using iter::sliding_window;
int main() {
    std::vector<int> v = {1,2,3,4,5,6,7,8,9};
    for (auto sec : sliding_window(v,4)) {
        for (auto i : sec) {
            std::cout << i << " ";
            i.get() = 90;
        }
        std::cout << std::endl;
    }

    for (auto sec : sliding_window(std::vector<int>{1,2,3,4,5,6,7,8,9} ,4)) {
        for (auto i : sec) {
            std::cout << i << " ";
            i.get() = 90;
        }
        std::cout << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <opencv2/highgui/highgui.hpp>
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include <vector>
using namespace cv;
using namespace std;

class Image{
 public:
	Image(){};
    Image(int w, int h, Mat image);
    Mat getCompressed();
    void displayFilter(Mat, int);
    void divide_image();
    vector<vector<vector<int> > > imageRGB;//(w, vector<vector<int> >(w, vector<int>(3))); // 3-d vector to store the rgb data
    vector<vector<vector<int> > > imageYBR;//(h, vector<vector<int> >(w, vector<int>(3))); // 3-d vector to store the luminance,Cb,Cr data

private:
	Mat compressedImage = imread("flower.jpg", CV_LOAD_IMAGE_COLOR);
	int width;
	int height;
	vector<vector<Mat> > sub_images;// 2-d vector of sub-images
};

// sub image is an image: 8x8 sub images will be instantiated
class Sub_Image: public Image{
 public:
	Sub_Image();
    Sub_Image(int w, int h, Mat image, int num_row, int num_col);
    void compress_sub_image();
    void cosine_transform();
	Mat self;
 private:
    int row;
    int col;
    int width;
    int height;
    Image father;
};

int main(){
    Mat image = imread("flower.jpg", CV_LOAD_IMAGE_COLOR); // reads in image into image object from the Matrix? class, not sure what CV_LO... is
    Mat imageYCBCR; // this was code I found online to convert RGB to YcBcR, but i couldnt get CV_BGR2YCBCR to function
    cvtColor(image,imageYCBCR,CV_BGR2YCrCb); // converts image from BGR to ycbcr YCBCR
    Mat filter[3];
    split(imageYCBCR,filter);
    Mat y = filter[0];
    Mat cr = filter[1];
    Mat cb = filter[2];
    Image compressed(image.cols, image.rows, image);
    compressed.displayFilter(image, 0);  // this doesn't do what I want it to do
	imshow("opencvtest", compressed.getCompressed()); // displays the image with title opencvtest
	cout << "entering_divide_image" << endl;
	Sub_Image subim( 100, 100, compressed.getCompressed(), 1, 1);
//	compressed.divide_image();
//  ^^^^^->>>>>segfault
//	imshow("ycbr", y);
//	imshow("luminance", y);
    imshow("lumiance", y);
    imshow("RED:", cr);
    imshow("BLUE:", cb);
    imshow("FLOWER:", image);
    waitKey(0); // not sure what this does
    return 0;
}

// displays either the Luminance or Chromiance of an image
void Image::displayFilter(Mat image, int filterIndex){
    for(int i = 0; i < image.rows; i++){
        for(int j = 0; j < image.cols; j++){
            image.at<Vec3b>(i, j)[2] = imageYBR[i][j][filterIndex];
            image.at<Vec3b>(i, j)[1] = imageYBR[i][j][filterIndex];
            image.at<Vec3b>(i, j)[0] = imageYBR[i][j][filterIndex];
        }
    }
    imshow("Filtered Image:", image);
}

Sub_Image::Sub_Image(){
	width = 1;
	height = 1;
	row = 1;
	col = 1;
}

// non-default constructor for sub-image: sets Mat.color position to the imageRGB of inherited Image
Sub_Image::Sub_Image(int w, int h, Mat image, int num_row, int num_col){
    width = w;
    height = h;
    row = num_row;
    col = num_col;
	Mat temp(width, height, 3, DataType<int>::type)
    for(int i = 0; i < width; i++){
        for(int j = 0; j < height; j++){
            // setting the self's color equal to its RGB position
    //        self.at<Vec3b>(i, j)[2] = imageRGB[num_row*i][num_col*j][2];
      //      self.at<Vec3b>(i, j)[1] = imageRGB[num_row*i][num_col*j][1];
        //    self.at<Vec3b>(i, j)[0] = imageRGB[num_row*i][num_col*j][0];
            // does sub_image inherit vector,vectorRGB?
        }
    }
}

// Since the human eye is less sensitive to an image's difference in chromiance
// we can down-sample the red and blue of the image from the pixels to 2x2 blocks of pixels
void Sub_Image::compress_sub_image(){
    int average_blue = 0;
    int average_red = 0;
	int y, cB, cR;
    for(int i = row; i < row + (width / 2); i++){
        for(int j = col; j < col + (height / 2); j++){
            // Blue Chromiance is stored here
            average_blue = (father.imageYBR[i][j][1] + father.imageYBR[i + 1][j][1] + father.imageYBR[i][j + 1][1] + father.imageYBR[i + 1][j + 1][1])/4;

            // Red Chromiance is stored here
            average_red = (father.imageYBR[i][j][2] + father.imageYBR[i + 1][j][2] + father.imageYBR[i][j + 1][2] + father.imageYBR[i + 1][j + 1][2])/4;

            // Assign the father image the compressed chromiance values
            father.imageYBR[i][j][1] = father.imageYBR[i + 1][j][1] = father.imageYBR[i][j + 1][1] = father.imageYBR[i + 1][j + 1][1] = average_blue;
            father.imageYBR[i][j][2] = father.imageYBR[i + 1][j][2] = father.imageYBR[i][j + 1][2] = father.imageYBR[i + 1][j + 1][2] = average_red;

			y = father.imageYBR[i][j][0];
			cB = father.imageYBR[i][j][1];
			cR = father.imageYBR[i][j][2];

			// give father image compressed RGB data translated from YcBcR
			father.imageRGB[i][j][0] = 1.0 * y + 0 * cB + 1.402 * cR;
			father.imageRGB[i][j][1] = 1.0 * y - 0.344136 * cB - 0.714136 * cR;
			father.imageRGB[i][j][2] = 1.0 * y + 1.772 * cB + 0 * cR;

			// self assign commpressed RGB data
			self.at<Vec3b>(i, j)[2] = father.imageRGB[i][j][2];
            self.at<Vec3b>(i, j)[1] = father.imageRGB[i][j][1];
            self.at<Vec3b>(i, j)[0] = father.imageRGB[i][j][0];

        }
    }

}

// divide image into 8x8 sub images
void Image::divide_image(){
	cout << "1" << endl;
    for(int i = 0; i < 8; i++){
        vector<Mat> temp;
		cout << "2: " << i << endl;
        for(int j = 0; j < 8; j++){
			cout << "3: " << j << endl;
            Sub_Image sub_image(width / 8, height / 8, getCompressed(), i, j);
	//		sub_image.compress_sub_image();
			imshow("sub-image", sub_image.self);
			temp.push_back(sub_image.self);
        }
		cout << "4: " << i << endl;
        sub_images.push_back(temp);
        temp.clear();
    }
}

Image::Image(int w, int h, Mat image){
    width = w;
    height = h;
    int temp, r, g, b;
//populate imageRGB matrix with rgb values of the image, now that i think about it, this is unnessesary since OpenCV already has the values stored which we can acces    s at any time, I leave it for now just in case this is more intuitive
    vector<vector<int> > tempVectorRGB;
    vector<int> innerTempVectorRGB;
    vector<vector<int> > tempVectorYBR;
    vector<int> innerTempVectorYBR; // should we use ints or double for this?????????????????????????????
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            r = image.at<Vec3b>(i, j)[2];
            g = image.at<Vec3b>(i, j)[1];
            b = image.at<Vec3b>(i, j)[0];

            innerTempVectorRGB.push_back(r);
            innerTempVectorRGB.push_back(g);
            innerTempVectorRGB.push_back(b);
            tempVectorRGB.push_back(innerTempVectorRGB);
            innerTempVectorRGB.clear();
            innerTempVectorYBR.push_back(r*.299 + g*.587 + b*.114);
            innerTempVectorYBR.push_back(r*-.16874 + g*-.33126 + b*.5);
            innerTempVectorYBR.push_back(r*.5 + g*-.41869 + b*-.08131);
            tempVectorYBR.push_back(innerTempVectorYBR);
            innerTempVectorYBR.clear();
        }
        imageRGB.push_back(tempVectorRGB);
        tempVectorRGB.clear();
        imageYBR.push_back(tempVectorYBR);
        tempVectorYBR.clear();
    }
}

Mat Image::getCompressed(){
    return compressedImage;
}
<commit_msg>updated readImage.cpp<commit_after>#include <opencv2/highgui/highgui.hpp>
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include <vector>
using namespace cv;
using namespace std;

class Image{
 public:
	Image(){};
    Image(int w, int h, Mat image);
    Mat getImage();
    void displayFilter(Mat, int);
    void divide_image(Image);		// divides image into 8x8 sub images
	// 3-d vectors (widthxheightx3): represent RGB and YcBcR color spaces
    vector<vector<vector<int> > > imageRGB;//(w, vector<vector<int> >(w, vector<int>(3))); // 3-d vector to store the rgb data
    vector<vector<vector<int> > > imageYBR;//(h, vector<vector<int> >(w, vector<int>(3))); // 3-d vector to store the luminance,Cb,Cr data

 private:
	Mat rawImage = imread("flower.jpg", CV_LOAD_IMAGE_COLOR);
	int width;
	int height;
	vector<vector<Mat> > sub_images;// 2-d vector of sub-images
};

// sub image inherits from image: 8x8 sub images will be instantiated
class Sub_Image: public Image{
 public:
	Sub_Image();
    Sub_Image(int w, int h, Image image, int num_row, int num_col);
    void compress_sub_image();
    void cosine_transform();
	Mat self;
 private:
    int row; 						// y position of sub-image relative to father
    int col;						// x position of sub-image relative to father
    int width;						// width of father / 8
    int height;						// height of father / 2
    Image father;					// father Image object
};

int main(){
    Mat image = imread("flower.jpg", CV_LOAD_IMAGE_COLOR); // reads in image into image object from the Matrix? class, not sure what CV_LO... is
    Mat imageYCBCR; // this was code I found online to convert RGB to YcBcR, but i couldnt get CV_BGR2YCBCR to function
    cvtColor(image,imageYCBCR,CV_BGR2YCrCb); // converts image from BGR to ycbcr YCBCR
    Mat filter[3];
    split(imageYCBCR,filter);
    Mat y = filter[0];
    Mat cr = filter[1];
    Mat cb = filter[2];
    Image compressed(image.cols, image.rows, image);
    compressed.displayFilter(image, 0);  // this doesn't do what I want it to do
	imshow("opencvtest", compressed.getImage()); // displays the image with title opencvtest
//	Sub_Image subim( 100, 100, compressed, 1, 1);
	compressed.divide_image(compressed);
//  ^^^^^->>>>>segfault
//	imshow("ycbr", y);
//	imshow("luminance", y);
    imshow("lumiance", y);
    imshow("RED:", cr);
    imshow("BLUE:", cb);
    imshow("FLOWER:", image);
    waitKey(0); // not sure what this does
    return 0;
}

// displays either the Luminance or Chromiance of an image
void Image::displayFilter(Mat image, int filterIndex){
    for(int i = 0; i < image.rows; i++){
        for(int j = 0; j < image.cols; j++){
            image.at<Vec3b>(i, j)[2] = imageYBR[i][j][filterIndex];
            image.at<Vec3b>(i, j)[1] = imageYBR[i][j][filterIndex];
            image.at<Vec3b>(i, j)[0] = imageYBR[i][j][filterIndex];
        }
    }
    imshow("Filtered Image:", image);
}

Sub_Image::Sub_Image(){
	width = 1;
	height = 1;
	row = 1;
	col = 1;
}

// non-default constructor for sub-image: sets Mat.color position to the imageRGB of inherited Image
Sub_Image::Sub_Image(int w, int h, Image dad, int num_row, int num_col){
    width = w;
    height = h;
    row = num_row;
    col = num_col;
	father = dad;
	Mat temp(width, height, 3, DataType<int>::type);
	self = temp;
    for(int i = 0; i < width; i++){
        for(int j = 0; j < height; j++){
            // setting the self's color equal to its RGB position
            self.at<Vec3b>(i, j)[2] = father.imageRGB[num_row*i][num_col*j][2];
            self.at<Vec3b>(i, j)[1] = father.imageRGB[num_row*i][num_col*j][1];
            self.at<Vec3b>(i, j)[0] = father.imageRGB[num_row*i][num_col*j][0];
            // does sub_image inherit vector,vectorRGB?
        }
    }
}

// Since the human eye is less sensitive to an image's difference in chromiance
// we can down-sample the red and blue of the image from the pixels to 2x2 blocks of pixels
void Sub_Image::compress_sub_image(){
    int average_blue = 0;
    int average_red = 0;
	int y, cB, cR;
    for(int i = row; i < row + (width / 2); i++){
        for(int j = col; j < col + (height / 2); j++){
            // Blue Chromiance is stored here
            average_blue = (father.imageYBR[i][j][1] + father.imageYBR[i + 1][j][1] + father.imageYBR[i][j + 1][1] + father.imageYBR[i + 1][j + 1][1])/4;

            // Red Chromiance is stored here
            average_red = (father.imageYBR[i][j][2] + father.imageYBR[i + 1][j][2] + father.imageYBR[i][j + 1][2] + father.imageYBR[i + 1][j + 1][2])/4;

            // Assign the father image the compressed chromiance values
            father.imageYBR[i][j][1] = father.imageYBR[i + 1][j][1] = father.imageYBR[i][j + 1][1] = father.imageYBR[i + 1][j + 1][1] = average_blue;
            father.imageYBR[i][j][2] = father.imageYBR[i + 1][j][2] = father.imageYBR[i][j + 1][2] = father.imageYBR[i + 1][j + 1][2] = average_red;

			y = father.imageYBR[i][j][0];
			cB = father.imageYBR[i][j][1];
			cR = father.imageYBR[i][j][2];

			// give father image compressed RGB data translated from YcBcR
			father.imageRGB[i][j][0] = 1.0 * y + 0 * cB + 1.402 * cR;
			father.imageRGB[i][j][1] = 1.0 * y - 0.344136 * cB - 0.714136 * cR;
			father.imageRGB[i][j][2] = 1.0 * y + 1.772 * cB + 0 * cR;

			// self assign commpressed RGB data
			self.at<Vec3b>(i, j)[2] = father.imageRGB[i][j][2];
            self.at<Vec3b>(i, j)[1] = father.imageRGB[i][j][1];
            self.at<Vec3b>(i, j)[0] = father.imageRGB[i][j][0];

        }
    }

}

// divide image into 8x8 sub images
void Image::divide_image(Image image){
	cout << "1" << endl;
    for(int i = 0; i < 8; i++){
        vector<Mat> temp;
		cout << "2: " << i << endl;
        for(int j = 0; j < 8; j++){
			cout << "3: " << j << endl;
            Sub_Image sub_image(width / 8, height / 8, image, i, j);
	//		sub_image.compress_sub_image();
			imshow("sub-image", sub_image.self);
			temp.push_back(sub_image.self);
        }
		cout << "4: " << i << endl;
        sub_images.push_back(temp);
        temp.clear();
    }
}

Image::Image(int w, int h, Mat image){
    width = w;
    height = h;
    int temp, r, g, b;
//populate imageRGB matrix with rgb values of the image, now that i think about it, this is unnessesary since OpenCV already has the values stored which we can acces    s at any time, I leave it for now just in case this is more intuitive
    vector<vector<int> > tempVectorRGB;
    vector<int> innerTempVectorRGB;
    vector<vector<int> > tempVectorYBR;
    vector<int> innerTempVectorYBR; // should we use ints or double for this?????????????????????????????
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            r = image.at<Vec3b>(i, j)[2];
            g = image.at<Vec3b>(i, j)[1];
            b = image.at<Vec3b>(i, j)[0];

            innerTempVectorRGB.push_back(r);
            innerTempVectorRGB.push_back(g);
            innerTempVectorRGB.push_back(b);
            tempVectorRGB.push_back(innerTempVectorRGB);
            innerTempVectorRGB.clear();
            innerTempVectorYBR.push_back(r*.299 + g*.587 + b*.114);
            innerTempVectorYBR.push_back(r*-.16874 + g*-.33126 + b*.5);
            innerTempVectorYBR.push_back(r*.5 + g*-.41869 + b*-.08131);
            tempVectorYBR.push_back(innerTempVectorYBR);
            innerTempVectorYBR.clear();
        }
        imageRGB.push_back(tempVectorRGB);
        tempVectorRGB.clear();
        imageYBR.push_back(tempVectorYBR);
        tempVectorYBR.clear();
    }
}

Mat Image::getImage(){
    return rawImage;
}
<|endoftext|>


<commit_before>/* ****************************************************************************
*
* FILE                     HostMgr.cpp
*
* AUTHOR                   Ken Zangelin
*
* CREATION DATE            Feb 10 2011
*
*/
#include <stdio.h>              // popen
#include <unistd.h>             // gethostname
#include <arpa/inet.h>          // sockaddr_in, inet_ntop
#include <ifaddrs.h>            // getifaddrs
#include <net/if.h>             // IFF_UP
#include <netdb.h>              //
#include <string.h>             // strstr

#include "logMsg.h"             // LM_*
#include "traceLevels.h"        // Trace Levels

#include "Host.h"               // Host
#include "HostMgr.h"            // Own interface
#include <stdlib.h>             // free

namespace ss
{

/* ****************************************************************************
*
* HostMgr
*/
HostMgr::HostMgr(unsigned int size)
{
	this->size = size;

	hostV = (Host**) calloc(size, sizeof(Host*));
	if (hostV == NULL)
		LM_X(1, ("error allocating room for %d delilah hosts", size));

	LM_M(("Allocated a Host Vector for %d hosts", size));
	localIps();
	list("init");
}

/* ****************************************************************************
*
* ipsGet - get all IPs for a machine
*/
void HostMgr::ipsGet(Host* hostP)
{
	struct ifaddrs*      addrs;
	struct ifaddrs*      iap;
	struct sockaddr_in*  sa;
	char                 buf[64];

	getifaddrs(&addrs);
	for (iap = addrs; iap != NULL; iap = iap->ifa_next)
	{
		if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET)
		{
			sa = (struct sockaddr_in*)(iap->ifa_addr);
			inet_ntop(iap->ifa_addr->sa_family, (void*) &(sa->sin_addr), buf, sizeof(buf));

			if ((hostP->ip == NULL) && (strcmp(buf, "127.0.0.1") != 0))
			{
				hostP->ip = strdup(buf);
				LM_M(("Setting IP '%s' for host '%s'", hostP->ip, hostP->name));
			}
			else
				aliasAdd(hostP, buf);
		}
	}

	freeifaddrs(addrs);
}

/* ****************************************************************************
*
* localIps -
*/
void HostMgr::localIps(void)
{
	char   hostName[128];
	char   domain[128];
	char   domainedName[128];
	Host*  hostP;

	if (gethostname(hostName, sizeof(hostName)) == -1)
		LM_X(1, ("gethostname: %s", strerror(errno)));

	hostP = insert(hostName, "127.0.0.1");

	memset(domainedName, 0, sizeof(domainedName));
	if (getdomainname(domain, sizeof(domain)) == -1)
		LM_X(1, ("getdomainname: %s", strerror(errno)));

	LM_TODO(("Would gethostname ever returned the 'domained' name ?"));

	if (domainedName[0] != 0)
	{
		snprintf(domainedName, sizeof(domainedName), "%s.%s", hostName, domain);
		aliasAdd(hostP, domainedName);
	}

	aliasAdd(hostP, "localhost");

	ipsGet(hostP);
}

/* ****************************************************************************
*
* HostMgr::hosts -
*/
int HostMgr::hosts(void)
{
	unsigned int  ix;
	int           hostNo = 0;

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] != NULL)
			++hostNo;
	}

	return hostNo;
}

/* ****************************************************************************
*
* HostMgr::insert -
*/
Host* HostMgr::insert(Host* hostP)
{
	unsigned int  ix;

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] == NULL)
		{
			LM_M(("Inserting host '%s'", hostP->name));
			hostV[ix] = hostP;
			list("Host Added");
			return hostV[ix];
		}
	}

	LM_RE(NULL, ("Please realloc host vector (%d hosts not enough) ...", size));
}

/* ****************************************************************************
*
* ip2string - convert integer ip address to string
*/
static void ip2string(int ip, char* ipString, int ipStringLen)
{
	snprintf(ipString, ipStringLen, "%d.%d.%d.%d",
			 ip & 0xFF,
			 (ip & 0xFF00) >> 8,
			 (ip & 0xFF0000) >> 16,
			 (ip & 0xFF000000) >> 24);
}

/* ****************************************************************************
*
* onlyDigitsAndDots -
*/
static bool onlyDigitsAndDots(const char* string)
{
	if ((string == NULL) || (string[0] == 0))
		LM_RE(false, ("Empty IP ..."));

	for (unsigned int ix = 0; ix < strlen(string); ix++)
	{
		if (string[ix] == 0)
			return true;

		if (string[ix] == '.')
			continue;

		if ((string[ix] >= '0') && (string[ix] <= '9'))
			continue;

		return false;
	}

	return true;
}

/* ****************************************************************************
*
* HostMgr::insert -
*/
Host* HostMgr::insert(const char* name, const char* ip)
{
	Host*  hostP;
	char   ipX[64];
	char*  dotP;
	char*  alias = NULL;

	LM_M(("***** New host: name: '%s', ip: '%s'", name, ip));

	if ((name == NULL) && (ip == NULL))
		LM_X(1, ("name AND ip NULL - cannot add a ghost host ..."));

	if (name == NULL)
	{
		LM_W(("NULL host name for IP '%s'", ip));
		name = "nohostname";
	}

	if ((hostP = lookup(name)) != NULL)
		return hostP;

	struct hostent* heP;

	heP = gethostbyname(name);

	if (heP == NULL)
		LM_W(("gethostbyname(%s) error", name));
	else
	{
		int ix = 0;

		LM_M(("gethostbyname proposed the name '%s' for '%s'", heP->h_name, name));
		ip2string(*((int*) heP->h_addr_list[ix]), ipX, sizeof(ipX));
		if (ip == NULL)
			ip = ipX;
		else
			alias = ipX;

		name = heP->h_name;

		while (heP->h_aliases[ix] != NULL)
		{
			LM_W(("alias %d: '%s' - should be added also", ix, heP->h_aliases[ix]));
			++ix;
		}

		for (ix = 1; ix < heP->h_length / 4; ix++)
		{
			if (heP->h_addr_list[ix] != NULL)
			{
				char ipY[64];

				ip2string(*((int*) heP->h_addr_list[ix]), ipX, sizeof(ipX));
				LM_W(("addr %d: '%s' should be added also", ix, ipY));
			}
		}
	}

	if ((ip != NULL) && (ip[0] != 0) && ((hostP = lookup(ip)) != NULL))
		return hostP;

	hostP  = (Host*) calloc(1, sizeof(Host));
	if (hostP == NULL)
		LM_X(1, ("malloc(%d): %s", sizeof(Host), strerror(errno)));

	LM_M(("name: '%s'", name));
	if (name != NULL)
		hostP->name = strdup(name);

	if (ip != NULL)
		hostP->ip = strdup(ip);

	if (alias != NULL)
		aliasAdd(hostP, alias);

	if ((dotP = (char*) strstr(name, ".")) != NULL)
	{
		if (onlyDigitsAndDots(name) == false)
		{
			*dotP = 0;
			aliasAdd(hostP, name);
		}
	}

	return insert(hostP);
}

/* ****************************************************************************
*
* aliasAdd -
*/
void HostMgr::aliasAdd(Host* host, const char* alias)
{
	if (lookup(alias) != NULL)
		return;

	for (unsigned int ix = 0; ix < sizeof(alias) / sizeof(alias[0]); ix++)
	{
		if (host->alias[ix] == NULL)
		{
			host->alias[ix] = strdup(alias);
			LM_M(("Added alias '%s' for host '%s'", host->alias[ix], host->name));
			return;
		}
	}

	LM_W(("Unable to add alias '%s' to host '%s' - no room in alias vector", alias, host->name));
}

/* ****************************************************************************
*
* remove -
*/
bool HostMgr::remove(const char* name)
{
	Host*          hostP;
	unsigned int   ix;

	hostP = lookup(name);
	if (hostP == NULL)
		LM_RE(false, ("Host '%s' not in list"));

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] != hostP)
			continue;

		if (hostP->name != NULL)
			free(hostP->name);

		if (hostP->ip != NULL)
			free(hostP->ip);

		LM_TODO(("Also free up aliases ..."));

		free(hostP);
		hostV[ix] = NULL;

		return true;
	}

	LM_RE(false, ("host pointer reurned from lookup not found ... internal bug!"));
}

/* ****************************************************************************
*
* lookup -
*/
Host* HostMgr::lookup(const char* name)
{
	unsigned int  ix;
	char*         nameNoDot = NULL;
	char*         dotP;

	if (name == NULL)
		return NULL;

	if ((dotP = (char*) strstr(name, ".")) != NULL)
	{
		nameNoDot = strdup(name);
		dotP      = (char*) strstr(nameNoDot, ".");
		*dotP     = 0;
	}

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] == NULL)
			continue;

		if ((hostV[ix]->name != NULL) && (strcmp(hostV[ix]->name, name) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((nameNoDot != NULL) && (hostV[ix]->name != NULL) && (strcmp(hostV[ix]->name, nameNoDot) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((hostV[ix]->ip != NULL) && (strcmp(hostV[ix]->ip, name) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((nameNoDot != NULL) && (hostV[ix]->ip != NULL) && (strcmp(hostV[ix]->ip, nameNoDot) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		for (unsigned int aIx = 0; aIx < sizeof(hostV[ix]->alias) / sizeof(hostV[ix]->alias[0]); aIx++)
		{
			if (hostV[ix]->alias[aIx] == NULL)
				continue;

			if (strcmp(hostV[ix]->alias[aIx], name) == 0)
			{
				if (nameNoDot != NULL)
					free(nameNoDot);
				return hostV[ix];
			}

			if ((nameNoDot != NULL) && (strcmp(hostV[ix]->alias[aIx], nameNoDot) == 0))
			{
				if (nameNoDot != NULL)
					free(nameNoDot);
				return hostV[ix];
			}
		}
	}

	return NULL;
}

/* ****************************************************************************
*
* lookup -
*/
bool HostMgr::match(Host* host, const char* ip)
{
	if (ip == NULL)
		return NULL;

	if (ip[0] == 0)
		return NULL;

	if ((host->name != NULL) && (strcmp(host->name, ip) == 0))
		return true;

	if ((host->ip != NULL) && (strcmp(host->ip, ip) == 0))
		return true;

	for (unsigned int aIx = 0; aIx < sizeof(host->alias) / sizeof(host->alias[0]); aIx++)
	{
		if (host->alias[aIx] == NULL)
			continue;

		if (strcmp(host->alias[aIx], ip) == 0)
			return true;
	}

	return false;
}

/* ****************************************************************************
*
* list - list the hosts in the list
*/
void HostMgr::list(const char* why)
{
	unsigned int ix;

	LM_F(("------------ Host List: %s ------------", why));
	for (ix = 0; ix < size; ix++)
    {
		char  line[512];
		Host* hostP;

        if (hostV[ix] == NULL)
            continue;

		hostP = hostV[ix];
		memset(line, sizeof(line), 0);
		snprintf(line, sizeof(line), "%02d: %-20s %-20s", ix, hostP->name, hostP->ip);

		for (unsigned int aIx = 0; aIx < sizeof(hostP->alias) / sizeof(hostP->alias[0]); aIx++)
		{
			char part[64];
			if (hostP->alias[aIx] == NULL)
				continue;

			snprintf(part, sizeof(part), " %-20s", hostP->alias[aIx]);
			strncat(line, part, sizeof(line));
		}

		LM_F((line));
	}
	LM_F(("---------------------------------------------------"));
}

}
<commit_msg>First fruit of valgrind studies - one very small memory leak fixed in Host manager<commit_after>/* ****************************************************************************
*
* FILE                     HostMgr.cpp
*
* AUTHOR                   Ken Zangelin
*
* CREATION DATE            Feb 10 2011
*
*/
#include <stdio.h>              // popen
#include <unistd.h>             // gethostname
#include <arpa/inet.h>          // sockaddr_in, inet_ntop
#include <ifaddrs.h>            // getifaddrs
#include <net/if.h>             // IFF_UP
#include <netdb.h>              //
#include <string.h>             // strstr

#include "logMsg.h"             // LM_*
#include "traceLevels.h"        // Trace Levels

#include "Host.h"               // Host
#include "HostMgr.h"            // Own interface
#include <stdlib.h>             // free

namespace ss
{

/* ****************************************************************************
*
* HostMgr
*/
HostMgr::HostMgr(unsigned int size)
{
	this->size = size;

	hostV = (Host**) calloc(size, sizeof(Host*));
	if (hostV == NULL)
		LM_X(1, ("error allocating room for %d delilah hosts", size));

	LM_M(("Allocated a Host Vector for %d hosts", size));
	localIps();
	list("init");
}

/* ****************************************************************************
*
* ipsGet - get all IPs for a machine
*/
void HostMgr::ipsGet(Host* hostP)
{
	struct ifaddrs*      addrs;
	struct ifaddrs*      iap;
	struct sockaddr_in*  sa;
	char                 buf[64];

	getifaddrs(&addrs);
	for (iap = addrs; iap != NULL; iap = iap->ifa_next)
	{
		if (iap->ifa_addr && (iap->ifa_flags & IFF_UP) && iap->ifa_addr->sa_family == AF_INET)
		{
			sa = (struct sockaddr_in*)(iap->ifa_addr);
			inet_ntop(iap->ifa_addr->sa_family, (void*) &(sa->sin_addr), buf, sizeof(buf));

			if ((hostP->ip == NULL) && (strcmp(buf, "127.0.0.1") != 0))
			{
				hostP->ip = strdup(buf);
				LM_M(("Setting IP '%s' for host '%s'", hostP->ip, hostP->name));
			}
			else
				aliasAdd(hostP, buf);
		}
	}

	freeifaddrs(addrs);
}

/* ****************************************************************************
*
* localIps -
*/
void HostMgr::localIps(void)
{
	char   hostName[128];
	char   domain[128];
	char   domainedName[128];
	Host*  hostP;

	if (gethostname(hostName, sizeof(hostName)) == -1)
		LM_X(1, ("gethostname: %s", strerror(errno)));

	hostP = insert(hostName, "127.0.0.1");

	memset(domainedName, 0, sizeof(domainedName));
	if (getdomainname(domain, sizeof(domain)) == -1)
		LM_X(1, ("getdomainname: %s", strerror(errno)));

	LM_TODO(("Would gethostname ever returned the 'domained' name ?"));

	if (domainedName[0] != 0)
	{
		snprintf(domainedName, sizeof(domainedName), "%s.%s", hostName, domain);
		aliasAdd(hostP, domainedName);
	}

	aliasAdd(hostP, "localhost");

	ipsGet(hostP);
}

/* ****************************************************************************
*
* HostMgr::hosts -
*/
int HostMgr::hosts(void)
{
	unsigned int  ix;
	int           hostNo = 0;

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] != NULL)
			++hostNo;
	}

	return hostNo;
}

/* ****************************************************************************
*
* HostMgr::insert -
*/
Host* HostMgr::insert(Host* hostP)
{
	unsigned int  ix;

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] == NULL)
		{
			LM_M(("Inserting host '%s'", hostP->name));
			hostV[ix] = hostP;
			list("Host Added");
			return hostV[ix];
		}
	}

	LM_RE(NULL, ("Please realloc host vector (%d hosts not enough) ...", size));
}

/* ****************************************************************************
*
* ip2string - convert integer ip address to string
*/
static void ip2string(int ip, char* ipString, int ipStringLen)
{
	snprintf(ipString, ipStringLen, "%d.%d.%d.%d",
			 ip & 0xFF,
			 (ip & 0xFF00) >> 8,
			 (ip & 0xFF0000) >> 16,
			 (ip & 0xFF000000) >> 24);
}

/* ****************************************************************************
*
* onlyDigitsAndDots -
*/
static bool onlyDigitsAndDots(const char* string)
{
	if ((string == NULL) || (string[0] == 0))
		LM_RE(false, ("Empty IP ..."));

	for (unsigned int ix = 0; ix < strlen(string); ix++)
	{
		if (string[ix] == 0)
			return true;

		if (string[ix] == '.')
			continue;

		if ((string[ix] >= '0') && (string[ix] <= '9'))
			continue;

		return false;
	}

	return true;
}

/* ****************************************************************************
*
* HostMgr::insert -
*/
Host* HostMgr::insert(const char* name, const char* ip)
{
	Host*  hostP;
	char   ipX[64];
	char*  dotP;
	char*  alias = NULL;

	LM_M(("***** New host: name: '%s', ip: '%s'", name, ip));

	if ((name == NULL) && (ip == NULL))
		LM_X(1, ("name AND ip NULL - cannot add a ghost host ..."));

	if (name == NULL)
	{
		LM_W(("NULL host name for IP '%s'", ip));
		name = "nohostname";
	}

	if ((hostP = lookup(name)) != NULL)
		return hostP;

	struct hostent* heP;

	heP = gethostbyname(name);

	if (heP == NULL)
		LM_W(("gethostbyname(%s) error", name));
	else
	{
		int ix = 0;

		LM_M(("gethostbyname proposed the name '%s' for '%s'", heP->h_name, name));
		ip2string(*((int*) heP->h_addr_list[ix]), ipX, sizeof(ipX));
		if (ip == NULL)
			ip = ipX;
		else
			alias = ipX;

		name = heP->h_name;

		while (heP->h_aliases[ix] != NULL)
		{
			LM_W(("alias %d: '%s' - should be added also", ix, heP->h_aliases[ix]));
			++ix;
		}

		for (ix = 1; ix < heP->h_length / 4; ix++)
		{
			if (heP->h_addr_list[ix] != NULL)
			{
				char ipY[64];

				ip2string(*((int*) heP->h_addr_list[ix]), ipX, sizeof(ipX));
				LM_W(("addr %d: '%s' should be added also", ix, ipY));
			}
		}
	}

	if ((ip != NULL) && (ip[0] != 0) && ((hostP = lookup(ip)) != NULL))
		return hostP;

	hostP  = (Host*) calloc(1, sizeof(Host));
	if (hostP == NULL)
		LM_X(1, ("malloc(%d): %s", sizeof(Host), strerror(errno)));

	LM_M(("name: '%s'", name));
	if (name != NULL)
		hostP->name = strdup(name);

	if (ip != NULL)
		hostP->ip = strdup(ip);

	if (alias != NULL)
		aliasAdd(hostP, alias);

	if ((dotP = (char*) strstr(name, ".")) != NULL)
	{
		if (onlyDigitsAndDots(name) == false)
		{
			*dotP = 0;
			aliasAdd(hostP, name);
		}
	}

	return insert(hostP);
}

/* ****************************************************************************
*
* aliasAdd -
*/
void HostMgr::aliasAdd(Host* host, const char* alias)
{
	if (lookup(alias) != NULL)
		return;

	for (unsigned int ix = 0; ix < sizeof(alias) / sizeof(alias[0]); ix++)
	{
		if (host->alias[ix] == NULL)
		{
			host->alias[ix] = strdup(alias);
			LM_M(("Added alias '%s' for host '%s'", host->alias[ix], host->name));
			return;
		}
	}

	LM_W(("Unable to add alias '%s' to host '%s' - no room in alias vector", alias, host->name));
}

/* ****************************************************************************
*
* remove -
*/
bool HostMgr::remove(const char* name)
{
	Host*          hostP;
	unsigned int   ix;

	hostP = lookup(name);
	if (hostP == NULL)
		LM_RE(false, ("Host '%s' not in list"));

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] != hostP)
			continue;

		if (hostP->name != NULL)
			free(hostP->name);

		if (hostP->ip != NULL)
			free(hostP->ip);

		LM_TODO(("Also free up aliases ..."));

		free(hostP);
		hostV[ix] = NULL;

		return true;
	}

	LM_RE(false, ("host pointer reurned from lookup not found ... internal bug!"));
}

/* ****************************************************************************
*
* lookup -
*/
Host* HostMgr::lookup(const char* name)
{
	unsigned int  ix;
	char*         nameNoDot = NULL;
	char*         dotP;

	if (name == NULL)
		return NULL;

	if ((dotP = (char*) strstr(name, ".")) != NULL)
	{
		nameNoDot = strdup(name);
		dotP      = (char*) strstr(nameNoDot, ".");
		*dotP     = 0;
	}

	for (ix = 0; ix < size; ix++)
	{
		if (hostV[ix] == NULL)
			continue;

		if ((hostV[ix]->name != NULL) && (strcmp(hostV[ix]->name, name) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((nameNoDot != NULL) && (hostV[ix]->name != NULL) && (strcmp(hostV[ix]->name, nameNoDot) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((hostV[ix]->ip != NULL) && (strcmp(hostV[ix]->ip, name) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		if ((nameNoDot != NULL) && (hostV[ix]->ip != NULL) && (strcmp(hostV[ix]->ip, nameNoDot) == 0))
		{
			if (nameNoDot != NULL)
				free(nameNoDot);
			return hostV[ix];
		}

		for (unsigned int aIx = 0; aIx < sizeof(hostV[ix]->alias) / sizeof(hostV[ix]->alias[0]); aIx++)
		{
			if (hostV[ix]->alias[aIx] == NULL)
				continue;

			if (strcmp(hostV[ix]->alias[aIx], name) == 0)
			{
				if (nameNoDot != NULL)
					free(nameNoDot);
				return hostV[ix];
			}

			if ((nameNoDot != NULL) && (strcmp(hostV[ix]->alias[aIx], nameNoDot) == 0))
			{
				if (nameNoDot != NULL)
					free(nameNoDot);
				return hostV[ix];
			}
		}
	}

	if (nameNoDot != NULL)
		free(nameNoDot);

	return NULL;
}

/* ****************************************************************************
*
* lookup -
*/
bool HostMgr::match(Host* host, const char* ip)
{
	if (ip == NULL)
		return NULL;

	if (ip[0] == 0)
		return NULL;

	if ((host->name != NULL) && (strcmp(host->name, ip) == 0))
		return true;

	if ((host->ip != NULL) && (strcmp(host->ip, ip) == 0))
		return true;

	for (unsigned int aIx = 0; aIx < sizeof(host->alias) / sizeof(host->alias[0]); aIx++)
	{
		if (host->alias[aIx] == NULL)
			continue;

		if (strcmp(host->alias[aIx], ip) == 0)
			return true;
	}

	return false;
}

/* ****************************************************************************
*
* list - list the hosts in the list
*/
void HostMgr::list(const char* why)
{
	unsigned int ix;

	LM_F(("------------ Host List: %s ------------", why));
	for (ix = 0; ix < size; ix++)
    {
		char  line[512];
		Host* hostP;

        if (hostV[ix] == NULL)
            continue;

		hostP = hostV[ix];
		memset(line, sizeof(line), 0);
		snprintf(line, sizeof(line), "%02d: %-20s %-20s", ix, hostP->name, hostP->ip);

		for (unsigned int aIx = 0; aIx < sizeof(hostP->alias) / sizeof(hostP->alias[0]); aIx++)
		{
			char part[64];
			if (hostP->alias[aIx] == NULL)
				continue;

			snprintf(part, sizeof(part), " %-20s", hostP->alias[aIx]);
			strncat(line, part, sizeof(line));
		}

		LM_F((line));
	}
	LM_F(("---------------------------------------------------"));
}

}
<|endoftext|>