<commit_before>// Scintilla source code edit control
/** @file XPM.cxx
 ** Define a class that holds data in the X Pixmap (XPM) format.
 **/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <string.h>
#include <stdlib.h>

#include "Platform.h"

#include "XPM.h"

static const char *NextField(const char *s) {
	while (*s && *s != ' ') {
		s++;
	}
	while (*s && *s == ' ') {
		s++;
	}
	return s;
}

// Data lines in XPM can be terminated either with NUL or "
static size_t MeasureLength(const char *s) {
	size_t i = 0;
	while (s[i] && (s[i] != '\"'))
		i++;
	return i;
}

ColourAllocated XPM::ColourFromCode(int ch) {
	return colourCodeTable[ch]->allocated;
#ifdef SLOW
	for (int i=0; i<nColours; i++) {
		if (codes[i] == ch) {
			return colours[i].allocated;
		}
	}
	return colours[0].allocated;
#endif
}

void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
	if ((code != codeTransparent) && (startX != x)) {
		PRectangle rc(startX, y, x, y+1);
		surface->FillRectangle(rc, ColourFromCode(code));
	}
}

XPM::XPM(const char *textForm) :
	data(0), codes(0), colours(0), lines(0) {
	Init(textForm);
}

XPM::XPM(const char * const *linesForm) :
	data(0), codes(0), colours(0), lines(0) {
	Init(linesForm);
}

XPM::~XPM() {
	Clear();
}

void XPM::Init(const char *textForm) {
	Clear();
	// Test done is two parts to avoid possibility of overstepping the memory
	// if memcmp implemented strangely. Must be 4 bytes at least at destination.
	if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
		// Build the lines form out of the text form
		const char **linesForm = LinesFormFromTextForm(textForm);
		Init(linesForm);
		delete []linesForm;
	} else {
		// It is really in line form
		Init(reinterpret_cast<const char * const *>(textForm));
	}
}

void XPM::Init(const char * const *linesForm) {
	Clear();
	height = 1;
	width = 1;
	nColours = 1;
	data = NULL;
	codeTransparent = ' ';
	codes = NULL;
	colours = NULL;
	lines = NULL;
	if (!linesForm)
		return;

	const char *line0 = linesForm[0];
	width = atoi(line0);
	line0 = NextField(line0);
	height = atoi(line0);
	line0 = NextField(line0);
	nColours = atoi(line0);
	codes = new char[nColours];
	colours = new ColourPair[nColours];

	int strings = 1+height+nColours;
	lines = new char *[strings];
	size_t allocation = 0;
	for (int i=0; i<strings; i++) {
		allocation += MeasureLength(linesForm[i]) + 1;
	}
	data = new char[allocation];
	char *nextBit = data;
	for (int j=0; j<strings; j++) {
		lines[j] = nextBit;
		size_t len = MeasureLength(linesForm[j]);
		memcpy(nextBit, linesForm[j], len);
		nextBit += len;
		*nextBit++ = '\0';
	}

	for (int code=0; code<256; code++) {
		colourCodeTable[code] = 0;
	}

	for (int c=0; c<nColours; c++) {
		const char *colourDef = linesForm[c+1];
		codes[c] = colourDef[0];
		colourDef += 4;
		if (*colourDef == '#') {
			colours[c].desired.Set(colourDef);
		} else {
			colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
			codeTransparent = codes[c];
		}
		colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]);
	}
}

void XPM::Clear() {
	delete []data;
	data = 0;
	delete []codes;
	codes = 0;
	delete []colours;
	colours = 0;
	delete []lines;
	lines = 0;
}

void XPM::RefreshColourPalette(Palette &pal, bool want) {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	for (int i=0; i<nColours; i++) {
		pal.WantFind(colours[i], want);
	}
}

void XPM::CopyDesiredColours() {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	for (int i=0; i<nColours; i++) {
		colours[i].Copy();
	}
}

void XPM::Draw(Surface *surface, PRectangle &rc) {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	// Centre the pixmap
	int startY = rc.top + (rc.Height() - height) / 2;
	int startX = rc.left + (rc.Width() - width) / 2;
	for (int y=0;y<height;y++) {
		int prevCode = 0;
		int xStartRun = 0;
		for (int x=0; x<width; x++) {
			int code = lines[y+nColours+1][x];
			if (code != prevCode) {
				FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
				xStartRun = x;
				prevCode = code;
			}
		}
		FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
	}
}

const char **XPM::LinesFormFromTextForm(const char *textForm) {
	// Build the lines form out of the text form
	const char **linesForm = 0;
	int countQuotes = 0;
	int strings=1;
	for (int j=0; countQuotes < (2*strings); j++) {
		if (textForm[j] == '\"') {
			if (countQuotes == 0) {
				const char *line0 = textForm + j + 1;
				// Skip width
				line0 = NextField(line0);
				// Add 1 line for each pixel of height
				strings += atoi(line0);
				line0 = NextField(line0);
				// Add 1 line for each colour
				strings += atoi(line0);
				linesForm = new const char *[strings];
			}
			if (linesForm && ((countQuotes & 1) == 0)) {
				linesForm[countQuotes / 2] = textForm + j + 1;
			}
			countQuotes++;
		}
	}
	return linesForm;
}

// In future, may want to minimize search time by sorting and using a binary search.

XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
}

XPMSet::~XPMSet() {
	Clear();
}

void XPMSet::Clear() {
	for (int i = 0; i < len; i++) {
		delete set[i];
	}
	delete []set;
	set = 0;
	len = 0;
	maximum = 0;
	height = -1;
	width = -1;
}

void XPMSet::Add(int id, const char *textForm) {
	// Invalidate cached dimensions
	height = -1;
	width = -1;

	// Replace if this id already present
	for (int i = 0; i < len; i++) {
		if (set[i]->GetId() == id) {
			set[i]->Init(textForm);
			return;
		}
	}

	// Not present, so add to end
	XPM *pxpm = new XPM(textForm);
	if (pxpm) {
		pxpm->SetId(id);
		pxpm->CopyDesiredColours();
		if (len == maximum) {
			maximum += 64;
			XPM **setNew = new XPM *[maximum];
			for (int i = 0; i < len; i++) {
				setNew[i] = set[i];
			}
			delete []set;
			set = setNew;
		}
		set[len] = pxpm;
		len++;
	}
}

XPM *XPMSet::Get(int id) {
	for (int i = 0; i < len; i++) {
		if (set[i]->GetId() == id) {
			return set[i];
		}
	}
	return 0;
}

int XPMSet::GetHeight() {
	if (height < 0) {
		for (int i = 0; i < len; i++) {
			if (height < set[i]->GetHeight()) {
				height = set[i]->GetHeight();
			}
		}
	}
	return (height > 0) ? height : 0;
}

int XPMSet::GetWidth() {
	if (width < 0) {
		for (int i = 0; i < len; i++) {
			if (width < set[i]->GetWidth()) {
				width = set[i]->GetWidth();
			}
		}
	}
	return (width > 0) ? width : 0;
}
<commit_msg>Patch from Philippe to make decoding safer.<commit_after>// Scintilla source code edit control
/** @file XPM.cxx
 ** Define a class that holds data in the X Pixmap (XPM) format.
 **/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <string.h>
#include <stdlib.h>

#include "Platform.h"

#include "XPM.h"

static const char *NextField(const char *s) {
	// In case there are leading spaces in the string
	while (*s && *s == ' ') {
		s++;
	}
	while (*s && *s != ' ') {
		s++;
	}
	while (*s && *s == ' ') {
		s++;
	}
	return s;
}

// Data lines in XPM can be terminated either with NUL or "
static size_t MeasureLength(const char *s) {
	size_t i = 0;
	while (s[i] && (s[i] != '\"'))
		i++;
	return i;
}

ColourAllocated XPM::ColourFromCode(int ch) {
	return colourCodeTable[ch]->allocated;
#ifdef SLOW
	for (int i=0; i<nColours; i++) {
		if (codes[i] == ch) {
			return colours[i].allocated;
		}
	}
	return colours[0].allocated;
#endif
}

void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
	if ((code != codeTransparent) && (startX != x)) {
		PRectangle rc(startX, y, x, y+1);
		surface->FillRectangle(rc, ColourFromCode(code));
	}
}

XPM::XPM(const char *textForm) :
	data(0), codes(0), colours(0), lines(0) {
	Init(textForm);
}

XPM::XPM(const char * const *linesForm) :
	data(0), codes(0), colours(0), lines(0) {
	Init(linesForm);
}

XPM::~XPM() {
	Clear();
}

void XPM::Init(const char *textForm) {
	Clear();
	// Test done is two parts to avoid possibility of overstepping the memory
	// if memcmp implemented strangely. Must be 4 bytes at least at destination.
	if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
		// Build the lines form out of the text form
		const char **linesForm = LinesFormFromTextForm(textForm);
		if (linesForm != 0) {
			Init(linesForm);
			delete []linesForm;
		}
	} else {
		// It is really in line form
		Init(reinterpret_cast<const char * const *>(textForm));
	}
}

void XPM::Init(const char * const *linesForm) {
	Clear();
	height = 1;
	width = 1;
	nColours = 1;
	data = NULL;
	codeTransparent = ' ';
	codes = NULL;
	colours = NULL;
	lines = NULL;
	if (!linesForm)
		return;

	const char *line0 = linesForm[0];
	width = atoi(line0);
	line0 = NextField(line0);
	height = atoi(line0);
	line0 = NextField(line0);
	nColours = atoi(line0);
	codes = new char[nColours];
	colours = new ColourPair[nColours];

	int strings = 1+height+nColours;
	lines = new char *[strings];
	size_t allocation = 0;
	for (int i=0; i<strings; i++) {
		allocation += MeasureLength(linesForm[i]) + 1;
	}
	data = new char[allocation];
	char *nextBit = data;
	for (int j=0; j<strings; j++) {
		lines[j] = nextBit;
		size_t len = MeasureLength(linesForm[j]);
		memcpy(nextBit, linesForm[j], len);
		nextBit += len;
		*nextBit++ = '\0';
	}

	for (int code=0; code<256; code++) {
		colourCodeTable[code] = 0;
	}

	for (int c=0; c<nColours; c++) {
		const char *colourDef = linesForm[c+1];
		codes[c] = colourDef[0];
		colourDef += 4;
		if (*colourDef == '#') {
			colours[c].desired.Set(colourDef);
		} else {
			colours[c].desired = ColourDesired(0xff, 0xff, 0xff);
			codeTransparent = codes[c];
		}
		colourCodeTable[static_cast<unsigned char>(codes[c])] = &(colours[c]);
	}
}

void XPM::Clear() {
	delete []data;
	data = 0;
	delete []codes;
	codes = 0;
	delete []colours;
	colours = 0;
	delete []lines;
	lines = 0;
}

void XPM::RefreshColourPalette(Palette &pal, bool want) {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	for (int i=0; i<nColours; i++) {
		pal.WantFind(colours[i], want);
	}
}

void XPM::CopyDesiredColours() {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	for (int i=0; i<nColours; i++) {
		colours[i].Copy();
	}
}

void XPM::Draw(Surface *surface, PRectangle &rc) {
	if (!data || !codes || !colours || !lines) {
		return;
	}
	// Centre the pixmap
	int startY = rc.top + (rc.Height() - height) / 2;
	int startX = rc.left + (rc.Width() - width) / 2;
	for (int y=0;y<height;y++) {
		int prevCode = 0;
		int xStartRun = 0;
		for (int x=0; x<width; x++) {
			int code = lines[y+nColours+1][x];
			if (code != prevCode) {
				FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x);
				xStartRun = x;
				prevCode = code;
			}
		}
		FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width);
	}
}

const char **XPM::LinesFormFromTextForm(const char *textForm) {
	// Build the lines form out of the text form
	const char **linesForm = 0;
	int countQuotes = 0;
	int strings=1;
	int j=0;
	for (; countQuotes < (2*strings) && textForm[j] != '\0'; j++) {
		if (textForm[j] == '\"') {
			if (countQuotes == 0) {
				// First field: width, height, number of colors, chars per pixel
				const char *line0 = textForm + j + 1;
				// Skip width
				line0 = NextField(line0);
				// Add 1 line for each pixel of height
				strings += atoi(line0);
				line0 = NextField(line0);
				// Add 1 line for each colour
				strings += atoi(line0);
				linesForm = new const char *[strings];
				if (linesForm == 0) {
					break;	// Memory error!
				}
			}
			if (countQuotes / 2 >= strings) {
				break;	// Bad height or number of colors!
			}
			if ((countQuotes & 1) == 0) {
				linesForm[countQuotes / 2] = textForm + j + 1;
			}
			countQuotes++;
		}
	}
	if (textForm[j] == '\0' || countQuotes / 2 > strings) {
		// Malformed XPM! Height + number of colors too high or too low
		delete []linesForm;
		linesForm = 0;
	}
	return linesForm;
}

// In future, may want to minimize search time by sorting and using a binary search.

XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) {
}

XPMSet::~XPMSet() {
	Clear();
}

void XPMSet::Clear() {
	for (int i = 0; i < len; i++) {
		delete set[i];
	}
	delete []set;
	set = 0;
	len = 0;
	maximum = 0;
	height = -1;
	width = -1;
}

void XPMSet::Add(int id, const char *textForm) {
	// Invalidate cached dimensions
	height = -1;
	width = -1;

	// Replace if this id already present
	for (int i = 0; i < len; i++) {
		if (set[i]->GetId() == id) {
			set[i]->Init(textForm);
			return;
		}
	}

	// Not present, so add to end
	XPM *pxpm = new XPM(textForm);
	if (pxpm) {
		pxpm->SetId(id);
		pxpm->CopyDesiredColours();
		if (len == maximum) {
			maximum += 64;
			XPM **setNew = new XPM *[maximum];
			for (int i = 0; i < len; i++) {
				setNew[i] = set[i];
			}
			delete []set;
			set = setNew;
		}
		set[len] = pxpm;
		len++;
	}
}

XPM *XPMSet::Get(int id) {
	for (int i = 0; i < len; i++) {
		if (set[i]->GetId() == id) {
			return set[i];
		}
	}
	return 0;
}

int XPMSet::GetHeight() {
	if (height < 0) {
		for (int i = 0; i < len; i++) {
			if (height < set[i]->GetHeight()) {
				height = set[i]->GetHeight();
			}
		}
	}
	return (height > 0) ? height : 0;
}

int XPMSet::GetWidth() {
	if (width < 0) {
		for (int i = 0; i < len; i++) {
			if (width < set[i]->GetWidth()) {
				width = set[i]->GetWidth();
			}
		}
	}
	return (width > 0) ? width : 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#if defined(DART_PRECOMPILER)

#include "vm/v8_snapshot_writer.h"

#include "vm/dart.h"
#include "vm/os.h"

namespace dart {

const char* ZoneString(Zone* Z, const char* str) {
  const intptr_t len = strlen(str) + 1;
  char* dest = Z->Alloc<char>(len);
  snprintf(dest, len, "%s", str);
  return dest;
}

V8SnapshotProfileWriter::V8SnapshotProfileWriter(Zone* zone)
    : zone_(zone),
      node_types_(zone_),
      edge_types_(zone_),
      strings_(zone),
      roots_(zone_, 100) {
  node_types_.Insert({"Unknown", kUnknown});
  node_types_.Insert({"ArtificialRoot", kArtificialRoot});

  edge_types_.Insert({"context", kContext});
  edge_types_.Insert({"element", kElement});
  edge_types_.Insert({"property", kProperty});
  edge_types_.Insert({"internal", kInternal});
  edge_types_.Insert({"hidden", kHidden});
  edge_types_.Insert({"shortcut", kShortcut});
  edge_types_.Insert({"weak", kWeak});
  edge_types_.Insert({"extra", kExtra});

  strings_.Insert({"<unknown>", kUnknownString});
  strings_.Insert({"<object>", kObjectString});
  strings_.Insert({"<property>", kPropertyString});
  strings_.Insert({"<artificial root>", kArtificialRootString});
}

void V8SnapshotProfileWriter::SetObjectTypeAndName(ObjectId object_id,
                                                   const char* type,
                                                   const char* name) {
  ASSERT(type != nullptr);
  NodeInfo* info = EnsureId(object_id);

  if (!node_types_.HasKey(type)) {
    node_types_.Insert({ZoneString(zone_, type), node_types_.Size()});
  }

  intptr_t type_id = node_types_.LookupValue(type);
  ASSERT(info->type == kUnknown || info->type == type_id);
  info->type = type_id;

  if (name != nullptr) {
    info->name = EnsureString(OS::SCreate(zone_, "[%s] %s", type, name));
  } else {
    info->name = EnsureString(type);
  }
}

void V8SnapshotProfileWriter::AttributeBytesTo(ObjectId object_id,
                                               size_t num_bytes) {
  EnsureId(object_id)->self_size += num_bytes;
}

void V8SnapshotProfileWriter::AttributeReferenceTo(ObjectId object_id,
                                                   Reference reference) {
  EnsureId(reference.to_object_id);
  NodeInfo* info = EnsureId(object_id);

  ASSERT(reference.offset_or_name >= 0);
  info->edges->Add({
      reference.reference_type == Reference::kElement ? kElement : kProperty,
      reference.offset_or_name,
      reference.to_object_id,
  });
  ++edge_count_;
}

V8SnapshotProfileWriter::NodeInfo V8SnapshotProfileWriter::DefaultNode(
    ObjectId object_id) {
  return {
      kUnknown,
      kUnknownString,
      object_id,
      0,
      new (zone_) ZoneGrowableArray<EdgeInfo>(zone_, 0),
      -1,
  };
}

V8SnapshotProfileWriter::NodeInfo V8SnapshotProfileWriter::ArtificialRoot() {
  return {
      kArtificialRoot, kArtificialRootString, {kArtificial, 0}, 0, nullptr, 0,
  };
}

V8SnapshotProfileWriter::NodeInfo* V8SnapshotProfileWriter::EnsureId(
    ObjectId object_id) {
  if (!nodes_.HasKey(object_id)) {
    NodeInfo info = DefaultNode(object_id);
    nodes_.Insert({object_id, info});
  }
  return &nodes_.Lookup(object_id)->value;
}

intptr_t V8SnapshotProfileWriter::EnsureString(const char* str) {
  if (!strings_.HasKey(str)) {
    strings_.Insert({ZoneString(zone_, str), strings_.Size()});
    return strings_.Size() - 1;
  }
  return strings_.LookupValue(str);
}

void V8SnapshotProfileWriter::WriteNodeInfo(JSONWriter* writer,
                                            const NodeInfo& info) {
  writer->PrintValue(info.type);
  writer->PrintValue(info.name);
  writer->PrintValue(NodeIdFor(info.id));
  writer->PrintValue(info.self_size);
  // The artificial root has 'nullptr' edges, it actually points to all the
  // roots.
  writer->PrintValue64(info.edges != nullptr ? info.edges->length()
                                             : roots_.length());
  writer->PrintNewline();
}

void V8SnapshotProfileWriter::WriteEdgeInfo(JSONWriter* writer,
                                            const EdgeInfo& info) {
  writer->PrintValue64(info.type);
  writer->PrintValue64(info.name_or_index);
  writer->PrintValue64(nodes_.LookupValue(info.to_node).offset);
  writer->PrintNewline();
}

void V8SnapshotProfileWriter::AddRoot(ObjectId object_id) {
  EnsureId(object_id);
  roots_.Add(object_id);
}

void V8SnapshotProfileWriter::WriteStringsTable(
    JSONWriter* writer,
    const DirectChainedHashMap<StringToIntMapTraits>& map) {
  const char** strings = zone_->Alloc<const char*>(map.Size());
  StringToIntMapTraits::Pair* pair = nullptr;
  auto it = map.GetIterator();
  while ((pair = it.Next()) != nullptr) {
    ASSERT(pair->value >= 0 && pair->value < map.Size());
    strings[pair->value] = pair->key;
  }
  for (intptr_t i = 0; i < map.Size(); ++i) {
    writer->PrintValue(strings[i]);
    writer->PrintNewline();
  }
}

void V8SnapshotProfileWriter::Write(JSONWriter* writer) {
  writer->OpenObject();

  writer->OpenObject("snapshot");
  {
    writer->OpenObject("meta");

    {
      writer->OpenArray("node_fields");
      writer->PrintValue("type");
      writer->PrintValue("name");
      writer->PrintValue("id");
      writer->PrintValue("self_size");
      writer->PrintValue("edge_count");
      writer->CloseArray();
    }

    {
      writer->OpenArray("node_types");
      {
        writer->OpenArray();
        WriteStringsTable(writer, node_types_);
        writer->CloseArray();
      }
      writer->CloseArray();
    }

    {
      writer->OpenArray("edge_fields");
      writer->PrintValue("type");
      writer->PrintValue("name_or_index");
      writer->PrintValue("to_node");
      writer->CloseArray();
    }

    {
      writer->OpenArray("edge_types");
      {
        writer->OpenArray();
        WriteStringsTable(writer, edge_types_);
        writer->CloseArray();
      }
      writer->CloseArray();
    }

    writer->CloseObject();

    writer->PrintProperty64("node_count",
                            nodes_.Size() + 1 /* artificial root */);
    writer->PrintProperty64("edge_count", edge_count_ + roots_.length());
  }
  writer->CloseObject();

  {
    writer->OpenArray("nodes");
    // Write the artificial root node.
    WriteNodeInfo(writer, ArtificialRoot());
    intptr_t offset = kNumNodeFields;
    ObjectIdToNodeInfoTraits::Pair* entry = nullptr;
    auto it = nodes_.GetIterator();
    while ((entry = it.Next()) != nullptr) {
      ASSERT(entry->key == entry->value.id);
      entry->value.offset = offset;
      WriteNodeInfo(writer, entry->value);
      offset += kNumNodeFields;
    }
    writer->CloseArray();
  }

  {
    writer->OpenArray("edges");

    // Write references from the artificial root to the actual roots.
    for (intptr_t i = 0; i < roots_.length(); ++i) {
      WriteEdgeInfo(writer, {kElement, i, roots_[i]});
    }

    ObjectIdToNodeInfoTraits::Pair* entry = nullptr;
    auto it = nodes_.GetIterator();
    while ((entry = it.Next()) != nullptr) {
      for (intptr_t i = 0; i < entry->value.edges->length(); ++i) {
        WriteEdgeInfo(writer, entry->value.edges->At(i));
      }
    }

    writer->CloseArray();
  }

  {
    writer->OpenArray("strings");
    WriteStringsTable(writer, strings_);
    writer->CloseArray();
  }

  writer->CloseObject();
}

void V8SnapshotProfileWriter::Write(const char* filename) {
  JSONWriter json;
  Write(&json);

  auto file_open = Dart::file_open_callback();
  auto file_write = Dart::file_write_callback();
  auto file_close = Dart::file_close_callback();
  if ((file_open == nullptr) || (file_write == nullptr) ||
      (file_close == nullptr)) {
    OS::PrintErr("Could not access file callbacks to write snapshot profile.");
    return;
  }

  auto file = file_open(filename, /*write=*/true);
  if (file == nullptr) {
    OS::PrintErr("Failed to open file %s\n", filename);
  } else {
    char* output = nullptr;
    intptr_t output_length = 0;
    json.Steal(&output, &output_length);
    file_write(output, output_length, file);
    free(output);
    file_close(file);
  }
}

}  // namespace dart

#endif
<commit_msg>Fix SDK build on Mac.<commit_after>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#if defined(DART_PRECOMPILER)

#include "vm/v8_snapshot_writer.h"

#include "vm/dart.h"
#include "vm/os.h"

namespace dart {

const char* ZoneString(Zone* Z, const char* str) {
  const intptr_t len = strlen(str) + 1;
  char* dest = Z->Alloc<char>(len);
  snprintf(dest, len, "%s", str);
  return dest;
}

V8SnapshotProfileWriter::V8SnapshotProfileWriter(Zone* zone)
    : zone_(zone),
      node_types_(zone_),
      edge_types_(zone_),
      strings_(zone),
      roots_(zone_, 100) {
  node_types_.Insert({"Unknown", kUnknown});
  node_types_.Insert({"ArtificialRoot", kArtificialRoot});

  edge_types_.Insert({"context", kContext});
  edge_types_.Insert({"element", kElement});
  edge_types_.Insert({"property", kProperty});
  edge_types_.Insert({"internal", kInternal});
  edge_types_.Insert({"hidden", kHidden});
  edge_types_.Insert({"shortcut", kShortcut});
  edge_types_.Insert({"weak", kWeak});
  edge_types_.Insert({"extra", kExtra});

  strings_.Insert({"<unknown>", kUnknownString});
  strings_.Insert({"<object>", kObjectString});
  strings_.Insert({"<property>", kPropertyString});
  strings_.Insert({"<artificial root>", kArtificialRootString});
}

void V8SnapshotProfileWriter::SetObjectTypeAndName(ObjectId object_id,
                                                   const char* type,
                                                   const char* name) {
  ASSERT(type != nullptr);
  NodeInfo* info = EnsureId(object_id);

  if (!node_types_.HasKey(type)) {
    node_types_.Insert({ZoneString(zone_, type), node_types_.Size()});
  }

  intptr_t type_id = node_types_.LookupValue(type);
  ASSERT(info->type == kUnknown || info->type == type_id);
  info->type = type_id;

  if (name != nullptr) {
    info->name = EnsureString(OS::SCreate(zone_, "[%s] %s", type, name));
  } else {
    info->name = EnsureString(type);
  }
}

void V8SnapshotProfileWriter::AttributeBytesTo(ObjectId object_id,
                                               size_t num_bytes) {
  EnsureId(object_id)->self_size += num_bytes;
}

void V8SnapshotProfileWriter::AttributeReferenceTo(ObjectId object_id,
                                                   Reference reference) {
  EnsureId(reference.to_object_id);
  NodeInfo* info = EnsureId(object_id);

  ASSERT(reference.offset_or_name >= 0);
  info->edges->Add({
      static_cast<intptr_t>(reference.reference_type == Reference::kElement
                                ? kElement
                                : kProperty),
      reference.offset_or_name,
      reference.to_object_id,
  });
  ++edge_count_;
}

V8SnapshotProfileWriter::NodeInfo V8SnapshotProfileWriter::DefaultNode(
    ObjectId object_id) {
  return {
      kUnknown,
      kUnknownString,
      object_id,
      0,
      new (zone_) ZoneGrowableArray<EdgeInfo>(zone_, 0),
      -1,
  };
}

V8SnapshotProfileWriter::NodeInfo V8SnapshotProfileWriter::ArtificialRoot() {
  return {
      kArtificialRoot, kArtificialRootString, {kArtificial, 0}, 0, nullptr, 0,
  };
}

V8SnapshotProfileWriter::NodeInfo* V8SnapshotProfileWriter::EnsureId(
    ObjectId object_id) {
  if (!nodes_.HasKey(object_id)) {
    NodeInfo info = DefaultNode(object_id);
    nodes_.Insert({object_id, info});
  }
  return &nodes_.Lookup(object_id)->value;
}

intptr_t V8SnapshotProfileWriter::EnsureString(const char* str) {
  if (!strings_.HasKey(str)) {
    strings_.Insert({ZoneString(zone_, str), strings_.Size()});
    return strings_.Size() - 1;
  }
  return strings_.LookupValue(str);
}

void V8SnapshotProfileWriter::WriteNodeInfo(JSONWriter* writer,
                                            const NodeInfo& info) {
  writer->PrintValue(info.type);
  writer->PrintValue(info.name);
  writer->PrintValue(NodeIdFor(info.id));
  writer->PrintValue(info.self_size);
  // The artificial root has 'nullptr' edges, it actually points to all the
  // roots.
  writer->PrintValue64(info.edges != nullptr ? info.edges->length()
                                             : roots_.length());
  writer->PrintNewline();
}

void V8SnapshotProfileWriter::WriteEdgeInfo(JSONWriter* writer,
                                            const EdgeInfo& info) {
  writer->PrintValue64(info.type);
  writer->PrintValue64(info.name_or_index);
  writer->PrintValue64(nodes_.LookupValue(info.to_node).offset);
  writer->PrintNewline();
}

void V8SnapshotProfileWriter::AddRoot(ObjectId object_id) {
  EnsureId(object_id);
  roots_.Add(object_id);
}

void V8SnapshotProfileWriter::WriteStringsTable(
    JSONWriter* writer,
    const DirectChainedHashMap<StringToIntMapTraits>& map) {
  const char** strings = zone_->Alloc<const char*>(map.Size());
  StringToIntMapTraits::Pair* pair = nullptr;
  auto it = map.GetIterator();
  while ((pair = it.Next()) != nullptr) {
    ASSERT(pair->value >= 0 && pair->value < map.Size());
    strings[pair->value] = pair->key;
  }
  for (intptr_t i = 0; i < map.Size(); ++i) {
    writer->PrintValue(strings[i]);
    writer->PrintNewline();
  }
}

void V8SnapshotProfileWriter::Write(JSONWriter* writer) {
  writer->OpenObject();

  writer->OpenObject("snapshot");
  {
    writer->OpenObject("meta");

    {
      writer->OpenArray("node_fields");
      writer->PrintValue("type");
      writer->PrintValue("name");
      writer->PrintValue("id");
      writer->PrintValue("self_size");
      writer->PrintValue("edge_count");
      writer->CloseArray();
    }

    {
      writer->OpenArray("node_types");
      {
        writer->OpenArray();
        WriteStringsTable(writer, node_types_);
        writer->CloseArray();
      }
      writer->CloseArray();
    }

    {
      writer->OpenArray("edge_fields");
      writer->PrintValue("type");
      writer->PrintValue("name_or_index");
      writer->PrintValue("to_node");
      writer->CloseArray();
    }

    {
      writer->OpenArray("edge_types");
      {
        writer->OpenArray();
        WriteStringsTable(writer, edge_types_);
        writer->CloseArray();
      }
      writer->CloseArray();
    }

    writer->CloseObject();

    writer->PrintProperty64("node_count",
                            nodes_.Size() + 1 /* artificial root */);
    writer->PrintProperty64("edge_count", edge_count_ + roots_.length());
  }
  writer->CloseObject();

  {
    writer->OpenArray("nodes");
    // Write the artificial root node.
    WriteNodeInfo(writer, ArtificialRoot());
    intptr_t offset = kNumNodeFields;
    ObjectIdToNodeInfoTraits::Pair* entry = nullptr;
    auto it = nodes_.GetIterator();
    while ((entry = it.Next()) != nullptr) {
      ASSERT(entry->key == entry->value.id);
      entry->value.offset = offset;
      WriteNodeInfo(writer, entry->value);
      offset += kNumNodeFields;
    }
    writer->CloseArray();
  }

  {
    writer->OpenArray("edges");

    // Write references from the artificial root to the actual roots.
    for (intptr_t i = 0; i < roots_.length(); ++i) {
      WriteEdgeInfo(writer, {kElement, i, roots_[i]});
    }

    ObjectIdToNodeInfoTraits::Pair* entry = nullptr;
    auto it = nodes_.GetIterator();
    while ((entry = it.Next()) != nullptr) {
      for (intptr_t i = 0; i < entry->value.edges->length(); ++i) {
        WriteEdgeInfo(writer, entry->value.edges->At(i));
      }
    }

    writer->CloseArray();
  }

  {
    writer->OpenArray("strings");
    WriteStringsTable(writer, strings_);
    writer->CloseArray();
  }

  writer->CloseObject();
}

void V8SnapshotProfileWriter::Write(const char* filename) {
  JSONWriter json;
  Write(&json);

  auto file_open = Dart::file_open_callback();
  auto file_write = Dart::file_write_callback();
  auto file_close = Dart::file_close_callback();
  if ((file_open == nullptr) || (file_write == nullptr) ||
      (file_close == nullptr)) {
    OS::PrintErr("Could not access file callbacks to write snapshot profile.");
    return;
  }

  auto file = file_open(filename, /*write=*/true);
  if (file == nullptr) {
    OS::PrintErr("Failed to open file %s\n", filename);
  } else {
    char* output = nullptr;
    intptr_t output_length = 0;
    json.Steal(&output, &output_length);
    file_write(output, output_length, file);
    free(output);
    file_close(file);
  }
}

}  // namespace dart

#endif
<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>
#include <termios.h>
#include <sys/ioctl.h>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>
#include <map>
#include <functional>
#include <experimental/optional>

#include "History.hpp"
#include "TerminalInfo.hpp"

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

// https://www.akkadia.org/drepper/tls.pdf

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::string printBuffer;
thread_local std::string::iterator printBufferPos;

using namespace yb;
thread_local History history;
thread_local History::const_iterator historyPos;

static char arrowIndicator = 0;

using ReadSignature = ssize_t (*)(int, void*, size_t);
using Char = unsigned char;
using CharOpt = std::experimental::optional<Char>;

CharOpt newlineHandler(Char);
CharOpt tabHandler(Char);
CharOpt backspaceHandler(Char);
CharOpt regularCHarHandler(Char);
CharOpt arrowHandler1(Char);
CharOpt arrowHandler2(Char);
CharOpt arrowHandler3(Char);

thread_local std::map<Char, std::function<CharOpt(Char)>> handlers = {
    {0x06, tabHandler},
    {0x0d, newlineHandler},
    {0x17, newlineHandler}, // TODO: this should delete one word
    {0x1b, arrowHandler1},
    {0x5b, arrowHandler2},
    {0x43, arrowHandler3},
    {0x7f, backspaceHandler}
};

void clearTerminalLine() {
    int pos, width;
    if (!(pos = TerminalInfo::getCursorPosition())) return;
    width = TerminalInfo::getWidth();
    for (int i = 0; i < width - pos; i++)
        printf(" ");
    fflush(stdout);
    for (int i = 0; i < width - pos; i++)
        cursor_backward(1);
}

std::string findCompletion(History::const_iterator start, const std::string &pattern) {
    for (auto it = start - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0) {
            historyPos = it;
            return *it;
        }
    }

    historyPos = history.end();
    return pattern;
}

void printCompletion(History::const_iterator startIterator, int offset) {
    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(startIterator, pattern);

    clearTerminalLine();

    if (offset)
        cursor_forward(offset);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());

    cursor_backward(completion.length() - pattern.length() + offset);
    fflush(stdout);
}

CharOpt newlineHandler(Char) {
    lineBuffer.fill(0);
    lineBufferPos = lineBuffer.begin();
    return {};
}

CharOpt backspaceHandler(Char) {
    if (lineBufferPos != lineBuffer.begin()) {
        *(--lineBufferPos) = 0;
    }

    return {};
}

CharOpt regularCharHandler(Char c) {
    *lineBufferPos = c;
    lineBufferPos++;

    printCompletion(history.end(), 1);

    return {};
}

CharOpt tabHandler(Char) {
    printCompletion(historyPos, 0);
    return Char{0}; // TODO: this does not seem to work.
}

CharOpt arrowHandler1(Char) {
    arrowIndicator = 1;
    return {};
}

CharOpt arrowHandler2(Char c) {
    if (arrowIndicator == 1) {
        arrowIndicator = 2;
        return {};
    }
    else {
        return regularCharHandler(c);
    }
}

CharOpt arrowHandler3(Char c) {
    CharOpt return_value = {};
    if (arrowIndicator == 2) {
        arrowIndicator = 0;
    }
    else {
        return_value = regularCharHandler(c);
    }
    try {
        printBuffer = historyPos->substr(lineBufferPos - lineBuffer.begin());
        printBufferPos = printBuffer.begin();
    } catch (...) {
        // FIXME:
    }

    return return_value;
}

static unsigned char yebash(unsigned char c) {

    // TODO: uncomment later
    //if (!getenv("YEBASH"))
    //    return;
    history.read(std::string{getenv("HOME")} + "/.bash_history");

    auto handler = handlers[c];

    // TODO(Mrokkk): There would be a problem with processing all escape codes
    // that bash is using (e.g. ctrl+r for history searching, arrows for moving, etc.).
    // It would be thoughtful if we just disable our yebash if any of these codes would
    // occur and reenable it after a newline
    CharOpt cReturned;

    if (handler) {
        cReturned = handler(c);
    }
    else {
        if (c < 0x20) {
            newlineHandler(c);
        }
        else {
            regularCharHandler(c);
        }
    }

    return cReturned.value_or(c);

}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;
    static thread_local ReadSignature realRead = nullptr;

    if (fd == 0) { // TODO: make it look good
        if (printBuffer.length()) {
            // Return printBuffer to bash one char at time
            *reinterpret_cast<char *>(buf) = *printBufferPos;
            *lineBufferPos++ =  *printBufferPos++;
            if (printBufferPos == printBuffer.end()) {
                printBuffer.erase(printBuffer.begin(), printBuffer.end());
            }
            return 1;
        }
    }

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0 && isatty(fileno(stdin)))
        *reinterpret_cast<unsigned char *>(buf) = yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;
}

<commit_msg>Some minor changes<commit_after>#include <dlfcn.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cstdlib>

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>
#include <map>
#include <functional>
#include <experimental/optional>

#include "History.hpp"
#include "TerminalInfo.hpp"

#define cursor_forward(x) printf("\033[%dC", static_cast<int>(x))
#define cursor_backward(x) printf("\033[%dD", static_cast<int>(x))

// https://www.akkadia.org/drepper/tls.pdf

using namespace yb;

thread_local std::array<char, 1024> lineBuffer;
thread_local auto lineBufferPos = lineBuffer.begin();

thread_local std::string printBuffer;
thread_local std::string::iterator printBufferPos;

thread_local History history;
thread_local History::const_iterator historyPos;

static char arrowIndicator = 0;

using ReadSignature = ssize_t (*)(int, void*, size_t);
using Char = unsigned char;
using CharOpt = std::experimental::optional<Char>;

CharOpt newlineHandler(Char);
CharOpt tabHandler(Char);
CharOpt backspaceHandler(Char);
CharOpt regularCHarHandler(Char);
CharOpt arrowHandler1(Char);
CharOpt arrowHandler2(Char);
CharOpt arrowHandler3(Char);

thread_local std::map<Char, std::function<CharOpt(Char)>> handlers = {
    {0x06, tabHandler},
    {0x0d, newlineHandler},
    {0x17, newlineHandler}, // TODO: this should delete one word
    {0x1b, arrowHandler1},
    {0x5b, arrowHandler2},
    {0x43, arrowHandler3},
    {0x7f, backspaceHandler}
};

void clearTerminalLine() {
    int pos, width;
    if (!(pos = TerminalInfo::getCursorPosition())) return;
    width = TerminalInfo::getWidth();
    for (int i = 0; i < width - pos; i++)
        printf(" ");
    fflush(stdout);
    for (int i = 0; i < width - pos; i++)
        cursor_backward(1);
}

std::string findCompletion(History::const_iterator start, const std::string &pattern) {
    for (auto it = start - 1; it > history.begin(); it--) {
        if (it->compare(0, pattern.length(), pattern) == 0) {
            historyPos = it;
            return *it;
        }
    }

    historyPos = history.end();
    return pattern;
}

void printCompletion(History::const_iterator startIterator, int offset) {
    std::string pattern(lineBuffer.data());
    auto completion = findCompletion(startIterator, pattern);

    clearTerminalLine();

    if (offset)
        cursor_forward(offset);
    printf("\e[1;30m%s\e[0m", completion.c_str() + pattern.length());

    cursor_backward(completion.length() - pattern.length() + offset);
    fflush(stdout);
}

CharOpt newlineHandler(Char) {
    lineBuffer.fill(0);
    lineBufferPos = lineBuffer.begin();
    return {};
}

CharOpt backspaceHandler(Char) {
    if (lineBufferPos != lineBuffer.begin()) {
        *(--lineBufferPos) = 0;
    }

    return {};
}

CharOpt regularCharHandler(Char c) {
    *lineBufferPos = c;
    lineBufferPos++;

    printCompletion(history.end(), 1);

    return {};
}

CharOpt tabHandler(Char) {
    printCompletion(historyPos, 0);
    return Char{0}; // TODO: this does not seem to work.
}

CharOpt arrowHandler1(Char) {
    arrowIndicator = 1;
    return {};
}

CharOpt arrowHandler2(Char c) {
    if (arrowIndicator == 1) {
        arrowIndicator = 2;
        return {};
    }
    else {
        return regularCharHandler(c);
    }
}

CharOpt arrowHandler3(Char c) {
    CharOpt return_value = {};
    if (arrowIndicator == 2) {
        arrowIndicator = 0;
    }
    else {
        return_value = regularCharHandler(c);
    }
    try {
        printBuffer = historyPos->substr(lineBufferPos - lineBuffer.begin());
        printBufferPos = printBuffer.begin();
    } catch (...) {
        // FIXME:
    }

    return return_value;
}

static unsigned char yebash(unsigned char c) {

    // TODO: uncomment later
    //if (!getenv("YEBASH"))
    //    return;
    history.read(std::string{getenv("HOME")} + "/.bash_history");

    auto handler = handlers[c];

    // TODO(Mrokkk): There would be a problem with processing all escape codes
    // that bash is using (e.g. ctrl+r for history searching, arrows for moving, etc.).
    // It would be thoughtful if we just disable our yebash if any of these codes would
    // occur and reenable it after a newline
    CharOpt cReturned;

    if (handler) {
        cReturned = handler(c);
    }
    else {
        if (c < 0x20) {
            newlineHandler(c);
        }
        else {
            regularCharHandler(c);
        }
    }

    return cReturned.value_or(c);

}

ssize_t read(int fd, void *buf, size_t count) {

    ssize_t returnValue;
    static thread_local ReadSignature realRead = nullptr;

    if (fd == 0) { // TODO: make it look good
        if (printBuffer.length()) {
            // Return printBuffer to bash one char at time
            *reinterpret_cast<char *>(buf) = *printBufferPos;
            *lineBufferPos++ =  *printBufferPos++;
            if (printBufferPos == printBuffer.end()) {
                printBuffer.erase(printBuffer.begin(), printBuffer.end());
            }
            return 1;
        }
    }

    if (!realRead)
        realRead = reinterpret_cast<ReadSignature>(dlsym(RTLD_NEXT, "read"));

    returnValue = realRead(fd, buf, count);

    if (fd == 0 && isatty(fileno(stdin)))
        *reinterpret_cast<unsigned char *>(buf) = yebash(*reinterpret_cast<unsigned char *>(buf));

    return returnValue;
}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "robot_utils/ros_thread_image.h"

class ROSThreadImageTester
{
    ros::NodeHandle nh;
    std::string   name;

    image_transport::ImageTransport   it;
    image_transport::Publisher image_pub;

public:
    explicit ROSThreadImageTester(std::string _name = "test") : name(_name), it(nh)
    {
        image_pub = it.advertise("/"+name+"/image", 1);
    }

    void sendTestImage()
    {
        // Let's create a 200x200 black image with a red circle in the center
        cv::Mat img(200, 200, CV_8UC3, cv::Scalar(0,0,0));
        cv::circle(img, cv::Point(100, 100), 20, CV_RGB(255,0,0), -1);

        // Publish the image
        sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", img).toImageMsg();
        image_pub.publish(msg);
    }

    ~ROSThreadImageTester() {}
};

class ROSImageInstance: public ROSThreadImage
{
private:
    cv::Point avg_coords;

public:
    explicit ROSImageInstance(std::string _name): ROSThreadImage(_name)
    {
        avg_coords = cv::Point(-1,-1);
        startThread();
    }

    void InternalThreadEntry()
    {
        while(ros::ok() && not isClosing())
        {
            cv::Mat img_in;

            if (not _img_empty)
            {
                // ROS_INFO("Processing image");
                {
                    std::lock_guard<std::mutex> lock(mutex_img);
                    img_in=_curr_img;
                }

                // Convert image to black and white
                cv::Mat gray;
                cv::cvtColor(img_in, gray, CV_BGR2GRAY);

                // Find contours
                std::vector<std::vector<cv::Point>> contours;
                findContours(gray, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0,0));

                // Finds the moments
                std::vector<cv::Moments> mu(contours.size() );
                for(size_t i = 0; i < contours.size(); i++ )
                {
                    mu[i] = moments(contours[i], false );
                }

                // Finds the centroid
                std::vector<cv::Point2f> mc(contours.size());
                for( size_t i = 0; i < contours.size(); i++ )
                {
                    mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
                    avg_coords.x = mu[i].m10/mu[i].m00;
                    avg_coords.y = mu[i].m01/mu[i].m00;
                }

                break;
            }
            r.sleep();
        }
    }

    //Self explaining return methods
    cv::Point centroid() {return avg_coords; }

};

TEST(rosimagetest, testinternalthreadentry)
{
    // Creates an object that sends a 200x200 black image with a red circle overlaid
    ROSThreadImageTester rtit("test");

    // Creates an object responsible for receiving an image
    // and finding the centroid of a contour
    ROSImageInstance rtii("test");

    // Sends a 200x200 image with a red circle overlayed in the middle
    rtit.sendTestImage();

    // Waits so that threads can finish
    ros::Rate rate(100);

    while(ros::ok() && (rtii.centroid() == cv::Point(-1,-1)))
    {
        // ROS_INFO("Waiting for ROSThreadImage loop. [x y]: [%i %i]",
        //                  rtii.centroid().x, rtii.centroid(),y);
        rate.sleep();
    }

    // Checks that x and y coordinates are correct against expected values
    EXPECT_EQ(rtii.centroid(), cv::Point(100, 100));
}

// Run all the tests that were declared with TEST()
int main(int argc, char **argv)
{
    ros::init(argc, argv, "ros_thread_test");
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<commit_msg>Minor<commit_after>#include <gtest/gtest.h>
#include "robot_utils/ros_thread_image.h"

class ROSThreadImageTester
{
    ros::NodeHandle nh;
    std::string   name;

    image_transport::ImageTransport   it;
    image_transport::Publisher image_pub;

public:
    explicit ROSThreadImageTester(std::string _name = "test") : name(_name), it(nh)
    {
        image_pub = it.advertise("/"+name+"/image", 1);
    }

    void sendTestImage()
    {
        // Let's create a 200x200 black image with a red circle in the center
        cv::Mat img(200, 200, CV_8UC3, cv::Scalar(0,0,0));
        cv::circle(img, cv::Point(100, 100), 20, CV_RGB(255,0,0), -1);

        // Publish the image
        sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", img).toImageMsg();
        image_pub.publish(msg);
    }

    ~ROSThreadImageTester() {}
};

class ROSThreadImageInstance: public ROSThreadImage
{
private:
    cv::Point avg_coords;

public:
    explicit ROSThreadImageInstance(std::string _name): ROSThreadImage(_name)
    {
        avg_coords = cv::Point(-1,-1);
        startThread();
    }

    void InternalThreadEntry()
    {
        while(ros::ok() && not isClosing())
        {
            cv::Mat img_in;

            if (not _img_empty)
            {
                // ROS_INFO("Processing image");
                {
                    std::lock_guard<std::mutex> lock(mutex_img);
                    img_in=_curr_img;
                }

                // Convert image to black and white
                cv::Mat gray;
                cv::cvtColor(img_in, gray, CV_BGR2GRAY);

                // Find contours
                std::vector<std::vector<cv::Point>> contours;
                findContours(gray, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0,0));

                // Finds the moments
                std::vector<cv::Moments> mu(contours.size() );
                for(size_t i = 0; i < contours.size(); i++ )
                {
                    mu[i] = moments(contours[i], false );
                }

                // Finds the centroid
                std::vector<cv::Point2f> mc(contours.size());
                for( size_t i = 0; i < contours.size(); i++ )
                {
                    mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 );
                    avg_coords.x = mu[i].m10/mu[i].m00;
                    avg_coords.y = mu[i].m01/mu[i].m00;
                }

                break;
            }
            r.sleep();
        }
    }

    //Self explaining return methods
    cv::Point centroid() {return avg_coords; }

};

TEST(rosimagetest, testinternalthreadentry)
{
    // Creates an object that sends a 200x200 black image with a red circle overlaid
    ROSThreadImageTester rtit("test");

    // Creates an object responsible for receiving an image
    // and finding the centroid of a contour
    ROSThreadImageInstance rtii("test");

    // Sends a 200x200 image with a red circle overlayed in the middle
    rtit.sendTestImage();

    // Waits so that threads can finish
    ros::Rate rate(100);

    while(ros::ok() && (rtii.centroid() == cv::Point(-1,-1)))
    {
        // ROS_INFO("Waiting for ROSThreadImage loop. [x y]: [%i %i]",
        //                  rtii.centroid().x, rtii.centroid(),y);
        rate.sleep();
    }

    // Checks that x and y coordinates are correct against expected values
    EXPECT_EQ(rtii.centroid(), cv::Point(100, 100));
}

// Run all the tests that were declared with TEST()
int main(int argc, char **argv)
{
    ros::init(argc, argv, "ros_thread_test");
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011, Blender Foundation.
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <Python.h>

#include "blender_sync.h"
#include "blender_session.h"

#include "util_opengl.h"
#include "util_path.h"

CCL_NAMESPACE_BEGIN

static PyObject *init_func(PyObject *self, PyObject *args)
{
	const char *path;

	if(!PyArg_ParseTuple(args, "s", &path))
		return NULL;

	path_init(path);

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *create_func(PyObject *self, PyObject *args)
{
	PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;

	if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
		return NULL;

	/* RNA */
	PointerRNA engineptr;
	RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
	BL::RenderEngine engine(engineptr);

	PointerRNA dataptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
	BL::BlendData data(dataptr);

	PointerRNA sceneptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
	BL::Scene scene(sceneptr);

	PointerRNA regionptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyregion), &regionptr);
	BL::Region region(regionptr);

	PointerRNA v3dptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyv3d), &v3dptr);
	BL::SpaceView3D v3d(v3dptr);

	PointerRNA rv3dptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyrv3d), &rv3dptr);
	BL::RegionView3D rv3d(rv3dptr);

	/* create session */
	BlenderSession *session;

	if(rv3d) {
		/* interactive session */
		int width = region.width();
		int height = region.height();

		session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height);
	}
	else {
		/* offline session */
		session = new BlenderSession(engine, data, scene);
	}

	return PyLong_FromVoidPtr(session);
}

static PyObject *free_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	delete (BlenderSession*)PyLong_AsVoidPtr(pysession);

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *render_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	Py_BEGIN_ALLOW_THREADS

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
	session->render();

	Py_END_ALLOW_THREADS

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *draw_func(PyObject *self, PyObject *args)
{
	PyObject *pysession, *pyv3d, *pyrv3d;

	if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
		return NULL;

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);

	bool draw_text = false;

	if(PyLong_AsVoidPtr(pyrv3d)) {
		/* 3d view drawing */
		int viewport[4];
		glGetIntegerv(GL_VIEWPORT, viewport);

		draw_text = session->draw(viewport[2], viewport[3]);
	}
	else {
		/* image editor drawing */
		draw_text = session->draw();
	}

	/* draw */
	PyObject *ret = PyTuple_New(2);

	if(!draw_text) {
		PyTuple_SetItem(ret, 0, PyUnicode_FromString(""));
		PyTuple_SetItem(ret, 1, PyUnicode_FromString(""));
	}
	else {
		string status, substatus;

		session->get_status(status, substatus);

		PyTuple_SetItem(ret, 0, PyUnicode_FromString(status.c_str()));
		PyTuple_SetItem(ret, 1, PyUnicode_FromString(substatus.c_str()));
	}

	return ret;
}

static PyObject *sync_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
	session->synchronize();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *available_devices_func(PyObject *self, PyObject *args)
{
	vector<DeviceType> types = Device::available_types();

	PyObject *ret = PyTuple_New(types.size());

	for(size_t i = 0; i < types.size(); i++) {
		string name = Device::string_from_type(types[i]);
		PyTuple_SetItem(ret, i, PyUnicode_FromString(name.c_str()));
	}

	return ret;
}

static PyObject *with_osl_func(PyObject *self, PyObject *args)
{
#ifdef WITH_OSL
	PyObject *ret = Py_True;
#else
	PyObject *ret = Py_False;
#endif

	return Py_INCREF(ret), ret;
}

static PyMethodDef methods[] = {
	{"init", init_func, METH_VARARGS, ""},
	{"create", create_func, METH_VARARGS, ""},
	{"free", free_func, METH_VARARGS, ""},
	{"render", render_func, METH_VARARGS, ""},
	{"draw", draw_func, METH_VARARGS, ""},
	{"sync", sync_func, METH_VARARGS, ""},
	{"available_devices", available_devices_func, METH_NOARGS, ""},
	{"with_osl", with_osl_func, METH_NOARGS, ""},
	{NULL, NULL},
};

static struct PyModuleDef module = {
	PyModuleDef_HEAD_INIT,
	"libcycles_blender",
	"Blender RNA to render exporter",
	-1,
	methods
};

CCL_NAMESPACE_END

PyMODINIT_FUNC PyInit_libcycles_blender()
{
	return PyModule_Create(&ccl::module);
}

<commit_msg>Cycles: compile warning fixes.<commit_after>/*
 * Copyright 2011, Blender Foundation.
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <Python.h>

#include "blender_sync.h"
#include "blender_session.h"

#include "util_opengl.h"
#include "util_path.h"

CCL_NAMESPACE_BEGIN

static PyObject *init_func(PyObject *self, PyObject *args)
{
	const char *path;

	if(!PyArg_ParseTuple(args, "s", &path))
		return NULL;

	path_init(path);

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *create_func(PyObject *self, PyObject *args)
{
	PyObject *pyengine, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;

	if(!PyArg_ParseTuple(args, "OOOOOO", &pyengine, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d))
		return NULL;

	/* RNA */
	PointerRNA engineptr;
	RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
	BL::RenderEngine engine(engineptr);

	PointerRNA dataptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
	BL::BlendData data(dataptr);

	PointerRNA sceneptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
	BL::Scene scene(sceneptr);

	PointerRNA regionptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyregion), &regionptr);
	BL::Region region(regionptr);

	PointerRNA v3dptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyv3d), &v3dptr);
	BL::SpaceView3D v3d(v3dptr);

	PointerRNA rv3dptr;
	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyrv3d), &rv3dptr);
	BL::RegionView3D rv3d(rv3dptr);

	/* create session */
	BlenderSession *session;

	if(rv3d) {
		/* interactive session */
		int width = region.width();
		int height = region.height();

		session = new BlenderSession(engine, data, scene, v3d, rv3d, width, height);
	}
	else {
		/* offline session */
		session = new BlenderSession(engine, data, scene);
	}

	return PyLong_FromVoidPtr(session);
}

static PyObject *free_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	delete (BlenderSession*)PyLong_AsVoidPtr(pysession);

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *render_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	Py_BEGIN_ALLOW_THREADS

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
	session->render();

	Py_END_ALLOW_THREADS

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *draw_func(PyObject *self, PyObject *args)
{
	PyObject *pysession, *pyv3d, *pyrv3d;

	if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
		return NULL;

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);

	bool draw_text = false;

	if(PyLong_AsVoidPtr(pyrv3d)) {
		/* 3d view drawing */
		int viewport[4];
		glGetIntegerv(GL_VIEWPORT, viewport);

		draw_text = session->draw(viewport[2], viewport[3]);
	}
	else {
		/* image editor drawing */
		draw_text = session->draw();
	}

	/* draw */
	PyObject *ret = PyTuple_New(2);

	if(!draw_text) {
		PyTuple_SetItem(ret, 0, PyUnicode_FromString(""));
		PyTuple_SetItem(ret, 1, PyUnicode_FromString(""));
	}
	else {
		string status, substatus;

		session->get_status(status, substatus);

		PyTuple_SetItem(ret, 0, PyUnicode_FromString(status.c_str()));
		PyTuple_SetItem(ret, 1, PyUnicode_FromString(substatus.c_str()));
	}

	return ret;
}

static PyObject *sync_func(PyObject *self, PyObject *args)
{
	PyObject *pysession;

	if(!PyArg_ParseTuple(args, "O", &pysession))
		return NULL;

	BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
	session->synchronize();

	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *available_devices_func(PyObject *self, PyObject *args)
{
	vector<DeviceType> types = Device::available_types();

	PyObject *ret = PyTuple_New(types.size());

	for(size_t i = 0; i < types.size(); i++) {
		string name = Device::string_from_type(types[i]);
		PyTuple_SetItem(ret, i, PyUnicode_FromString(name.c_str()));
	}

	return ret;
}

static PyObject *with_osl_func(PyObject *self, PyObject *args)
{
#ifdef WITH_OSL
	PyObject *ret = Py_True;
#else
	PyObject *ret = Py_False;
#endif

	return Py_INCREF(ret), ret;
}

static PyMethodDef methods[] = {
	{"init", init_func, METH_VARARGS, ""},
	{"create", create_func, METH_VARARGS, ""},
	{"free", free_func, METH_VARARGS, ""},
	{"render", render_func, METH_VARARGS, ""},
	{"draw", draw_func, METH_VARARGS, ""},
	{"sync", sync_func, METH_VARARGS, ""},
	{"available_devices", available_devices_func, METH_NOARGS, ""},
	{"with_osl", with_osl_func, METH_NOARGS, ""},
	{NULL, NULL, 0, NULL},
};

static struct PyModuleDef module = {
	PyModuleDef_HEAD_INIT,
	"libcycles_blender",
	"Blender RNA to render exporter",
	-1,
	methods,
	NULL, NULL, NULL, NULL
};

CCL_NAMESPACE_END

PyMODINIT_FUNC PyInit_libcycles_blender()
{
	return PyModule_Create(&ccl::module);
}

<|endoftext|>


<commit_before>#include <iostream>

#include <Poco/Version.h>
#include <Poco/Logger.h>
#include <Poco/String.h>
#include <Poco/Message.h>
#include <Poco/Environment.h>
#include <Poco/Exception.h>
#include <Poco/StringTokenizer.h>
#include <Poco/Util/Option.h>
#include <Poco/Util/HelpFormatter.h>

#include "util/Startup.h"

using namespace std;
using namespace Poco;
using namespace Poco::Util;
using namespace BeeeOn;

static Option optConfig("config", "c",
		"general configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optServices("services", "s",
		"services configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optLogging("logging", "l",
		"logging configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optLogLevel("log-level", "L",
		"change startup log-level (trace, debug, [info],"
		" notice, warn, error, fatal, trace)",
		false,
		"<level>",
		true);
static Option optPort("port", "p",
		"server port to listen on",
		false,
		"<port>",
		true);
static Option optDefine("define", "D",
		"define configuration options (to override configuration files)",
		false,
		"<key>=<value>",
		true);
static Option optHelp("help", "h", "print help");

int ServerStartup::parseLogLevel(const string &level)
{
	if (icompare(level, "info") == 0)
		return Message::PRIO_INFORMATION;
	if (icompare(level, "warn") == 0)
		return Message::PRIO_WARNING;
	if (icompare(level, "err") == 0)
		return Message::PRIO_ERROR;
	if (icompare(level, "crit") == 0)
		return Message::PRIO_CRITICAL;

	return Logger::parseLevel(level);
}

void ServerStartup::overrideConfig(const string text)
{
	StringTokenizer tokenizer(text, "=", StringTokenizer::TOK_TRIM);
	if (tokenizer.count() != 2)
		throw InvalidArgumentException("-D option requires a <key>=<value> pair");

	logger().debug("overriding " + tokenizer[0] + " = " + tokenizer[1],
			__FILE__, __LINE__);
	config().setString(tokenizer[0], tokenizer[1]);
}

void ServerStartup::handleOption(const string &name, const string &value)
{
	if (name == "services")
		m_userServices = value;
	if (name == "logging")
		m_userLogging = value;
	if (name == "config")
		m_userConfig = value;
	if (name == "help")
		m_printHelp = true;
	if (name == "log-level")
		logger().setLevel(parseLogLevel(value));
	if (name == "port")
		m_serverPort = stoi(value);
	if (name == "define")
		overrideConfig(value);

	if (m_printHelp)
		stopOptionsProcessing();

	Application::handleOption(name, value);
}

void ServerStartup::loadAllConfiguration()
{
	findAndLoadConfig();
	findAndLoadLogging();
	findAndLoadServices();
}

string ServerStartup::parentPath(const File &file)
{
	Path path(file.path());
	return path.parent().toString();
}

bool ServerStartup::readConfiguration(const File &file)
{
	if (!file.exists()) {
		logger().debug("configuration file "
				+ file.path() + " not found");
		return false;
	}

	loadConfiguration(file.path());
	logger().notice("configuration file "
			+ file.path() + " loaded");
	return true;
}

void ServerStartup::findAndLoadConfig()
{
	File user(m_userConfig);
	File system(defaultConfigFile());

	config().setString("config.dir",
		config().getString("application.dir"));

	if (!m_userConfig.empty() && readConfiguration(user))
		config().setString("config.dir", parentPath(user));
	else if (readConfiguration(system))
		config().setString("config.dir", parentPath(system));
	else
		logger().warning("no main configration found");
}

void ServerStartup::findAndLoadLogging()
{
	File user(m_userLogging);
	File system(config().getString(
			"ui.config.logging", defaultLoggingFile()));

	if (!m_userLogging.empty() && readConfiguration(user))
		return;
	else if (!readConfiguration(system.path()))
		logger().warning("no logging configuration found");
}

void ServerStartup::findAndLoadServices()
{
	File user(m_userServices);
	File system(config().getString(
			"ui.config.services", defaultServicesFile()));

	if (!m_userServices.empty() && readConfiguration(user))
		return;
	else if (!readConfiguration(system))
		logger().warning("no services configuration found");
}

void ServerStartup::initialize(Application &app)
{
	if (m_printHelp)
		return;

	loadAllConfiguration();
	Application::initialize(app);
}

void ServerStartup::defineOptions(OptionSet &options)
{
	options.addOption(optConfig);
	options.addOption(optServices);
	options.addOption(optLogging);
	options.addOption(optLogLevel);
	options.addOption(optPort);
	optDefine.repeatable(true);
	options.addOption(optDefine);
	options.addOption(optHelp);
	Application::defineOptions(options);
}

int ServerStartup::printHelp()
{
	HelpFormatter help(options());
	help.setCommand(config().getString("application.baseName"));
	help.setUnixStyle(true);
	help.setWidth(80);
	help.setUsage("[-h] ...");
	help.format(cout);

	return 0;
}

string ServerStartup::defaultLoggingFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/logging.ini";
}

string ServerStartup::defaultConfigFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/server.ini";
}

string ServerStartup::defaultServicesFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/services.xml";
}

static string pocoVersion(unsigned long version = 0)
{
	version = version == 0? Environment::libraryVersion() : version;

	unsigned int major = (version >> 24) & 0xff;
	unsigned int minor = (version >> 16) & 0xff;
	unsigned int alpha = (version >>  8) & 0xff;
	unsigned int  beta = (version >>  0) & 0xff;

	return to_string(major) + "." + to_string(minor) + "." + to_string(alpha) + "-" + to_string(beta);
}

static string pocoLinkedVersion(void)
{
	return pocoVersion(POCO_VERSION);
}

int ServerStartup::main(const vector<string> &args)
{
	logger().notice("Poco library " + pocoVersion() + " (headers " + pocoLinkedVersion() + ")");

	logger().notice("OS " + Environment::osDisplayName()
		+ " (" + Environment::osName() + " " + Environment::osVersion() + ")");
	logger().notice("Machine " + Environment::osArchitecture() + " (cores: " + to_string(Environment::processorCount()) + ")");
	logger().debug("Node " +  Environment::nodeName() + " (" + Environment::nodeId() + ")");

	if (m_printHelp)
		return printHelp();

	return execute();
}

int BeeeOn::generic_main(int argc, char **argv, ServerApplication &app)
{
	try {
		poco_throw_on_signal;

		app.setUnixOptions(true);
		return app.run(argc, argv);
	} catch(Exception &e) {
		cerr << e.displayText() << endl;
	} catch(exception &e) {
		cerr << e.what() << endl;
	} catch(const char *s) {
		cerr << s << endl;
	}

	return -1;
}
<commit_msg>Startup: warn about Poco library older then recommended<commit_after>#include <iostream>

#include <Poco/Version.h>
#include <Poco/Logger.h>
#include <Poco/String.h>
#include <Poco/Message.h>
#include <Poco/Environment.h>
#include <Poco/Exception.h>
#include <Poco/StringTokenizer.h>
#include <Poco/Util/Option.h>
#include <Poco/Util/HelpFormatter.h>

#include "util/Startup.h"
#include "util/PocoVersion.h"

using namespace std;
using namespace Poco;
using namespace Poco::Util;
using namespace BeeeOn;

static Option optConfig("config", "c",
		"general configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optServices("services", "s",
		"services configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optLogging("logging", "l",
		"logging configuration file to be used (xml, ini, properties)",
		false,
		"<file>",
		true);
static Option optLogLevel("log-level", "L",
		"change startup log-level (trace, debug, [info],"
		" notice, warn, error, fatal, trace)",
		false,
		"<level>",
		true);
static Option optPort("port", "p",
		"server port to listen on",
		false,
		"<port>",
		true);
static Option optDefine("define", "D",
		"define configuration options (to override configuration files)",
		false,
		"<key>=<value>",
		true);
static Option optHelp("help", "h", "print help");

int ServerStartup::parseLogLevel(const string &level)
{
	if (icompare(level, "info") == 0)
		return Message::PRIO_INFORMATION;
	if (icompare(level, "warn") == 0)
		return Message::PRIO_WARNING;
	if (icompare(level, "err") == 0)
		return Message::PRIO_ERROR;
	if (icompare(level, "crit") == 0)
		return Message::PRIO_CRITICAL;

	return Logger::parseLevel(level);
}

void ServerStartup::overrideConfig(const string text)
{
	StringTokenizer tokenizer(text, "=", StringTokenizer::TOK_TRIM);
	if (tokenizer.count() != 2)
		throw InvalidArgumentException("-D option requires a <key>=<value> pair");

	logger().debug("overriding " + tokenizer[0] + " = " + tokenizer[1],
			__FILE__, __LINE__);
	config().setString(tokenizer[0], tokenizer[1]);
}

void ServerStartup::handleOption(const string &name, const string &value)
{
	if (name == "services")
		m_userServices = value;
	if (name == "logging")
		m_userLogging = value;
	if (name == "config")
		m_userConfig = value;
	if (name == "help")
		m_printHelp = true;
	if (name == "log-level")
		logger().setLevel(parseLogLevel(value));
	if (name == "port")
		m_serverPort = stoi(value);
	if (name == "define")
		overrideConfig(value);

	if (m_printHelp)
		stopOptionsProcessing();

	Application::handleOption(name, value);
}

void ServerStartup::loadAllConfiguration()
{
	findAndLoadConfig();
	findAndLoadLogging();
	findAndLoadServices();
}

string ServerStartup::parentPath(const File &file)
{
	Path path(file.path());
	return path.parent().toString();
}

bool ServerStartup::readConfiguration(const File &file)
{
	if (!file.exists()) {
		logger().debug("configuration file "
				+ file.path() + " not found");
		return false;
	}

	loadConfiguration(file.path());
	logger().notice("configuration file "
			+ file.path() + " loaded");
	return true;
}

void ServerStartup::findAndLoadConfig()
{
	File user(m_userConfig);
	File system(defaultConfigFile());

	config().setString("config.dir",
		config().getString("application.dir"));

	if (!m_userConfig.empty() && readConfiguration(user))
		config().setString("config.dir", parentPath(user));
	else if (readConfiguration(system))
		config().setString("config.dir", parentPath(system));
	else
		logger().warning("no main configration found");
}

void ServerStartup::findAndLoadLogging()
{
	File user(m_userLogging);
	File system(config().getString(
			"ui.config.logging", defaultLoggingFile()));

	if (!m_userLogging.empty() && readConfiguration(user))
		return;
	else if (!readConfiguration(system.path()))
		logger().warning("no logging configuration found");
}

void ServerStartup::findAndLoadServices()
{
	File user(m_userServices);
	File system(config().getString(
			"ui.config.services", defaultServicesFile()));

	if (!m_userServices.empty() && readConfiguration(user))
		return;
	else if (!readConfiguration(system))
		logger().warning("no services configuration found");
}

void ServerStartup::initialize(Application &app)
{
	if (m_printHelp)
		return;

	loadAllConfiguration();
	Application::initialize(app);
}

void ServerStartup::defineOptions(OptionSet &options)
{
	options.addOption(optConfig);
	options.addOption(optServices);
	options.addOption(optLogging);
	options.addOption(optLogLevel);
	options.addOption(optPort);
	optDefine.repeatable(true);
	options.addOption(optDefine);
	options.addOption(optHelp);
	Application::defineOptions(options);
}

int ServerStartup::printHelp()
{
	HelpFormatter help(options());
	help.setCommand(config().getString("application.baseName"));
	help.setUnixStyle(true);
	help.setWidth(80);
	help.setUsage("[-h] ...");
	help.format(cout);

	return 0;
}

string ServerStartup::defaultLoggingFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/logging.ini";
}

string ServerStartup::defaultConfigFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/server.ini";
}

string ServerStartup::defaultServicesFile() const
{
	string path("/etc");
	return path + "/" + m_appGroup + "/" + m_appName + "/services.xml";
}

static string pocoVersion(unsigned long version = 0)
{
	version = version == 0? Environment::libraryVersion() : version;

	unsigned int major = (version >> 24) & 0xff;
	unsigned int minor = (version >> 16) & 0xff;
	unsigned int alpha = (version >>  8) & 0xff;
	unsigned int  beta = (version >>  0) & 0xff;

	return to_string(major) + "." + to_string(minor) + "." + to_string(alpha) + "-" + to_string(beta);
}

static string pocoLinkedVersion(void)
{
	return pocoVersion(POCO_VERSION);
}

static void warnAboutPocoVersion(Logger &logger)
{
	bool upgrade = false;

	if (Environment::libraryVersion() > POCO_VERSION)
		logger.warning("runtime Poco library is newer than built-in headers", __FILE__, __LINE__);

	if (POCO_VERSION < RECOMMENDED_POCO_VERSION) {
		logger.warning("Poco library headers are older then recommended",
				__FILE__, __LINE__);
		upgrade = true;
	}

	if (Environment::libraryVersion() < RECOMMENDED_POCO_VERSION) {
		logger.warning("runtime Poco library is older then recommended",
				__FILE__, __LINE__);
		upgrade = true;
	}

	if (upgrade) {
		logger.warning("recommended to upgrade to Poco library "
				+ pocoVersion(RECOMMENDED_POCO_VERSION) + " or newer",
				__FILE__, __LINE__);
	}
}

int ServerStartup::main(const vector<string> &args)
{
	logger().notice("Poco library " + pocoVersion() + " (headers " + pocoLinkedVersion() + ")");
	warnAboutPocoVersion(logger());

	logger().notice("OS " + Environment::osDisplayName()
		+ " (" + Environment::osName() + " " + Environment::osVersion() + ")");
	logger().notice("Machine " + Environment::osArchitecture() + " (cores: " + to_string(Environment::processorCount()) + ")");
	logger().debug("Node " +  Environment::nodeName() + " (" + Environment::nodeId() + ")");

	if (m_printHelp)
		return printHelp();

	return execute();
}

int BeeeOn::generic_main(int argc, char **argv, ServerApplication &app)
{
	try {
		poco_throw_on_signal;

		app.setUnixOptions(true);
		return app.run(argc, argv);
	} catch(Exception &e) {
		cerr << e.displayText() << endl;
	} catch(exception &e) {
		cerr << e.what() << endl;
	} catch(const char *s) {
		cerr << s << endl;
	}

	return -1;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
// autogenerated file with codegen.pl

#include <testshl/simpleheader.hxx>
#include <rtl/locale.hxx>
#include <osl/thread.h>

namespace rtl_locale
{
    // default locale for test purpose
    void setDefaultLocale()
    {
        rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE")), /* rtl::OUString() */ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch")) );
    }

class getDefault : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getDefault_000()
    {
        // this is demonstration code
        // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);

        // due to the fact, we set the default locale at first, this test is no longer possible
       // ::rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        // CPPUNIT_ASSERT_MESSAGE("locale must be null", aLocale.getData() == NULL);

    }

    void getDefault_001()
    {
        // rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE")), rtl::OUString());
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        CPPUNIT_ASSERT_MESSAGE("locale must not null", aLocale.getData() != NULL);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getDefault);
    CPPUNIT_TEST(getDefault_000);
    CPPUNIT_TEST(getDefault_001);
    CPPUNIT_TEST_SUITE_END();
}; // class getDefault

class setDefault : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
        setDefaultLocale();
    }

    // insert your test code here.
    void setDefault_001()
    {
        rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        CPPUNIT_ASSERT_MESSAGE("locale must not null", aLocale.getData() != NULL);

        // be sure to not GPF
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(setDefault);
    CPPUNIT_TEST(setDefault_001);
    CPPUNIT_TEST_SUITE_END();
}; // class setDefault

class getLanguage : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getLanguage_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suLanguage = aLocale.getLanguage();
        t_print("Language: %s\n", rtl::OUStringToOString(suLanguage, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale language must be 'de'", suLanguage.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de"))));
    }
    void getLanguage_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suLanguage = rtl_locale_getLanguage(aLocale.getData());
        t_print("Language: %s\n", rtl::OUStringToOString(suLanguage, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale language must be 'de'", suLanguage.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getLanguage);
    CPPUNIT_TEST(getLanguage_001);
    CPPUNIT_TEST(getLanguage_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getLanguage

class getCountry : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getCountry_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suCountry = aLocale.getCountry();
        t_print("Country: %s\n", rtl::OUStringToOString(suCountry, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale country must be 'DE'", suCountry.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE"))));
    }
    void getCountry_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suCountry = rtl_locale_getCountry(aLocale.getData());
        t_print("Country: %s\n", rtl::OUStringToOString(suCountry, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale country must be 'DE'", suCountry.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getCountry);
    CPPUNIT_TEST(getCountry_001);
    CPPUNIT_TEST(getCountry_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getCountry

class getVariant : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getVariant_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suVariant = aLocale.getVariant();
        t_print("Variant: %s\n", rtl::OUStringToOString(suVariant, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale variant must be 'hochdeutsch'", suVariant.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch"))));
    }
    void getVariant_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suVariant = rtl_locale_getVariant(aLocale.getData());
        t_print("Variant: %s\n", rtl::OUStringToOString(suVariant, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale variant must be 'hochdeutsch'", suVariant.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getVariant);
    CPPUNIT_TEST(getVariant_001);
    CPPUNIT_TEST(getVariant_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getVariant

class hashCode : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void hashCode_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        sal_Int32 nHashCode = aLocale.hashCode();
        t_print("Hashcode: %d\n", nHashCode);
        CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
    }
    void hashCode_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        sal_Int32 nHashCode = rtl_locale_hashCode(aLocale.getData());
        t_print("Hashcode: %d\n", nHashCode);
        CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(hashCode);
    CPPUNIT_TEST(hashCode_001);
    CPPUNIT_TEST(hashCode_002);
    CPPUNIT_TEST_SUITE_END();
}; // class hashCode

class equals : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void equals_001()
    {
        rtl::OLocale aLocale1 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
        rtl::OLocale aLocale2 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")));

        sal_Bool bLocaleAreEqual = sal_False;
        bLocaleAreEqual = (aLocale1 == aLocale2);

        CPPUNIT_ASSERT_MESSAGE("check operator ==()", bLocaleAreEqual == sal_True);
    }

    void equals_002()
    {
        rtl::OLocale aLocale1 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
        rtl::OLocale aLocale2 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")));

        sal_Int32 nEqual = rtl_locale_equals(aLocale1.getData(), aLocale2.getData());
        t_print("rtl_locale_equals() result: %d\n", nEqual);
        CPPUNIT_ASSERT(nEqual != 0);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(equals);
    CPPUNIT_TEST(equals_001);
    CPPUNIT_TEST(equals_002);
    CPPUNIT_TEST_SUITE_END();
}; // class equals

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::getDefault, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::setDefault, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::getLanguage, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::getCountry, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::getVariant, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::hashCode, "rtl_locale");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_locale::equals, "rtl_locale");
} // namespace rtl_locale

// -----------------------------------------------------------------------------

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.
// NOADDITIONAL;

void RegisterAdditionalFunctions(FktRegFuncPtr)
{
    // start message
    t_print("Initializing ...\n" );
    rtl_locale::setDefaultLocale();
    t_print("Initialization Done.\n" );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Make the qa/rtl/rtl_locale test compile again.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
// autogenerated file with codegen.pl

#include <osl/thread.h>
#include <rtl/locale.hxx>

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

namespace rtl_locale
{
    // default locale for test purpose
    void setDefaultLocale()
    {
        rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE")), /* rtl::OUString() */ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch")) );
    }

class getDefault : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getDefault_000()
    {
        // this is demonstration code
        // CPPUNIT_ASSERT_MESSAGE("a message", 1 == 1);

        // due to the fact, we set the default locale at first, this test is no longer possible
       // ::rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        // CPPUNIT_ASSERT_MESSAGE("locale must be null", aLocale.getData() == NULL);

    }

    void getDefault_001()
    {
        // rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE")), rtl::OUString());
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        CPPUNIT_ASSERT_MESSAGE("locale must not null", aLocale.getData() != NULL);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getDefault);
    CPPUNIT_TEST(getDefault_000);
    CPPUNIT_TEST(getDefault_001);
    CPPUNIT_TEST_SUITE_END();
}; // class getDefault

class setDefault : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
        setDefaultLocale();
    }

    // insert your test code here.
    void setDefault_001()
    {
        rtl::OLocale::setDefault(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        CPPUNIT_ASSERT_MESSAGE("locale must not null", aLocale.getData() != NULL);

        // be sure to not GPF
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(setDefault);
    CPPUNIT_TEST(setDefault_001);
    CPPUNIT_TEST_SUITE_END();
}; // class setDefault

class getLanguage : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getLanguage_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suLanguage = aLocale.getLanguage();
        printf("Language: %s\n", rtl::OUStringToOString(suLanguage, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale language must be 'de'", suLanguage.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de"))));
    }
    void getLanguage_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suLanguage = rtl_locale_getLanguage(aLocale.getData());
        printf("Language: %s\n", rtl::OUStringToOString(suLanguage, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale language must be 'de'", suLanguage.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("de"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getLanguage);
    CPPUNIT_TEST(getLanguage_001);
    CPPUNIT_TEST(getLanguage_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getLanguage

class getCountry : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getCountry_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suCountry = aLocale.getCountry();
        printf("Country: %s\n", rtl::OUStringToOString(suCountry, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale country must be 'DE'", suCountry.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE"))));
    }
    void getCountry_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suCountry = rtl_locale_getCountry(aLocale.getData());
        printf("Country: %s\n", rtl::OUStringToOString(suCountry, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale country must be 'DE'", suCountry.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DE"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getCountry);
    CPPUNIT_TEST(getCountry_001);
    CPPUNIT_TEST(getCountry_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getCountry

class getVariant : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void getVariant_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suVariant = aLocale.getVariant();
        printf("Variant: %s\n", rtl::OUStringToOString(suVariant, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale variant must be 'hochdeutsch'", suVariant.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch"))));
    }
    void getVariant_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        rtl::OUString suVariant = rtl_locale_getVariant(aLocale.getData());
        printf("Variant: %s\n", rtl::OUStringToOString(suVariant, osl_getThreadTextEncoding()).getStr());
        CPPUNIT_ASSERT_MESSAGE("locale variant must be 'hochdeutsch'", suVariant.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hochdeutsch"))));
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(getVariant);
    CPPUNIT_TEST(getVariant_001);
    CPPUNIT_TEST(getVariant_002);
    CPPUNIT_TEST_SUITE_END();
}; // class getVariant

class hashCode : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void hashCode_001()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        sal_Int32 nHashCode = aLocale.hashCode();
        printf("Hashcode: %d\n", nHashCode);
        CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
    }
    void hashCode_002()
    {
       rtl::OLocale aLocale = ::rtl::OLocale::getDefault();
        sal_Int32 nHashCode = rtl_locale_hashCode(aLocale.getData());
        printf("Hashcode: %d\n", nHashCode);
        CPPUNIT_ASSERT_MESSAGE("locale hashcode must be 3831", nHashCode != 0);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(hashCode);
    CPPUNIT_TEST(hashCode_001);
    CPPUNIT_TEST(hashCode_002);
    CPPUNIT_TEST_SUITE_END();
}; // class hashCode

class equals : public CppUnit::TestFixture
{
public:
    // initialise your test code values here.
    void setUp()
    {
        // start message
        rtl_locale::setDefaultLocale();
    }

    void tearDown()
    {
    }

    // insert your test code here.
    void equals_001()
    {
        rtl::OLocale aLocale1 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
        rtl::OLocale aLocale2 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")));

        sal_Bool bLocaleAreEqual = sal_False;
        bLocaleAreEqual = (aLocale1 == aLocale2);

        CPPUNIT_ASSERT_MESSAGE("check operator ==()", bLocaleAreEqual == sal_True);
    }

    void equals_002()
    {
        rtl::OLocale aLocale1 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString());
        rtl::OLocale aLocale2 = rtl::OLocale::registerLocale(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")));

        sal_Int32 nEqual = rtl_locale_equals(aLocale1.getData(), aLocale2.getData());
        printf("rtl_locale_equals() result: %d\n", nEqual);
        CPPUNIT_ASSERT(nEqual != 0);
    }

    // Change the following lines only, if you add, remove or rename
    // member functions of the current class,
    // because these macros are need by auto register mechanism.

    CPPUNIT_TEST_SUITE(equals);
    CPPUNIT_TEST(equals_001);
    CPPUNIT_TEST(equals_002);
    CPPUNIT_TEST_SUITE_END();
}; // class equals

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getDefault);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::setDefault);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getLanguage);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getCountry);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::getVariant);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::hashCode);
CPPUNIT_TEST_SUITE_REGISTRATION(rtl_locale::equals);
} // namespace rtl_locale

// -----------------------------------------------------------------------------

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>