<commit_before>#pragma once

#include <eosio/chain/authority.hpp>
#include <eosio/chain/chain_config.hpp>
#include <eosio/chain/config.hpp>
#include <eosio/chain/types.hpp>

namespace eosio { namespace chain {

using action_name    = eosio::chain::action_name;

struct newaccount {
   account_name                     creator;
   account_name                     name;
   authority                        owner;
   authority                        active;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(newaccount) );
   }
};

struct setcode {
   account_name                     account;
   uint8_t                          vmtype = 0;
   uint8_t                          vmversion = 0;
   bytes                            code;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(setcode) );
   }
};

struct setabi {
   account_name                     account;
   bytes                            abi;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(setabi) );
   }
};

struct updateauth {
   account_name                      account;
   permission_name                   permission;
   permission_name                   parent;
   authority                         auth;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(updateauth) );
   }
};

struct deleteauth {
   deleteauth() = default;
   deleteauth(const account_name& account, const permission_name& permission)
   :account(account), permission(permission)
   {}

   account_name                      account;
   permission_name                   permission;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(deleteauth) );
   }
};

struct linkauth {
   linkauth() = default;
   linkauth(const account_name& account, const account_name& code, const action_name& type, const permission_name& requirement)
   :account(account), code(code), type(type), requirement(requirement)
   {}

   account_name                      account;
   account_name                      code;
   action_name                       type;
   permission_name                   requirement;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(linkauth) );
   }
};

struct unlinkauth {
   unlinkauth() = default;
   unlinkauth(const account_name& account, const account_name& code, const action_name& type)
   :account(account), code(code), type(type)
   {}

   account_name                      account;
   account_name                      code;
   action_name                       type;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(unlinkauth) );
   }
};

struct canceldelay {
   permission_level      canceling_auth;
   transaction_id_type   trx_id;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(canceldelay) );
   }
};

struct onerror {
   uint128_t      sender_id;
   bytes          sent_trx;

   onerror( uint128_t sid, const char* data, size_t len )
   :sender_id(sid),sent_trx(data,data+len){}

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return action_name( N(onerror) );
   }
};

} } /// namespace eosio::chain

FC_REFLECT( eosio::chain::newaccount                       , (creator)(name)(owner)(active) )
FC_REFLECT( eosio::chain::setcode                          , (account)(vmtype)(vmversion)(code) )
FC_REFLECT( eosio::chain::setabi                           , (account)(abi) )
FC_REFLECT( eosio::chain::updateauth                       , (account)(permission)(parent)(auth) )
FC_REFLECT( eosio::chain::deleteauth                       , (account)(permission) )
FC_REFLECT( eosio::chain::linkauth                         , (account)(code)(type)(requirement) )
FC_REFLECT( eosio::chain::unlinkauth                       , (account)(code)(type) )
FC_REFLECT( eosio::chain::canceldelay                      , (canceling_auth)(trx_id) )
FC_REFLECT( eosio::chain::onerror                          , (sender_id)(sent_trx) )
<commit_msg>Revert unneeded explicit wrap of account_name constructor<commit_after>#pragma once

#include <eosio/chain/authority.hpp>
#include <eosio/chain/chain_config.hpp>
#include <eosio/chain/config.hpp>
#include <eosio/chain/types.hpp>

namespace eosio { namespace chain {

using action_name    = eosio::chain::action_name;

struct newaccount {
   account_name                     creator;
   account_name                     name;
   authority                        owner;
   authority                        active;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(newaccount);
   }
};

struct setcode {
   account_name                     account;
   uint8_t                          vmtype = 0;
   uint8_t                          vmversion = 0;
   bytes                            code;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(setcode);
   }
};

struct setabi {
   account_name                     account;
   bytes                            abi;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(setabi);
   }
};

struct updateauth {
   account_name                      account;
   permission_name                   permission;
   permission_name                   parent;
   authority                         auth;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(updateauth);
   }
};

struct deleteauth {
   deleteauth() = default;
   deleteauth(const account_name& account, const permission_name& permission)
   :account(account), permission(permission)
   {}

   account_name                      account;
   permission_name                   permission;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(deleteauth);
   }
};

struct linkauth {
   linkauth() = default;
   linkauth(const account_name& account, const account_name& code, const action_name& type, const permission_name& requirement)
   :account(account), code(code), type(type), requirement(requirement)
   {}

   account_name                      account;
   account_name                      code;
   action_name                       type;
   permission_name                   requirement;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(linkauth);
   }
};

struct unlinkauth {
   unlinkauth() = default;
   unlinkauth(const account_name& account, const account_name& code, const action_name& type)
   :account(account), code(code), type(type)
   {}

   account_name                      account;
   account_name                      code;
   action_name                       type;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(unlinkauth);
   }
};

struct canceldelay {
   permission_level      canceling_auth;
   transaction_id_type   trx_id;

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(canceldelay);
   }
};

struct onerror {
   uint128_t      sender_id;
   bytes          sent_trx;

   onerror( uint128_t sid, const char* data, size_t len )
   :sender_id(sid),sent_trx(data,data+len){}

   static account_name get_account() {
      return config::system_account_name;
   }

   static action_name get_name() {
      return N(onerror);
   }
};

} } /// namespace eosio::chain

FC_REFLECT( eosio::chain::newaccount                       , (creator)(name)(owner)(active) )
FC_REFLECT( eosio::chain::setcode                          , (account)(vmtype)(vmversion)(code) )
FC_REFLECT( eosio::chain::setabi                           , (account)(abi) )
FC_REFLECT( eosio::chain::updateauth                       , (account)(permission)(parent)(auth) )
FC_REFLECT( eosio::chain::deleteauth                       , (account)(permission) )
FC_REFLECT( eosio::chain::linkauth                         , (account)(code)(type)(requirement) )
FC_REFLECT( eosio::chain::unlinkauth                       , (account)(code)(type) )
FC_REFLECT( eosio::chain::canceldelay                      , (canceling_auth)(trx_id) )
FC_REFLECT( eosio::chain::onerror                          , (sender_id)(sent_trx) )
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

typedef struct Point {
  int x;
  int y;
} Point;

int solve(Point a[], int n, int d);
int shift(Point a[], int n, int d, int idx);
bool cmpX(Point a, Point b);
bool cmpY(Point a, Point b);
bool cmp(Point a, Point b);

int main() {
  int n, d;

  int cnt = 0;
  while (cin >> n >> d) {
    if (n == 0 && d == 0)
      break;

    cnt++;
    Point a[n];

    for (int i = 0; i < n; i++)
      cin >> a[i].x >> a[i].y;
    sort(a, a + n, cmp);

    int res = solve(a, n, d);

    cout << "Case " << cnt << ": " << res << endl;
  }
}

int solve(Point a[], int n, int d) {
  int cnt = 0;

  int idx = 0;
  while (idx < n) {
    int tmp = shift(a, n, d, idx);

    if (tmp == -1)
      return -1;

    cnt++;
    idx += tmp;
  }

  return cnt;
}

int shift(Point a[], int n, int d, int idx) {
  int ret = 1;

  if (a[idx].y > d)
    return -1;

  int radarPos = sqrt(d^2 - a[idx].y^2) + a[idx].x;

  for (int i = idx + 1; i < n; i++) {
    if (i == n)
      break;

    int dist = d^2 - (a[i].x - radarPos)^2 - a[i].y^2;

    if (dist >= 0)
      ret++;
    else
      break;
  }

  return ret;
}

bool cmp(Point a, Point b) {
  if (a.x != b.x)
    return a.x < b.x;
  else
    return a.y < b.y;
}

bool cmpX(Point a, Point b) {
  return a.x < b.x;
}

bool cmpY(Point a, Point b) {
  return a.y < b.y;
}
<commit_msg>p1328<commit_after>#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

typedef struct Point {
  float x;
  float y;
} Point;

int solve(Point a[], int n, float d);
int shift(Point a[], int n, float d, int idx);
bool cmpX(Point a, Point b);
bool cmpY(Point a, Point b);
bool cmp(Point a, Point b);

int main() {
  int n;
  float d;

  int cnt = 0;
  while (cin >> n >> d) {
    if (n == 0 && d == 0.0)
      break;

    cnt++;
    Point a[n];

    for (int i = 0; i < n; i++)
      cin >> a[i].x >> a[i].y;
    sort(a, a + n, cmp);

    int res = solve(a, n, d);

    cout << "Case " << cnt << ": " << res << endl;
  }
}

int solve(Point a[], int n, float d) {
  int cnt = 0;

  int idx = 0;
  while (idx < n) {
    int tmp = shift(a, n, d, idx);

    if (tmp == -1)
      return -1;

    cnt++;
    idx += tmp;
  }

  return cnt;
}

int shift(Point a[], int n, float d, int idx) {
  int ret = 1;

  if (a[idx].y > d)
    return -1;

  float radarPos = sqrt(d * d - a[idx].y * a[idx].y) + a[idx].x;

  for (int i = idx + 1; i < n; i++) {
    if (i == n)
      break;

    float diffX = a[i].x - radarPos;
    float dist = d * d - diffX * diffX - a[i].y * a[i].y;

    if (dist >= 0)
      ret++;
    else
      break;
  }

  return ret;
}

bool cmp(Point a, Point b) {
  if (a.x != b.x)
    return a.x < b.x;
  else
    return a.y < b.y;
}

bool cmpX(Point a, Point b) {
  return a.x < b.x;
}

bool cmpY(Point a, Point b) {
  return a.y < b.y;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2018 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "filtered_socket.hxx"
#include "lease.hxx"

/**
 * Wrapper for a #FilteredSocket which may be released at some point.
 * After that, remaining data in the input buffer can still be read.
 */
class FilteredSocketLease {
    FilteredSocket socket;
    struct lease_ref lease_ref;

public:
    FilteredSocketLease(EventLoop &event_loop,
                        SocketDescriptor fd, FdType fd_type,
                        Lease &lease,
                        const struct timeval *read_timeout,
                        const struct timeval *write_timeout,
                        const SocketFilter *filter, void *filter_ctx,
                        BufferedSocketHandler &handler) noexcept
        :socket(event_loop)
    {
        socket.Init(fd, fd_type, read_timeout, write_timeout,
                    filter, filter_ctx,
                    handler);
        lease_ref.Set(lease);
    }

    ~FilteredSocketLease() noexcept {
        assert(IsReleased());

        socket.Destroy();
    }

    EventLoop &GetEventLoop() noexcept {
        return socket.GetEventLoop();
    }

    gcc_pure
    bool IsValid() const noexcept {
        return socket.IsValid();
    }

    gcc_pure
    bool IsConnected() const noexcept {
        return socket.IsConnected();
    }

    gcc_pure
    bool HasFilter() const noexcept {
        assert(!IsReleased());

        return socket.HasFilter();
    }

#ifndef NDEBUG
    gcc_pure
    bool HasEnded() const noexcept {
        assert(!IsReleased());

        return socket.ended;
    }
#endif

    void Release(bool reuse) noexcept {
        socket.Abandon();
        lease_ref.Release(reuse);
    }

#ifndef NDEBUG
    bool IsReleased() const noexcept {
        return lease_ref.released;
    }
#endif

    gcc_pure
    FdType GetType() const noexcept {
        assert(!IsReleased());

        return socket.GetType();
    }

    void SetDirect(bool _direct) noexcept {
        assert(!IsReleased());

        socket.SetDirect(_direct);
    }

    int AsFD() noexcept {
        assert(!IsReleased());

        return socket.AsFD();
    }

    gcc_pure
    bool IsEmpty() const noexcept {
        return socket.IsEmpty();
    }

    gcc_pure
    size_t GetAvailable() const noexcept {
        return socket.GetAvailable();
    }

    WritableBuffer<void> ReadBuffer() const noexcept {
        return socket.ReadBuffer();
    }

    void Consumed(size_t nbytes) noexcept {
        socket.Consumed(nbytes);
    }

    bool Read(bool expect_more) noexcept {
        return socket.Read(expect_more);
    }

    void ScheduleReadTimeout(bool expect_more,
                             const struct timeval *timeout) noexcept {
        assert(!IsReleased());

        socket.ScheduleReadTimeout(expect_more, timeout);
    }

    void ScheduleReadNoTimeout(bool expect_more) noexcept {
        assert(!IsReleased());

        socket.ScheduleReadNoTimeout(expect_more);
    }

    ssize_t Write(const void *data, size_t size) noexcept {
        assert(!IsReleased());

        return socket.Write(data, size);
    }

    void ScheduleWrite() noexcept {
        assert(!IsReleased());

        socket.ScheduleWrite();
    }

    void UnscheduleWrite() noexcept {
        assert(!IsReleased());

        socket.UnscheduleWrite();
    }

    ssize_t WriteV(const struct iovec *v, size_t n) noexcept {
        assert(!IsReleased());

        return socket.WriteV(v, n);
    }

    ssize_t WriteFrom(int fd, FdType fd_type, size_t length) noexcept {
        assert(!IsReleased());

        return socket.WriteFrom(fd, fd_type, length);
    }
};
<commit_msg>fs_lease: remove dangerous method IsValid()<commit_after>/*
 * Copyright 2007-2018 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "filtered_socket.hxx"
#include "lease.hxx"

/**
 * Wrapper for a #FilteredSocket which may be released at some point.
 * After that, remaining data in the input buffer can still be read.
 */
class FilteredSocketLease {
    FilteredSocket socket;
    struct lease_ref lease_ref;

public:
    FilteredSocketLease(EventLoop &event_loop,
                        SocketDescriptor fd, FdType fd_type,
                        Lease &lease,
                        const struct timeval *read_timeout,
                        const struct timeval *write_timeout,
                        const SocketFilter *filter, void *filter_ctx,
                        BufferedSocketHandler &handler) noexcept
        :socket(event_loop)
    {
        socket.Init(fd, fd_type, read_timeout, write_timeout,
                    filter, filter_ctx,
                    handler);
        lease_ref.Set(lease);
    }

    ~FilteredSocketLease() noexcept {
        assert(IsReleased());

        socket.Destroy();
    }

    EventLoop &GetEventLoop() noexcept {
        return socket.GetEventLoop();
    }

    gcc_pure
    bool IsConnected() const noexcept {
        return socket.IsConnected();
    }

    gcc_pure
    bool HasFilter() const noexcept {
        assert(!IsReleased());

        return socket.HasFilter();
    }

#ifndef NDEBUG
    gcc_pure
    bool HasEnded() const noexcept {
        assert(!IsReleased());

        return socket.ended;
    }
#endif

    void Release(bool reuse) noexcept {
        socket.Abandon();
        lease_ref.Release(reuse);
    }

#ifndef NDEBUG
    bool IsReleased() const noexcept {
        return lease_ref.released;
    }
#endif

    gcc_pure
    FdType GetType() const noexcept {
        assert(!IsReleased());

        return socket.GetType();
    }

    void SetDirect(bool _direct) noexcept {
        assert(!IsReleased());

        socket.SetDirect(_direct);
    }

    int AsFD() noexcept {
        assert(!IsReleased());

        return socket.AsFD();
    }

    gcc_pure
    bool IsEmpty() const noexcept {
        return socket.IsEmpty();
    }

    gcc_pure
    size_t GetAvailable() const noexcept {
        return socket.GetAvailable();
    }

    WritableBuffer<void> ReadBuffer() const noexcept {
        return socket.ReadBuffer();
    }

    void Consumed(size_t nbytes) noexcept {
        socket.Consumed(nbytes);
    }

    bool Read(bool expect_more) noexcept {
        return socket.Read(expect_more);
    }

    void ScheduleReadTimeout(bool expect_more,
                             const struct timeval *timeout) noexcept {
        assert(!IsReleased());

        socket.ScheduleReadTimeout(expect_more, timeout);
    }

    void ScheduleReadNoTimeout(bool expect_more) noexcept {
        assert(!IsReleased());

        socket.ScheduleReadNoTimeout(expect_more);
    }

    ssize_t Write(const void *data, size_t size) noexcept {
        assert(!IsReleased());

        return socket.Write(data, size);
    }

    void ScheduleWrite() noexcept {
        assert(!IsReleased());

        socket.ScheduleWrite();
    }

    void UnscheduleWrite() noexcept {
        assert(!IsReleased());

        socket.UnscheduleWrite();
    }

    ssize_t WriteV(const struct iovec *v, size_t n) noexcept {
        assert(!IsReleased());

        return socket.WriteV(v, n);
    }

    ssize_t WriteFrom(int fd, FdType fd_type, size_t length) noexcept {
        assert(!IsReleased());

        return socket.WriteFrom(fd, fd_type, length);
    }
};
<|endoftext|>


<commit_before>#include "burner_ethernet.h"
BurnerEthernet net;

#include "burner_config.h"
extern BurnerConfig cfg;

#include "pits_burner.h"
extern PitsBurner burner;

#include <EtherCard.h>
const byte ecoPelletMac[] = {0x1E, 0x98, 0xB5, 0xDF, 0x9A, 0x42}; //not IEEE mac, just random
//const byte ecoPelletIp[] = {192, 168, 3, 66};
byte Ethernet::buffer[300]; //was 500
BufferFiller bfill;

void BurnerEthernet::init()
{
   //Serial.println(F("Net init"));

  if (ether.begin(sizeof Ethernet::buffer, ecoPelletMac) == 0)
    Serial.println(F("Ethernet setup failed"));

  if (!ether.dhcpSetup("EcoPellet", true))
    Serial.println(F("DHCP failed"));
  //ether.staticSetup(ecoPelletIp);

  //ether.printIp("MAC: ", ecoPelletMac);
  ether.printIp("IP: ", ether.myip);
  ether.printIp("Mask: ", ether.netmask);
  ether.printIp("GW: ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
}

static word writeResponse() {

  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;

  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "{CurT:$D"
    ",ExhT:$D"
    ",FedT:$D"
    ",Flame:$D"
    ",Fan:$D"
    ",Feed:$D"
    ",FeedS:$D"
    ",Ign:$D"
    ",NoFlm:$D"
    ",Alrm:$D"
    ",Mode:$D"
    ",Fuel:$D"
    ",Batt:$D"
    ",MaxT:$D"
    ",MxDT:$D"
    ",ReqT:$D"
    ",HstT:$D"
    ",ExdT:$D"
    ",UpTm:$D$D:$D$D:$D$D"
    "}"),
    burner.getCurrentTemp(),
    burner.getExhaustTemp(),
    burner.getFeederTemp(),
    burner.getFlame(),
    burner.getFan(),
    burner.getFeed(),
    burner.getFeedTime(),
    burner.isIgnition(),
    burner.getSecondsWithoutFlame(),
    burner.getAlarmStatus(),
    burner.getCurrentMode(),
    burner.getFuelLevel(),
    burner.getBattLevel(),
    cfg.getMaxTemp(),
    cfg.getMaxDropTemp(),
    cfg.getRequiredTemp(),
    cfg.getHysteresisTemp(),
    cfg.getExhaustDeltaTemp(),
    h/10, h%10, m/10, m%10, s/10, s%10
    );

  return bfill.position();
}

void BurnerEthernet::listen() {
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(writeResponse()); // send web page data
}

const byte* BurnerEthernet::getMac() {
  return ecoPelletMac;
}

<commit_msg>- buildin led on if ethernet error<commit_after>#include "burner_ethernet.h"
BurnerEthernet net;

#include "burner_config.h"
extern BurnerConfig cfg;

#include "pits_burner.h"
extern PitsBurner burner;

#include <EtherCard.h>
const byte ecoPelletMac[] = {0x1E, 0x98, 0xB5, 0xDF, 0x9A, 0x42}; //not IEEE mac, just random
//const byte ecoPelletIp[] = {192, 168, 3, 66};
byte Ethernet::buffer[300]; //was 500
BufferFiller bfill;

void BurnerEthernet::init()
{
  Serial.println(F("Net init"));

  if (ether.begin(sizeof Ethernet::buffer, ecoPelletMac) == 0) {
    Serial.println(F("Ethernet setup failed"));
    digitalWrite(LED_BUILTIN, HIGH);
  }

  if (!ether.dhcpSetup("EcoPellet", true)) {
    Serial.println(F("DHCP failed"));
    digitalWrite(LED_BUILTIN, HIGH);
  }
  //ether.staticSetup(ecoPelletIp);

  //ether.printIp("MAC: ", ecoPelletMac);
  ether.printIp("IP: ", ether.myip);
  ether.printIp("Mask: ", ether.netmask);
  ether.printIp("GW: ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
}

static word writeResponse() {

  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;

  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "{CurT:$D"
    ",ExhT:$D"
    ",FedT:$D"
    ",Flame:$D"
    ",Fan:$D"
    ",Feed:$D"
    ",FeedS:$D"
    ",Ign:$D"
    ",NoFlm:$D"
    ",Alrm:$D"
    ",Mode:$D"
    ",Fuel:$D"
    ",Batt:$D"
    ",MaxT:$D"
    ",MxDT:$D"
    ",ReqT:$D"
    ",HstT:$D"
    ",ExdT:$D"
    ",UpTm:$D$D:$D$D:$D$D"
    "}"),
    burner.getCurrentTemp(),
    burner.getExhaustTemp(),
    burner.getFeederTemp(),
    burner.getFlame(),
    burner.getFan(),
    burner.getFeed(),
    burner.getFeedTime(),
    burner.isIgnition(),
    burner.getSecondsWithoutFlame(),
    burner.getAlarmStatus(),
    burner.getCurrentMode(),
    burner.getFuelLevel(),
    burner.getBattLevel(),
    cfg.getMaxTemp(),
    cfg.getMaxDropTemp(),
    cfg.getRequiredTemp(),
    cfg.getHysteresisTemp(),
    cfg.getExhaustDeltaTemp(),
    h/10, h%10, m/10, m%10, s/10, s%10
    );

  return bfill.position();
}

void BurnerEthernet::listen() {
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);

  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(writeResponse()); // send web page data
}

const byte* BurnerEthernet::getMac() {
  return ecoPelletMac;
}

<|endoftext|>


<commit_before>#include "erl_nif.h"

static ErlNifResourceType* bulleterl_RESOURCE = NULL;

struct bulleterl_handle
{
}; // end bulleterl_handle

// Prototypes
static ERL_NIF_TERM bulleterl_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM bulleterl_myfunction(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);

static ErlNifFunc nif_funcs[] = {
    {"new", 0, bulleterl_new},
    {"myfunction", 1, bulleterl_myfunction}
}; // end nif_funcs

static ERL_NIF_TERM bulleterl_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    bulleterl_handle* handle = (bulleterl_handle*) enif_alloc_resource(bulleterl_RESOURCE, sizeof(bulleterl_handle));
    ERL_NIF_TERM result = enif_make_resource(env, handle);
    enif_release_resource(handle);

    return enif_make_tuple2(env, enif_make_atom(env, "ok"), result);
} // end bulleterl_new

static ERL_NIF_TERM bulleterl_myfunction(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    return enif_make_atom(env, "ok");
} // end bulleterl_myfunction

static void bulleterl_resource_cleanup(ErlNifEnv* env, void* arg)
{
    /* Delete any dynamically allocated memory stored in bulleterl_handle */
    /* bulleterl_handle* handle = (bulleterl_handle*)arg; */
} // end bulleterl_resource_cleanup

static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
    ErlNifResourceFlags flags = ErlNifResourceFlags(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);

    ErlNifResourceType* rt = enif_open_resource_type(env, NULL,
			"bulleterl_resource", &bulleterl_resource_cleanup, flags, NULL);

    if(rt == NULL)
	{
        return -1;
	} // end if

    bulleterl_RESOURCE = rt;

    return 0;
} // end on_load

ERL_NIF_INIT(bulleterl, nif_funcs, &on_load, NULL, NULL, NULL);
<commit_msg>Updated bulleterl.cpp to work with BulletEngine.<commit_after>#include "erl_nif.h"

#include "BulletEngine.h"

static ErlNifResourceType* bulleterlType = NULL;

namespace bulleterl
{

	static ERL_NIF_TERM new_(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
	{
		BulletEngine* engine = new (enif_alloc_resource(bulleterlType, sizeof(BulletEngine))) BulletEngine();
		ERL_NIF_TERM result = enif_make_resource(env, engine);
		enif_release_resource(engine);

		return enif_make_tuple2(env, enif_make_atom(env, "bulleterl"), result);
	} // end new_

	static ERL_NIF_TERM myfunction(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
	{
		return enif_make_atom(env, "ok");
	} // end myfunction

	static void cleanup(ErlNifEnv* env, void* obj)
	{
		BulletEngine* handle = (BulletEngine*) obj;
		handle->~BulletEngine();
	} // end cleanup

	static int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
	{
		ErlNifResourceFlags flags = ErlNifResourceFlags(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);

		ErlNifResourceType* rt;

		rt = enif_open_resource_type(env, NULL, "bulleterl", &bulleterl::cleanup, flags, NULL);
		if(rt == NULL) { return -1; }
		bulleterlType = rt;

		return 0;
	} // end on_load

}; // end bulleterl

static ErlNifFunc nif_funcs[] = {
    {"new", 0, bulleterl::new_},
    {"myfunction", 1, bulleterl::myfunction}
}; // end nif_funcs

ERL_NIF_INIT(bulleterl, nif_funcs, &bulleterl::on_load, NULL, NULL, NULL);
<|endoftext|>


<commit_before>#include "AbstractUniformImplementation.h"

#include <globjects/globjects.h>

#include "BindlessUniformImplementation.h"
#include "LegacyUniformImplementation.h"

namespace glo {

AbstractUniformImplementation::AbstractUniformImplementation()
{
}

AbstractUniformImplementation::~AbstractUniformImplementation()
{
}

AbstractUniformImplementation * AbstractUniformImplementation::create()
{
    if (hasExtension(gl::GLextension::GL_EXT_direct_state_access))
    {
        return new BindlessUniformImplementation();
    }
    else
    {
        return new LegacyUniformImplementation();
    }
}

} // namespace glo
<commit_msg>Fix required extension for bindless uniform setters<commit_after>#include "AbstractUniformImplementation.h"

#include <globjects/globjects.h>

#include "BindlessUniformImplementation.h"
#include "LegacyUniformImplementation.h"

namespace glo {

AbstractUniformImplementation::AbstractUniformImplementation()
{
}

AbstractUniformImplementation::~AbstractUniformImplementation()
{
}

AbstractUniformImplementation * AbstractUniformImplementation::create()
{
    if (hasExtension(gl::GLextension::GL_ARB_separate_shader_objects))
    {
        return new BindlessUniformImplementation();
    }
    else
    {
        return new LegacyUniformImplementation();
    }
}

} // namespace glo
<|endoftext|>


<commit_before>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtprogresslabel.h"
#include <QProgressBar>
#include <QBasicTimer>
#include <QTime>

class QxtProgressLabelPrivate : public QxtPrivate<QxtProgressLabel>
{
public:
    QXT_DECLARE_PUBLIC(QxtProgressLabel);
    QxtProgressLabelPrivate();

    QTime start;
    int interval;
    int cachedMin;
    int cachedMax;
    int cachedVal;
    QString cformat;
    QString tformat;
    QBasicTimer timer;
};

QxtProgressLabelPrivate::QxtProgressLabelPrivate()
        : interval(-1), cachedMin(0), cachedMax(0), cachedVal(0)
{}

/*!
    \class QxtProgressLabel
    \inmodule QxtGui
    \brief The QxtProgressLabel widget is a label showing progress related time values.

    QxtProgressLabel is a label widget able to show elapsed and remaining
    time of a progress. Usage is as simple as connecting signal
    QProgressBar::valueChanged() to slot QxtProgressLabel::setValue().

    Example usage:
    \code
    QProgressBar* bar = new QProgressBar(this);
    QxtProgressLabel* label = new QxtProgressLabel(this);
    connect(bar, SIGNAL(valueChanged(int)), label, SLOT(setValue(int)));
    \endcode

    \image qxtprogresslabel.png "QxtProgressLabel in action."
 */

/*!
    Constructs a new QxtProgressLabel with \a parent and \a flags.
 */
QxtProgressLabel::QxtProgressLabel(QWidget* parent, Qt::WindowFlags flags)
        : QLabel(parent, flags)
{
    QXT_INIT_PRIVATE(QxtProgressLabel);
    refresh();
}

/*!
    Constructs a new QxtProgressLabel with \a text, \a parent and \a flags.
 */
QxtProgressLabel::QxtProgressLabel(const QString& text, QWidget* parent, Qt::WindowFlags flags)
        : QLabel(text, parent, flags)
{
    QXT_INIT_PRIVATE(QxtProgressLabel);
    refresh();
}

/*!
    Destructs the progress label.
 */
QxtProgressLabel::~QxtProgressLabel()
{}

/*!
    \property QxtProgressLabel::contentFormat
    \brief the content format of the progress label

    The content of the label is formatted according to this property.
    The default value is an empty string which defaults to \bold "ETA: %r".

    The following variables may be used in the format string:

Variable	Output

\%e	elapsed time

\%r	remaining time

    \sa timeFormat
 */
QString QxtProgressLabel::contentFormat() const
{
    return qxt_d().cformat;
}

void QxtProgressLabel::setContentFormat(const QString& format)
{
    if (qxt_d().cformat != format)
    {
        qxt_d().cformat = format;
        refresh();
    }
}

/*!
    \property QxtProgressLabel::timeFormat
    \brief the time format of the progress label

    Time values are formatted according to this property.
    The default value is an empty string which defaults to \bold "mm:ss".

    \sa contentFormat, QTime::toString()
 */
QString QxtProgressLabel::timeFormat() const
{
    return qxt_d().tformat;
}

void QxtProgressLabel::setTimeFormat(const QString& format)
{
    if (qxt_d().tformat != format)
    {
        qxt_d().tformat = format;
        refresh();
    }
}

/*!
    \property QxtProgressLabel::updateInterval
    \brief the update interval of the progress label

    The content of the progress label is updated according to this interval.
    A negative interval makes the content to update only during value changes.
    The default value is \c -1.
 */
int QxtProgressLabel::updateInterval() const
{
    return qxt_d().interval;
}

void QxtProgressLabel::setUpdateInterval(int msecs)
{
    qxt_d().interval = msecs;
    if (msecs < 0)
    {
        if (qxt_d().timer.isActive())
            qxt_d().timer.stop();
    }
    else
    {
        if (!qxt_d().timer.isActive())
            qxt_d().timer.start(msecs, this);
    }
}

/*!
    Sets the current value to \a value.

    \bold {Note:} Calling this slot by hand has no effect.
    Connect this slot to QProgressBar::valueChange().
 */
void QxtProgressLabel::setValue(int value)
{
    QProgressBar* bar = qobject_cast<QProgressBar*>(sender());
    if (bar)
    {
        if (!qxt_d().start.isValid())
            restart();

        qxt_d().cachedMin = bar->minimum();
        qxt_d().cachedMax = bar->maximum();
        qxt_d().cachedVal = value;

        refresh();
    }
}

/*!
    Restarts the calculation of elapsed and remaining times.
 */
void QxtProgressLabel::restart()
{
    qxt_d().cachedMin = 0;
    qxt_d().cachedMax = 0;
    qxt_d().cachedVal = 0;
    qxt_d().start.restart();
    refresh();
}

/*!
    Refreshes the content.
 */
void QxtProgressLabel::refresh()
{
    // elapsed
    qreal elapsed = 0;
    if (qxt_d().start.isValid())
        elapsed = qxt_d().start.elapsed() / 1000.0;
    QTime etime(0, 0);
    etime = etime.addSecs(static_cast<int>(elapsed));

    // percentage
    qreal percent = 0;
    if (qxt_d().cachedMax != 0)
        percent = (qxt_d().cachedVal - qxt_d().cachedMin) / static_cast<qreal>(qxt_d().cachedMax);
    qreal total = 0;
    if (percent != 0)
        total = elapsed / percent;

    // remaining
    QTime rtime(0, 0);
    rtime = rtime.addSecs(static_cast<int>(total - elapsed));

    // format
    QString tformat = qxt_d().tformat;
    if (tformat.isEmpty())
        tformat = tr("mm:ss");
    QString cformat = qxt_d().cformat;
    if (cformat.isEmpty())
        cformat = tr("ETA: %r");

    QString result = QString(cformat).replace("%e", etime.toString(tformat));
    result = result.replace("%r", rtime.toString(tformat));
    setText(result);
}

/*!
    \reimp
 */
void QxtProgressLabel::timerEvent(QTimerEvent* event)
{
    Q_UNUSED(event);
    refresh();
}
<commit_msg>Revised QxtProgressLabel docs.<commit_after>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtprogresslabel.h"
#include <QProgressBar>
#include <QBasicTimer>
#include <QTime>

class QxtProgressLabelPrivate : public QxtPrivate<QxtProgressLabel>
{
public:
    QXT_DECLARE_PUBLIC(QxtProgressLabel);
    QxtProgressLabelPrivate();

    QTime start;
    int interval;
    int cachedMin;
    int cachedMax;
    int cachedVal;
    QString cformat;
    QString tformat;
    QBasicTimer timer;
};

QxtProgressLabelPrivate::QxtProgressLabelPrivate()
        : interval(-1), cachedMin(0), cachedMax(0), cachedVal(0)
{}

/*!
    \class QxtProgressLabel
    \inmodule QxtGui
    \brief The QxtProgressLabel widget is a label showing progress related time values.

    QxtProgressLabel is a label widget able to show elapsed and remaining
    time of a progress. Usage is as simple as connecting signal
    QProgressBar::valueChanged() to slot QxtProgressLabel::setValue().

    Example usage:
    \code
    QProgressBar* bar = new QProgressBar(this);
    QxtProgressLabel* label = new QxtProgressLabel(this);
    connect(bar, SIGNAL(valueChanged(int)), label, SLOT(setValue(int)));
    \endcode

    \image qxtprogresslabel.png "QxtProgressLabel in action."
 */

/*!
    Constructs a new QxtProgressLabel with \a parent and \a flags.
 */
QxtProgressLabel::QxtProgressLabel(QWidget* parent, Qt::WindowFlags flags)
        : QLabel(parent, flags)
{
    QXT_INIT_PRIVATE(QxtProgressLabel);
    refresh();
}

/*!
    Constructs a new QxtProgressLabel with \a text, \a parent and \a flags.
 */
QxtProgressLabel::QxtProgressLabel(const QString& text, QWidget* parent, Qt::WindowFlags flags)
        : QLabel(text, parent, flags)
{
    QXT_INIT_PRIVATE(QxtProgressLabel);
    refresh();
}

/*!
    Destructs the progress label.
 */
QxtProgressLabel::~QxtProgressLabel()
{}

/*!
    \property QxtProgressLabel::contentFormat
    \brief the content format of the progress label

    The content of the label is formatted according to this property.
    The default value is an empty string which defaults to \bold "ETA: %r".

    The following variables may be used in the format string:
    \table
    \header \i Variable \i Output
    \row \i \%e \i elapsed time
    \row \i \%r \i remaining time
    \endtable

    \sa timeFormat
 */
QString QxtProgressLabel::contentFormat() const
{
    return qxt_d().cformat;
}

void QxtProgressLabel::setContentFormat(const QString& format)
{
    if (qxt_d().cformat != format)
    {
        qxt_d().cformat = format;
        refresh();
    }
}

/*!
    \property QxtProgressLabel::timeFormat
    \brief the time format of the progress label

    Time values are formatted according to this property.
    The default value is an empty string which defaults to \bold "mm:ss".

    \sa contentFormat, QTime::toString()
 */
QString QxtProgressLabel::timeFormat() const
{
    return qxt_d().tformat;
}

void QxtProgressLabel::setTimeFormat(const QString& format)
{
    if (qxt_d().tformat != format)
    {
        qxt_d().tformat = format;
        refresh();
    }
}

/*!
    \property QxtProgressLabel::updateInterval
    \brief the update interval of the progress label

    The content of the progress label is updated according to this interval.
    A negative interval makes the content to update only during value changes.
    The default value is \c -1.
 */
int QxtProgressLabel::updateInterval() const
{
    return qxt_d().interval;
}

void QxtProgressLabel::setUpdateInterval(int msecs)
{
    qxt_d().interval = msecs;
    if (msecs < 0)
    {
        if (qxt_d().timer.isActive())
            qxt_d().timer.stop();
    }
    else
    {
        if (!qxt_d().timer.isActive())
            qxt_d().timer.start(msecs, this);
    }
}

/*!
    Sets the current value to \a value.

    \bold {Note:} Calling this slot by hand has no effect.
    Connect this slot to QProgressBar::valueChange().
 */
void QxtProgressLabel::setValue(int value)
{
    QProgressBar* bar = qobject_cast<QProgressBar*>(sender());
    if (bar)
    {
        if (!qxt_d().start.isValid())
            restart();

        qxt_d().cachedMin = bar->minimum();
        qxt_d().cachedMax = bar->maximum();
        qxt_d().cachedVal = value;

        refresh();
    }
}

/*!
    Restarts the calculation of elapsed and remaining times.
 */
void QxtProgressLabel::restart()
{
    qxt_d().cachedMin = 0;
    qxt_d().cachedMax = 0;
    qxt_d().cachedVal = 0;
    qxt_d().start.restart();
    refresh();
}

/*!
    Refreshes the content.
 */
void QxtProgressLabel::refresh()
{
    // elapsed
    qreal elapsed = 0;
    if (qxt_d().start.isValid())
        elapsed = qxt_d().start.elapsed() / 1000.0;
    QTime etime(0, 0);
    etime = etime.addSecs(static_cast<int>(elapsed));

    // percentage
    qreal percent = 0;
    if (qxt_d().cachedMax != 0)
        percent = (qxt_d().cachedVal - qxt_d().cachedMin) / static_cast<qreal>(qxt_d().cachedMax);
    qreal total = 0;
    if (percent != 0)
        total = elapsed / percent;

    // remaining
    QTime rtime(0, 0);
    rtime = rtime.addSecs(static_cast<int>(total - elapsed));

    // format
    QString tformat = qxt_d().tformat;
    if (tformat.isEmpty())
        tformat = tr("mm:ss");
    QString cformat = qxt_d().cformat;
    if (cformat.isEmpty())
        cformat = tr("ETA: %r");

    QString result = QString(cformat).replace("%e", etime.toString(tformat));
    result = result.replace("%r", rtime.toString(tformat));
    setText(result);
}

/*!
    \reimp
 */
void QxtProgressLabel::timerEvent(QTimerEvent* event)
{
    Q_UNUSED(event);
    refresh();
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling | FileCheck %s

// Checks:
// Savannah #99210 https://savannah.cern.ch/bugs/index.php?99210
// Savannah #99234 https://savannah.cern.ch/bugs/?99234

// Let's start with simpler example pointing out the issue:
int i = 1; i++; int j = i;
j
// CHECK: (int) 2

extern "C" int printf(const char*,...);
.rawInput
class RAII {
public:
   RAII(int i) { I = new int(i); printf("RAII%d\n", ++InstanceCount); };
   int incr() { return ++(*I); }
   int get() { return *I; }
   ~RAII() { delete I; printf("~RAII%d\n", InstanceCount--); }
private:
   RAII(RAII&) {throw;};
   RAII& operator=(RAII) {throw;}
   int* I;
   static int InstanceCount; // will notice object copy
};
int RAII::InstanceCount = 0;
.rawInput

// This works because each line ends up in a separate wrapper
RAII R(12); // CHECK: RAII1
R.get();
int res = R.incr() // CHECK: 13

// This does not work because the decls and their inits are run before the
// call to R2.incr(), i.e. the second statement in the line.
// Savannah #99210 https://savannah.cern.ch/bugs/index.php?99210
RAII R2(42);R2.incr();int res2 = R2.get()
// CHECK: RAII2
// CHECK: 43
.q

// CHECK: ~RAII2
// CHECK: ~RAII1
// Enforce that only two objects got ever constructed:
// CHECK-NOT: ~RAII0
<commit_msg>Windows: Trivial fix for initorder.C.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling | FileCheck %s

// Checks:
// Savannah #99210 https://savannah.cern.ch/bugs/index.php?99210
// Savannah #99234 https://savannah.cern.ch/bugs/?99234

// Let's start with simpler example pointing out the issue:
int i = 1; i++; int j = i;
j
// CHECK: (int) 2

extern "C" int printf(const char*,...);
.rawInput
class RAII {
public:
   RAII(int i) { I = new int(i); printf("RAII%d\n", ++InstanceCount); };
   int incr() { return ++(*I); }
   int get() { return *I; }
   ~RAII() { delete I; printf("~RAII%d\n", InstanceCount--); }
private:
   RAII(RAII&);
   RAII& operator=(RAII);
   int* I;
   static int InstanceCount; // will notice object copy
};
int RAII::InstanceCount = 0;
.rawInput

// This works because each line ends up in a separate wrapper
RAII R(12); // CHECK: RAII1
R.get();
int res = R.incr() // CHECK: 13

// This does not work because the decls and their inits are run before the
// call to R2.incr(), i.e. the second statement in the line.
// Savannah #99210 https://savannah.cern.ch/bugs/index.php?99210
RAII R2(42);R2.incr();int res2 = R2.get()
// CHECK: RAII2
// CHECK: 43
.q

// CHECK: ~RAII2
// CHECK: ~RAII1
// Enforce that only two objects got ever constructed:
// CHECK-NOT: ~RAII0
<|endoftext|>


<commit_before><commit_msg>Improve handling of null pointers in link properties<commit_after><|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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 "rtkfdk_ggo.h"
#include "rtkGgoFunctions.h"
#include "rtkConfiguration.h"

#include "rtkThreeDCircularProjectionGeometryXMLFile.h"
#include "rtkProjectionsReader.h"
#include "rtkDisplacedDetectorImageFilter.h"
#include "rtkParkerShortScanImageFilter.h"
#include "rtkFDKConeBeamReconstructionFilter.h"
#if CUDA_FOUND
# include "rtkCudaFDKConeBeamReconstructionFilter.h"
#endif
#if OPENCL_FOUND
# include "rtkOpenCLFDKConeBeamReconstructionFilter.h"
#endif

#include <itkRegularExpressionSeriesFileNames.h>
#include <itkStreamingImageFilter.h>
#include <itkImageFileWriter.h>

int main(int argc, char * argv[])
{
  GGO(rtkfdk, args_info);

  typedef float OutputPixelType;
  const unsigned int Dimension = 3;

  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  // Generate file names
  itk::RegularExpressionSeriesFileNames::Pointer names = itk::RegularExpressionSeriesFileNames::New();
  names->SetDirectory(args_info.path_arg);
  names->SetNumericSort(false);
  names->SetRegularExpression(args_info.regexp_arg);
  names->SetSubMatch(0);

  if(args_info.verbose_flag)
    std::cout << "Regular expression matches "
              << names->GetFileNames().size()
              << " file(s)..."
              << std::endl;

  // Projections reader
  typedef rtk::ProjectionsReader< OutputImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileNames( names->GetFileNames() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( reader->GenerateOutputInformation() );

  itk::TimeProbe readerProbe;
  if(!args_info.lowmem_flag)
    {
    if(args_info.verbose_flag)
      std::cout << "Reading... " << std::flush;
    readerProbe.Start();
    TRY_AND_EXIT_ON_ITK_EXCEPTION( reader->Update() )
    readerProbe.Stop();
    if(args_info.verbose_flag)
      std::cout << "It took " << readerProbe.GetMeanTime() << ' ' << readerProbe.GetUnit() << std::endl;
    }

  // Geometry
  if(args_info.verbose_flag)
    std::cout << "Reading geometry information from "
              << args_info.geometry_arg
              << "..."
              << std::endl;
  rtk::ThreeDCircularProjectionGeometryXMLFileReader::Pointer geometryReader;
  geometryReader = rtk::ThreeDCircularProjectionGeometryXMLFileReader::New();
  geometryReader->SetFilename(args_info.geometry_arg);
  TRY_AND_EXIT_ON_ITK_EXCEPTION( geometryReader->GenerateOutputInformation() )

  // Displaced detector weighting
  typedef rtk::DisplacedDetectorImageFilter< OutputImageType > DDFType;
  DDFType::Pointer ddf = DDFType::New();
  ddf->SetInput( reader->GetOutput() );
  ddf->SetGeometry( geometryReader->GetOutputObject() );

  // Short scan image filter
  typedef rtk::ParkerShortScanImageFilter< OutputImageType > PSSFType;
  PSSFType::Pointer pssf = PSSFType::New();
  pssf->SetInput( ddf->GetOutput() );
  pssf->SetGeometry( geometryReader->GetOutputObject() );
  pssf->InPlaceOff();

  // Create reconstructed image
  typedef rtk::ConstantImageSource< OutputImageType > ConstantImageSourceType;
  ConstantImageSourceType::Pointer constantImageSource = ConstantImageSourceType::New();
  rtk::SetConstantImageSourceFromGgo<ConstantImageSourceType, args_info_rtkfdk>(constantImageSource, args_info);

  // This macro sets options for fdk filter which I can not see how to do better
  // because TFFTPrecision is not the same, e.g. for CPU and CUDA (SR)
#define SET_FELDKAMP_OPTIONS(f) \
    f->SetInput( 0, constantImageSource->GetOutput() ); \
    f->SetInput( 1, pssf->GetOutput() ); \
    f->SetGeometry( geometryReader->GetOutputObject() ); \
    f->GetRampFilter()->SetTruncationCorrection(args_info.pad_arg); \
    f->GetRampFilter()->SetHannCutFrequency(args_info.hann_arg);

  // FDK reconstruction filtering
  itk::ImageToImageFilter<OutputImageType, OutputImageType>::Pointer feldkamp;
  typedef rtk::FDKConeBeamReconstructionFilter< OutputImageType > FDKCPUType;
#if CUDA_FOUND
  typedef rtk::CudaFDKConeBeamReconstructionFilter                FDKCUDAType;
#endif
#if OPENCL_FOUND
  typedef rtk::OpenCLFDKConeBeamReconstructionFilter              FDKOPENCLType;
#endif
  if(!strcmp(args_info.hardware_arg, "cpu") )
    {
    feldkamp = FDKCPUType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKCPUType*>(feldkamp.GetPointer()) );
    }
  else if(!strcmp(args_info.hardware_arg, "cuda") )
    {
#if CUDA_FOUND
    feldkamp = FDKCUDAType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKCUDAType*>(feldkamp.GetPointer()) );
#else
    std::cerr << "The program has not been compiled with cuda option" << std::endl;
    return EXIT_FAILURE;
#endif
    }
  else if(!strcmp(args_info.hardware_arg, "opencl") )
    {
#if OPENCL_FOUND
    feldkamp = FDKOPENCLType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKOPENCLType*>(feldkamp.GetPointer()) );
#else
    std::cerr << "The program has not been compiled with opencl option" << std::endl;
    return EXIT_FAILURE;
#endif
    }

  // Streaming depending on streaming capability of writer
  typedef itk::StreamingImageFilter<OutputImageType, OutputImageType> StreamerType;
  StreamerType::Pointer streamerBP = StreamerType::New();
  itk::ImageIOBase::Pointer imageIOBase;
  streamerBP->SetInput( feldkamp->GetOutput() );
  streamerBP->SetNumberOfStreamDivisions( args_info.divisions_arg );

  // Write
  typedef itk::ImageFileWriter<  OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( args_info.output_arg );
  writer->SetInput( streamerBP->GetOutput() );

  if(args_info.verbose_flag)
    std::cout << "Reconstructing and writing... " << std::flush;
  itk::TimeProbe writerProbe;

  writerProbe.Start();
  TRY_AND_EXIT_ON_ITK_EXCEPTION( writer->Update() );
  writerProbe.Stop();

  if(args_info.verbose_flag)
    {
    std::cout << "It took " << writerProbe.GetMeanTime() << ' ' << readerProbe.GetUnit() << std::endl;
    if(!strcmp(args_info.hardware_arg, "cpu") )
      static_cast<FDKCPUType* >(feldkamp.GetPointer())->PrintTiming(std::cout);
#if CUDA_FOUND
    else if(!strcmp(args_info.hardware_arg, "cuda") )
      static_cast<FDKCUDAType*>(feldkamp.GetPointer())->PrintTiming(std::cout);
#endif
#if OPENCL_FOUND
    else if(!strcmp(args_info.hardware_arg, "opencl") )
      static_cast<FDKOPENCLType*>(feldkamp.GetPointer())->PrintTiming(std::cout);
#endif
    }

  return EXIT_SUCCESS;
}
<commit_msg>Removed useless line<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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 "rtkfdk_ggo.h"
#include "rtkGgoFunctions.h"
#include "rtkConfiguration.h"

#include "rtkThreeDCircularProjectionGeometryXMLFile.h"
#include "rtkProjectionsReader.h"
#include "rtkDisplacedDetectorImageFilter.h"
#include "rtkParkerShortScanImageFilter.h"
#include "rtkFDKConeBeamReconstructionFilter.h"
#if CUDA_FOUND
# include "rtkCudaFDKConeBeamReconstructionFilter.h"
#endif
#if OPENCL_FOUND
# include "rtkOpenCLFDKConeBeamReconstructionFilter.h"
#endif

#include <itkRegularExpressionSeriesFileNames.h>
#include <itkStreamingImageFilter.h>
#include <itkImageFileWriter.h>

int main(int argc, char * argv[])
{
  GGO(rtkfdk, args_info);

  typedef float OutputPixelType;
  const unsigned int Dimension = 3;

  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  // Generate file names
  itk::RegularExpressionSeriesFileNames::Pointer names = itk::RegularExpressionSeriesFileNames::New();
  names->SetDirectory(args_info.path_arg);
  names->SetNumericSort(false);
  names->SetRegularExpression(args_info.regexp_arg);
  names->SetSubMatch(0);

  if(args_info.verbose_flag)
    std::cout << "Regular expression matches "
              << names->GetFileNames().size()
              << " file(s)..."
              << std::endl;

  // Projections reader
  typedef rtk::ProjectionsReader< OutputImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileNames( names->GetFileNames() );
  TRY_AND_EXIT_ON_ITK_EXCEPTION( reader->GenerateOutputInformation() );

  itk::TimeProbe readerProbe;
  if(!args_info.lowmem_flag)
    {
    if(args_info.verbose_flag)
      std::cout << "Reading... " << std::flush;
    readerProbe.Start();
    TRY_AND_EXIT_ON_ITK_EXCEPTION( reader->Update() )
    readerProbe.Stop();
    if(args_info.verbose_flag)
      std::cout << "It took " << readerProbe.GetMeanTime() << ' ' << readerProbe.GetUnit() << std::endl;
    }

  // Geometry
  if(args_info.verbose_flag)
    std::cout << "Reading geometry information from "
              << args_info.geometry_arg
              << "..."
              << std::endl;
  rtk::ThreeDCircularProjectionGeometryXMLFileReader::Pointer geometryReader;
  geometryReader = rtk::ThreeDCircularProjectionGeometryXMLFileReader::New();
  geometryReader->SetFilename(args_info.geometry_arg);
  TRY_AND_EXIT_ON_ITK_EXCEPTION( geometryReader->GenerateOutputInformation() )

  // Displaced detector weighting
  typedef rtk::DisplacedDetectorImageFilter< OutputImageType > DDFType;
  DDFType::Pointer ddf = DDFType::New();
  ddf->SetInput( reader->GetOutput() );
  ddf->SetGeometry( geometryReader->GetOutputObject() );

  // Short scan image filter
  typedef rtk::ParkerShortScanImageFilter< OutputImageType > PSSFType;
  PSSFType::Pointer pssf = PSSFType::New();
  pssf->SetInput( ddf->GetOutput() );
  pssf->SetGeometry( geometryReader->GetOutputObject() );
  pssf->InPlaceOff();

  // Create reconstructed image
  typedef rtk::ConstantImageSource< OutputImageType > ConstantImageSourceType;
  ConstantImageSourceType::Pointer constantImageSource = ConstantImageSourceType::New();
  rtk::SetConstantImageSourceFromGgo<ConstantImageSourceType, args_info_rtkfdk>(constantImageSource, args_info);

  // This macro sets options for fdk filter which I can not see how to do better
  // because TFFTPrecision is not the same, e.g. for CPU and CUDA (SR)
#define SET_FELDKAMP_OPTIONS(f) \
    f->SetInput( 0, constantImageSource->GetOutput() ); \
    f->SetInput( 1, pssf->GetOutput() ); \
    f->SetGeometry( geometryReader->GetOutputObject() ); \
    f->GetRampFilter()->SetTruncationCorrection(args_info.pad_arg); \
    f->GetRampFilter()->SetHannCutFrequency(args_info.hann_arg);

  // FDK reconstruction filtering
  itk::ImageToImageFilter<OutputImageType, OutputImageType>::Pointer feldkamp;
  typedef rtk::FDKConeBeamReconstructionFilter< OutputImageType > FDKCPUType;
#if CUDA_FOUND
  typedef rtk::CudaFDKConeBeamReconstructionFilter                FDKCUDAType;
#endif
#if OPENCL_FOUND
  typedef rtk::OpenCLFDKConeBeamReconstructionFilter              FDKOPENCLType;
#endif
  if(!strcmp(args_info.hardware_arg, "cpu") )
    {
    feldkamp = FDKCPUType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKCPUType*>(feldkamp.GetPointer()) );
    }
  else if(!strcmp(args_info.hardware_arg, "cuda") )
    {
#if CUDA_FOUND
    feldkamp = FDKCUDAType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKCUDAType*>(feldkamp.GetPointer()) );
#else
    std::cerr << "The program has not been compiled with cuda option" << std::endl;
    return EXIT_FAILURE;
#endif
    }
  else if(!strcmp(args_info.hardware_arg, "opencl") )
    {
#if OPENCL_FOUND
    feldkamp = FDKOPENCLType::New();
    SET_FELDKAMP_OPTIONS( static_cast<FDKOPENCLType*>(feldkamp.GetPointer()) );
#else
    std::cerr << "The program has not been compiled with opencl option" << std::endl;
    return EXIT_FAILURE;
#endif
    }

  // Streaming depending on streaming capability of writer
  typedef itk::StreamingImageFilter<OutputImageType, OutputImageType> StreamerType;
  StreamerType::Pointer streamerBP = StreamerType::New();
  streamerBP->SetInput( feldkamp->GetOutput() );
  streamerBP->SetNumberOfStreamDivisions( args_info.divisions_arg );

  // Write
  typedef itk::ImageFileWriter<  OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( args_info.output_arg );
  writer->SetInput( streamerBP->GetOutput() );

  if(args_info.verbose_flag)
    std::cout << "Reconstructing and writing... " << std::flush;
  itk::TimeProbe writerProbe;

  writerProbe.Start();
  TRY_AND_EXIT_ON_ITK_EXCEPTION( writer->Update() );
  writerProbe.Stop();

  if(args_info.verbose_flag)
    {
    std::cout << "It took " << writerProbe.GetMeanTime() << ' ' << readerProbe.GetUnit() << std::endl;
    if(!strcmp(args_info.hardware_arg, "cpu") )
      static_cast<FDKCPUType* >(feldkamp.GetPointer())->PrintTiming(std::cout);
#if CUDA_FOUND
    else if(!strcmp(args_info.hardware_arg, "cuda") )
      static_cast<FDKCUDAType*>(feldkamp.GetPointer())->PrintTiming(std::cout);
#endif
#if OPENCL_FOUND
    else if(!strcmp(args_info.hardware_arg, "opencl") )
      static_cast<FDKOPENCLType*>(feldkamp.GetPointer())->PrintTiming(std::cout);
#endif
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#include <string>
#include <iterator>

#include <windows.h>
#include <winnt.h>
#include <winternl.h>

#include <hadesmem/config.hpp>
#include <hadesmem/detail/winternl.hpp>
#include <hadesmem/find_procedure.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/patcher.hpp>
#include <hadesmem/process.hpp>

// TODO: Write a test app to exercise all the hooked APIs and information
// classes.

namespace winternl = hadesmem::detail::winternl;

std::unique_ptr<hadesmem::Process> g_process;

std::unique_ptr<hadesmem::PatchDetour> g_nt_query_system_information_hk;

class SystemProcessInformationEnum
{
public:
  explicit SystemProcessInformationEnum(
    winternl::SYSTEM_INFORMATION_CLASS info_class,
    void* buffer) HADESMEM_DETAIL_NOEXCEPT
    : buffer_(GetRealBuffer(info_class, buffer)),
      prev_(nullptr),
      info_class_(info_class),
      unlinked_(false)
  {
    HADESMEM_DETAIL_ASSERT(buffer_);
    HADESMEM_DETAIL_ASSERT(
      info_class == winternl::SystemProcessInformation ||
      info_class == winternl::SystemExtendedProcessInformation ||
      info_class == winternl::SystemSessionProcessInformation ||
      info_class == winternl::SystemFullProcessInformation);
  }

  SystemProcessInformationEnum(SystemProcessInformationEnum const&) = delete;

  SystemProcessInformationEnum& operator=(SystemProcessInformationEnum const&) =
    delete;

  void Advance() HADESMEM_DETAIL_NOEXCEPT
  {
    if (!unlinked_)
    {
      prev_ = buffer_;
    }

    unlinked_ = false;

    if (buffer_->NextEntryOffset)
    {
      buffer_ = reinterpret_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(
        reinterpret_cast<DWORD_PTR>(buffer_) + buffer_->NextEntryOffset);
    }
    else
    {
      buffer_ = nullptr;
    }
  }

  bool Valid() const HADESMEM_DETAIL_NOEXCEPT
  {
    return buffer_ != nullptr;
  }

  void Unlink() HADESMEM_DETAIL_NOEXCEPT
  {
    HADESMEM_DETAIL_ASSERT(buffer_);

    HADESMEM_DETAIL_ASSERT(!unlinked_);

    if (prev_)
    {
      if (buffer_->NextEntryOffset)
      {
        prev_->NextEntryOffset += buffer_->NextEntryOffset;
      }
      else
      {
        prev_->NextEntryOffset = 0UL;
      }

      unlinked_ = true;
    }
    else
    {
      // Unlinking the first process is unsupported.
      HADESMEM_DETAIL_ASSERT(false);
    }
  }

  bool HasName() const HADESMEM_DETAIL_NOEXCEPT
  {
    return buffer_->ImageName.Buffer != nullptr && buffer_->ImageName.Length;
  }

  // TODO: Remove dependency on std::wstring, we shouldn't need to allocate
  // and copy here. This should be a noexcept function returning a range over
  // the existing string buffer.
  std::wstring GetName() const
  {
    auto const str_end =
      std::find(buffer_->ImageName.Buffer,
                buffer_->ImageName.Buffer + buffer_->ImageName.Length,
                L'\0');
    // SystemFullProcessInformation returns the full path rather than just the
    // image name.
    if (info_class_ == winternl::SystemFullProcessInformation)
    {
      auto const name_beg =
        std::find(std::reverse_iterator<wchar_t*>(str_end),
                  std::reverse_iterator<wchar_t*>(buffer_->ImageName.Buffer),
                  L'\\');
      return {name_beg.base(), str_end};
    }
    else
    {
      return {buffer_->ImageName.Buffer, str_end};
    }
  }

private:
  winternl::SYSTEM_PROCESS_INFORMATION*
    GetRealBuffer(winternl::SYSTEM_INFORMATION_CLASS info_class,
                  void* buffer) const HADESMEM_DETAIL_NOEXCEPT
  {
    if (info_class == winternl::SystemProcessInformation ||
        info_class == winternl::SystemExtendedProcessInformation ||
        info_class == winternl::SystemFullProcessInformation)
    {
      return static_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(buffer);
    }
    else if (info_class == winternl::SystemSessionProcessInformation)
    {
      return static_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(
        static_cast<winternl::SYSTEM_SESSION_PROCESS_INFORMATION*>(buffer)
          ->Buffer);
    }
    else
    {
      HADESMEM_DETAIL_ASSERT(false);
      return nullptr;
    }
  }

  winternl::SYSTEM_PROCESS_INFORMATION* buffer_;
  winternl::SYSTEM_PROCESS_INFORMATION* prev_;
  winternl::SYSTEM_INFORMATION_CLASS info_class_;
  bool unlinked_;
};

// TODO: Preserve LastError value.
extern "C" NTSTATUS WINAPI NtQuerySystemInformationHk(
  winternl::SYSTEM_INFORMATION_CLASS system_information_class,
  PVOID system_information,
  ULONG system_information_length,
  PULONG return_length) HADESMEM_DETAIL_NOEXCEPT
{
  HADESMEM_DETAIL_TRACE_FORMAT_A("Args: [%d] [%p] [%u] [%p].",
                                 system_information_class,
                                 system_information,
                                 system_information_length,
                                 return_length);
  auto const nt_query_system_information =
    g_nt_query_system_information_hk
      ->GetTrampoline<decltype(&NtQuerySystemInformationHk)>();
  auto const ret = nt_query_system_information(system_information_class,
                                               system_information,
                                               system_information_length,
                                               return_length);
  HADESMEM_DETAIL_TRACE_FORMAT_A("Ret: [%ld].", ret);

  // TODO: Handle SystemProcessIdInformation (88).
  if (system_information_class != winternl::SystemProcessInformation &&
      system_information_class != winternl::SystemExtendedProcessInformation &&
      system_information_class != winternl::SystemSessionProcessInformation &&
      system_information_class != winternl::SystemFullProcessInformation)
  {
    HADESMEM_DETAIL_TRACE_A("Unhandled information class.");
    return ret;
  }

  if (!NT_SUCCESS(ret))
  {
    HADESMEM_DETAIL_TRACE_A("Trampoline returned failure.");
    return ret;
  }

  try
  {
    HADESMEM_DETAIL_TRACE_A("Enumerating processes.");
    for (SystemProcessInformationEnum process_info{system_information_class,
                                                   system_information};
         process_info.Valid();
         process_info.Advance())
    {
      if (process_info.HasName())
      {
        auto const process_name = process_info.GetName();
        HADESMEM_DETAIL_TRACE_FORMAT_W(L"Name: [%s].", process_name.c_str());
        if (process_name == L"hades.exe")
        {
          HADESMEM_DETAIL_TRACE_A("Unlinking process.");
          process_info.Unlink();
        }
      }
      else
      {
        HADESMEM_DETAIL_TRACE_A("WARNING! Invalid name.");
      }
    }
  }
  catch (...)
  {
    HADESMEM_DETAIL_TRACE_A(
      boost::current_exception_diagnostic_information().c_str());
    HADESMEM_DETAIL_ASSERT(false);
  }

  return ret;
}

extern "C" HADESMEM_DETAIL_DLLEXPORT DWORD_PTR Load() HADESMEM_DETAIL_NOEXCEPT
{
  try
  {
    g_process.reset(new hadesmem::Process(::GetCurrentProcessId()));
    hadesmem::Module const ntdll(*g_process, L"ntdll.dll");
    auto const nt_query_system_information =
      hadesmem::FindProcedure(*g_process, ntdll, "NtQuerySystemInformation");
    auto const nt_query_system_information_ptr =
      hadesmem::detail::UnionCast<void*>(nt_query_system_information);
    auto const nt_query_system_information_hk =
      hadesmem::detail::UnionCast<void*>(&NtQuerySystemInformationHk);
    g_nt_query_system_information_hk.reset(
      new hadesmem::PatchDetour(*g_process,
                                nt_query_system_information_ptr,
                                nt_query_system_information_hk));
    g_nt_query_system_information_hk->Apply();
    HADESMEM_DETAIL_TRACE_A("NtQuerySystemInformationHk hooked.");
  }
  catch (...)
  {
    HADESMEM_DETAIL_TRACE_A(
      boost::current_exception_diagnostic_information().c_str());
    HADESMEM_DETAIL_ASSERT(false);
  }

  return 0;
}

// TODO: Safe unhooking and unloading.
extern "C" HADESMEM_DETAIL_DLLEXPORT DWORD_PTR Free() HADESMEM_DETAIL_NOEXCEPT
{
  return 0;
}

BOOL WINAPI
  DllMain(HINSTANCE /*instance*/, DWORD /*reason*/, LPVOID /*reserved*/)
{
  return TRUE;
}
<commit_msg>* [Cerberus] Remove TODO because it's easier to just copy the string than deal with all the nonsense of non-null-terminated strings, string length extending past the null, etc.<commit_after>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#include <string>
#include <iterator>

#include <windows.h>
#include <winnt.h>
#include <winternl.h>

#include <hadesmem/config.hpp>
#include <hadesmem/detail/winternl.hpp>
#include <hadesmem/find_procedure.hpp>
#include <hadesmem/module.hpp>
#include <hadesmem/patcher.hpp>
#include <hadesmem/process.hpp>

// TODO: Write a test app to exercise all the hooked APIs and information
// classes.

namespace winternl = hadesmem::detail::winternl;

std::unique_ptr<hadesmem::Process> g_process;

std::unique_ptr<hadesmem::PatchDetour> g_nt_query_system_information_hk;

class SystemProcessInformationEnum
{
public:
  explicit SystemProcessInformationEnum(
    winternl::SYSTEM_INFORMATION_CLASS info_class,
    void* buffer) HADESMEM_DETAIL_NOEXCEPT
    : buffer_(GetRealBuffer(info_class, buffer)),
      prev_(nullptr),
      info_class_(info_class),
      unlinked_(false)
  {
    HADESMEM_DETAIL_ASSERT(buffer_);
    HADESMEM_DETAIL_ASSERT(
      info_class == winternl::SystemProcessInformation ||
      info_class == winternl::SystemExtendedProcessInformation ||
      info_class == winternl::SystemSessionProcessInformation ||
      info_class == winternl::SystemFullProcessInformation);
  }

  SystemProcessInformationEnum(SystemProcessInformationEnum const&) = delete;

  SystemProcessInformationEnum& operator=(SystemProcessInformationEnum const&) =
    delete;

  void Advance() HADESMEM_DETAIL_NOEXCEPT
  {
    if (!unlinked_)
    {
      prev_ = buffer_;
    }

    unlinked_ = false;

    if (buffer_->NextEntryOffset)
    {
      buffer_ = reinterpret_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(
        reinterpret_cast<DWORD_PTR>(buffer_) + buffer_->NextEntryOffset);
    }
    else
    {
      buffer_ = nullptr;
    }
  }

  bool Valid() const HADESMEM_DETAIL_NOEXCEPT
  {
    return buffer_ != nullptr;
  }

  void Unlink() HADESMEM_DETAIL_NOEXCEPT
  {
    HADESMEM_DETAIL_ASSERT(buffer_);

    HADESMEM_DETAIL_ASSERT(!unlinked_);

    if (prev_)
    {
      if (buffer_->NextEntryOffset)
      {
        prev_->NextEntryOffset += buffer_->NextEntryOffset;
      }
      else
      {
        prev_->NextEntryOffset = 0UL;
      }

      unlinked_ = true;
    }
    else
    {
      // Unlinking the first process is unsupported.
      HADESMEM_DETAIL_ASSERT(false);
    }
  }

  bool HasName() const HADESMEM_DETAIL_NOEXCEPT
  {
    return buffer_->ImageName.Buffer != nullptr && buffer_->ImageName.Length;
  }

  std::wstring GetName() const
  {
    auto const str_end =
      std::find(buffer_->ImageName.Buffer,
                buffer_->ImageName.Buffer + buffer_->ImageName.Length,
                L'\0');
    // SystemFullProcessInformation returns the full path rather than just the
    // image name.
    if (info_class_ == winternl::SystemFullProcessInformation)
    {
      auto const name_beg =
        std::find(std::reverse_iterator<wchar_t*>(str_end),
                  std::reverse_iterator<wchar_t*>(buffer_->ImageName.Buffer),
                  L'\\');
      return {name_beg.base(), str_end};
    }
    else
    {
      return {buffer_->ImageName.Buffer, str_end};
    }
  }

private:
  winternl::SYSTEM_PROCESS_INFORMATION*
    GetRealBuffer(winternl::SYSTEM_INFORMATION_CLASS info_class,
                  void* buffer) const HADESMEM_DETAIL_NOEXCEPT
  {
    if (info_class == winternl::SystemProcessInformation ||
        info_class == winternl::SystemExtendedProcessInformation ||
        info_class == winternl::SystemFullProcessInformation)
    {
      return static_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(buffer);
    }
    else if (info_class == winternl::SystemSessionProcessInformation)
    {
      return static_cast<winternl::SYSTEM_PROCESS_INFORMATION*>(
        static_cast<winternl::SYSTEM_SESSION_PROCESS_INFORMATION*>(buffer)
          ->Buffer);
    }
    else
    {
      HADESMEM_DETAIL_ASSERT(false);
      return nullptr;
    }
  }

  winternl::SYSTEM_PROCESS_INFORMATION* buffer_;
  winternl::SYSTEM_PROCESS_INFORMATION* prev_;
  winternl::SYSTEM_INFORMATION_CLASS info_class_;
  bool unlinked_;
};

// TODO: Preserve LastError value.
extern "C" NTSTATUS WINAPI NtQuerySystemInformationHk(
  winternl::SYSTEM_INFORMATION_CLASS system_information_class,
  PVOID system_information,
  ULONG system_information_length,
  PULONG return_length) HADESMEM_DETAIL_NOEXCEPT
{
  HADESMEM_DETAIL_TRACE_FORMAT_A("Args: [%d] [%p] [%u] [%p].",
                                 system_information_class,
                                 system_information,
                                 system_information_length,
                                 return_length);
  auto const nt_query_system_information =
    g_nt_query_system_information_hk
      ->GetTrampoline<decltype(&NtQuerySystemInformationHk)>();
  auto const ret = nt_query_system_information(system_information_class,
                                               system_information,
                                               system_information_length,
                                               return_length);
  HADESMEM_DETAIL_TRACE_FORMAT_A("Ret: [%ld].", ret);

  // TODO: Handle SystemProcessIdInformation (88).
  if (system_information_class != winternl::SystemProcessInformation &&
      system_information_class != winternl::SystemExtendedProcessInformation &&
      system_information_class != winternl::SystemSessionProcessInformation &&
      system_information_class != winternl::SystemFullProcessInformation)
  {
    HADESMEM_DETAIL_TRACE_A("Unhandled information class.");
    return ret;
  }

  if (!NT_SUCCESS(ret))
  {
    HADESMEM_DETAIL_TRACE_A("Trampoline returned failure.");
    return ret;
  }

  try
  {
    HADESMEM_DETAIL_TRACE_A("Enumerating processes.");
    for (SystemProcessInformationEnum process_info{system_information_class,
                                                   system_information};
         process_info.Valid();
         process_info.Advance())
    {
      if (process_info.HasName())
      {
        auto const process_name = process_info.GetName();
        HADESMEM_DETAIL_TRACE_FORMAT_W(L"Name: [%s].", process_name.c_str());
        if (process_name == L"hades.exe")
        {
          HADESMEM_DETAIL_TRACE_A("Unlinking process.");
          process_info.Unlink();
        }
      }
      else
      {
        HADESMEM_DETAIL_TRACE_A("WARNING! Invalid name.");
      }
    }
  }
  catch (...)
  {
    HADESMEM_DETAIL_TRACE_A(
      boost::current_exception_diagnostic_information().c_str());
    HADESMEM_DETAIL_ASSERT(false);
  }

  return ret;
}

extern "C" HADESMEM_DETAIL_DLLEXPORT DWORD_PTR Load() HADESMEM_DETAIL_NOEXCEPT
{
  try
  {
    g_process.reset(new hadesmem::Process(::GetCurrentProcessId()));
    hadesmem::Module const ntdll(*g_process, L"ntdll.dll");
    auto const nt_query_system_information =
      hadesmem::FindProcedure(*g_process, ntdll, "NtQuerySystemInformation");
    auto const nt_query_system_information_ptr =
      hadesmem::detail::UnionCast<void*>(nt_query_system_information);
    auto const nt_query_system_information_hk =
      hadesmem::detail::UnionCast<void*>(&NtQuerySystemInformationHk);
    g_nt_query_system_information_hk.reset(
      new hadesmem::PatchDetour(*g_process,
                                nt_query_system_information_ptr,
                                nt_query_system_information_hk));
    g_nt_query_system_information_hk->Apply();
    HADESMEM_DETAIL_TRACE_A("NtQuerySystemInformationHk hooked.");
  }
  catch (...)
  {
    HADESMEM_DETAIL_TRACE_A(
      boost::current_exception_diagnostic_information().c_str());
    HADESMEM_DETAIL_ASSERT(false);
  }

  return 0;
}

// TODO: Safe unhooking and unloading.
extern "C" HADESMEM_DETAIL_DLLEXPORT DWORD_PTR Free() HADESMEM_DETAIL_NOEXCEPT
{
  return 0;
}

BOOL WINAPI
  DllMain(HINSTANCE /*instance*/, DWORD /*reason*/, LPVOID /*reserved*/)
{
  return TRUE;
}
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2012, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_debug.h"
#include "backward_file_reader.h"

BackwardFileReader::BWReaderBuffer::BWReaderBuffer(int cb/*=0*/, char * input /* = NULL*/)
	: data(input)
	, cbData(cb)
	, cbAlloc(cb)
	, at_eof(false)
	, text_mode(false)
	, error(0)
{
	if (input) {
		cbAlloc = cbData = cb;
	} else if (cb > 0) {
		data = (char*)malloc(cb);
		if (data) memset(data, 17, cb);
		cbData = 0;
	}
}

void BackwardFileReader::BWReaderBuffer::setsize(int cb)
{
	cbData = cb;
	ASSERT(cbData <= cbAlloc);
}

bool BackwardFileReader::BWReaderBuffer::reserve(int cb)
{
	if (data && cbAlloc >= cb)
		return true;

	void * pv = realloc(data, cb);
	if (pv) {
		data = (char*)pv;
		cbAlloc = cb;
		return true;
	}
	return false;
}

int BackwardFileReader::BWReaderBuffer::fread_at(FILE * file, off_t offset, int cb)
{
	if ( ! reserve(((cb + 16) & ~15) + 16))
		return 0;

	fseek(file, offset, SEEK_SET);

	int ret = (int)fread(data, 1, cb, file);
	cbData = ret;

	if (ret <= 0) {
		error = ferror(file);
		return 0;
	} else {
		error = 0;
	}

	// on windows in text mode we can consume more than we read because of \r
	// but since we are scanning backward this can cause us to re-read
	// the same bytes more than once. So lop off the end of the buffer so
	// so we only get back the unique bytes
	at_eof = feof(file);
	if (text_mode && ! at_eof) {
		off_t end_offset = ftell(file);
		int extra = (int)(end_offset - (offset + ret));
		ret -= extra;
	}

	if (ret < cbAlloc) {
		data[ret] =  0; // force null terminate.
	} else {
		// this should NOT happen
		EXCEPT("BWReadBuffer is unexpectedly too small!");
	}

	return ret;
}

BackwardFileReader::BackwardFileReader(std::string filename, int open_flags)
	: error(0), file(NULL), cbFile(0), cbPos(0)
{
#ifdef WIN32
	open_flags |= O_BINARY;
#endif
	int fd = safe_open_wrapper_follow(filename.c_str(), open_flags);
	if (fd < 0)
		error = errno;
	else if ( ! OpenFile(fd, "rb"))
		close(fd);
}

BackwardFileReader::BackwardFileReader(int fd, const char * open_options)
	: error(0), file(NULL), cbFile(0), cbPos(0)
{
	OpenFile(fd, open_options);
}
/*
BackwardFileReader::~BackwardFileReader()
{
	if (file) fclose(file);
	file = NULL;
}
*/

bool BackwardFileReader::PrevLine(std::string & str)
{
	str.clear();

	// can we get a previous line out of our existing buffer?
	// then do that.
	if (PrevLineFromBuf(str))
		return true;

	// no line in the buffer? then return false
	if (AtBOF())
		return false;

	const int cbBack = 512;
	while (true) {
		int off = cbPos > cbBack ? cbPos - cbBack : 0;
		int cbToRead = (int)(cbPos - off);

		// we want to read in cbBack chunks at cbBack aligment, of course
		// this only makes sense to do if cbBack is a power of 2.
		// also, in order to get EOF to register, we have to read a little
		// so we may want the first read (from the end, of course) to be a bit
		// larger than cbBack so that we read at least cbBack but also end up
		// on cbBack alignment.
		if (cbFile == cbPos) {
			// test to see if cbBack is a power of 2, if it is, then set our
			// seek to align on cbBack.
			if (!(cbBack & (cbBack-1))) {
				// seek to an even multiple of cbBack at least cbBack from the end of the file.
				off = (cbFile - cbBack) & ~(cbBack-1);
				cbToRead = cbFile - off;
			}
			cbToRead += 16;
		}

		if ( ! buf.fread_at(file, off, cbToRead)) {
			if (buf.LastError()) {
				error = buf.LastError();
				return false;
			}
		}

		cbPos = off;

		// try again to get some data from the buffer
		if (PrevLineFromBuf(str) || AtBOF())
			return true;
	}
}

bool BackwardFileReader::OpenFile(int fd, const char * open_options)
{
	file = fdopen(fd, open_options);
	if ( ! file) {
		error = errno;
	} else {
		// seek to the end of the file.
		fseek(file, 0, SEEK_END);
		cbFile = cbPos = ftell(file);
		error = 0;
		buf.SetTextMode( ! strchr(open_options,'b'));
	}
	return error == 0;
}

// prefixes or part of a line into str, and updates internal
// variables to keep track of what parts of the buffer have been returned.
bool BackwardFileReader::PrevLineFromBuf(std::string & str)
{
	// if we have no buffered data, then there is nothing to do
	int cb = buf.size();
	if (cb <= 0)
		return false;

	// if buffer ends in a newline, convert it to a \0
	if (buf[cb-1] == '\n') {
		buf[--cb] = 0;
		// if the input string is not empty, then the previous
		// buffer ended _exactly_ at a newline boundary, so return
		// the string rather than concatinating it to the newline.
		if ( ! str.empty()) {
			if (buf[cb-1] == '\r')
				buf[--cb] = 0;
			buf.setsize(cb);
			return true;
		}
	}
	// because of windows style \r\n, we also tolerate a \r at the end of the line
	if (buf[cb-1] == '\r') {
		buf[--cb] = 0;
	}

	// now we walk backward through the buffer until we encounter another newline
	// returning all of the characters that we found.
	while (cb > 0) {
		if (buf[--cb] == '\n') {
			str.insert(0, &buf[cb+1]);
			buf[cb] = 0;
			buf.setsize(cb);
			return true;
		}
	}

	// we hit the start of the buffer without finding another newline,
	// so return that text, but only return true if we are also at the start
	// of the file.
	str.insert(0, &buf[0]);
	buf[0] = 0;
	buf.clear();

	return (0 == cbPos);
}
<commit_msg>Always check return value of fseek #6345<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2012, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_debug.h"
#include "backward_file_reader.h"

BackwardFileReader::BWReaderBuffer::BWReaderBuffer(int cb/*=0*/, char * input /* = NULL*/)
	: data(input)
	, cbData(cb)
	, cbAlloc(cb)
	, at_eof(false)
	, text_mode(false)
	, error(0)
{
	if (input) {
		cbAlloc = cbData = cb;
	} else if (cb > 0) {
		data = (char*)malloc(cb);
		if (data) memset(data, 17, cb);
		cbData = 0;
	}
}

void BackwardFileReader::BWReaderBuffer::setsize(int cb)
{
	cbData = cb;
	ASSERT(cbData <= cbAlloc);
}

bool BackwardFileReader::BWReaderBuffer::reserve(int cb)
{
	if (data && cbAlloc >= cb)
		return true;

	void * pv = realloc(data, cb);
	if (pv) {
		data = (char*)pv;
		cbAlloc = cb;
		return true;
	}
	return false;
}

int BackwardFileReader::BWReaderBuffer::fread_at(FILE * file, off_t offset, int cb)
{
	if ( ! reserve(((cb + 16) & ~15) + 16))
		return 0;

	int ret = fseek(file, offset, SEEK_SET);
	if (ret <= 0) {
		error = ferror(file);
		return 0;
	} else {
		error = 0;
	}

	ret = (int)fread(data, 1, cb, file);
	cbData = ret;

	if (ret <= 0) {
		error = ferror(file);
		return 0;
	} else {
		error = 0;
	}

	// on windows in text mode we can consume more than we read because of \r
	// but since we are scanning backward this can cause us to re-read
	// the same bytes more than once. So lop off the end of the buffer so
	// so we only get back the unique bytes
	at_eof = feof(file);
	if (text_mode && ! at_eof) {
		off_t end_offset = ftell(file);
		int extra = (int)(end_offset - (offset + ret));
		ret -= extra;
	}

	if (ret < cbAlloc) {
		data[ret] =  0; // force null terminate.
	} else {
		// this should NOT happen
		EXCEPT("BWReadBuffer is unexpectedly too small!");
	}

	return ret;
}

BackwardFileReader::BackwardFileReader(std::string filename, int open_flags)
	: error(0), file(NULL), cbFile(0), cbPos(0)
{
#ifdef WIN32
	open_flags |= O_BINARY;
#endif
	int fd = safe_open_wrapper_follow(filename.c_str(), open_flags);
	if (fd < 0)
		error = errno;
	else if ( ! OpenFile(fd, "rb"))
		close(fd);
}

BackwardFileReader::BackwardFileReader(int fd, const char * open_options)
	: error(0), file(NULL), cbFile(0), cbPos(0)
{
	OpenFile(fd, open_options);
}
/*
BackwardFileReader::~BackwardFileReader()
{
	if (file) fclose(file);
	file = NULL;
}
*/

bool BackwardFileReader::PrevLine(std::string & str)
{
	str.clear();

	// can we get a previous line out of our existing buffer?
	// then do that.
	if (PrevLineFromBuf(str))
		return true;

	// no line in the buffer? then return false
	if (AtBOF())
		return false;

	const int cbBack = 512;
	while (true) {
		int off = cbPos > cbBack ? cbPos - cbBack : 0;
		int cbToRead = (int)(cbPos - off);

		// we want to read in cbBack chunks at cbBack aligment, of course
		// this only makes sense to do if cbBack is a power of 2.
		// also, in order to get EOF to register, we have to read a little
		// so we may want the first read (from the end, of course) to be a bit
		// larger than cbBack so that we read at least cbBack but also end up
		// on cbBack alignment.
		if (cbFile == cbPos) {
			// test to see if cbBack is a power of 2, if it is, then set our
			// seek to align on cbBack.
			if (!(cbBack & (cbBack-1))) {
				// seek to an even multiple of cbBack at least cbBack from the end of the file.
				off = (cbFile - cbBack) & ~(cbBack-1);
				cbToRead = cbFile - off;
			}
			cbToRead += 16;
		}

		if ( ! buf.fread_at(file, off, cbToRead)) {
			if (buf.LastError()) {
				error = buf.LastError();
				return false;
			}
		}

		cbPos = off;

		// try again to get some data from the buffer
		if (PrevLineFromBuf(str) || AtBOF())
			return true;
	}
}

bool BackwardFileReader::OpenFile(int fd, const char * open_options)
{
	file = fdopen(fd, open_options);
	if ( ! file) {
		error = errno;
	} else {
		// seek to the end of the file.
		fseek(file, 0, SEEK_END);
		cbFile = cbPos = ftell(file);
		error = 0;
		buf.SetTextMode( ! strchr(open_options,'b'));
	}
	return error == 0;
}

// prefixes or part of a line into str, and updates internal
// variables to keep track of what parts of the buffer have been returned.
bool BackwardFileReader::PrevLineFromBuf(std::string & str)
{
	// if we have no buffered data, then there is nothing to do
	int cb = buf.size();
	if (cb <= 0)
		return false;

	// if buffer ends in a newline, convert it to a \0
	if (buf[cb-1] == '\n') {
		buf[--cb] = 0;
		// if the input string is not empty, then the previous
		// buffer ended _exactly_ at a newline boundary, so return
		// the string rather than concatinating it to the newline.
		if ( ! str.empty()) {
			if (buf[cb-1] == '\r')
				buf[--cb] = 0;
			buf.setsize(cb);
			return true;
		}
	}
	// because of windows style \r\n, we also tolerate a \r at the end of the line
	if (buf[cb-1] == '\r') {
		buf[--cb] = 0;
	}

	// now we walk backward through the buffer until we encounter another newline
	// returning all of the characters that we found.
	while (cb > 0) {
		if (buf[--cb] == '\n') {
			str.insert(0, &buf[cb+1]);
			buf[cb] = 0;
			buf.setsize(cb);
			return true;
		}
	}

	// we hit the start of the buffer without finding another newline,
	// so return that text, but only return true if we are also at the start
	// of the file.
	str.insert(0, &buf[0]);
	buf[0] = 0;
	buf.clear();

	return (0 == cbPos);
}
<|endoftext|>


<commit_before>#include "storage_engine/compression.h"
#include "util.h"

#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <zlib.h>
#include <cstring>

using namespace Akumuli;

int main(int argc, char** argv) {
    if (argc == 1) {
        return 1;
    }
    std::string file_name(argv[1]);
    std::fstream input(file_name, std::ios::binary|std::ios::in|std::ios::out);
    UncompressedChunk header;

    double tx;
    aku_Timestamp ts;
    while(input) {
        input.read(reinterpret_cast<char*>(&ts), sizeof(ts));
        if (input) {
            input.read(reinterpret_cast<char*>(&tx), sizeof(tx));
        }
        if (input) {
            header.timestamps.push_back(ts);
            header.values.push_back(tx);
        }
    }

    ByteVector buffer(32 + header.timestamps.size()*32, 0);
    StorageEngine::DataBlockWriter writer(42, buffer.data(), static_cast<int>(buffer.size()));

    for (u32 i = 0; i < header.timestamps.size(); i++) {
        aku_Status status = writer.put(header.timestamps.at(i), header.values.at(i));
        if (status != AKU_SUCCESS) {
            AKU_PANIC("Can't compress data: " + std::to_string(status));
        }
    }

    StorageEngine::DataBlockReader reader(buffer.data(), buffer.size());
    for (u32 i = 0; i < header.timestamps.size(); i++) {
        aku_Timestamp ts;
        double tx;
        aku_Status status;
        std::tie(status, ts, tx) = reader.next();
        if (status != AKU_SUCCESS) {
            AKU_PANIC("Can't decompress data: " + std::to_string(status));
        }
        if (ts != header.timestamps.at(i)) {
            AKU_PANIC("Bad timestamp at: " + std::to_string(i));
        }
        if (tx != header.values.at(i)) {
            AKU_PANIC("Bad value at: " + std::to_string(i));
        }
    }
    return 0;
}
<commit_msg>AFL test fixed<commit_after>#include "storage_engine/compression.h"
#include "util.h"

#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <zlib.h>
#include <cstring>

using namespace Akumuli;

int main(int argc, char** argv) {
    if (argc == 1) {
        return 1;
    }
    std::string file_name(argv[1]);
    std::fstream input(file_name, std::ios::binary|std::ios::in|std::ios::out);
    UncompressedChunk header;

    double tx;
    aku_Timestamp ts;
    while(input) {
        input.read(reinterpret_cast<char*>(&ts), sizeof(ts));
        if (input) {
            input.read(reinterpret_cast<char*>(&tx), sizeof(tx));
        }
        if (input) {
            header.timestamps.push_back(ts);
            header.values.push_back(tx);
        }
    }

    for (size_t i = 1; i < header.timestamps.size(); i++) {
        if (header.timestamps.at(i) < header.timestamps.at(i-1)) {
            return -1;
        }
    }

    ByteVector buffer(32 + header.timestamps.size()*32, 0);
    StorageEngine::DataBlockWriter writer(42, buffer.data(), static_cast<int>(buffer.size()));

    size_t commit_size = 0;
    for (u32 i = 0; i < header.timestamps.size(); i++) {
        aku_Status status = writer.put(header.timestamps.at(i), header.values.at(i));
        if (status != AKU_SUCCESS) {
            AKU_PANIC("Can't compress data: " + std::to_string(status));
        }
        commit_size = writer.commit();
    }

    StorageEngine::DataBlockReader reader(buffer.data(), commit_size);
    for (u32 i = 0; i < header.timestamps.size(); i++) {
        aku_Timestamp ts;
        double tx;
        aku_Status status;
        std::tie(status, ts, tx) = reader.next();
        if (status != AKU_SUCCESS) {
            AKU_PANIC("Can't decompress data: " + std::to_string(status));
        }
        if (ts != header.timestamps.at(i)) {
            AKU_PANIC("Bad timestamp at: " + std::to_string(i));
        }
        if (tx != header.values.at(i)) {
            AKU_PANIC("Bad value at: " + std::to_string(i));
        }
    }
    return 0;
}
<|endoftext|>