<commit_before>#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601

#undef WINVER
#define WINVER 0x0601

#include "keyboard-layout-manager.h"

#include <string>
#include <windows.h>

using namespace v8;

std::string ToUTF8(const std::wstring& string) {
  if (string.length() < 1) {
    return std::string();
  }

  // NB: In the pathological case, each character could expand up
  // to 4 bytes in UTF8.
  int cbLen = (string.length()+1) * sizeof(char) * 4;
  char* buf = new char[cbLen];
  int retLen = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), buf, cbLen, NULL, NULL);
  buf[retLen] = 0;

  std::string ret;
  ret.assign(buf);
  return ret;
}

void KeyboardLayoutManager::Init(Handle<Object> exports, Handle<Object> module) {
  Nan::HandleScope scope;
  Local<FunctionTemplate> newTemplate = Nan::New<FunctionTemplate>(KeyboardLayoutManager::New);
  newTemplate->SetClassName(Nan::New<String>("KeyboardLayoutManager").ToLocalChecked());
  newTemplate->InstanceTemplate()->SetInternalFieldCount(1);
  Local<ObjectTemplate> proto = newTemplate->PrototypeTemplate();

  Nan::SetMethod(proto, "getCurrentKeyboardLayout", KeyboardLayoutManager::GetCurrentKeyboardLayout);
  Nan::SetMethod(proto, "getCurrentKeyboardLanguage", KeyboardLayoutManager::GetCurrentKeyboardLanguage);
  Nan::SetMethod(proto, "getInstalledKeyboardLanguages", KeyboardLayoutManager::GetInstalledKeyboardLanguages);
  Nan::SetMethod(proto, "getCurrentKeymap", KeyboardLayoutManager::GetCurrentKeymap);

  module->Set(Nan::New("exports").ToLocalChecked(), newTemplate->GetFunction());
}

NODE_MODULE(keyboard_layout_manager, KeyboardLayoutManager::Init)

NAN_METHOD(KeyboardLayoutManager::New) {
  Nan::HandleScope scope;

  Local<Function> callbackHandle = info[0].As<Function>();
  Nan::Callback *callback = new Nan::Callback(callbackHandle);

  KeyboardLayoutManager *manager = new KeyboardLayoutManager(callback);
  manager->Wrap(info.This());
  return;
}

KeyboardLayoutManager::KeyboardLayoutManager(Nan::Callback *callback) : callback(callback) {
}

KeyboardLayoutManager::~KeyboardLayoutManager() {
  delete callback;
};

void KeyboardLayoutManager::HandleKeyboardLayoutChanged() {
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeyboardLayout) {
  Nan::HandleScope scope;

  char layoutName[KL_NAMELENGTH];
  if (::GetKeyboardLayoutName(layoutName))
    info.GetReturnValue().Set(Nan::New(layoutName).ToLocalChecked());
  else
    info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeyboardLanguage) {
  Nan::HandleScope scope;

  HKL layout;
  DWORD dwThreadId = 0;
  HWND hWnd = GetForegroundWindow();

  if (hWnd != NULL) {
    dwThreadId = GetWindowThreadProcessId(hWnd, NULL);
  }

  layout = GetKeyboardLayout(dwThreadId);

  wchar_t buf[LOCALE_NAME_MAX_LENGTH];
  std::wstring wstr;
  LCIDToLocaleName(MAKELCID((UINT)layout & 0xFFFF, SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
  wstr.assign(buf);

  std::string str = ToUTF8(wstr);
  info.GetReturnValue().Set(Nan::New<String>(str.data(), str.size()).ToLocalChecked());
}

NAN_METHOD(KeyboardLayoutManager::GetInstalledKeyboardLanguages) {
  Nan::HandleScope scope;

  int layoutCount = GetKeyboardLayoutList(0, NULL);
  HKL* layouts = new HKL[layoutCount];
  GetKeyboardLayoutList(layoutCount, layouts);

  Local<Array> result = Nan::New<Array>(layoutCount);
  wchar_t buf[LOCALE_NAME_MAX_LENGTH];

  for (int i=0; i < layoutCount; i++) {
    std::wstring wstr;
    LCIDToLocaleName(MAKELCID((UINT)layouts[i] & 0xFFFF, SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
    wstr.assign(buf);

    std::string str = ToUTF8(wstr);
    result->Set(i, Nan::New<String>(str.data(), str.size()).ToLocalChecked());
  }

  delete[] layouts;
  info.GetReturnValue().Set(result);
}

struct KeycodeMapEntry {
  UINT scanCode;
  const char *dom3Code;
};

#define USB_KEYMAP_DECLARATION static const KeycodeMapEntry keyCodeMap[] =
#define USB_KEYMAP(usb, evdev, xkb, win, mac, code, id) {win, code}

#include "keycode_converter_data.inc"

Local<String> CharacterForNativeCode(HKL keyboardLayout, UINT keyCode, UINT scanCode,
                                     BYTE *keyboardState, bool shift, bool altGraph) {
  memset(keyboardState, 0, 256);
  if (shift) {
    keyboardState[VK_SHIFT] |= 0x80;
  }

  if (altGraph) {
    keyboardState[VK_MENU] |= 0x80;
    keyboardState[VK_CONTROL] |= 0x80;
  }

  wchar_t characters[5];
  int count = ToUnicodeEx(keyCode, scanCode, keyboardState, characters, 5, 0, keyboardLayout);
  return Nan::New<String>(reinterpret_cast<const uint16_t *>(characters), count).ToLocalChecked();
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeymap) {
  BYTE keyboardState[256];
  HKL keyboardLayout = GetKeyboardLayout(0);

  Handle<Object> result = Nan::New<Object>();
  Local<String> unmodifiedKey = Nan::New("unmodified").ToLocalChecked();
  Local<String> withShiftKey = Nan::New("withShift").ToLocalChecked();
  Local<String> withAltGrKey = Nan::New("withAltGr").ToLocalChecked();
  Local<String> withAltGrShiftKey = Nan::New("withAltGrShift").ToLocalChecked();

  size_t keyCodeMapSize = sizeof(keyCodeMap) / sizeof(keyCodeMap[0]);
  for (size_t i = 0; i < keyCodeMapSize; i++) {
    const char *dom3Code = keyCodeMap[i].dom3Code;
    UINT scanCode = keyCodeMap[i].scanCode;

    if (dom3Code && scanCode < 0xffff) {
      memset(keyboardState, 0, 256);
      UINT keyCode = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK, keyboardLayout);

      Local<String> dom3CodeKey = Nan::New(dom3Code).ToLocalChecked();
      Local<String> unmodified = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, false, false);
      Local<String> withShift = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, true, false);
      Local<String> withAltGr = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, false, true);
      Local<String> withAltGrShift = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, true, true);

      Local<Object> entry = Nan::New<Object>();
      entry->Set(unmodifiedKey, unmodified);
      entry->Set(withShiftKey, withShift);
      entry->Set(withAltGrKey, withAltGr);
      entry->Set(withAltGrShiftKey, withAltGrShift);

      result->Set(dom3CodeKey, entry);
    }
  }

  info.GetReturnValue().Set(result);

}
<commit_msg>Use assignment rather than bitwise or<commit_after>#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601

#undef WINVER
#define WINVER 0x0601

#include "keyboard-layout-manager.h"

#include <string>
#include <windows.h>

using namespace v8;

std::string ToUTF8(const std::wstring& string) {
  if (string.length() < 1) {
    return std::string();
  }

  // NB: In the pathological case, each character could expand up
  // to 4 bytes in UTF8.
  int cbLen = (string.length()+1) * sizeof(char) * 4;
  char* buf = new char[cbLen];
  int retLen = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), string.length(), buf, cbLen, NULL, NULL);
  buf[retLen] = 0;

  std::string ret;
  ret.assign(buf);
  return ret;
}

void KeyboardLayoutManager::Init(Handle<Object> exports, Handle<Object> module) {
  Nan::HandleScope scope;
  Local<FunctionTemplate> newTemplate = Nan::New<FunctionTemplate>(KeyboardLayoutManager::New);
  newTemplate->SetClassName(Nan::New<String>("KeyboardLayoutManager").ToLocalChecked());
  newTemplate->InstanceTemplate()->SetInternalFieldCount(1);
  Local<ObjectTemplate> proto = newTemplate->PrototypeTemplate();

  Nan::SetMethod(proto, "getCurrentKeyboardLayout", KeyboardLayoutManager::GetCurrentKeyboardLayout);
  Nan::SetMethod(proto, "getCurrentKeyboardLanguage", KeyboardLayoutManager::GetCurrentKeyboardLanguage);
  Nan::SetMethod(proto, "getInstalledKeyboardLanguages", KeyboardLayoutManager::GetInstalledKeyboardLanguages);
  Nan::SetMethod(proto, "getCurrentKeymap", KeyboardLayoutManager::GetCurrentKeymap);

  module->Set(Nan::New("exports").ToLocalChecked(), newTemplate->GetFunction());
}

NODE_MODULE(keyboard_layout_manager, KeyboardLayoutManager::Init)

NAN_METHOD(KeyboardLayoutManager::New) {
  Nan::HandleScope scope;

  Local<Function> callbackHandle = info[0].As<Function>();
  Nan::Callback *callback = new Nan::Callback(callbackHandle);

  KeyboardLayoutManager *manager = new KeyboardLayoutManager(callback);
  manager->Wrap(info.This());
  return;
}

KeyboardLayoutManager::KeyboardLayoutManager(Nan::Callback *callback) : callback(callback) {
}

KeyboardLayoutManager::~KeyboardLayoutManager() {
  delete callback;
};

void KeyboardLayoutManager::HandleKeyboardLayoutChanged() {
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeyboardLayout) {
  Nan::HandleScope scope;

  char layoutName[KL_NAMELENGTH];
  if (::GetKeyboardLayoutName(layoutName))
    info.GetReturnValue().Set(Nan::New(layoutName).ToLocalChecked());
  else
    info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeyboardLanguage) {
  Nan::HandleScope scope;

  HKL layout;
  DWORD dwThreadId = 0;
  HWND hWnd = GetForegroundWindow();

  if (hWnd != NULL) {
    dwThreadId = GetWindowThreadProcessId(hWnd, NULL);
  }

  layout = GetKeyboardLayout(dwThreadId);

  wchar_t buf[LOCALE_NAME_MAX_LENGTH];
  std::wstring wstr;
  LCIDToLocaleName(MAKELCID((UINT)layout & 0xFFFF, SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
  wstr.assign(buf);

  std::string str = ToUTF8(wstr);
  info.GetReturnValue().Set(Nan::New<String>(str.data(), str.size()).ToLocalChecked());
}

NAN_METHOD(KeyboardLayoutManager::GetInstalledKeyboardLanguages) {
  Nan::HandleScope scope;

  int layoutCount = GetKeyboardLayoutList(0, NULL);
  HKL* layouts = new HKL[layoutCount];
  GetKeyboardLayoutList(layoutCount, layouts);

  Local<Array> result = Nan::New<Array>(layoutCount);
  wchar_t buf[LOCALE_NAME_MAX_LENGTH];

  for (int i=0; i < layoutCount; i++) {
    std::wstring wstr;
    LCIDToLocaleName(MAKELCID((UINT)layouts[i] & 0xFFFF, SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0);
    wstr.assign(buf);

    std::string str = ToUTF8(wstr);
    result->Set(i, Nan::New<String>(str.data(), str.size()).ToLocalChecked());
  }

  delete[] layouts;
  info.GetReturnValue().Set(result);
}

struct KeycodeMapEntry {
  UINT scanCode;
  const char *dom3Code;
};

#define USB_KEYMAP_DECLARATION static const KeycodeMapEntry keyCodeMap[] =
#define USB_KEYMAP(usb, evdev, xkb, win, mac, code, id) {win, code}

#include "keycode_converter_data.inc"

Local<String> CharacterForNativeCode(HKL keyboardLayout, UINT keyCode, UINT scanCode,
                                     BYTE *keyboardState, bool shift, bool altGraph) {
  memset(keyboardState, 0, 256);
  if (shift) {
    keyboardState[VK_SHIFT] = 0x80;
  }

  if (altGraph) {
    keyboardState[VK_MENU] = 0x80;
    keyboardState[VK_CONTROL] = 0x80;
  }

  wchar_t characters[5];
  int count = ToUnicodeEx(keyCode, scanCode, keyboardState, characters, 5, 0, keyboardLayout);
  return Nan::New<String>(reinterpret_cast<const uint16_t *>(characters), count).ToLocalChecked();
}

NAN_METHOD(KeyboardLayoutManager::GetCurrentKeymap) {
  BYTE keyboardState[256];
  HKL keyboardLayout = GetKeyboardLayout(0);

  Handle<Object> result = Nan::New<Object>();
  Local<String> unmodifiedKey = Nan::New("unmodified").ToLocalChecked();
  Local<String> withShiftKey = Nan::New("withShift").ToLocalChecked();
  Local<String> withAltGrKey = Nan::New("withAltGr").ToLocalChecked();
  Local<String> withAltGrShiftKey = Nan::New("withAltGrShift").ToLocalChecked();

  size_t keyCodeMapSize = sizeof(keyCodeMap) / sizeof(keyCodeMap[0]);
  for (size_t i = 0; i < keyCodeMapSize; i++) {
    const char *dom3Code = keyCodeMap[i].dom3Code;
    UINT scanCode = keyCodeMap[i].scanCode;

    if (dom3Code && scanCode < 0xffff) {
      memset(keyboardState, 0, 256);
      UINT keyCode = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK, keyboardLayout);

      Local<String> dom3CodeKey = Nan::New(dom3Code).ToLocalChecked();
      Local<String> unmodified = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, false, false);
      Local<String> withShift = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, true, false);
      Local<String> withAltGr = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, false, true);
      Local<String> withAltGrShift = CharacterForNativeCode(keyboardLayout, keyCode, scanCode, keyboardState, true, true);

      Local<Object> entry = Nan::New<Object>();
      entry->Set(unmodifiedKey, unmodified);
      entry->Set(withShiftKey, withShift);
      entry->Set(withAltGrKey, withAltGr);
      entry->Set(withAltGrShiftKey, withAltGrShift);

      result->Set(dom3CodeKey, entry);
    }
  }

  info.GetReturnValue().Set(result);

}
<|endoftext|>


<commit_before>#include "MqttConnection.h"

PubSubClient * g_mqttClient;

void  mycallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if ((char)payload[0] == '1') {
    Serial.println("Ping received");
    String tmp_string = topic;
    tmp_string += " : I'm alive!!!!";

    g_mqttClient->publish("connection_events", tmp_string.c_str());

  } else {
    Serial.println("doing nothing");

  }

}

/****************************** Wifi connect function ***************************************/
void MqttConnection::wifiSetup(const char* ssid, const char* pass) {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void MqttConnection::publishValue(const char * leafTopic, float value, int precision)
{
    char msg[50];
    String  format = "\%." + precision;
    format += "f";

    snprintf (msg, 75, "%.*f", precision, value);
    //String tmp = value;
    Serial.print("Publish message: ");
    Serial.println(msg);

    String outTopic = sensorId_ + "/";
    outTopic += leafTopic;
    Serial.print("on topic: ");
    Serial.println(outTopic.c_str());
    publish(outTopic.c_str(), msg);
}

void MqttConnection::subscribeAll()
{
	for (int i = 0; i < nbLeafTopic_; i++) {
	  char* tmpLeafTopic = leafTopicList_[i];
	  Serial.print("Subscribing to");
	  Serial.println(tmpLeafTopic);
      String tmp_string = sensorId_;
      tmp_string += tmpLeafTopic;
	  subscribe(tmp_string.c_str());
	}

}

void MqttConnection::reconnect() {
  // Loop until we're reconnected
  while (!connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = sensorId_;

    // Attempt to connect
    if (connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      String connectMsg = "New connection from " + clientId;
      publish("connection_events", connectMsg.c_str());
      // ... and resubscribe
	  subscribeAll();

    }
    else {
      Serial.print("failed, rc=");
      Serial.print(state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void MqttConnection::addSubscription(const char * leafTopic)
{
	if(nbLeafTopic_ < MAX_SUBSCRIBE_LEAF_TOPIC - 1)
	{
	    nbLeafTopic_++;
	    strcpy(leafTopicList_[nbLeafTopic_ - 1], leafTopic);
	}
	else
	{
		Serial.print("Error : too many topics to subscribe");
	}
}

MqttConnection::MqttConnection(const char* sensorId, const char* ssid, const char* pass, const char* mqttServer, int mqttPort) : PubSubClient(wifiClient_)
{
  addSubscription(PING_LEAF_TOPIC);
  sensorId_ = sensorId;
  wifiSetup(ssid, pass);

 // mqttClient_ = new PubSubClient(*wifiClient_);
  setServer(mqttServer, mqttPort);
  setCallback(mycallback);
  g_mqttClient = this;

}

<commit_msg>fixed ping subscription<commit_after>#include "MqttConnection.h"

PubSubClient * g_mqttClient;

void  mycallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  if ((char)payload[0] == '1') {
    Serial.println("Ping received");
    String tmp_string = topic;
    tmp_string += " : I'm alive!!!!";

    g_mqttClient->publish("connection_events", tmp_string.c_str());
    Serial.println("after publish");
  } else {
    Serial.println("doing nothing");

  }

}

/****************************** Wifi connect function ***************************************/
void MqttConnection::wifiSetup(const char* ssid, const char* pass) {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void MqttConnection::publishValue(const char * leafTopic, float value, int precision)
{
    char msg[50];
    String  format = "\%." + precision;
    format += "f";

    snprintf (msg, 75, "%.*f", precision, value);
    //String tmp = value;
    Serial.print("Publish message: ");
    Serial.println(msg);

    String outTopic = sensorId_ + "/";
    outTopic += leafTopic;
    Serial.print("on topic: ");
    Serial.println(outTopic.c_str());
    publish(outTopic.c_str(), msg);
}

void MqttConnection::subscribeAll()
{
	for (int i = 0; i < nbLeafTopic_; i++) {
	  char* tmpLeafTopic = leafTopicList_[i];

      String tmp_string = sensorId_;
	  tmp_string += "/";
      tmp_string += tmpLeafTopic;
	  Serial.print("Subscribing to : ");
	  Serial.println(tmp_string.c_str());
	  subscribe(tmp_string.c_str());
	}

}

void MqttConnection::reconnect() {
  // Loop until we're reconnected
  while (!connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = sensorId_;

    // Attempt to connect
    if (connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      String connectMsg = "New connection from " + clientId;
      publish("connection_events", connectMsg.c_str());
      // ... and resubscribe
	  subscribeAll();

    }
    else {
      Serial.print("failed, rc=");
      Serial.print(state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void MqttConnection::addSubscription(const char * leafTopic)
{
	if(nbLeafTopic_ < MAX_SUBSCRIBE_LEAF_TOPIC - 1)
	{
	    nbLeafTopic_++;
	    strcpy(leafTopicList_[nbLeafTopic_ - 1], leafTopic);
	}
	else
	{
		Serial.print("Error : too many topics to subscribe");
	}
}

MqttConnection::MqttConnection(const char* sensorId, const char* ssid, const char* pass, const char* mqttServer, int mqttPort) : PubSubClient(wifiClient_)
{
  addSubscription(PING_LEAF_TOPIC);
  sensorId_ = sensorId;
  wifiSetup(ssid, pass);

 // mqttClient_ = new PubSubClient(*wifiClient_);
  setServer(mqttServer, mqttPort);
  setCallback(mycallback);
  g_mqttClient = this;

}

<|endoftext|>


<commit_before>// @(#)root/hist:$Name:  $:$Id: TPolyMarker.cxx,v 1.23 2007/01/12 16:03:16 brun Exp $
// Author: Rene Brun   12/12/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TPolyMarker.h"
#include "TClass.h"
#include "TMath.h"

ClassImp(TPolyMarker)

//______________________________________________________________________________
//
//  a PolyMarker is defined by an array on N points in a 2-D space.
// At each point x[i], y[i] a marker is drawn.
// Marker attributes are managed by TAttMarker.
// See TMarker for the list of possible marker types.
//

//______________________________________________________________________________
TPolyMarker::TPolyMarker(): TObject()
{
   // Default constructor.

   fN = 0;
   fX = fY = 0;
   fLastPoint = -1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
   if (!x || !y) return;
   for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
   fLastPoint = fN-1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
   if (!x || !y) return;
   for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
   fLastPoint = fN-1;
}

//______________________________________________________________________________
TPolyMarker& TPolyMarker::operator=(const TPolyMarker& pm)
{
   //assignment operator
   if(this!=&pm) {
      TObject::operator=(pm);
      TAttMarker::operator=(pm);
      fN=pm.fN;
      fLastPoint=pm.fLastPoint;
      fX=pm.fX;
      fY=pm.fY;
      fOption=pm.fOption;
   }
   return *this;
}

//______________________________________________________________________________
TPolyMarker::~TPolyMarker()
{
   // Desctructor.

   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fLastPoint = -1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(const TPolyMarker &polymarker) : TObject(polymarker), TAttMarker(polymarker)
{
   // Copy constructor.

   ((TPolyMarker&)polymarker).Copy(*this);
}

//______________________________________________________________________________
void TPolyMarker::Copy(TObject &obj) const
{

   // Copy.

   TObject::Copy(obj);
   TAttMarker::Copy(((TPolyMarker&)obj));
   ((TPolyMarker&)obj).fN = fN;
   if (fN > 0) {
      ((TPolyMarker&)obj).fX = new Double_t [fN];
      ((TPolyMarker&)obj).fY = new Double_t [fN];
      for (Int_t i=0; i<fN;i++) { ((TPolyMarker&)obj).fX[i] = fX[i], ((TPolyMarker&)obj).fY[i] = fY[i]; }
   } else {
      ((TPolyMarker&)obj).fX = 0;
      ((TPolyMarker&)obj).fY = 0;
   }
   ((TPolyMarker&)obj).fOption = fOption;
   ((TPolyMarker&)obj).fLastPoint = fLastPoint;
}

//______________________________________________________________________________
Int_t TPolyMarker::DistancetoPrimitive(Int_t px, Int_t py)
{
   // Compute distance from point px,py to a polymarker.
   //
   //  Compute the closest distance of approach from point px,py to each point
   //  of the polymarker.
   //  Returns when the distance found is below DistanceMaximum.
   //  The distance is computed in pixels units.

   const Int_t big = 9999;

   // check if point is near one of the points
   Int_t i, pxp, pyp, d;
   Int_t distance = big;

   for (i=0;i<Size();i++) {
      pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
      pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
      d   = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
      if (d < distance) distance = d;
   }
   return distance;
}

//______________________________________________________________________________
void TPolyMarker::Draw(Option_t *option)
{
   // Draw.

   AppendPad(option);
}

//______________________________________________________________________________
void TPolyMarker::DrawPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *)
{
   // Draw polymarker.

   TPolyMarker *newpolymarker = new TPolyMarker(n,x,y);
   TAttMarker::Copy(*newpolymarker);
   newpolymarker->fOption = fOption;
   newpolymarker->SetBit(kCanDelete);
   newpolymarker->AppendPad();
}

//______________________________________________________________________________
void TPolyMarker::ExecuteEvent(Int_t, Int_t, Int_t)
{
   // Execute action corresponding to one event.
   //
   //  This member function must be implemented to realize the action
   //  corresponding to the mouse click on the object in the window
}

//______________________________________________________________________________
void TPolyMarker::ls(Option_t *) const
{
   // ls.

   TROOT::IndentLevel();
   printf("TPolyMarker  N=%d\n",fN);
}

//______________________________________________________________________________
Int_t TPolyMarker::Merge(TCollection *li)
{
   // Merge polymarkers in the collection in this polymarker.

   if (!li) return 0;
   TIter next(li);

   //first loop to count the number of entries
   TPolyMarker *pm;
   Int_t npoints = 0;
   while ((pm = (TPolyMarker*)next())) {
      if (!pm->InheritsFrom(TPolyMarker::Class())) {
         Error("Add","Attempt to add object of class: %s to a %s",pm->ClassName(),this->ClassName());
         return -1;
      }
      npoints += pm->Size();
   }

   //extend this polymarker to hold npoints
   pm->SetPoint(npoints-1,0,0);

   //merge all polymarkers
   next.Reset();
   while ((pm = (TPolyMarker*)next())) {
      Int_t np = pm->Size();
      Double_t *x = pm->GetX();
      Double_t *y = pm->GetY();
      for (Int_t i=0;i<np;i++) {
         SetPoint(i,x[i],y[i]);
      }
   }

   return npoints;
}

//______________________________________________________________________________
void TPolyMarker::Paint(Option_t *option)
{
   // Paint.

   PaintPolyMarker(fLastPoint+1, fX, fY, option);
}

//______________________________________________________________________________
void TPolyMarker::PaintPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
{
   // Paint polymarker.

   if (n <= 0) return;
   TAttMarker::Modify();  //Change marker attributes only if necessary
   Double_t *xx = x;
   Double_t *yy = y;
   if (gPad->GetLogx()) {
      xx = new Double_t[n];
      for (Int_t ix=0;ix<n;ix++) xx[ix] = gPad->XtoPad(x[ix]);
   }
   if (gPad->GetLogy()) {
      yy = new Double_t[n];
      for (Int_t iy=0;iy<n;iy++) yy[iy] = gPad->YtoPad(y[iy]);
   }
   gPad->PaintPolyMarker(n,xx,yy,option);
   if (x != xx) delete [] xx;
   if (y != yy) delete [] yy;
}

//______________________________________________________________________________
void TPolyMarker::Print(Option_t *) const
{
   // Print polymarker.

   printf("TPolyMarker  N=%d\n",fN);
}

//______________________________________________________________________________
void TPolyMarker::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
{
   // Save primitive as a C++ statement(s) on output stream out.

   char quote = '"';
   out<<"   "<<endl;
   out<<"   Double_t *dum = 0;"<<endl;
   if (gROOT->ClassSaved(TPolyMarker::Class())) {
      out<<"   ";
   } else {
      out<<"   TPolyMarker *";
   }
   out<<"pmarker = new TPolyMarker("<<fN<<",dum,dum,"<<quote<<fOption<<quote<<");"<<endl;

   SaveMarkerAttributes(out,"pmarker",1,1,1);

   for (Int_t i=0;i<Size();i++) {
      out<<"   pmarker->SetPoint("<<i<<","<<fX[i]<<","<<fY[i]<<");"<<endl;
   }
   out<<"   pmarker->Draw("
      <<quote<<option<<quote<<");"<<endl;
}

//______________________________________________________________________________
Int_t TPolyMarker::SetNextPoint(Double_t x, Double_t y)
{
   // Set point following LastPoint to x, y.
   // Returns index of the point (new last point).

   fLastPoint++;
   SetPoint(fLastPoint, x, y);
   return fLastPoint;
}

//______________________________________________________________________________
void TPolyMarker::SetPoint(Int_t n, Double_t x, Double_t y)
{
   // Set point number n.
   // if n is greater than the current size, the arrays are automatically
   // extended

   if (n < 0) return;
   if (!fX || !fY || n >= fN) {
      // re-allocate the object
      Int_t newN = TMath::Max(2*fN,n+1);
      Double_t *savex = new Double_t [newN];
      Double_t *savey = new Double_t [newN];
      if (fX && fN){
         memcpy(savex,fX,fN*sizeof(Double_t));
         memset(&savex[fN],0,(newN-fN)*sizeof(Double_t));
         delete [] fX;
      }
      if (fY && fN){
         memcpy(savey,fY,fN*sizeof(Double_t));
         memset(&savey[fN],0,(newN-fN)*sizeof(Double_t));
         delete [] fY;
      }
      fX = savex;
      fY = savey;
      fN = newN;
   }
   fX[n] = x;
   fY[n] = y;
   fLastPoint = TMath::Max(fLastPoint,n);
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n)
{
   // If n <= 0 the current arrays of points are deleted.

   SetPoint(n-1,0,0);
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
{
   // If n <= 0 the current arrays of points are deleted.

   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      delete [] fX;
      delete [] fY;
      fX = fY = 0;
      return;
   }
   fN =n;
   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fX = new Double_t[fN];
   fY = new Double_t[fN];
   for (Int_t i=0; i<fN;i++) {
      if (x) fX[i] = (Double_t)x[i];
      if (y) fY[i] = (Double_t)y[i];
   }
   fOption = option;
   fLastPoint = fN-1;
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
{
   // If n <= 0 the current arrays of points are deleted.

   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      delete [] fX;
      delete [] fY;
      fX = fY = 0;
      return;
   }
   fN =n;
   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fX = new Double_t[fN];
   fY = new Double_t[fN];
   for (Int_t i=0; i<fN;i++) {
      if (x) fX[i] = x[i];
      if (y) fY[i] = y[i];
   }
   fOption = option;
   fLastPoint = fN-1;
}

//_______________________________________________________________________
void TPolyMarker::Streamer(TBuffer &R__b)
{
   // Stream a class object.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         R__b.ReadClassBuffer(TPolyMarker::Class(), this, R__v, R__s, R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      TObject::Streamer(R__b);
      TAttMarker::Streamer(R__b);
      R__b >> fN;
      fX = new Double_t[fN];
      fY = new Double_t[fN];
      Int_t i;
      Float_t xold,yold;
      for (i=0;i<fN;i++) {R__b >> xold; fX[i] = xold;}
      for (i=0;i<fN;i++) {R__b >> yold; fY[i] = yold;}
      fOption.Streamer(R__b);
      R__b.CheckByteCount(R__s, R__c, TPolyMarker::IsA());
      //====end of old versions

   } else {
      R__b.WriteClassBuffer(TPolyMarker::Class(),this);
   }
}
<commit_msg>From Olivier: - Make SetPolyMarker(Int_t n) compliant with   SetPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)   and with the documentation, ie:   "If n <= 0 the current arrays of points are deleted"<commit_after>// @(#)root/hist:$Name:  $:$Id: TPolyMarker.cxx,v 1.24 2007/02/06 15:00:56 brun Exp $
// Author: Rene Brun   12/12/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TPolyMarker.h"
#include "TClass.h"
#include "TMath.h"

ClassImp(TPolyMarker)

//______________________________________________________________________________
//
//  a PolyMarker is defined by an array on N points in a 2-D space.
// At each point x[i], y[i] a marker is drawn.
// Marker attributes are managed by TAttMarker.
// See TMarker for the list of possible marker types.
//

//______________________________________________________________________________
TPolyMarker::TPolyMarker(): TObject()
{
   // Default constructor.

   fN = 0;
   fX = fY = 0;
   fLastPoint = -1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
   if (!x || !y) return;
   for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
   fLastPoint = fN-1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
      :TObject(), TAttMarker()
{
   // Constructor.

   fOption = option;
   SetBit(kCanDelete);
   fLastPoint = -1;
   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      fX = fY = 0;
      return;
   }
   fN = n;
   fX = new Double_t [fN];
   fY = new Double_t [fN];
   if (!x || !y) return;
   for (Int_t i=0; i<fN;i++) { fX[i] = x[i]; fY[i] = y[i]; }
   fLastPoint = fN-1;
}

//______________________________________________________________________________
TPolyMarker& TPolyMarker::operator=(const TPolyMarker& pm)
{
   //assignment operator
   if(this!=&pm) {
      TObject::operator=(pm);
      TAttMarker::operator=(pm);
      fN=pm.fN;
      fLastPoint=pm.fLastPoint;
      fX=pm.fX;
      fY=pm.fY;
      fOption=pm.fOption;
   }
   return *this;
}

//______________________________________________________________________________
TPolyMarker::~TPolyMarker()
{
   // Desctructor.

   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fLastPoint = -1;
}

//______________________________________________________________________________
TPolyMarker::TPolyMarker(const TPolyMarker &polymarker) : TObject(polymarker), TAttMarker(polymarker)
{
   // Copy constructor.

   ((TPolyMarker&)polymarker).Copy(*this);
}

//______________________________________________________________________________
void TPolyMarker::Copy(TObject &obj) const
{

   // Copy.

   TObject::Copy(obj);
   TAttMarker::Copy(((TPolyMarker&)obj));
   ((TPolyMarker&)obj).fN = fN;
   if (fN > 0) {
      ((TPolyMarker&)obj).fX = new Double_t [fN];
      ((TPolyMarker&)obj).fY = new Double_t [fN];
      for (Int_t i=0; i<fN;i++) { ((TPolyMarker&)obj).fX[i] = fX[i], ((TPolyMarker&)obj).fY[i] = fY[i]; }
   } else {
      ((TPolyMarker&)obj).fX = 0;
      ((TPolyMarker&)obj).fY = 0;
   }
   ((TPolyMarker&)obj).fOption = fOption;
   ((TPolyMarker&)obj).fLastPoint = fLastPoint;
}

//______________________________________________________________________________
Int_t TPolyMarker::DistancetoPrimitive(Int_t px, Int_t py)
{
   // Compute distance from point px,py to a polymarker.
   //
   //  Compute the closest distance of approach from point px,py to each point
   //  of the polymarker.
   //  Returns when the distance found is below DistanceMaximum.
   //  The distance is computed in pixels units.

   const Int_t big = 9999;

   // check if point is near one of the points
   Int_t i, pxp, pyp, d;
   Int_t distance = big;

   for (i=0;i<Size();i++) {
      pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
      pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
      d   = TMath::Abs(pxp-px) + TMath::Abs(pyp-py);
      if (d < distance) distance = d;
   }
   return distance;
}

//______________________________________________________________________________
void TPolyMarker::Draw(Option_t *option)
{
   // Draw.

   AppendPad(option);
}

//______________________________________________________________________________
void TPolyMarker::DrawPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *)
{
   // Draw polymarker.

   TPolyMarker *newpolymarker = new TPolyMarker(n,x,y);
   TAttMarker::Copy(*newpolymarker);
   newpolymarker->fOption = fOption;
   newpolymarker->SetBit(kCanDelete);
   newpolymarker->AppendPad();
}

//______________________________________________________________________________
void TPolyMarker::ExecuteEvent(Int_t, Int_t, Int_t)
{
   // Execute action corresponding to one event.
   //
   //  This member function must be implemented to realize the action
   //  corresponding to the mouse click on the object in the window
}

//______________________________________________________________________________
void TPolyMarker::ls(Option_t *) const
{
   // ls.

   TROOT::IndentLevel();
   printf("TPolyMarker  N=%d\n",fN);
}

//______________________________________________________________________________
Int_t TPolyMarker::Merge(TCollection *li)
{
   // Merge polymarkers in the collection in this polymarker.

   if (!li) return 0;
   TIter next(li);

   //first loop to count the number of entries
   TPolyMarker *pm;
   Int_t npoints = 0;
   while ((pm = (TPolyMarker*)next())) {
      if (!pm->InheritsFrom(TPolyMarker::Class())) {
         Error("Add","Attempt to add object of class: %s to a %s",pm->ClassName(),this->ClassName());
         return -1;
      }
      npoints += pm->Size();
   }

   //extend this polymarker to hold npoints
   pm->SetPoint(npoints-1,0,0);

   //merge all polymarkers
   next.Reset();
   while ((pm = (TPolyMarker*)next())) {
      Int_t np = pm->Size();
      Double_t *x = pm->GetX();
      Double_t *y = pm->GetY();
      for (Int_t i=0;i<np;i++) {
         SetPoint(i,x[i],y[i]);
      }
   }

   return npoints;
}

//______________________________________________________________________________
void TPolyMarker::Paint(Option_t *option)
{
   // Paint.

   PaintPolyMarker(fLastPoint+1, fX, fY, option);
}

//______________________________________________________________________________
void TPolyMarker::PaintPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
{
   // Paint polymarker.

   if (n <= 0) return;
   TAttMarker::Modify();  //Change marker attributes only if necessary
   Double_t *xx = x;
   Double_t *yy = y;
   if (gPad->GetLogx()) {
      xx = new Double_t[n];
      for (Int_t ix=0;ix<n;ix++) xx[ix] = gPad->XtoPad(x[ix]);
   }
   if (gPad->GetLogy()) {
      yy = new Double_t[n];
      for (Int_t iy=0;iy<n;iy++) yy[iy] = gPad->YtoPad(y[iy]);
   }
   gPad->PaintPolyMarker(n,xx,yy,option);
   if (x != xx) delete [] xx;
   if (y != yy) delete [] yy;
}

//______________________________________________________________________________
void TPolyMarker::Print(Option_t *) const
{
   // Print polymarker.

   printf("TPolyMarker  N=%d\n",fN);
}

//______________________________________________________________________________
void TPolyMarker::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
{
   // Save primitive as a C++ statement(s) on output stream out.

   char quote = '"';
   out<<"   "<<endl;
   out<<"   Double_t *dum = 0;"<<endl;
   if (gROOT->ClassSaved(TPolyMarker::Class())) {
      out<<"   ";
   } else {
      out<<"   TPolyMarker *";
   }
   out<<"pmarker = new TPolyMarker("<<fN<<",dum,dum,"<<quote<<fOption<<quote<<");"<<endl;

   SaveMarkerAttributes(out,"pmarker",1,1,1);

   for (Int_t i=0;i<Size();i++) {
      out<<"   pmarker->SetPoint("<<i<<","<<fX[i]<<","<<fY[i]<<");"<<endl;
   }
   out<<"   pmarker->Draw("
      <<quote<<option<<quote<<");"<<endl;
}

//______________________________________________________________________________
Int_t TPolyMarker::SetNextPoint(Double_t x, Double_t y)
{
   // Set point following LastPoint to x, y.
   // Returns index of the point (new last point).

   fLastPoint++;
   SetPoint(fLastPoint, x, y);
   return fLastPoint;
}

//______________________________________________________________________________
void TPolyMarker::SetPoint(Int_t n, Double_t x, Double_t y)
{
   // Set point number n.
   // if n is greater than the current size, the arrays are automatically
   // extended

   if (n < 0) return;
   if (!fX || !fY || n >= fN) {
      // re-allocate the object
      Int_t newN = TMath::Max(2*fN,n+1);
      Double_t *savex = new Double_t [newN];
      Double_t *savey = new Double_t [newN];
      if (fX && fN){
         memcpy(savex,fX,fN*sizeof(Double_t));
         memset(&savex[fN],0,(newN-fN)*sizeof(Double_t));
         delete [] fX;
      }
      if (fY && fN){
         memcpy(savey,fY,fN*sizeof(Double_t));
         memset(&savey[fN],0,(newN-fN)*sizeof(Double_t));
         delete [] fY;
      }
      fX = savex;
      fY = savey;
      fN = newN;
   }
   fX[n] = x;
   fY[n] = y;
   fLastPoint = TMath::Max(fLastPoint,n);
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n)
{
   // If n <= 0 the current arrays of points are deleted.

   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      delete [] fX;
      delete [] fY;
      fX = fY = 0;
      return;
   }
   SetPoint(n-1,0,0);
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option)
{
   // If n <= 0 the current arrays of points are deleted.

   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      delete [] fX;
      delete [] fY;
      fX = fY = 0;
      return;
   }
   fN =n;
   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fX = new Double_t[fN];
   fY = new Double_t[fN];
   for (Int_t i=0; i<fN;i++) {
      if (x) fX[i] = (Double_t)x[i];
      if (y) fY[i] = (Double_t)y[i];
   }
   fOption = option;
   fLastPoint = fN-1;
}

//______________________________________________________________________________
void TPolyMarker::SetPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option)
{
   // If n <= 0 the current arrays of points are deleted.

   if (n <= 0) {
      fN = 0;
      fLastPoint = -1;
      delete [] fX;
      delete [] fY;
      fX = fY = 0;
      return;
   }
   fN =n;
   if (fX) delete [] fX;
   if (fY) delete [] fY;
   fX = new Double_t[fN];
   fY = new Double_t[fN];
   for (Int_t i=0; i<fN;i++) {
      if (x) fX[i] = x[i];
      if (y) fY[i] = y[i];
   }
   fOption = option;
   fLastPoint = fN-1;
}

//_______________________________________________________________________
void TPolyMarker::Streamer(TBuffer &R__b)
{
   // Stream a class object.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         R__b.ReadClassBuffer(TPolyMarker::Class(), this, R__v, R__s, R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      TObject::Streamer(R__b);
      TAttMarker::Streamer(R__b);
      R__b >> fN;
      fX = new Double_t[fN];
      fY = new Double_t[fN];
      Int_t i;
      Float_t xold,yold;
      for (i=0;i<fN;i++) {R__b >> xold; fX[i] = xold;}
      for (i=0;i<fN;i++) {R__b >> yold; fY[i] = yold;}
      fOption.Streamer(R__b);
      R__b.CheckByteCount(R__s, R__c, TPolyMarker::IsA());
      //====end of old versions

   } else {
      R__b.WriteClassBuffer(TPolyMarker::Class(),this);
   }
}
<|endoftext|>


<commit_before>//===--- tools/extra/clang-tidy/ClangTidy.cpp - Clang tidy tool -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
///  \file This file implements a clang-tidy tool.
///
///  This tool uses the Clang Tooling infrastructure, see
///    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
///  for details on setting it up with LLVM source tree.
///
//===----------------------------------------------------------------------===//

#include "ClangTidy.h"
#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyModuleRegistry.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include <algorithm>
#include <vector>
// FIXME: Move AnalysisConsumer to include/clang/StaticAnalyzer/Frontend.
#include "../lib/StaticAnalyzer/Frontend/AnalysisConsumer.h"

using namespace clang::ast_matchers;
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;

namespace clang {
namespace tidy {

namespace {
static const char *AnalyzerCheckerNamePrefix = "clang-analyzer-";

static StringRef StaticAnalyzerCheckers[] = {
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)       \
  FULLNAME,
#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
};

} // namespace

ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
    StringRef EnableChecksRegex, StringRef DisableChecksRegex,
    ClangTidyContext &Context)
    : Filter(EnableChecksRegex, DisableChecksRegex), Context(Context),
      CheckFactories(new ClangTidyCheckFactories) {
  for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
                                         E = ClangTidyModuleRegistry::end();
       I != E; ++I) {
    OwningPtr<ClangTidyModule> Module(I->instantiate());
    Module->addCheckFactories(*CheckFactories);
  }

  CheckFactories->createChecks(Filter, Checks);

  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I) {
    (*I)->setContext(&Context);
    (*I)->registerMatchers(&Finder);
  }
}

ClangTidyASTConsumerFactory::~ClangTidyASTConsumerFactory() {
  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I)
    delete *I;
}

clang::ASTConsumer *ClangTidyASTConsumerFactory::CreateASTConsumer(
    clang::CompilerInstance &Compiler, StringRef File) {
  // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
  // modify Compiler.
  Context.setSourceManager(&Compiler.getSourceManager());
  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I)
    (*I)->registerPPCallbacks(Compiler);

  AnalyzerOptionsRef Options = Compiler.getAnalyzerOpts();
  Options->CheckersControlList = getCheckersControlList();
  Options->AnalysisStoreOpt = RegionStoreModel;
  Options->AnalysisDiagOpt = PD_TEXT;
  Options->AnalyzeNestedBlocks = true;
  Options->eagerlyAssumeBinOpBifurcation = true;
  ASTConsumer *Consumers[] = {
    Finder.newASTConsumer(),
    ento::CreateAnalysisConsumer(Compiler.getPreprocessor(),
                                 Compiler.getFrontendOpts().OutputFile, Options,
                                 Compiler.getFrontendOpts().Plugins)
  };
  return new MultiplexConsumer(Consumers);
}

std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
  std::vector<std::string> CheckNames;
  for (ClangTidyCheckFactories::FactoryMap::const_iterator
           I = CheckFactories->begin(),
           E = CheckFactories->end();
       I != E; ++I) {
    if (Filter.IsCheckEnabled(I->first))
      CheckNames.push_back(I->first);
  }

  CheckersList AnalyzerChecks = getCheckersControlList();
  for (CheckersList::const_iterator I = AnalyzerChecks.begin(),
                                    E = AnalyzerChecks.end();
       I != E; ++I)
    CheckNames.push_back(AnalyzerCheckerNamePrefix + I->first);

  std::sort(CheckNames.begin(), CheckNames.end());
  return CheckNames;
}

ClangTidyASTConsumerFactory::CheckersList
ClangTidyASTConsumerFactory::getCheckersControlList() {
  CheckersList List;
  ArrayRef<StringRef> Checkers(StaticAnalyzerCheckers);

  bool AnalyzerChecksEnabled = false;
  for (unsigned i = 0; i < Checkers.size(); ++i) {
    std::string Checker((AnalyzerCheckerNamePrefix + Checkers[i]).str());
    AnalyzerChecksEnabled |=
        Filter.IsCheckEnabled(Checker) && !Checkers[i].startswith("debug");
  }

  if (AnalyzerChecksEnabled) {
    // Run our regex against all possible static analyzer checkers.  Note that
    // debug checkers print values / run programs to visualize the CFG and are
    // thus not applicable to clang-tidy in general.
    //
    // Always add all core checkers if any other static analyzer checks are
    // enabled. This is currently necessary, as other path sensitive checks
    // rely on the core checkers.
    for (unsigned i = 0; i < Checkers.size(); ++i) {
      std::string Checker((AnalyzerCheckerNamePrefix + Checkers[i]).str());

      if (Checkers[i].startswith("core") ||
          (!Checkers[i].startswith("debug") && Filter.IsCheckEnabled(Checker)))
        List.push_back(std::make_pair(Checkers[i], true));
    }
  }
  return List;
}

ChecksFilter::ChecksFilter(StringRef EnableChecksRegex,
                           StringRef DisableChecksRegex)
    : EnableChecks(EnableChecksRegex), DisableChecks(DisableChecksRegex) {}

bool ChecksFilter::IsCheckEnabled(StringRef Name) {
  return EnableChecks.match(Name) && !DisableChecks.match(Name);
}

ClangTidyMessage::ClangTidyMessage(StringRef Message) : Message(Message) {}

ClangTidyMessage::ClangTidyMessage(StringRef Message,
                                   const SourceManager &Sources,
                                   SourceLocation Loc)
    : Message(Message) {
  FilePath = Sources.getFilename(Loc);
  FileOffset = Sources.getFileOffset(Loc);
}

ClangTidyError::ClangTidyError(const ClangTidyMessage &Message)
    : Message(Message) {}

DiagnosticBuilder ClangTidyContext::Diag(SourceLocation Loc,
                                         StringRef Message) {
  return DiagEngine->Report(
      Loc, DiagEngine->getCustomDiagID(DiagnosticsEngine::Warning, Message));
}

void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) {
  DiagEngine = Engine;
}

void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
  DiagEngine->setSourceManager(SourceMgr);
}

/// \brief Store a \c ClangTidyError.
void ClangTidyContext::storeError(const ClangTidyError &Error) {
  Errors->push_back(Error);
}

void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
  Context->setSourceManager(Result.SourceManager);
  check(Result);
}

std::vector<std::string> getCheckNames(StringRef EnableChecksRegex,
                                       StringRef DisableChecksRegex) {
  SmallVector<ClangTidyError, 8> Errors;
  clang::tidy::ClangTidyContext Context(&Errors);
  ClangTidyASTConsumerFactory Factory(EnableChecksRegex, DisableChecksRegex,
                                      Context);
  return Factory.getCheckNames();
}

void runClangTidy(StringRef EnableChecksRegex, StringRef DisableChecksRegex,
                  const tooling::CompilationDatabase &Compilations,
                  ArrayRef<std::string> Ranges,
                  SmallVectorImpl<ClangTidyError> *Errors) {
  // FIXME: Ranges are currently full files. Support selecting specific
  // (line-)ranges.
  ClangTool Tool(Compilations, Ranges);
  clang::tidy::ClangTidyContext Context(Errors);
  ClangTidyDiagnosticConsumer DiagConsumer(Context);

  Tool.setDiagnosticConsumer(&DiagConsumer);

  class ActionFactory : public FrontendActionFactory {
  public:
    ActionFactory(ClangTidyASTConsumerFactory *ConsumerFactory)
        : ConsumerFactory(ConsumerFactory) {}
    FrontendAction *create() LLVM_OVERRIDE {
      return new Action(ConsumerFactory);
    }

  private:
    class Action : public ASTFrontendAction {
    public:
      Action(ClangTidyASTConsumerFactory *Factory) : Factory(Factory) {}
      ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler,
                                     StringRef File) LLVM_OVERRIDE {
        return Factory->CreateASTConsumer(Compiler, File);
      }

    private:
      ClangTidyASTConsumerFactory *Factory;
    };

    ClangTidyASTConsumerFactory *ConsumerFactory;
  };

  Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(
      EnableChecksRegex, DisableChecksRegex, Context)));
}

static void reportDiagnostic(const ClangTidyMessage &Message,
                             SourceManager &SourceMgr,
                             DiagnosticsEngine::Level Level,
                             DiagnosticsEngine &Diags) {
  SourceLocation Loc;
  if (!Message.FilePath.empty()) {
    const FileEntry *File =
        SourceMgr.getFileManager().getFile(Message.FilePath);
    FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
    Loc = SourceMgr.getLocForStartOfFile(ID);
    Loc = Loc.getLocWithOffset(Message.FileOffset);
  }
  Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message));
}

void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
  FileManager Files((FileSystemOptions()));
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  DiagnosticConsumer *DiagPrinter =
      new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts);
  DiagnosticsEngine Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
                          &*DiagOpts, DiagPrinter);
  DiagPrinter->BeginSourceFile(LangOptions());
  SourceManager SourceMgr(Diags, Files);
  Rewriter Rewrite(SourceMgr, LangOptions());
  for (SmallVectorImpl<ClangTidyError>::iterator I = Errors.begin(),
                                                 E = Errors.end();
       I != E; ++I) {
    reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags);
    for (unsigned i = 0, e = I->Notes.size(); i != e; ++i) {
      reportDiagnostic(I->Notes[i], SourceMgr, DiagnosticsEngine::Note, Diags);
    }
    tooling::applyAllReplacements(I->Fix, Rewrite);
  }
  // FIXME: Run clang-format on changes.
  if (Fix)
    Rewrite.overwriteChangedFiles();
}

} // namespace tidy
} // namespace clang
<commit_msg>A follow-up to r198426: move AnalysisConsumer.h to include/clang/...<commit_after>//===--- tools/extra/clang-tidy/ClangTidy.cpp - Clang tidy tool -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
///  \file This file implements a clang-tidy tool.
///
///  This tool uses the Clang Tooling infrastructure, see
///    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
///  for details on setting it up with LLVM source tree.
///
//===----------------------------------------------------------------------===//

#include "ClangTidy.h"
#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyModuleRegistry.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include <algorithm>
#include <vector>

using namespace clang::ast_matchers;
using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;

namespace clang {
namespace tidy {

namespace {
static const char *AnalyzerCheckerNamePrefix = "clang-analyzer-";

static StringRef StaticAnalyzerCheckers[] = {
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)       \
  FULLNAME,
#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
};

} // namespace

ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
    StringRef EnableChecksRegex, StringRef DisableChecksRegex,
    ClangTidyContext &Context)
    : Filter(EnableChecksRegex, DisableChecksRegex), Context(Context),
      CheckFactories(new ClangTidyCheckFactories) {
  for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
                                         E = ClangTidyModuleRegistry::end();
       I != E; ++I) {
    OwningPtr<ClangTidyModule> Module(I->instantiate());
    Module->addCheckFactories(*CheckFactories);
  }

  CheckFactories->createChecks(Filter, Checks);

  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I) {
    (*I)->setContext(&Context);
    (*I)->registerMatchers(&Finder);
  }
}

ClangTidyASTConsumerFactory::~ClangTidyASTConsumerFactory() {
  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I)
    delete *I;
}

clang::ASTConsumer *ClangTidyASTConsumerFactory::CreateASTConsumer(
    clang::CompilerInstance &Compiler, StringRef File) {
  // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
  // modify Compiler.
  Context.setSourceManager(&Compiler.getSourceManager());
  for (SmallVectorImpl<ClangTidyCheck *>::iterator I = Checks.begin(),
                                                   E = Checks.end();
       I != E; ++I)
    (*I)->registerPPCallbacks(Compiler);

  AnalyzerOptionsRef Options = Compiler.getAnalyzerOpts();
  Options->CheckersControlList = getCheckersControlList();
  Options->AnalysisStoreOpt = RegionStoreModel;
  Options->AnalysisDiagOpt = PD_TEXT;
  Options->AnalyzeNestedBlocks = true;
  Options->eagerlyAssumeBinOpBifurcation = true;
  ASTConsumer *Consumers[] = {
    Finder.newASTConsumer(),
    ento::CreateAnalysisConsumer(Compiler.getPreprocessor(),
                                 Compiler.getFrontendOpts().OutputFile, Options,
                                 Compiler.getFrontendOpts().Plugins)
  };
  return new MultiplexConsumer(Consumers);
}

std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
  std::vector<std::string> CheckNames;
  for (ClangTidyCheckFactories::FactoryMap::const_iterator
           I = CheckFactories->begin(),
           E = CheckFactories->end();
       I != E; ++I) {
    if (Filter.IsCheckEnabled(I->first))
      CheckNames.push_back(I->first);
  }

  CheckersList AnalyzerChecks = getCheckersControlList();
  for (CheckersList::const_iterator I = AnalyzerChecks.begin(),
                                    E = AnalyzerChecks.end();
       I != E; ++I)
    CheckNames.push_back(AnalyzerCheckerNamePrefix + I->first);

  std::sort(CheckNames.begin(), CheckNames.end());
  return CheckNames;
}

ClangTidyASTConsumerFactory::CheckersList
ClangTidyASTConsumerFactory::getCheckersControlList() {
  CheckersList List;
  ArrayRef<StringRef> Checkers(StaticAnalyzerCheckers);

  bool AnalyzerChecksEnabled = false;
  for (unsigned i = 0; i < Checkers.size(); ++i) {
    std::string Checker((AnalyzerCheckerNamePrefix + Checkers[i]).str());
    AnalyzerChecksEnabled |=
        Filter.IsCheckEnabled(Checker) && !Checkers[i].startswith("debug");
  }

  if (AnalyzerChecksEnabled) {
    // Run our regex against all possible static analyzer checkers.  Note that
    // debug checkers print values / run programs to visualize the CFG and are
    // thus not applicable to clang-tidy in general.
    //
    // Always add all core checkers if any other static analyzer checks are
    // enabled. This is currently necessary, as other path sensitive checks
    // rely on the core checkers.
    for (unsigned i = 0; i < Checkers.size(); ++i) {
      std::string Checker((AnalyzerCheckerNamePrefix + Checkers[i]).str());

      if (Checkers[i].startswith("core") ||
          (!Checkers[i].startswith("debug") && Filter.IsCheckEnabled(Checker)))
        List.push_back(std::make_pair(Checkers[i], true));
    }
  }
  return List;
}

ChecksFilter::ChecksFilter(StringRef EnableChecksRegex,
                           StringRef DisableChecksRegex)
    : EnableChecks(EnableChecksRegex), DisableChecks(DisableChecksRegex) {}

bool ChecksFilter::IsCheckEnabled(StringRef Name) {
  return EnableChecks.match(Name) && !DisableChecks.match(Name);
}

ClangTidyMessage::ClangTidyMessage(StringRef Message) : Message(Message) {}

ClangTidyMessage::ClangTidyMessage(StringRef Message,
                                   const SourceManager &Sources,
                                   SourceLocation Loc)
    : Message(Message) {
  FilePath = Sources.getFilename(Loc);
  FileOffset = Sources.getFileOffset(Loc);
}

ClangTidyError::ClangTidyError(const ClangTidyMessage &Message)
    : Message(Message) {}

DiagnosticBuilder ClangTidyContext::Diag(SourceLocation Loc,
                                         StringRef Message) {
  return DiagEngine->Report(
      Loc, DiagEngine->getCustomDiagID(DiagnosticsEngine::Warning, Message));
}

void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) {
  DiagEngine = Engine;
}

void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
  DiagEngine->setSourceManager(SourceMgr);
}

/// \brief Store a \c ClangTidyError.
void ClangTidyContext::storeError(const ClangTidyError &Error) {
  Errors->push_back(Error);
}

void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
  Context->setSourceManager(Result.SourceManager);
  check(Result);
}

std::vector<std::string> getCheckNames(StringRef EnableChecksRegex,
                                       StringRef DisableChecksRegex) {
  SmallVector<ClangTidyError, 8> Errors;
  clang::tidy::ClangTidyContext Context(&Errors);
  ClangTidyASTConsumerFactory Factory(EnableChecksRegex, DisableChecksRegex,
                                      Context);
  return Factory.getCheckNames();
}

void runClangTidy(StringRef EnableChecksRegex, StringRef DisableChecksRegex,
                  const tooling::CompilationDatabase &Compilations,
                  ArrayRef<std::string> Ranges,
                  SmallVectorImpl<ClangTidyError> *Errors) {
  // FIXME: Ranges are currently full files. Support selecting specific
  // (line-)ranges.
  ClangTool Tool(Compilations, Ranges);
  clang::tidy::ClangTidyContext Context(Errors);
  ClangTidyDiagnosticConsumer DiagConsumer(Context);

  Tool.setDiagnosticConsumer(&DiagConsumer);

  class ActionFactory : public FrontendActionFactory {
  public:
    ActionFactory(ClangTidyASTConsumerFactory *ConsumerFactory)
        : ConsumerFactory(ConsumerFactory) {}
    FrontendAction *create() LLVM_OVERRIDE {
      return new Action(ConsumerFactory);
    }

  private:
    class Action : public ASTFrontendAction {
    public:
      Action(ClangTidyASTConsumerFactory *Factory) : Factory(Factory) {}
      ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler,
                                     StringRef File) LLVM_OVERRIDE {
        return Factory->CreateASTConsumer(Compiler, File);
      }

    private:
      ClangTidyASTConsumerFactory *Factory;
    };

    ClangTidyASTConsumerFactory *ConsumerFactory;
  };

  Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(
      EnableChecksRegex, DisableChecksRegex, Context)));
}

static void reportDiagnostic(const ClangTidyMessage &Message,
                             SourceManager &SourceMgr,
                             DiagnosticsEngine::Level Level,
                             DiagnosticsEngine &Diags) {
  SourceLocation Loc;
  if (!Message.FilePath.empty()) {
    const FileEntry *File =
        SourceMgr.getFileManager().getFile(Message.FilePath);
    FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
    Loc = SourceMgr.getLocForStartOfFile(ID);
    Loc = Loc.getLocWithOffset(Message.FileOffset);
  }
  Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message));
}

void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) {
  FileManager Files((FileSystemOptions()));
  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
  DiagnosticConsumer *DiagPrinter =
      new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts);
  DiagnosticsEngine Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
                          &*DiagOpts, DiagPrinter);
  DiagPrinter->BeginSourceFile(LangOptions());
  SourceManager SourceMgr(Diags, Files);
  Rewriter Rewrite(SourceMgr, LangOptions());
  for (SmallVectorImpl<ClangTidyError>::iterator I = Errors.begin(),
                                                 E = Errors.end();
       I != E; ++I) {
    reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags);
    for (unsigned i = 0, e = I->Notes.size(); i != e; ++i) {
      reportDiagnostic(I->Notes[i], SourceMgr, DiagnosticsEngine::Note, Diags);
    }
    tooling::applyAllReplacements(I->Fix, Rewrite);
  }
  // FIXME: Run clang-format on changes.
  if (Fix)
    Rewrite.overwriteChangedFiles();
}

} // namespace tidy
} // namespace clang
<|endoftext|>


<commit_before>//RUN: cat %s | %cling -Xclang -verify -DCLING='" %cling "'
//RUN: rm -f /tmp/__cling_fwd_*
#include "cling/Interpreter/Interpreter.h"

#include "llvm/ADT/SmallVector.h"

#include <string>
#include <regex>

#include "dirent.h" // For lightweight dir access.

typedef llvm::SmallVector<std::string, 16> Includes;
Includes includePaths;
gCling->GetIncludePaths(includePaths, /*system=*/true, /*withflags=*/false);
DIR *dir;
struct dirent *ent;
static std::regex dirsToIgnore("(.*)/backward");
// Limited regexp support, cannot do file by file.
std::string filesToIgnore = "bfd.h;bfdlink.h;";
// LLVM/Clang internals, cannot be directly included:
filesToIgnore += "varargs.h;wmmintrin.h;altivec.h;";
filesToIgnore += "shaintrin.h;xopintrin.h;lzcntintrin.h;rdseedintrin.h;";
filesToIgnore += "pmmintrin.h;tmmintrin.h;ia32intrin.h;bmiintrin.h;arm_neon.h;";
filesToIgnore += "prfchwintrin.h;fmaintrin.h;bmi2intrin.h;ammintrin.h;";
filesToIgnore += "module.modulemap;smmintrin.h;Intrin.h;avxintrin.h;tbmintrin.h;";
filesToIgnore += "f16cintrin.h;nmmintrin.h;__wmmintrin_aes.h;popcntintrin.h;";
filesToIgnore += "__wmmintrin_pclmul.h;rtmintrin.h;fma4intrin.h;avx2intrin.h;";
// Wrong setups, i.e not self-contained header files:
filesToIgnore += "dlg_colors.h;dialog.h;plugin-api.h;regexp.h;etip.h;dlg_keys.h;";
filesToIgnore += "cursesw.h;cursesm.h;cursesf.h;cursslk.h;cursesapp.h;term_entry.h;";
filesToIgnore += "cursesp.h;ft2build.h;";

// AUX:
filesToIgnore += "Makefile;CMakeLists.txt;";

// Temporary
filesToIgnore += "map;";

.rawInput 1
bool has_suffix(const std::string &str, const std::string &suffix) {
    return str.size() >= suffix.size() &&
           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}
.rawInput 0

std::string fwdDeclFile;
std::string nestedCling = CLING; nestedCling += " -Xclang -verify ";
for (int i = 0; i < 1 /*includePaths.size()*/; ++i) { // We know STL is first.
  if (std::regex_match(includePaths[i], dirsToIgnore))
    continue;
  if ((dir = opendir(includePaths[i].c_str())) != NULL) {
    /* print all the files and directories within directory */
    while ((ent = readdir(dir)) != NULL) {
      if (filesToIgnore.find(ent->d_name) != std::string::npos)
        continue;
      if (includePaths[i] == "." && !has_suffix(ent->d_name, ".h"))
        continue;
      if (ent->d_type == DT_REG && strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) {
        fwdDeclFile = "/tmp/__cling_fwd_"; fwdDeclFile += ent->d_name;
        gCling->GenerateAutoloadingMap(ent->d_name, fwdDeclFile);
        // Run it in separate cling and assert it went all fine:
        printf("%s\n", (nestedCling + fwdDeclFile + " " + ent->d_name).c_str());
        system((nestedCling + fwdDeclFile + " " + ent->d_name).c_str());
        //printf("%s\n", ent->d_name);
      }
    }
    closedir(dir);
  }
 }
//expected-no-diagnostics
.q
<commit_msg>Disable #inclusion of the generated fwd decl headers.<commit_after>//RUN: cat %s | %cling -Xclang -verify -DCLING='" %cling "'
//RUN: rm -f /tmp/__cling_fwd_*
#include "cling/Interpreter/Interpreter.h"

#include "llvm/ADT/SmallVector.h"

#include <string>
#include <regex>

#include "dirent.h" // For lightweight dir access.

typedef llvm::SmallVector<std::string, 16> Includes;
Includes includePaths;
gCling->GetIncludePaths(includePaths, /*system=*/true, /*withflags=*/false);
DIR *dir;
struct dirent *ent;
static std::regex dirsToIgnore("(.*)/backward");
// Limited regexp support, cannot do file by file.
std::string filesToIgnore = "bfd.h;bfdlink.h;";
// LLVM/Clang internals, cannot be directly included:
filesToIgnore += "varargs.h;wmmintrin.h;altivec.h;";
filesToIgnore += "shaintrin.h;xopintrin.h;lzcntintrin.h;rdseedintrin.h;";
filesToIgnore += "pmmintrin.h;tmmintrin.h;ia32intrin.h;bmiintrin.h;arm_neon.h;";
filesToIgnore += "prfchwintrin.h;fmaintrin.h;bmi2intrin.h;ammintrin.h;";
filesToIgnore += "module.modulemap;smmintrin.h;Intrin.h;avxintrin.h;tbmintrin.h;";
filesToIgnore += "f16cintrin.h;nmmintrin.h;__wmmintrin_aes.h;popcntintrin.h;";
filesToIgnore += "__wmmintrin_pclmul.h;rtmintrin.h;fma4intrin.h;avx2intrin.h;";
// Wrong setups, i.e not self-contained header files:
filesToIgnore += "dlg_colors.h;dialog.h;plugin-api.h;regexp.h;etip.h;dlg_keys.h;";
filesToIgnore += "cursesw.h;cursesm.h;cursesf.h;cursslk.h;cursesapp.h;term_entry.h;";
filesToIgnore += "cursesp.h;ft2build.h;";

// AUX:
filesToIgnore += "Makefile;CMakeLists.txt;";

// Temporary
filesToIgnore += "map;";

.rawInput 1
bool has_suffix(const std::string &str, const std::string &suffix) {
    return str.size() >= suffix.size() &&
           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}
.rawInput 0

std::string fwdDeclFile;
std::string nestedCling = CLING; nestedCling += " -Xclang -verify ";
for (int i = 0; i < 1 /*includePaths.size()*/; ++i) { // We know STL is first.
  if (std::regex_match(includePaths[i], dirsToIgnore))
    continue;
  if ((dir = opendir(includePaths[i].c_str())) != NULL) {
    /* print all the files and directories within directory */
    while ((ent = readdir(dir)) != NULL) {
      if (filesToIgnore.find(ent->d_name) != std::string::npos)
        continue;
      if (includePaths[i] == "." && !has_suffix(ent->d_name, ".h"))
        continue;
      if (ent->d_type == DT_REG && strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) {
        fwdDeclFile = "/tmp/__cling_fwd_"; fwdDeclFile += ent->d_name;
        gCling->GenerateAutoloadingMap(ent->d_name, fwdDeclFile);
        // Run it in separate cling and assert it went all fine:
        printf("%s\n", (nestedCling + fwdDeclFile + " " + ent->d_name).c_str());
        //system((nestedCling + fwdDeclFile + " " + ent->d_name).c_str());
        //printf("%s\n", ent->d_name);
      }
    }
    closedir(dir);
  }
 }
//expected-no-diagnostics
.q
<|endoftext|>


<commit_before>#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include "lsm303Accelerometer.h"

/**
 * @brief LSM303Accelerometer::LSM303Accelerometer
 *
 * ctor
 *
 * @param device                    device to open, eg. /dev/i2c-x
 * @param address                   i2c chip address
 * @param sensorID                  chip id
 */
LSM303Accelerometer::LSM303Accelerometer(char *device, unsigned char address) : Firmware_I2C(device, address) {
    printf("device %s address 0x%0x\n", device, address);

    /// openDevice in firmware_i2c open's the i2c device and set's the slave address (ioctl)
    int status = Firmware_I2C::openDevice();
    if (status < 0)
        std::cerr << __func__ << " openDevice failed with error " << status << std::endl;

    /// Clear the raw accel data
    raw.x = 0;
    raw.y = 0;
    raw.z = 0;
}

/**
 * @brief LSM303Accelerometer::write_byte
 * @param reg
 * @param value
 * @return
 */
int LSM303Accelerometer::write_byte(char reg, char value)
{
    /// write controll reg A to address 0x57
    unsigned char buffer[2];

    buffer[0] = reg;
    buffer[1] = value;

    /// write start address to device
    int status = writeData(buffer, 2);
    if (status < 0) {
        std::cerr << __func__ << " writeData failed with error " << status << std::endl;
        return -1;
    }

    return 0;
}

/**
 * @brief LSM303Accelerometer::begin
 *
 * open i2c device and read ID
 *
 * @return                          zero on success, negative error value on failure
 */
int LSM303Accelerometer::init()
{
    int status = -1;
    char value = 0x57;

    status = write_byte(LSM303RegisterAccelerometerCtrlReg1_A, value);
    if (status < 0) {
        std::cerr << __func__ << " write_byte failed with error " << status << std::endl;
        return -1;
    }

    unsigned char buffer[1];
    memset(buffer, 0, 1);

    /// read back controll register back to verify that we're connected
    status = readData(buffer, 1);
    if (status < 0) {
        std::cerr << __func__ << " readData failed with error " << status << std::endl;
        return -2;
    }

    if (buffer[0] != value) {
        return -3;
    }

    return 0;
}

int LSM303Accelerometer::getRegister(char reg, char *value)
{
    unsigned char data[1] = { reg };

    /// set value to zero - by default
    *value = 0x00;

    /// write register we will read to device
    int status = writeData(data, 1);
    if (status < 0) {
        std::cerr << __func__ << ":" << __LINE__ << " write failed " << status << std::endl;
        return -1;
    }

    /// clear data buffer
    memset(data, 0, 1);

    status = readData(data, 1);
    if (status < 0) {
        std::cerr << __func__ << ":" << __LINE__ << " read failed " << status << std::endl;
        return -2;
    }

    *value = data[0];

    return 0;

}

/**
 * @brief LSM303Accelerometer::read
 */
int LSM303Accelerometer::read()
{
    unsigned char buffer[6];
    memset(buffer, 0, 6);

    buffer[0] = LSM303RegisterAccelerometerOut_X_L_A | 0x80;

    /// write data start address to device
    int status = writeData(buffer, 1);
    if (status < 0) {
        std::cerr << __func__ << " writeData failed with error " << status << std::endl;
        return -1;
    }

    usleep(100);

    /// read 6 bytes of data from device
    status = readData(buffer, 6);
    if (status < 0) {
        std::cerr << __func__ << " readData failed with error " << status << std::endl;
        return -2;
    }

    char xlo = buffer[0];
    char xhi = buffer[1];
    char ylo = buffer[2];
    char yhi = buffer[3];
    char zlo = buffer[4];
    char zhi = buffer[5];

    //printf("Six bytes: %d %d %d %d %d %d\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);

    raw.x = (unsigned int)(xlo | (xhi << 8)) >> 4;
    raw.y = (unsigned int)(ylo | (yhi << 8)) >> 4;
    raw.z = (unsigned int)(zlo | (zhi << 8)) >> 4;

    return 0;
}

/**
 * @brief LSM303Accelerometer::getEvent
 * @param event
 *
 * @return                          zero on success, negative error value on failure
 */
int LSM303Accelerometer::getEvent(accel_event_t *event)
{
    unsigned char buffer[6];

    /// clear data buffers
    memset(event, 0, sizeof(accel_event_t));
    memset(buffer, 0, 6);

    /// read device
    int status = read();
    if (status < 0) {
        std::cerr << __func__ << ": read failed with error " << status << std::endl;
        return -1;
    }

    status = gettimeofday(&event->timestamp, NULL);
    if (status < 0) {
        std::cerr << __func__ << ": gettimeofday failed with error " << status << std::endl;
        return -2;
    }

    event->version          = sizeof(accel_event_t);
    event->acceleration.x   = (float)raw.x * lsm303Accel_MG_LSB * SensorGravityEarth;
    event->acceleration.y   = (float)raw.y * lsm303Accel_MG_LSB * SensorGravityEarth;
    event->acceleration.z   = (float)raw.z * lsm303Accel_MG_LSB * SensorGravityEarth;

    return 0;
}
<commit_msg>* swapped writeData then readData with readRegister<commit_after>#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include "lsm303Accelerometer.h"

/**
 * @brief LSM303Accelerometer::LSM303Accelerometer
 *
 * ctor
 *
 * @param device                    device to open, eg. /dev/i2c-x
 * @param address                   i2c chip address
 * @param sensorID                  chip id
 */
LSM303Accelerometer::LSM303Accelerometer(char *device, unsigned char address) : Firmware_I2C(device, address) {
    printf("device %s address 0x%0x\n", device, address);

    /// openDevice in firmware_i2c open's the i2c device and set's the slave address (ioctl)
    int status = Firmware_I2C::openDevice();
    if (status < 0)
        std::cerr << __func__ << " openDevice failed with error " << status << std::endl;

    /// Clear the raw accel data
    raw.x = 0;
    raw.y = 0;
    raw.z = 0;
}

/**
 * @brief LSM303Accelerometer::write_byte
 * @param reg
 * @param value
 * @return
 */
int LSM303Accelerometer::write_byte(char reg, char value)
{
    /// write controll reg A to address 0x57
    unsigned char buffer[2];

    buffer[0] = reg;
    buffer[1] = value;

    /// write start address to device
    int status = writeData(buffer, 2);
    if (status < 0) {
        std::cerr << __func__ << " writeData failed with error " << status << std::endl;
        return -1;
    }

    return 0;
}

/**
 * @brief LSM303Accelerometer::begin
 *
 * open i2c device and read ID
 *
 * @return                          zero on success, negative error value on failure
 */
int LSM303Accelerometer::init()
{
    int status = -1;
    char value = 0x57;

    status = write_byte(LSM303RegisterAccelerometerCtrlReg1_A, value);
    if (status < 0) {
        std::cerr << __func__ << " write_byte failed with error " << status << std::endl;
        return -1;
    }

    unsigned char buffer[1];
    memset(buffer, 0, 1);

    /// read back controll register back to verify that we're connected
    status = readData(buffer, 1);
    if (status < 0) {
        std::cerr << __func__ << " readData failed with error " << status << std::endl;
        return -2;
    }

    if (buffer[0] != value) {
        return -3;
    }

    return 0;
}

int LSM303Accelerometer::getRegister(char reg, char *value)
{
    /// set value to zero - by default
    *value = 0x00;

    int status = readRegister(reg, value);
    if (status < 0) {
        std::cerr << __func__ << ":" << __LINE__ << " Firmware_I2C::readRegister failed with error " << status << std::endl;
        return -1;
    }

    *value = (char)status;

    return 0;

}

/**
 * @brief LSM303Accelerometer::read
 */
int LSM303Accelerometer::read()
{
    unsigned char buffer[6];
    memset(buffer, 0, 6);

    buffer[0] = LSM303RegisterAccelerometerOut_X_L_A | 0x80;

    /// write data start address to device
    int status = writeData(buffer, 1);
    if (status < 0) {
        std::cerr << __func__ << " writeData failed with error " << status << std::endl;
        return -1;
    }

    usleep(100);

    /// read 6 bytes of data from device
    status = readData(buffer, 6);
    if (status < 0) {
        std::cerr << __func__ << " readData failed with error " << status << std::endl;
        return -2;
    }

    char xlo = buffer[0];
    char xhi = buffer[1];
    char ylo = buffer[2];
    char yhi = buffer[3];
    char zlo = buffer[4];
    char zhi = buffer[5];

    //printf("Six bytes: %d %d %d %d %d %d\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);

    raw.x = (unsigned int)(xlo | (xhi << 8)) >> 4;
    raw.y = (unsigned int)(ylo | (yhi << 8)) >> 4;
    raw.z = (unsigned int)(zlo | (zhi << 8)) >> 4;

    return 0;
}

/**
 * @brief LSM303Accelerometer::getEvent
 * @param event
 *
 * @return                          zero on success, negative error value on failure
 */
int LSM303Accelerometer::getEvent(accel_event_t *event)
{
    unsigned char buffer[6];

    /// clear data buffers
    memset(event, 0, sizeof(accel_event_t));
    memset(buffer, 0, 6);

    /// read device
    int status = read();
    if (status < 0) {
        std::cerr << __func__ << ": read failed with error " << status << std::endl;
        return -1;
    }

    status = gettimeofday(&event->timestamp, NULL);
    if (status < 0) {
        std::cerr << __func__ << ": gettimeofday failed with error " << status << std::endl;
        return -2;
    }

    event->version          = sizeof(accel_event_t);
    event->acceleration.x   = (float)raw.x * lsm303Accel_MG_LSB * SensorGravityEarth;
    event->acceleration.y   = (float)raw.y * lsm303Accel_MG_LSB * SensorGravityEarth;
    event->acceleration.z   = (float)raw.z * lsm303Accel_MG_LSB * SensorGravityEarth;

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>added tests for big_number (peer_id/node_id/sha1_hash)<commit_after><|endoftext|>


<commit_before>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.2.0, packaged on September 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

 *****************************************************************************/
//! \file glc_bsrep.cpp implementation for the GLC_BSRep class.

#include "glc_bsrep.h"
#include "../glc_fileformatexception.h"

// The binary rep suffix
const QString GLC_BSRep::m_Suffix("BSRep");

// The binary rep magic number
const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");

// The binary rep version
const quint32 GLC_BSRep::m_Version= 100;

// Default constructor
GLC_BSRep::GLC_BSRep(const QString& fileName, bool useCompression, int compressionLevel)
: m_FileInfo()
, m_pFile(NULL)
, m_DataStream()
, m_UseCompression(useCompression)
, m_CompressionLevel(compressionLevel)
{
	setAbsoluteFileName(fileName);
	m_DataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
}

// Copy constructor
GLC_BSRep::GLC_BSRep(const GLC_BSRep& binaryRep)
: m_FileInfo(binaryRep.m_FileInfo)
, m_pFile(NULL)
, m_DataStream()
, m_UseCompression(binaryRep.m_UseCompression)
, m_CompressionLevel(binaryRep.m_CompressionLevel)
{
	m_DataStream.setFloatingPointPrecision(binaryRep.m_DataStream.floatingPointPrecision());
}

GLC_BSRep::~GLC_BSRep()
{
	delete m_pFile;
}

// Return true if the binary rep is up to date
bool GLC_BSRep::repIsUpToDate(const QDateTime& timeStamp)
{
	qDebug() << "GLC_BSRep::repIsUpToDate";
	bool isUpToDate= false;
	if (open(QIODevice::ReadOnly))
	{
		if (headerIsOk())
		{
			isUpToDate= timeStampOk(timeStamp);
			isUpToDate= isUpToDate && close();
		}
		else
		{
			QString message(QString("GLC_BSRep::loadRep File not recognise ") + m_FileInfo.fileName());
			qDebug() << message;
			GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
			close();
			throw(fileFormatException);
		}
	}
	else
	{
		QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
		qDebug() << message;
		GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
		close();
		throw(fileFormatException);
	}

	return isUpToDate;
}

//////////////////////////////////////////////////////////////////////
// name Get Functions
//////////////////////////////////////////////////////////////////////
// Load the binary rep
GLC_3DRep GLC_BSRep::loadRep()
{
	qDebug() << "GLC_BSRep::loadRep";
	GLC_3DRep loadedRep;

	if (open(QIODevice::ReadOnly))
	{
		if (headerIsOk())
		{
			timeStampOk(QDateTime());
			GLC_BoundingBox boundingBox;
			m_DataStream >> boundingBox;
			bool useCompression;
			m_DataStream >> useCompression;
			if (useCompression)
			{
				QByteArray CompresseBuffer;
				m_DataStream >> CompresseBuffer;
				QByteArray uncompressedBuffer= qUncompress(CompresseBuffer);
				CompresseBuffer.clear();
				QDataStream bufferStream(uncompressedBuffer);
				bufferStream >> loadedRep;
			}
			else
			{
				m_DataStream >> loadedRep;
			}

			if (!close())
			{
				QString message(QString("GLC_BSRep::loadRep An error occur when loading file ") + m_FileInfo.fileName());
				qDebug() << message;
				GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
				throw(fileFormatException);
			}
		}
		else
		{
			QString message(QString("GLC_BSRep::loadRep File not supported ") + m_FileInfo.fileName());
			qDebug() << message;
			GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotSupported);
			close();
			throw(fileFormatException);
		}
	}
	else
	{
		QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
		qDebug() << message;
		GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
		close();
		throw(fileFormatException);
	}

	return loadedRep;
}

// Return bsrep suffix
QString GLC_BSRep::suffix()
{
	return m_Suffix;
}

//////////////////////////////////////////////////////////////////////
//name Set Functions
//////////////////////////////////////////////////////////////////////
// Set the binary representation file name
void GLC_BSRep::setAbsoluteFileName(const QString& fileName)
{
	m_FileInfo.setFile(fileName);
	if (m_FileInfo.suffix() != m_Suffix)
	{
		m_FileInfo.setFile(fileName + '.' + m_Suffix);
	}

}

// Save the GLC_3DRep in serialised binary
bool GLC_BSRep::save(const GLC_3DRep& rep)
{
	qDebug() << "GLC_BSRep::save";
	//! Check if the currentFileInfo is valid and writable
	bool saveOk= open(QIODevice::WriteOnly);
	if (saveOk)
	{
		writeHeader(rep.lastModified());

		// Representation Bounding Box
		m_DataStream << rep.boundingBox();

		// Compression usage
		m_DataStream << m_UseCompression;
		if (m_UseCompression)
		{
			QByteArray uncompressedBuffer;
			QDataStream bufferStream(&uncompressedBuffer, QIODevice::WriteOnly);
			bufferStream << rep;
			m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel);
		}
		else
		{
			// Binary representation geometry
			// Add the rep
			m_DataStream << rep;
		}

		// Close the file
		saveOk= close();
	}
	return saveOk;
}

// Open the file
bool GLC_BSRep::open(QIODevice::OpenMode mode)
{
	qDebug() << "Open :" << m_FileInfo.fileName();
	bool openOk= m_FileInfo.exists();
	if (openOk || (mode == QIODevice::WriteOnly))
	{
		m_DataStream.setDevice(NULL);
		delete m_pFile;
		m_pFile= new QFile(m_FileInfo.filePath());
		openOk= m_pFile->open(mode);
		if (openOk)
		{
			m_DataStream.setDevice(m_pFile);
		}
	}
	else
	{
		qDebug() << "File info " << m_FileInfo.filePath() << " do not exists";
	}
	return openOk;
}

// Close the file
bool GLC_BSRep::close()
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	bool closeOk= m_DataStream.status() == QDataStream::Ok;
	m_DataStream.setDevice(NULL);
	m_pFile->close();
	delete m_pFile;
	m_pFile= NULL;

	return closeOk;
}

// Write the header
void GLC_BSRep::writeHeader(const QDateTime& dateTime)
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::WriteOnly);

	// Binary representation Header
	// Add the magic number
	m_DataStream << m_Uuid;
	// Add the version
	m_DataStream << m_Version;
	// Add the time stamp
	m_DataStream << dateTime;
}

// Check the header
bool GLC_BSRep::headerIsOk()
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);

	QUuid uuid;
	quint32 version;
	m_DataStream >> uuid;
	m_DataStream >> version;

	bool headerOk= (uuid == m_Uuid);
	headerOk= headerOk && (version == m_Version);

	return headerOk;
}

// Check the time Stamp
bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp)
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);

	QDateTime dateTime;
	m_DataStream >> dateTime;

	bool timeStampOk= (dateTime == timeStamp);
	if (timeStampOk)
	{
		qDebug() << "Time Stamp OK";
	}
	else
	{
		qDebug() << "Time Stamp KO";
	}
	return timeStampOk;
}

<commit_msg>Remove some qDebug() lines.<commit_after>/****************************************************************************

 This file is part of the GLC-lib library.
 Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
 Version 1.2.0, packaged on September 2009.

 http://glc-lib.sourceforge.net

 GLC-lib is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 GLC-lib is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GLC-lib; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

 *****************************************************************************/
//! \file glc_bsrep.cpp implementation for the GLC_BSRep class.

#include "glc_bsrep.h"
#include "../glc_fileformatexception.h"

// The binary rep suffix
const QString GLC_BSRep::m_Suffix("BSRep");

// The binary rep magic number
const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");

// The binary rep version
const quint32 GLC_BSRep::m_Version= 100;

// Default constructor
GLC_BSRep::GLC_BSRep(const QString& fileName, bool useCompression, int compressionLevel)
: m_FileInfo()
, m_pFile(NULL)
, m_DataStream()
, m_UseCompression(useCompression)
, m_CompressionLevel(compressionLevel)
{
	setAbsoluteFileName(fileName);
	m_DataStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
}

// Copy constructor
GLC_BSRep::GLC_BSRep(const GLC_BSRep& binaryRep)
: m_FileInfo(binaryRep.m_FileInfo)
, m_pFile(NULL)
, m_DataStream()
, m_UseCompression(binaryRep.m_UseCompression)
, m_CompressionLevel(binaryRep.m_CompressionLevel)
{
	m_DataStream.setFloatingPointPrecision(binaryRep.m_DataStream.floatingPointPrecision());
}

GLC_BSRep::~GLC_BSRep()
{
	delete m_pFile;
}

// Return true if the binary rep is up to date
bool GLC_BSRep::repIsUpToDate(const QDateTime& timeStamp)
{
	qDebug() << "GLC_BSRep::repIsUpToDate";
	bool isUpToDate= false;
	if (open(QIODevice::ReadOnly))
	{
		if (headerIsOk())
		{
			isUpToDate= timeStampOk(timeStamp);
			isUpToDate= isUpToDate && close();
		}
		else
		{
			QString message(QString("GLC_BSRep::loadRep File not recognise ") + m_FileInfo.fileName());
			qDebug() << message;
			GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
			close();
			throw(fileFormatException);
		}
	}
	else
	{
		QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
		qDebug() << message;
		GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
		close();
		throw(fileFormatException);
	}

	if (!isUpToDate) qDebug() << "Rep is not up to date";
	return isUpToDate;
}

//////////////////////////////////////////////////////////////////////
// name Get Functions
//////////////////////////////////////////////////////////////////////
// Load the binary rep
GLC_3DRep GLC_BSRep::loadRep()
{
	//qDebug() << "GLC_BSRep::loadRep";
	GLC_3DRep loadedRep;

	if (open(QIODevice::ReadOnly))
	{
		if (headerIsOk())
		{
			timeStampOk(QDateTime());
			GLC_BoundingBox boundingBox;
			m_DataStream >> boundingBox;
			bool useCompression;
			m_DataStream >> useCompression;
			if (useCompression)
			{
				QByteArray CompresseBuffer;
				m_DataStream >> CompresseBuffer;
				QByteArray uncompressedBuffer= qUncompress(CompresseBuffer);
				CompresseBuffer.clear();
				QDataStream bufferStream(uncompressedBuffer);
				bufferStream >> loadedRep;
			}
			else
			{
				m_DataStream >> loadedRep;
			}

			if (!close())
			{
				QString message(QString("GLC_BSRep::loadRep An error occur when loading file ") + m_FileInfo.fileName());
				qDebug() << message;
				GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::WrongFileFormat);
				throw(fileFormatException);
			}
		}
		else
		{
			QString message(QString("GLC_BSRep::loadRep File not supported ") + m_FileInfo.fileName());
			qDebug() << message;
			GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotSupported);
			close();
			throw(fileFormatException);
		}
	}
	else
	{
		QString message(QString("GLC_BSRep::loadRep Enable to open the file ") + m_FileInfo.fileName());
		qDebug() << message;
		GLC_FileFormatException fileFormatException(message, m_FileInfo.fileName(), GLC_FileFormatException::FileNotFound);
		close();
		throw(fileFormatException);
	}

	return loadedRep;
}

// Return bsrep suffix
QString GLC_BSRep::suffix()
{
	return m_Suffix;
}

//////////////////////////////////////////////////////////////////////
//name Set Functions
//////////////////////////////////////////////////////////////////////
// Set the binary representation file name
void GLC_BSRep::setAbsoluteFileName(const QString& fileName)
{
	m_FileInfo.setFile(fileName);
	if (m_FileInfo.suffix() != m_Suffix)
	{
		m_FileInfo.setFile(fileName + '.' + m_Suffix);
	}

}

// Save the GLC_3DRep in serialised binary
bool GLC_BSRep::save(const GLC_3DRep& rep)
{
	qDebug() << "GLC_BSRep::save";
	//! Check if the currentFileInfo is valid and writable
	bool saveOk= open(QIODevice::WriteOnly);
	if (saveOk)
	{
		writeHeader(rep.lastModified());

		// Representation Bounding Box
		m_DataStream << rep.boundingBox();

		// Compression usage
		m_DataStream << m_UseCompression;
		if (m_UseCompression)
		{
			QByteArray uncompressedBuffer;
			QDataStream bufferStream(&uncompressedBuffer, QIODevice::WriteOnly);
			bufferStream << rep;
			m_DataStream << qCompress(uncompressedBuffer, m_CompressionLevel);
		}
		else
		{
			// Binary representation geometry
			// Add the rep
			m_DataStream << rep;
		}

		// Close the file
		saveOk= close();
	}
	return saveOk;
}

// Open the file
bool GLC_BSRep::open(QIODevice::OpenMode mode)
{
	//qDebug() << "Open :" << m_FileInfo.fileName();
	bool openOk= m_FileInfo.exists();
	if (openOk || (mode == QIODevice::WriteOnly))
	{
		m_DataStream.setDevice(NULL);
		delete m_pFile;
		m_pFile= new QFile(m_FileInfo.filePath());
		openOk= m_pFile->open(mode);
		if (openOk)
		{
			m_DataStream.setDevice(m_pFile);
		}
	}
	else
	{
		qDebug() << "File info " << m_FileInfo.filePath() << " do not exists";
	}
	return openOk;
}

// Close the file
bool GLC_BSRep::close()
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	bool closeOk= m_DataStream.status() == QDataStream::Ok;
	m_DataStream.setDevice(NULL);
	m_pFile->close();
	delete m_pFile;
	m_pFile= NULL;

	return closeOk;
}

// Write the header
void GLC_BSRep::writeHeader(const QDateTime& dateTime)
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::WriteOnly);

	// Binary representation Header
	// Add the magic number
	m_DataStream << m_Uuid;
	// Add the version
	m_DataStream << m_Version;
	// Add the time stamp
	m_DataStream << dateTime;
}

// Check the header
bool GLC_BSRep::headerIsOk()
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);

	QUuid uuid;
	quint32 version;
	m_DataStream >> uuid;
	m_DataStream >> version;

	bool headerOk= (uuid == m_Uuid);
	headerOk= headerOk && (version == m_Version);

	return headerOk;
}

// Check the time Stamp
bool GLC_BSRep::timeStampOk(const QDateTime& timeStamp)
{
	Q_ASSERT(m_pFile != NULL);
	Q_ASSERT(m_DataStream.device() != NULL);
	Q_ASSERT(m_pFile->openMode() == QIODevice::ReadOnly);

	QDateTime dateTime;
	m_DataStream >> dateTime;

	bool timeStampOk= !timeStamp.isValid() || (dateTime == timeStamp);
	return timeStampOk;
}

<|endoftext|>